In preparation for implementing lockless slab shrink,
we need to dynamically allocate the vmw-balloon shrinker,
so that it can be freed asynchronously using kfree_rcu().
Then it doesn't need to wait for RCU read-side critical
section when releasing the struct vmballoon.
Signed-off-by: Qi Zheng <[email protected]>
---
drivers/misc/vmw_balloon.c | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/drivers/misc/vmw_balloon.c b/drivers/misc/vmw_balloon.c
index 9ce9b9e0e9b6..2f86f666b476 100644
--- a/drivers/misc/vmw_balloon.c
+++ b/drivers/misc/vmw_balloon.c
@@ -380,7 +380,7 @@ struct vmballoon {
/**
* @shrinker: shrinker interface that is used to avoid over-inflation.
*/
- struct shrinker shrinker;
+ struct shrinker *shrinker;
/**
* @shrinker_registered: whether the shrinker was registered.
@@ -1569,7 +1569,7 @@ static unsigned long vmballoon_shrinker_count(struct shrinker *shrinker,
static void vmballoon_unregister_shrinker(struct vmballoon *b)
{
if (b->shrinker_registered)
- unregister_shrinker(&b->shrinker);
+ unregister_and_free_shrinker(b->shrinker);
b->shrinker_registered = false;
}
@@ -1581,14 +1581,18 @@ static int vmballoon_register_shrinker(struct vmballoon *b)
if (!vmwballoon_shrinker_enable)
return 0;
- b->shrinker.scan_objects = vmballoon_shrinker_scan;
- b->shrinker.count_objects = vmballoon_shrinker_count;
- b->shrinker.seeks = DEFAULT_SEEKS;
+ b->shrinker = shrinker_alloc_and_init(vmballoon_shrinker_count,
+ vmballoon_shrinker_scan,
+ 0, DEFAULT_SEEKS, 0, b);
+ if (!b->shrinker)
+ return -ENOMEM;
- r = register_shrinker(&b->shrinker, "vmw-balloon");
+ r = register_shrinker(b->shrinker, "vmw-balloon");
if (r == 0)
b->shrinker_registered = true;
+ else
+ shrinker_free(b->shrinker);
return r;
}
--
2.30.2