Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

mm/slab: allow specifying free pointer offset when using constructor

When a slab cache has a constructor, the free pointer is placed after the
object because certain fields must not be overwritten even after the
object is freed.

However, some fields that the constructor does not initialize can safely
be overwritten after free. Allow specifying the free pointer offset within
the object, reducing the overall object size when some fields can be reused
for the free pointer.

Adjust the document accordingly.

Signed-off-by: Harry Yoo <harry.yoo@oracle.com>
Link: https://patch.msgid.link/20260113061845.159790-3-harry.yoo@oracle.com
Signed-off-by: Vlastimil Babka <vbabka@suse.cz>

authored by

Harry Yoo and committed by
Vlastimil Babka
a13b68d7 b85f369b

+21 -17
+16 -14
include/linux/slab.h
··· 299 299 unsigned int usersize; 300 300 /** 301 301 * @freeptr_offset: Custom offset for the free pointer 302 - * in &SLAB_TYPESAFE_BY_RCU caches 302 + * in caches with &SLAB_TYPESAFE_BY_RCU or @ctor 303 303 * 304 - * By default &SLAB_TYPESAFE_BY_RCU caches place the free pointer 305 - * outside of the object. This might cause the object to grow in size. 306 - * Cache creators that have a reason to avoid this can specify a custom 307 - * free pointer offset in their struct where the free pointer will be 308 - * placed. 304 + * By default, &SLAB_TYPESAFE_BY_RCU and @ctor caches place the free 305 + * pointer outside of the object. This might cause the object to grow 306 + * in size. Cache creators that have a reason to avoid this can specify 307 + * a custom free pointer offset in their data structure where the free 308 + * pointer will be placed. 309 309 * 310 - * Note that placing the free pointer inside the object requires the 311 - * caller to ensure that no fields are invalidated that are required to 312 - * guard against object recycling (See &SLAB_TYPESAFE_BY_RCU for 313 - * details). 310 + * For caches with &SLAB_TYPESAFE_BY_RCU, the caller must ensure that 311 + * the free pointer does not overlay fields required to guard against 312 + * object recycling (See &SLAB_TYPESAFE_BY_RCU for details). 313 + * 314 + * For caches with @ctor, the caller must ensure that the free pointer 315 + * does not overlay fields initialized by the constructor. 316 + * 317 + * Currently, only caches with &SLAB_TYPESAFE_BY_RCU or @ctor 318 + * may specify @freeptr_offset. 314 319 * 315 320 * Using %0 as a value for @freeptr_offset is valid. If @freeptr_offset 316 - * is specified, %use_freeptr_offset must be set %true. 317 - * 318 - * Note that @ctor currently isn't supported with custom free pointers 319 - * as a @ctor requires an external free pointer. 321 + * is specified, @use_freeptr_offset must be set %true. 320 322 */ 321 323 unsigned int freeptr_offset; 322 324 /**
+1 -1
mm/slab_common.c
··· 239 239 err = -EINVAL; 240 240 if (args->use_freeptr_offset && 241 241 (args->freeptr_offset >= object_size || 242 - !(flags & SLAB_TYPESAFE_BY_RCU) || 242 + (!(flags & SLAB_TYPESAFE_BY_RCU) && !args->ctor) || 243 243 !IS_ALIGNED(args->freeptr_offset, __alignof__(freeptr_t)))) 244 244 goto out; 245 245
+4 -2
mm/slub.c
··· 7998 7998 s->inuse = size; 7999 7999 8000 8000 if (((flags & SLAB_TYPESAFE_BY_RCU) && !args->use_freeptr_offset) || 8001 - (flags & SLAB_POISON) || s->ctor || 8001 + (flags & SLAB_POISON) || 8002 + (s->ctor && !args->use_freeptr_offset) || 8002 8003 ((flags & SLAB_RED_ZONE) && 8003 8004 (s->object_size < sizeof(void *) || slub_debug_orig_size(s)))) { 8004 8005 /* ··· 8020 8019 */ 8021 8020 s->offset = size; 8022 8021 size += sizeof(void *); 8023 - } else if ((flags & SLAB_TYPESAFE_BY_RCU) && args->use_freeptr_offset) { 8022 + } else if (((flags & SLAB_TYPESAFE_BY_RCU) || s->ctor) && 8023 + args->use_freeptr_offset) { 8024 8024 s->offset = args->freeptr_offset; 8025 8025 } else { 8026 8026 /*