linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
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
>>



  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