]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
mm/slab: only allow SLAB_OBJ_EXT_IN_OBJ for unmergeable caches
authorHarry Yoo <harry.yoo@oracle.com>
Tue, 27 Jan 2026 10:31:51 +0000 (19:31 +0900)
committerVlastimil Babka <vbabka@suse.cz>
Wed, 4 Feb 2026 09:05:36 +0000 (10:05 +0100)
While SLAB_OBJ_EXT_IN_OBJ allows to reduce memory overhead to account
slab objects, it prevents slab merging because merging can change
the metadata layout.

As pointed out Vlastimil Babka, disabling merging solely for this memory
optimization may not be a net win, because disabling slab merging tends
to increase overall memory usage.

Restrict SLAB_OBJ_EXT_IN_OBJ to caches that are already unmergeable for
other reasons (e.g., those with constructors or SLAB_TYPESAFE_BY_RCU).

Suggested-by: Vlastimil Babka <vbabka@suse.cz>
Signed-off-by: Harry Yoo <harry.yoo@oracle.com>
Link: https://patch.msgid.link/20260127103151.21883-3-harry.yoo@oracle.com
Signed-off-by: Vlastimil Babka <vbabka@suse.cz>
mm/slab.h
mm/slab_common.c
mm/slub.c

index 43b7c5ababb5089212359e3bb751906784b31a45..3f49666e943cbb7a95b7f48deee4e9b688920a49 100644 (file)
--- a/mm/slab.h
+++ b/mm/slab.h
@@ -411,6 +411,7 @@ extern void create_boot_cache(struct kmem_cache *, const char *name,
                        unsigned int useroffset, unsigned int usersize);
 
 int slab_unmergeable(struct kmem_cache *s);
+bool slab_args_unmergeable(struct kmem_cache_args *args, slab_flags_t flags);
 
 slab_flags_t kmem_cache_flags(slab_flags_t flags, const char *name);
 
index 886d02fa94fb02416e766d83d6c64ff177be2694..094afa2792d05a60fede5149c8bb1c728236ee8c 100644 (file)
@@ -174,8 +174,7 @@ int slab_unmergeable(struct kmem_cache *s)
        return 0;
 }
 
-static bool slab_args_unmergeable(struct kmem_cache_args *args,
-                                 slab_flags_t flags)
+bool slab_args_unmergeable(struct kmem_cache_args *args, slab_flags_t flags)
 {
        if (slab_nomerge)
                return true;
index 0805c09d4b5581d7d52e1d6279744e4e8f379aae..18ac9460f9e9b41f92df8bf73fc0ef5a117b7d7e 100644 (file)
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -8382,7 +8382,8 @@ static int calculate_sizes(struct kmem_cache_args *args, struct kmem_cache *s)
         */
        aligned_size = ALIGN(size, s->align);
 #if defined(CONFIG_SLAB_OBJ_EXT) && defined(CONFIG_64BIT)
-       if (aligned_size - size >= sizeof(struct slabobj_ext))
+       if (slab_args_unmergeable(args, s->flags) &&
+                       (aligned_size - size >= sizeof(struct slabobj_ext)))
                s->flags |= SLAB_OBJ_EXT_IN_OBJ;
 #endif
        size = aligned_size;