.. | .. |
---|
45 | 45 | #include <linux/mm.h> |
---|
46 | 46 | #include <linux/notifier.h> |
---|
47 | 47 | #include <linux/export.h> |
---|
| 48 | +#include <linux/semaphore.h> |
---|
48 | 49 | |
---|
49 | 50 | #include <asm/page.h> |
---|
50 | | -#include <asm/pgtable.h> |
---|
51 | 51 | #include <asm/xen/hypervisor.h> |
---|
52 | 52 | #include <asm/hypervisor.h> |
---|
53 | 53 | #include <xen/xenbus.h> |
---|
.. | .. |
---|
205 | 205 | .uevent = xenbus_uevent_backend, |
---|
206 | 206 | .probe = xenbus_dev_probe, |
---|
207 | 207 | .remove = xenbus_dev_remove, |
---|
208 | | - .shutdown = xenbus_dev_shutdown, |
---|
209 | 208 | .dev_groups = xenbus_dev_groups, |
---|
210 | 209 | }, |
---|
211 | 210 | }; |
---|
.. | .. |
---|
255 | 254 | return NOTIFY_DONE; |
---|
256 | 255 | } |
---|
257 | 256 | |
---|
| 257 | +static int backend_reclaim_memory(struct device *dev, void *data) |
---|
| 258 | +{ |
---|
| 259 | + const struct xenbus_driver *drv; |
---|
| 260 | + struct xenbus_device *xdev; |
---|
| 261 | + |
---|
| 262 | + if (!dev->driver) |
---|
| 263 | + return 0; |
---|
| 264 | + drv = to_xenbus_driver(dev->driver); |
---|
| 265 | + if (drv && drv->reclaim_memory) { |
---|
| 266 | + xdev = to_xenbus_device(dev); |
---|
| 267 | + if (down_trylock(&xdev->reclaim_sem)) |
---|
| 268 | + return 0; |
---|
| 269 | + drv->reclaim_memory(xdev); |
---|
| 270 | + up(&xdev->reclaim_sem); |
---|
| 271 | + } |
---|
| 272 | + return 0; |
---|
| 273 | +} |
---|
| 274 | + |
---|
| 275 | +/* |
---|
| 276 | + * Returns 0 always because we are using shrinker to only detect memory |
---|
| 277 | + * pressure. |
---|
| 278 | + */ |
---|
| 279 | +static unsigned long backend_shrink_memory_count(struct shrinker *shrinker, |
---|
| 280 | + struct shrink_control *sc) |
---|
| 281 | +{ |
---|
| 282 | + bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, |
---|
| 283 | + backend_reclaim_memory); |
---|
| 284 | + return 0; |
---|
| 285 | +} |
---|
| 286 | + |
---|
| 287 | +static struct shrinker backend_memory_shrinker = { |
---|
| 288 | + .count_objects = backend_shrink_memory_count, |
---|
| 289 | + .seeks = DEFAULT_SEEKS, |
---|
| 290 | +}; |
---|
| 291 | + |
---|
258 | 292 | static int __init xenbus_probe_backend_init(void) |
---|
259 | 293 | { |
---|
260 | 294 | static struct notifier_block xenstore_notifier = { |
---|
.. | .. |
---|
271 | 305 | |
---|
272 | 306 | register_xenstore_notifier(&xenstore_notifier); |
---|
273 | 307 | |
---|
| 308 | + if (register_shrinker(&backend_memory_shrinker)) |
---|
| 309 | + pr_warn("shrinker registration failed\n"); |
---|
| 310 | + |
---|
274 | 311 | return 0; |
---|
275 | 312 | } |
---|
276 | 313 | subsys_initcall(xenbus_probe_backend_init); |
---|