From: Vlastimil Babka <vbabka@suse.cz>
To: Hyeonggon Yoo <42.hyeyoo@gmail.com>,
Christoph Lameter <cl@linux.com>,
Pekka Enberg <penberg@kernel.org>,
David Rientjes <rientjes@google.com>,
Joonsoo Kim <iamjoonsoo.kim@lge.com>,
Andrew Morton <akpm@linux-foundation.org>,
Roman Gushchin <roman.gushchin@linux.dev>
Cc: linux-mm@kvack.org, Jinjie Ruan <ruanjinjie@huawei.com>,
Liu Shixin <liushixin2@huawei.com>
Subject: Re: [PATCH v1] mm/slab: Allow cache creation to proceed even if sysfs registration fails
Date: Fri, 1 Nov 2024 14:58:26 +0100 [thread overview]
Message-ID: <35f58f1b-6e71-42ce-8619-2ecd810b4510@suse.cz> (raw)
In-Reply-To: <CAB=+i9SonBNVG7OgLme_UWMmYFga+_XbNkEHNkKt0eB_pS=4CA@mail.gmail.com>
On 11/1/24 14:15, Hyeonggon Yoo wrote:
> On Fri, Nov 1, 2024 at 10:08 PM Hyeonggon Yoo <42.hyeyoo@gmail.com> wrote:
>>
>> When kobject_init_and_add() fails during cache creation,
>> kobj->name can be leaked because SLUB does not call kobject_put(),
>> which should be invoked per the kobject API documentation.
>> This has a bit of historical context, though; SLUB does not call
>> kobject_put() to avoid double-free for struct kmem_cache because
>> 1) simply calling it would free all resources related to the cache, and
>> 2) struct kmem_cache descriptor is always freed by cache_cache()'s
>> error handling path, causing struct kmem_cache to be freed twice.
>>
>> This issue can be reproduced by creating new slab caches while applying
>> failslab for kernfs_node_cache. This makes kobject_add_varg() succeed,
>> but causes kobject_add_internal() to fail in kobject_init_and_add()
>> during cache creation.
>>
>> Historically, this issue has attracted developers' attention several times.
>> Each time a fix addressed either the leak or the double-free,
>> it caused the other issue. Let's summarize a bit of history here:
>>
>> The leak has existed since the early days of SLUB.
>>
>> Commit 54b6a731025f ("slub: fix leak of 'name' in sysfs_slab_add")
>> introduced a double-free bug while fixing the leak.
>>
>> Commit 80da026a8e5d ("mm/slub: fix slab double-free in case of duplicate
>> sysfs filename") re-introduced the leak while fixing the double-free
>> error.
>>
>> Commit dde3c6b72a16 ("mm/slub: fix a memory leak in sysfs_slab_add()")
>> fixed the memory leak, but it was later reverted by commit 757fed1d0898
>> ("Revert "mm/slub: fix a memory leak in sysfs_slab_add()"") to avoid
>> the double-free error.
>>
>> This is where we are now: we've chosen a memory leak over a double-free.
>>
>> To resolve this memory leak, skip creating sysfs files if it fails
>> and continue with cache creation regardless (as suggested by Christoph).
>> This resolves the memory leak because both the cache and the kobject
>> remain alive on kobject_init_and_add() failure.
>>
>> If SLUB tries to create an alias for a cache without sysfs files,
>> its symbolic link will not be generated.
>>
>> Since a slab cache might not have associated sysfs files, call kobject_del()
>> only if such files exist.
>>
>> Signed-off-by: Hyeonggon Yoo <42.hyeyoo@gmail.com>
Thanks, added to slab/for-next
>
> [+Cc Jinjie, Liu]
>
>> ---
>>
>> RFC -> v1: Make sysfs optional instead of destroying the cache on sysfs
>> errors. (Suggested by Christoph)
>
> RFC version for reference:
> https://lore.kernel.org/linux-mm/20241021091413.154775-1-42.hyeyoo@gmail.com/
>
>> mm/slub.c | 21 +++++++++++++++++----
>> 1 file changed, 17 insertions(+), 4 deletions(-)
>>
>> diff --git a/mm/slub.c b/mm/slub.c
>> index 151a987dc3a0..b4b211468f77 100644
>> --- a/mm/slub.c
>> +++ b/mm/slub.c
>> @@ -6116,7 +6116,8 @@ __kmem_cache_alias(const char *name, unsigned int size, unsigned int align,
>> s = find_mergeable(size, align, flags, name, ctor);
>> if (s) {
>> if (sysfs_slab_alias(s, name))
>> - return NULL;
>> + pr_err("SLUB: Unable to add slab alias %s to sysfs\n",
I've changed "slab" to "cache".
>> + name);
>>
>> s->refcount++;
>>
>> @@ -6204,9 +6205,15 @@ int do_kmem_cache_create(struct kmem_cache *s, const char *name,
>> goto out;
>> }
>>
>> + /*
>> + * Failing to create sysfs files is not critical to SLUB functionality.
>> + * If it fails, proceed with cache creation without these files.
>> + */
>> err = sysfs_slab_add(s);
>> - if (err)
>> - goto out;
>> + if (err) {
>> + err = 0;
>> + pr_err("SLUB: Unable to add slab %s to sysfs\n", s->name);
Also here, and simplified to "if (sysfs_slab_add(s)) ... " to avoid dealing
with err.
>> + }
>>
>> if (s->flags & SLAB_STORE_USER)
>> debugfs_slab_add(s);
>> @@ -7276,7 +7283,8 @@ static int sysfs_slab_add(struct kmem_cache *s)
>>
>> void sysfs_slab_unlink(struct kmem_cache *s)
>> {
>> - kobject_del(&s->kobj);
>> + if (s->kobj.state_in_sysfs)
>> + kobject_del(&s->kobj);
>> }
>>
>> void sysfs_slab_release(struct kmem_cache *s)
>> @@ -7305,6 +7313,11 @@ static int sysfs_slab_alias(struct kmem_cache *s, const char *name)
>> * If we have a leftover link then remove it.
>> */
>> sysfs_remove_link(&slab_kset->kobj, name);
>> + /*
>> + * The original cache may have failed to generate sysfs file.
>> + * In that case, sysfs_create_link() returns -ENOENT and
>> + * symbolic link creation is skipped.
>> + */
>> return sysfs_create_link(&slab_kset->kobj, &s->kobj, name);
>> }
>>
>> --
>> 2.45.0
>>
next prev parent reply other threads:[~2024-11-01 13:58 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-11-01 13:08 Hyeonggon Yoo
2024-11-01 13:15 ` Hyeonggon Yoo
2024-11-01 13:58 ` Vlastimil Babka [this message]
2024-11-02 7:18 ` Hyeonggon Yoo
2024-11-02 8:53 ` Vlastimil Babka
2024-11-02 10:07 ` Hyeonggon Yoo
2024-11-02 10:16 ` Hyeonggon Yoo
2024-11-02 14:51 ` Hyeonggon Yoo
2024-11-04 9:28 ` Vlastimil Babka
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=35f58f1b-6e71-42ce-8619-2ecd810b4510@suse.cz \
--to=vbabka@suse.cz \
--cc=42.hyeyoo@gmail.com \
--cc=akpm@linux-foundation.org \
--cc=cl@linux.com \
--cc=iamjoonsoo.kim@lge.com \
--cc=linux-mm@kvack.org \
--cc=liushixin2@huawei.com \
--cc=penberg@kernel.org \
--cc=rientjes@google.com \
--cc=roman.gushchin@linux.dev \
--cc=ruanjinjie@huawei.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox