* [PATCH v3] mm/slub: fix missing debugfs entries for caches created before sysfs init
@ 2026-07-29 10:18 Li Xiasong
2026-07-29 16:21 ` Vlastimil Babka (SUSE)
2026-07-30 3:55 ` Harry Yoo
0 siblings, 2 replies; 3+ messages in thread
From: Li Xiasong @ 2026-07-29 10:18 UTC (permalink / raw)
To: Vlastimil Babka, Harry Yoo, Andrew Morton
Cc: stable, Hao Li, Christoph Lameter, David Rientjes, Roman Gushchin,
Rasmus Villemoes, linux-mm, linux-kernel, yuehaibing,
zhangchangzhong, weiyongjun1
slab_debugfs_init() creates the slab debugfs root at device initcall
time, while slab_sysfs_init() moves slab_state to FULL at late initcall
time. SLAB_STORE_USER caches created in this window miss their debugfs
entries because do_kmem_cache_create() skips debugfs_slab_add() when
slab_state <= UP. This was observed with MPTCP's request_sock_subflow_v6
cache, whose slab debugfs directory was missing.
The affected window is:
slab_debugfs_init()
slab_debugfs_root = debugfs_create_dir(...)
list_for_each_entry(s, &slab_caches, list)
debugfs_slab_add(s)
kmem_cache_create(..., SLAB_STORE_USER, ...)
do_kmem_cache_create()
if (slab_state <= UP)
return without debugfs entries
slab_sysfs_init()
slab_state = FULL
Initialize the debugfs root and add debugfs entries while holding
slab_mutex, walking slab_caches exactly once and handling both sysfs
and debugfs entries in the same pass. This gives the sysfs and debugfs
initialization an explicit order and prevents caches from being
created between the debugfs scan and slab_state reaching FULL.
Gate the new slab_late_init() on either sysfs or debugfs being enabled,
with the slab_kset creation and alias_list processing factored into
helpers that have empty no-sysfs variants, as suggested by Vlastimil
Babka. On slab_kset_init() failure, slab_state stays below FULL so
kmem_cache_create() keeps taking the early-boot path, matching prior
behavior.
Guard debugfs_slab_release() against an uninitialized debugfs root,
since the root is now created later and a cache may be released before
it exists.
Fixes: 1a5ad30b89b4 ("mm: slub: make slab_sysfs_init() a late_initcall")
Cc: stable@vger.kernel.org
Suggested-by: Vlastimil Babka <vbabka@kernel.org>
Signed-off-by: Li Xiasong <lixiasong1@huawei.com>
---
Changes in v3:
- Introduce a generic slab_late_init() that runs when either sysfs or
SLUB debugfs support is enabled.
- Factor slab_kset initialization and saved alias processing into
sysfs-specific helpers with empty no-sysfs variants.
Changes in v2:
- Move debugfs root and cache entry initialization into
slab_sysfs_init() so both use the same mutex-protected cache walk.
- Guard debugfs_slab_release() against an uninitialized debugfs root.
- Update the commit message accordingly.
v2: https://lore.kernel.org/linux-mm/20260723115532.761920-1-lixiasong1@huawei.com/
v1: https://lore.kernel.org/linux-mm/20260720145124.3684976-1-lixiasong1@huawei.com/
---
mm/slub.c | 76 +++++++++++++++++++++++++++++++++++--------------------
1 file changed, 48 insertions(+), 28 deletions(-)
diff --git a/mm/slub.c b/mm/slub.c
index 0337e60db5ac..4ef84de4f3d7 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -333,14 +333,20 @@ enum track_item { TRACK_ALLOC, TRACK_FREE };
#ifdef SLAB_SUPPORTS_SYSFS
static int sysfs_slab_add(struct kmem_cache *);
+static int __init slab_kset_init(void);
+static void __init slab_sysfs_process_aliases(void);
#else
static inline int sysfs_slab_add(struct kmem_cache *s) { return 0; }
+static inline int slab_kset_init(void) { return 0; }
+static inline void slab_sysfs_process_aliases(void) { }
#endif
#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_SLUB_DEBUG)
static void debugfs_slab_add(struct kmem_cache *);
+static void __init slab_debugfs_root_init(void);
#else
static inline void debugfs_slab_add(struct kmem_cache *s) { }
+static inline void slab_debugfs_root_init(void) { }
#endif
enum add_mode {
@@ -9734,28 +9740,20 @@ int sysfs_slab_alias(struct kmem_cache *s, const char *name)
return 0;
}
-static int __init slab_sysfs_init(void)
+static int __init slab_kset_init(void)
{
- struct kmem_cache *s;
- int err;
-
- mutex_lock(&slab_mutex);
-
slab_kset = kset_create_and_add("slab", NULL, kernel_kobj);
if (!slab_kset) {
- mutex_unlock(&slab_mutex);
pr_err("Cannot register slab subsystem.\n");
return -ENOMEM;
}
- slab_state = FULL;
+ return 0;
+}
- list_for_each_entry(s, &slab_caches, list) {
- err = sysfs_slab_add(s);
- if (err)
- pr_err("SLUB: Unable to add boot slab %s to sysfs\n",
- s->name);
- }
+static void __init slab_sysfs_process_aliases(void)
+{
+ int err;
while (alias_list) {
struct saved_alias *al = alias_list;
@@ -9767,12 +9765,41 @@ static int __init slab_sysfs_init(void)
al->name);
kfree(al);
}
+}
+#endif /* SLAB_SUPPORTS_SYSFS */
+
+#if defined(SLAB_SUPPORTS_SYSFS) || \
+ (defined(CONFIG_SLUB_DEBUG) && defined(CONFIG_DEBUG_FS))
+static int __init slab_late_init(void)
+{
+ struct kmem_cache *s;
+ int err;
+ mutex_lock(&slab_mutex);
+
+ err = slab_kset_init();
+ if (err)
+ goto out;
+
+ slab_debugfs_root_init();
+ slab_state = FULL;
+
+ list_for_each_entry(s, &slab_caches, list) {
+ if (sysfs_slab_add(s))
+ pr_err("SLUB: Unable to add boot slab %s to sysfs\n",
+ s->name);
+
+ if (s->flags & SLAB_STORE_USER)
+ debugfs_slab_add(s);
+ }
+
+ slab_sysfs_process_aliases();
+out:
mutex_unlock(&slab_mutex);
- return 0;
+ return err;
}
-late_initcall(slab_sysfs_init);
-#endif /* SLAB_SUPPORTS_SYSFS */
+late_initcall(slab_late_init);
+#endif
#if defined(CONFIG_SLUB_DEBUG) && defined(CONFIG_DEBUG_FS)
static int slab_debugfs_show(struct seq_file *seq, void *v)
@@ -9964,23 +9991,16 @@ static void debugfs_slab_add(struct kmem_cache *s)
void debugfs_slab_release(struct kmem_cache *s)
{
+ if (unlikely(!slab_debugfs_root))
+ return;
+
debugfs_lookup_and_remove(s->name, slab_debugfs_root);
}
-static int __init slab_debugfs_init(void)
+static void __init slab_debugfs_root_init(void)
{
- struct kmem_cache *s;
-
slab_debugfs_root = debugfs_create_dir("slab", NULL);
-
- list_for_each_entry(s, &slab_caches, list)
- if (s->flags & SLAB_STORE_USER)
- debugfs_slab_add(s);
-
- return 0;
-
}
-__initcall(slab_debugfs_init);
#endif
/*
* The /proc/slabinfo ABI
--
2.34.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH v3] mm/slub: fix missing debugfs entries for caches created before sysfs init
2026-07-29 10:18 [PATCH v3] mm/slub: fix missing debugfs entries for caches created before sysfs init Li Xiasong
@ 2026-07-29 16:21 ` Vlastimil Babka (SUSE)
2026-07-30 3:55 ` Harry Yoo
1 sibling, 0 replies; 3+ messages in thread
From: Vlastimil Babka (SUSE) @ 2026-07-29 16:21 UTC (permalink / raw)
To: Li Xiasong, Harry Yoo, Andrew Morton
Cc: stable, Hao Li, Christoph Lameter, David Rientjes, Roman Gushchin,
Rasmus Villemoes, linux-mm, linux-kernel, yuehaibing,
zhangchangzhong, weiyongjun1
On 7/29/26 12:18, Li Xiasong wrote:
> slab_debugfs_init() creates the slab debugfs root at device initcall
> time, while slab_sysfs_init() moves slab_state to FULL at late initcall
> time. SLAB_STORE_USER caches created in this window miss their debugfs
> entries because do_kmem_cache_create() skips debugfs_slab_add() when
> slab_state <= UP. This was observed with MPTCP's request_sock_subflow_v6
> cache, whose slab debugfs directory was missing.
>
> The affected window is:
>
> slab_debugfs_init()
> slab_debugfs_root = debugfs_create_dir(...)
> list_for_each_entry(s, &slab_caches, list)
> debugfs_slab_add(s)
>
> kmem_cache_create(..., SLAB_STORE_USER, ...)
> do_kmem_cache_create()
> if (slab_state <= UP)
> return without debugfs entries
>
> slab_sysfs_init()
> slab_state = FULL
>
> Initialize the debugfs root and add debugfs entries while holding
> slab_mutex, walking slab_caches exactly once and handling both sysfs
> and debugfs entries in the same pass. This gives the sysfs and debugfs
> initialization an explicit order and prevents caches from being
> created between the debugfs scan and slab_state reaching FULL.
>
> Gate the new slab_late_init() on either sysfs or debugfs being enabled,
> with the slab_kset creation and alias_list processing factored into
> helpers that have empty no-sysfs variants, as suggested by Vlastimil
> Babka. On slab_kset_init() failure, slab_state stays below FULL so
> kmem_cache_create() keeps taking the early-boot path, matching prior
> behavior.
>
> Guard debugfs_slab_release() against an uninitialized debugfs root,
> since the root is now created later and a cache may be released before
> it exists.
>
> Fixes: 1a5ad30b89b4 ("mm: slub: make slab_sysfs_init() a late_initcall")
> Cc: stable@vger.kernel.org
> Suggested-by: Vlastimil Babka <vbabka@kernel.org>
> Signed-off-by: Li Xiasong <lixiasong1@huawei.com>
Added to slab/for-next, thanks!
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH v3] mm/slub: fix missing debugfs entries for caches created before sysfs init
2026-07-29 10:18 [PATCH v3] mm/slub: fix missing debugfs entries for caches created before sysfs init Li Xiasong
2026-07-29 16:21 ` Vlastimil Babka (SUSE)
@ 2026-07-30 3:55 ` Harry Yoo
1 sibling, 0 replies; 3+ messages in thread
From: Harry Yoo @ 2026-07-30 3:55 UTC (permalink / raw)
To: Li Xiasong, Vlastimil Babka, Andrew Morton
Cc: stable, Hao Li, Christoph Lameter, David Rientjes, Roman Gushchin,
Rasmus Villemoes, linux-mm, linux-kernel, yuehaibing,
zhangchangzhong, weiyongjun1
[-- Attachment #1.1: Type: text/plain, Size: 2105 bytes --]
On 7/29/26 7:18 PM, Li Xiasong wrote:
> slab_debugfs_init() creates the slab debugfs root at device initcall
> time, while slab_sysfs_init() moves slab_state to FULL at late initcall
> time. SLAB_STORE_USER caches created in this window miss their debugfs
> entries because do_kmem_cache_create() skips debugfs_slab_add() when
> slab_state <= UP. This was observed with MPTCP's request_sock_subflow_v6
> cache, whose slab debugfs directory was missing.
Ouch, good catch!
> The affected window is:
>
> slab_debugfs_init()
> slab_debugfs_root = debugfs_create_dir(...)
> list_for_each_entry(s, &slab_caches, list)
> debugfs_slab_add(s)
>
> kmem_cache_create(..., SLAB_STORE_USER, ...)
> do_kmem_cache_create()
> if (slab_state <= UP)
> return without debugfs entries
>
> slab_sysfs_init()
> slab_state = FULL
>
> Initialize the debugfs root and add debugfs entries while holding
> slab_mutex, walking slab_caches exactly once and handling both sysfs
> and debugfs entries in the same pass. This gives the sysfs and debugfs
> initialization an explicit order and prevents caches from being
> created between the debugfs scan and slab_state reaching FULL.
>
> Gate the new slab_late_init() on either sysfs or debugfs being enabled,
> with the slab_kset creation and alias_list processing factored into
> helpers that have empty no-sysfs variants, as suggested by Vlastimil
> Babka. On slab_kset_init() failure, slab_state stays below FULL so
> kmem_cache_create() keeps taking the early-boot path, matching prior
> behavior.
>
> Guard debugfs_slab_release() against an uninitialized debugfs root,
> since the root is now created later and a cache may be released before
> it exists.
>
> Fixes: 1a5ad30b89b4 ("mm: slub: make slab_sysfs_init() a late_initcall")
> Cc: stable@vger.kernel.org
> Suggested-by: Vlastimil Babka <vbabka@kernel.org>
> Signed-off-by: Li Xiasong <lixiasong1@huawei.com>
> ---
Looks good to me,
Reviewed-by: Harry Yoo (Oracle) <harry@kernel.org>
--
Cheers,
Harry / Hyeonggon
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-07-30 3:55 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-29 10:18 [PATCH v3] mm/slub: fix missing debugfs entries for caches created before sysfs init Li Xiasong
2026-07-29 16:21 ` Vlastimil Babka (SUSE)
2026-07-30 3:55 ` Harry Yoo
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox