Message ID | 20230824034304.37411-28-zhengqi.arch@bytedance.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | use refcount+RCU method to implement lockless slab shrink | expand |
> On Aug 23, 2023, at 8:42 PM, Qi Zheng <zhengqi.arch@bytedance.com> wrote: > > In preparation for implementing lockless slab shrink, use new APIs to > dynamically allocate the vmw-balloon shrinker, so that it can be freed > asynchronously via RCU. Then it doesn't need to wait for RCU read-side > critical section when releasing the struct vmballoon. > > And we can simply exit vmballoon_init() when registering the shrinker > fails. So the shrinker_registered indication is redundant, just remove it. ... Ugh. We should have already moved to OOM notifier instead... > static void vmballoon_unregister_shrinker(struct vmballoon *b) > { > - if (b->shrinker_registered) > - unregister_shrinker(&b->shrinker); > - b->shrinker_registered = false; > + shrinker_free(b->shrinker); > } If the patch goes through another iteration, please add: b->shrinker = NULL; Not that this is a real issue, but I prefer it so in order to more easily identify UAF if the function is called elsewhere. Otherwise, LGTM. Thanks.
Hi Nadav, On 2023/8/24 23:28, Nadav Amit wrote: > > >> On Aug 23, 2023, at 8:42 PM, Qi Zheng <zhengqi.arch@bytedance.com> wrote: >> >> In preparation for implementing lockless slab shrink, use new APIs to >> dynamically allocate the vmw-balloon shrinker, so that it can be freed >> asynchronously via RCU. Then it doesn't need to wait for RCU read-side >> critical section when releasing the struct vmballoon. >> >> And we can simply exit vmballoon_init() when registering the shrinker >> fails. So the shrinker_registered indication is redundant, just remove it. > > ... > > Ugh. We should have already moved to OOM notifier instead... > >> static void vmballoon_unregister_shrinker(struct vmballoon *b) >> { >> - if (b->shrinker_registered) >> - unregister_shrinker(&b->shrinker); >> - b->shrinker_registered = false; >> + shrinker_free(b->shrinker); >> } > > If the patch goes through another iteration, please add: > > b->shrinker = NULL; > > Not that this is a real issue, but I prefer it so in order to more easily > identify UAF if the function is called elsewhere. OK, will add it. > > Otherwise, LGTM. Thanks. Thanks for your review! Qi >
diff --git a/drivers/misc/vmw_balloon.c b/drivers/misc/vmw_balloon.c index 9ce9b9e0e9b6..ac2cdb6cdf74 100644 --- a/drivers/misc/vmw_balloon.c +++ b/drivers/misc/vmw_balloon.c @@ -380,16 +380,7 @@ struct vmballoon { /** * @shrinker: shrinker interface that is used to avoid over-inflation. */ - struct shrinker shrinker; - - /** - * @shrinker_registered: whether the shrinker was registered. - * - * The shrinker interface does not handle gracefully the removal of - * shrinker that was not registered before. This indication allows to - * simplify the unregistration process. - */ - bool shrinker_registered; + struct shrinker *shrinker; }; static struct vmballoon balloon; @@ -1568,29 +1559,27 @@ 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); - b->shrinker_registered = false; + shrinker_free(b->shrinker); } static int vmballoon_register_shrinker(struct vmballoon *b) { - int r; - /* Do nothing if the shrinker is not enabled */ 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(0, "vmw-balloon"); + if (!b->shrinker) + return -ENOMEM; - r = register_shrinker(&b->shrinker, "vmw-balloon"); + b->shrinker->scan_objects = vmballoon_shrinker_scan; + b->shrinker->count_objects = vmballoon_shrinker_count; + b->shrinker->seeks = DEFAULT_SEEKS; + b->shrinker->private_data = b; - if (r == 0) - b->shrinker_registered = true; + shrinker_register(b->shrinker); - return r; + return 0; } /* @@ -1883,7 +1872,7 @@ static int __init vmballoon_init(void) error = vmballoon_register_shrinker(&balloon); if (error) - goto fail; + return error; /* * Initialization of compaction must be done after the call to @@ -1905,9 +1894,6 @@ static int __init vmballoon_init(void) vmballoon_debugfs_init(&balloon); return 0; -fail: - vmballoon_unregister_shrinker(&balloon); - return error; } /*