FAILED: patch "[PATCH] mm/slub: fix missing debugfs entries for caches created" failed to apply to 6.12-stable tree
Subsystems (3)
[email protected]
maintainerThe patch below does not apply to the 6.12-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.12.y
git checkout FETCH_HEAD
git cherry-pick -x 7e98f856395618011c517f767fb80ac3fe90de2b
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026090309-stool-flyaway-37a0@gregkh' --subject-prefix 'PATCH 6.12.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 7e98f856395618011c517f767fb80ac3fe90de2b Mon Sep 17 00:00:00 2001
From: Li Xiasong <[email protected]>
Date: Wed, 29 Jul 2026 18:18:49 +0800
Subject: [PATCH] mm/slub: fix missing debugfs entries for caches created
before sysfs init
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.
mm/slub.c +49 -29
@@ -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 {
@@ -9746,28 +9752,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;
@@ -9779,13 +9777,42 @@ static int __init slab_sysfs_init(void) al->name); kfree(al); } - -mutex_unlock (&slab_mutex); -return 0 ; } -late_initcall (slab_sysfs_init);#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 err; +} +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) {
@@ -9976,23 +10003,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
Sasha Levin
maintainerPATCH 1/3 slab: simplify init_kmem_cache_nodes() error handling
From: Vlastimil Babka <[email protected]>
[ Upstream commit 9d4e6ab865c48c70e684b176d3ee1574d092626f ]
We don't need to call free_kmem_cache_nodes() immediately when failing to allocate a kmem_cache_node, because when we return 0, do_kmem_cache_create() calls __kmem_cache_release() which also performs free_kmem_cache_nodes().
Stable-dep-of: 7e98f8563956 ("mm/slub: fix missing debugfs entries for caches created before sysfs init")
--- mm/slub.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
mm/slub.c +1 -3
@@ -5323,10 +5323,8 @@ static int init_kmem_cache_nodes(struct kmem_cache *s) n =kmem_cache_alloc_node (kmem_cache_node,GFP_KERNEL , node); -if (!n) { -free_kmem_cache_nodes (s); +if (!n)return 0 ; - }init_kmem_cache_node (n); s->node[node] = n;
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 2/3 mm/slab: move and refactor __kmem_cache_alias()
From: Vlastimil Babka <[email protected]>
[ Upstream commit 8598351edc42f38d2a1eaed9abca39c98e7b0bbf ]
Move __kmem_cache_alias() to slab_common.c since it's called by __kmem_cache_create_args() and calls find_mergeable() that both are in this file. We can remove two slab.h declarations and make them static. Instead declare sysfs_slab_alias() from slub.c so that __kmem_cache_alias() can keep calling it.
Add args parameter to __kmem_cache_alias() and find_mergeable() instead of align and ctor. With that we can also move the checks for usersize and sheaf_capacity there from __kmem_cache_create_args() and make the result more symmetric with slab_unmergeable().
No functional changes intended.
Stable-dep-of: 7e98f8563956 ("mm/slub: fix missing debugfs entries for caches created before sysfs init")
--- mm/slab.h | 8 +++----- mm/slab_common.c | 41 +++++++++++++++++++++++++++++++++-------- mm/slub.c | 29 +---------------------------- 3 files changed, 37 insertions(+), 41 deletions(-)
mm/slab.h +3 -5
@@ -318,9 +318,12 @@ struct kmem_cache {#define SLAB_SUPPORTS_SYSFS 1void sysfs_slab_unlink (struct kmem_cache *s);void sysfs_slab_release (struct kmem_cache *s); +int sysfs_slab_alias (struct kmem_cache *s,const char *name);#else static inline void sysfs_slab_unlink (struct kmem_cache *s) { }static inline void sysfs_slab_release (struct kmem_cache *s) { } +static inline int sysfs_slab_alias (struct kmem_cache *s,const char *name) + {return 0 ; }#endif void *fixup_red_left (struct kmem_cache *s,void *p);
@@ -441,11 +444,6 @@ extern void create_boot_cache(struct kmem_cache *, const char *name, unsigned int useroffset, unsigned int usersize);int slab_unmergeable (struct kmem_cache *s); -struct kmem_cache *find_mergeable (unsigned size,unsigned align, -slab_flags_t flags,const char *name,void (*ctor)(void *)); -struct kmem_cache * -__kmem_cache_alias (const char *name,unsigned int size,unsigned int align, -slab_flags_t flags,void (*ctor)(void *));slab_flags_t kmem_cache_flags (slab_flags_t flags,const char *name);
mm/slab_common.c +33 -8
74 lines not on this page · raw message
mm/slub.c +1 -28
@@ -333,11 +333,8 @@ enum track_item { TRACK_ALLOC, TRACK_FREE };#ifdef SLAB_SUPPORTS_SYSFS static int sysfs_slab_add (struct kmem_cache *); -static int sysfs_slab_alias (struct kmem_cache *,const char *);#else static inline int sysfs_slab_add (struct kmem_cache *s) {return 0 ; } -static inline int sysfs_slab_alias (struct kmem_cache *s,const char *p) - {return 0 ; }#endif #if defined(CONFIG_DEBUG_FS ) && defined(CONFIG_SLUB_DEBUG )
@@ -6040,30 +6037,6 @@ void __init kmem_cache_init_late(void)#endif } -struct kmem_cache * -__kmem_cache_alias (const char *name,unsigned int size,unsigned int align, -slab_flags_t flags,void (*ctor)(void *)) -{ -struct kmem_cache *s; - - s =find_mergeable (size, align, flags, name, ctor); -if (s) { -if (sysfs_slab_alias (s, name)) -return NULL ; - - s->refcount++; - -/* -* Adjust the object sizes so that we clear -* the complete object on kzalloc. -*/ - s->object_size =max (s->object_size, size); - s->inuse =max (s->inuse,ALIGN (size,sizeof (void *))); - } - -return s; -} -int do_kmem_cache_create (struct kmem_cache *s,const char *name,unsigned int size,struct kmem_cache_args *args,slab_flags_t flags)
@@ -7229,7 +7202,7 @@ struct saved_alias {static struct saved_alias *alias_list; -static int sysfs_slab_alias (struct kmem_cache *s,const char *name) +int sysfs_slab_alias (struct kmem_cache *s,const char *name) {struct saved_alias *al;
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 3/3 mm/slub: fix missing debugfs entries for caches created before sysfs init
In reply to Sasha LevinFrom: Li Xiasong <[email protected]>
[ Upstream commit 7e98f856395618011c517f767fb80ac3fe90de2b ]
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.
--- mm/slub.c | 76 +++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 48 insertions(+), 28 deletions(-)
mm/slub.c +48 -28
@@ -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 stat_item {
@@ -7226,28 +7232,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;
@@ -7259,12 +7257,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)
@@ -7462,23 +7489,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
Signature · 1 line
2.53.0