Commit 2f35fee9 authored by Harry Yoo's avatar Harry Yoo Committed by Vlastimil Babka
Browse files

mm/slab: only allow SLAB_OBJ_EXT_IN_OBJ for unmergeable caches



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: default avatarVlastimil Babka <vbabka@suse.cz>
Signed-off-by: default avatarHarry Yoo <harry.yoo@oracle.com>
Link: https://patch.msgid.link/20260127103151.21883-3-harry.yoo@oracle.com


Signed-off-by: default avatarVlastimil Babka <vbabka@suse.cz>
parent a77d6d33
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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);

+1 −2
Original line number Diff line number Diff line
@@ -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;
+2 −1
Original line number Diff line number Diff line
@@ -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;