diff options
Diffstat (limited to 'drivers/xen/xenbus/xenbus_probe_backend.c')
| -rw-r--r-- | drivers/xen/xenbus/xenbus_probe_backend.c | 38 | 
1 files changed, 38 insertions, 0 deletions
diff --git a/drivers/xen/xenbus/xenbus_probe_backend.c b/drivers/xen/xenbus/xenbus_probe_backend.c index 14876faff3b0..791f6fe01e91 100644 --- a/drivers/xen/xenbus/xenbus_probe_backend.c +++ b/drivers/xen/xenbus/xenbus_probe_backend.c @@ -247,6 +247,41 @@ static int backend_probe_and_watch(struct notifier_block *notifier,  	return NOTIFY_DONE;  } +static int backend_reclaim_memory(struct device *dev, void *data) +{ +	const struct xenbus_driver *drv; +	struct xenbus_device *xdev; + +	if (!dev->driver) +		return 0; +	drv = to_xenbus_driver(dev->driver); +	if (drv && drv->reclaim_memory) { +		xdev = to_xenbus_device(dev); +		if (!spin_trylock(&xdev->reclaim_lock)) +			return 0; +		drv->reclaim_memory(xdev); +		spin_unlock(&xdev->reclaim_lock); +	} +	return 0; +} + +/* + * Returns 0 always because we are using shrinker to only detect memory + * pressure. + */ +static unsigned long backend_shrink_memory_count(struct shrinker *shrinker, +				struct shrink_control *sc) +{ +	bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, +			backend_reclaim_memory); +	return 0; +} + +static struct shrinker backend_memory_shrinker = { +	.count_objects = backend_shrink_memory_count, +	.seeks = DEFAULT_SEEKS, +}; +  static int __init xenbus_probe_backend_init(void)  {  	static struct notifier_block xenstore_notifier = { @@ -263,6 +298,9 @@ static int __init xenbus_probe_backend_init(void)  	register_xenstore_notifier(&xenstore_notifier); +	if (register_shrinker(&backend_memory_shrinker)) +		pr_warn("shrinker registration failed\n"); +  	return 0;  }  subsys_initcall(xenbus_probe_backend_init);  |