Before enabling sheaves for all caches (with automatically determined
capacity), their enablement should no longer prevent merging of caches.
Limit this merge prevention only to caches that were created with a
specific sheaf capacity, by adding the SLAB_NO_MERGE flag to them.
Signed-off-by: Vlastimil Babka <vbabka@suse.cz>
---
mm/slab_common.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/mm/slab_common.c b/mm/slab_common.c
index 52591d9c04f3..54c17dc6d5ec 100644
--- a/mm/slab_common.c
+++ b/mm/slab_common.c
@@ -163,9 +163,6 @@ int slab_unmergeable(struct kmem_cache *s)
return 1;
#endif
- if (s->cpu_sheaves)
- return 1;
-
/*
* We may have set a slab to be unmergeable during bootstrap.
*/
@@ -190,9 +187,6 @@ static struct kmem_cache *find_mergeable(unsigned int size, slab_flags_t flags,
if (IS_ENABLED(CONFIG_HARDENED_USERCOPY) && args->usersize)
return NULL;
- if (args->sheaf_capacity)
- return NULL;
-
flags = kmem_cache_flags(flags, name);
if (flags & SLAB_NEVER_MERGE)
@@ -337,6 +331,13 @@ struct kmem_cache *__kmem_cache_create_args(const char *name,
flags &= ~SLAB_DEBUG_FLAGS;
#endif
+ /*
+ * Caches with specific capacity are special enough. It's simpler to
+ * make them unmergeable.
+ */
+ if (args->sheaf_capacity)
+ flags |= SLAB_NO_MERGE;
+
mutex_lock(&slab_mutex);
err = kmem_cache_sanity_check(name, object_size);
--
2.52.0
On Mon, Jan 12, 2026 at 3:17 PM Vlastimil Babka <vbabka@suse.cz> wrote: > > Before enabling sheaves for all caches (with automatically determined > capacity), their enablement should no longer prevent merging of caches. > Limit this merge prevention only to caches that were created with a > specific sheaf capacity, by adding the SLAB_NO_MERGE flag to them. > > Signed-off-by: Vlastimil Babka <vbabka@suse.cz> > --- > mm/slab_common.c | 13 +++++++------ > 1 file changed, 7 insertions(+), 6 deletions(-) > > diff --git a/mm/slab_common.c b/mm/slab_common.c > index 52591d9c04f3..54c17dc6d5ec 100644 > --- a/mm/slab_common.c > +++ b/mm/slab_common.c > @@ -163,9 +163,6 @@ int slab_unmergeable(struct kmem_cache *s) > return 1; > #endif > > - if (s->cpu_sheaves) > - return 1; > - > /* > * We may have set a slab to be unmergeable during bootstrap. > */ > @@ -190,9 +187,6 @@ static struct kmem_cache *find_mergeable(unsigned int size, slab_flags_t flags, > if (IS_ENABLED(CONFIG_HARDENED_USERCOPY) && args->usersize) > return NULL; > > - if (args->sheaf_capacity) > - return NULL; > - > flags = kmem_cache_flags(flags, name); > > if (flags & SLAB_NEVER_MERGE) > @@ -337,6 +331,13 @@ struct kmem_cache *__kmem_cache_create_args(const char *name, > flags &= ~SLAB_DEBUG_FLAGS; > #endif > > + /* > + * Caches with specific capacity are special enough. It's simpler to > + * make them unmergeable. > + */ > + if (args->sheaf_capacity) > + flags |= SLAB_NO_MERGE; So, this is very subtle and maybe not that important but the comment for kmem_cache_args.sheaf_capacity claims "When slub_debug is enabled for the cache, the sheaf_capacity argument is ignored.". With this change this argument is not completely ignored anymore... It sets SLAB_NO_MERGE even if slub_debug is enabled, doesn't it? > + > mutex_lock(&slab_mutex); > > err = kmem_cache_sanity_check(name, object_size); > > -- > 2.52.0 >
On 1/16/26 01:22, Suren Baghdasaryan wrote: > On Mon, Jan 12, 2026 at 3:17 PM Vlastimil Babka <vbabka@suse.cz> wrote: >> >> Before enabling sheaves for all caches (with automatically determined >> capacity), their enablement should no longer prevent merging of caches. >> Limit this merge prevention only to caches that were created with a >> specific sheaf capacity, by adding the SLAB_NO_MERGE flag to them. >> >> Signed-off-by: Vlastimil Babka <vbabka@suse.cz> >> --- >> mm/slab_common.c | 13 +++++++------ >> 1 file changed, 7 insertions(+), 6 deletions(-) >> >> diff --git a/mm/slab_common.c b/mm/slab_common.c >> index 52591d9c04f3..54c17dc6d5ec 100644 >> --- a/mm/slab_common.c >> +++ b/mm/slab_common.c >> @@ -163,9 +163,6 @@ int slab_unmergeable(struct kmem_cache *s) >> return 1; >> #endif >> >> - if (s->cpu_sheaves) >> - return 1; >> - >> /* >> * We may have set a slab to be unmergeable during bootstrap. >> */ >> @@ -190,9 +187,6 @@ static struct kmem_cache *find_mergeable(unsigned int size, slab_flags_t flags, >> if (IS_ENABLED(CONFIG_HARDENED_USERCOPY) && args->usersize) >> return NULL; >> >> - if (args->sheaf_capacity) >> - return NULL; >> - >> flags = kmem_cache_flags(flags, name); >> >> if (flags & SLAB_NEVER_MERGE) >> @@ -337,6 +331,13 @@ struct kmem_cache *__kmem_cache_create_args(const char *name, >> flags &= ~SLAB_DEBUG_FLAGS; >> #endif >> >> + /* >> + * Caches with specific capacity are special enough. It's simpler to >> + * make them unmergeable. >> + */ >> + if (args->sheaf_capacity) >> + flags |= SLAB_NO_MERGE; > > So, this is very subtle and maybe not that important but the comment > for kmem_cache_args.sheaf_capacity claims "When slub_debug is enabled > for the cache, the sheaf_capacity argument is ignored.". With this > change this argument is not completely ignored anymore... It sets > SLAB_NO_MERGE even if slub_debug is enabled, doesn't it? True, but the various debug flags set by slub_debug also prevent merging so it doesn't change the outcome. >> + >> mutex_lock(&slab_mutex); >> >> err = kmem_cache_sanity_check(name, object_size); >> >> -- >> 2.52.0 >>
On Thu, Jan 15, 2026 at 11:24 PM Vlastimil Babka <vbabka@suse.cz> wrote: > > On 1/16/26 01:22, Suren Baghdasaryan wrote: > > On Mon, Jan 12, 2026 at 3:17 PM Vlastimil Babka <vbabka@suse.cz> wrote: > >> > >> Before enabling sheaves for all caches (with automatically determined > >> capacity), their enablement should no longer prevent merging of caches. > >> Limit this merge prevention only to caches that were created with a > >> specific sheaf capacity, by adding the SLAB_NO_MERGE flag to them. > >> > >> Signed-off-by: Vlastimil Babka <vbabka@suse.cz> > >> --- > >> mm/slab_common.c | 13 +++++++------ > >> 1 file changed, 7 insertions(+), 6 deletions(-) > >> > >> diff --git a/mm/slab_common.c b/mm/slab_common.c > >> index 52591d9c04f3..54c17dc6d5ec 100644 > >> --- a/mm/slab_common.c > >> +++ b/mm/slab_common.c > >> @@ -163,9 +163,6 @@ int slab_unmergeable(struct kmem_cache *s) > >> return 1; > >> #endif > >> > >> - if (s->cpu_sheaves) > >> - return 1; > >> - > >> /* > >> * We may have set a slab to be unmergeable during bootstrap. > >> */ > >> @@ -190,9 +187,6 @@ static struct kmem_cache *find_mergeable(unsigned int size, slab_flags_t flags, > >> if (IS_ENABLED(CONFIG_HARDENED_USERCOPY) && args->usersize) > >> return NULL; > >> > >> - if (args->sheaf_capacity) > >> - return NULL; > >> - > >> flags = kmem_cache_flags(flags, name); > >> > >> if (flags & SLAB_NEVER_MERGE) > >> @@ -337,6 +331,13 @@ struct kmem_cache *__kmem_cache_create_args(const char *name, > >> flags &= ~SLAB_DEBUG_FLAGS; > >> #endif > >> > >> + /* > >> + * Caches with specific capacity are special enough. It's simpler to > >> + * make them unmergeable. > >> + */ > >> + if (args->sheaf_capacity) > >> + flags |= SLAB_NO_MERGE; > > > > So, this is very subtle and maybe not that important but the comment > > for kmem_cache_args.sheaf_capacity claims "When slub_debug is enabled > > for the cache, the sheaf_capacity argument is ignored.". With this > > change this argument is not completely ignored anymore... It sets > > SLAB_NO_MERGE even if slub_debug is enabled, doesn't it? > > True, but the various debug flags set by slub_debug also prevent merging so > it doesn't change the outcome. Yeah, I thought that would not matter much but wanted to make sure. After finishing the review I'll have to remember to verify if that comment on slub_debug/sheaf interplay stays true even after args->sheaf_capacity becomes the min sheaf capacity. > > >> + > >> mutex_lock(&slab_mutex); > >> > >> err = kmem_cache_sanity_check(name, object_size); > >> > >> -- > >> 2.52.0 > >> >
On Fri, Jan 16, 2026 at 08:24:02AM +0100, Vlastimil Babka wrote: > On 1/16/26 01:22, Suren Baghdasaryan wrote: > > On Mon, Jan 12, 2026 at 3:17 PM Vlastimil Babka <vbabka@suse.cz> wrote: > >> @@ -337,6 +331,13 @@ struct kmem_cache *__kmem_cache_create_args(const char *name, > >> flags &= ~SLAB_DEBUG_FLAGS; > >> #endif > >> > >> + /* > >> + * Caches with specific capacity are special enough. It's simpler to > >> + * make them unmergeable. > >> + */ > >> + if (args->sheaf_capacity) > >> + flags |= SLAB_NO_MERGE; > > > > So, this is very subtle and maybe not that important but the comment > > for kmem_cache_args.sheaf_capacity claims "When slub_debug is enabled > > for the cache, the sheaf_capacity argument is ignored.". With this > > change this argument is not completely ignored anymore... It sets > > SLAB_NO_MERGE even if slub_debug is enabled, doesn't it? > > True, but the various debug flags set by slub_debug also prevent merging so > it doesn't change the outcome. nit: except for slub_debug=F (SLAB_CONSISTENCY_CHECKS), since it doesn't prevent merging (it's in SLAB_DEBUG_FLAGS but not in SLAB_NEVER_MERGE). -- Cheers, Harry / Hyeonggon
On 1/16/26 09:46, Harry Yoo wrote: > On Fri, Jan 16, 2026 at 08:24:02AM +0100, Vlastimil Babka wrote: >> On 1/16/26 01:22, Suren Baghdasaryan wrote: >> > On Mon, Jan 12, 2026 at 3:17 PM Vlastimil Babka <vbabka@suse.cz> wrote: >> >> @@ -337,6 +331,13 @@ struct kmem_cache *__kmem_cache_create_args(const char *name, >> >> flags &= ~SLAB_DEBUG_FLAGS; >> >> #endif >> >> >> >> + /* >> >> + * Caches with specific capacity are special enough. It's simpler to >> >> + * make them unmergeable. >> >> + */ >> >> + if (args->sheaf_capacity) >> >> + flags |= SLAB_NO_MERGE; >> > >> > So, this is very subtle and maybe not that important but the comment >> > for kmem_cache_args.sheaf_capacity claims "When slub_debug is enabled >> > for the cache, the sheaf_capacity argument is ignored.". With this >> > change this argument is not completely ignored anymore... It sets >> > SLAB_NO_MERGE even if slub_debug is enabled, doesn't it? >> >> True, but the various debug flags set by slub_debug also prevent merging so >> it doesn't change the outcome. > > nit: except for slub_debug=F (SLAB_CONSISTENCY_CHECKS), since it doesn't > prevent merging (it's in SLAB_DEBUG_FLAGS but not in SLAB_NEVER_MERGE). Hm right. But I think that's wrong then and it should be there. SLAB_CONSISTENCY_CHECKS is enough to stop using the fastpaths (both before/after sheaves) so it should be a reason not to merge.
On Fri, Jan 16, 2026 at 12:01:23PM +0100, Vlastimil Babka wrote: > On 1/16/26 09:46, Harry Yoo wrote: > > On Fri, Jan 16, 2026 at 08:24:02AM +0100, Vlastimil Babka wrote: > >> On 1/16/26 01:22, Suren Baghdasaryan wrote: > >> > On Mon, Jan 12, 2026 at 3:17 PM Vlastimil Babka <vbabka@suse.cz> wrote: > >> >> @@ -337,6 +331,13 @@ struct kmem_cache *__kmem_cache_create_args(const char *name, > >> >> flags &= ~SLAB_DEBUG_FLAGS; > >> >> #endif > >> >> > >> >> + /* > >> >> + * Caches with specific capacity are special enough. It's simpler to > >> >> + * make them unmergeable. > >> >> + */ > >> >> + if (args->sheaf_capacity) > >> >> + flags |= SLAB_NO_MERGE; > >> > > >> > So, this is very subtle and maybe not that important but the comment > >> > for kmem_cache_args.sheaf_capacity claims "When slub_debug is enabled > >> > for the cache, the sheaf_capacity argument is ignored.". With this > >> > change this argument is not completely ignored anymore... It sets > >> > SLAB_NO_MERGE even if slub_debug is enabled, doesn't it? > >> > >> True, but the various debug flags set by slub_debug also prevent merging so > >> it doesn't change the outcome. > > > > nit: except for slub_debug=F (SLAB_CONSISTENCY_CHECKS), since it doesn't > > prevent merging (it's in SLAB_DEBUG_FLAGS but not in SLAB_NEVER_MERGE). > > Hm right. But I think that's wrong then and it should be there. > SLAB_CONSISTENCY_CHECKS is enough to stop using the fastpaths (both > before/after sheaves) so it should be a reason not to merge. Agreed! -- Cheers, Harry / Hyeonggon
On Mon, Jan 12, 2026 at 04:16:57PM +0100, Vlastimil Babka wrote: > Before enabling sheaves for all caches (with automatically determined > capacity), their enablement should no longer prevent merging of caches. > Limit this merge prevention only to caches that were created with a > specific sheaf capacity, by adding the SLAB_NO_MERGE flag to them. > > Signed-off-by: Vlastimil Babka <vbabka@suse.cz> > --- Looks good to me, Reviewed-by: Harry Yoo <harry.yoo@oracle.com> -- Cheers, Harry / Hyeonggon
© 2016 - 2026 Red Hat, Inc.