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: use stride to access slabobj_ext

Use a configurable stride value when accessing slab object extension
metadata instead of assuming a fixed sizeof(struct slabobj_ext).

Store stride value in free bits of slab->counters field. This allows
for flexibility in cases where the extension is embedded within
slab objects.

Since these free bits exist only on 64-bit, any future optimizations
that need to change stride value cannot be enabled on 32-bit architectures.

Suggested-by: Vlastimil Babka <vbabka@suse.cz>
Reviewed-by: Suren Baghdasaryan <surenb@google.com>
Signed-off-by: Harry Yoo <harry.yoo@oracle.com>
Link: https://patch.msgid.link/20260113061845.159790-6-harry.yoo@oracle.com
Signed-off-by: Vlastimil Babka <vbabka@suse.cz>

authored by

Harry Yoo and committed by
Vlastimil Babka
7a8e71bc 52f1ca8a

+35 -4
+33 -4
mm/slab.h
··· 55 55 * that the slab was corrupted 56 56 */ 57 57 unsigned frozen:1; 58 + #ifdef CONFIG_64BIT 59 + /* 60 + * Some optimizations use free bits in 'counters' field 61 + * to save memory. In case ->stride field is not available, 62 + * such optimizations are disabled. 63 + */ 64 + unsigned short stride; 65 + #endif 58 66 }; 59 67 }; 60 68 }; ··· 537 529 return obj_exts & ~OBJEXTS_FLAGS_MASK; 538 530 } 539 531 532 + #ifdef CONFIG_64BIT 533 + static inline void slab_set_stride(struct slab *slab, unsigned short stride) 534 + { 535 + slab->stride = stride; 536 + } 537 + static inline unsigned short slab_get_stride(struct slab *slab) 538 + { 539 + return slab->stride; 540 + } 541 + #else 542 + static inline void slab_set_stride(struct slab *slab, unsigned short stride) 543 + { 544 + VM_WARN_ON_ONCE(stride != sizeof(struct slabobj_ext)); 545 + } 546 + static inline unsigned short slab_get_stride(struct slab *slab) 547 + { 548 + return sizeof(struct slabobj_ext); 549 + } 550 + #endif 551 + 540 552 /* 541 553 * slab_obj_ext - get the pointer to the slab object extension metadata 542 554 * associated with an object in a slab. ··· 570 542 unsigned long obj_exts, 571 543 unsigned int index) 572 544 { 573 - struct slabobj_ext *obj_ext; 574 - 575 545 VM_WARN_ON_ONCE(obj_exts != slab_obj_exts(slab)); 576 546 577 - obj_ext = (struct slabobj_ext *)obj_exts; 578 - return &obj_ext[index]; 547 + return (struct slabobj_ext *)(obj_exts + slab_get_stride(slab) * index); 579 548 } 580 549 581 550 int alloc_slab_obj_exts(struct slab *slab, struct kmem_cache *s, ··· 591 566 { 592 567 return NULL; 593 568 } 569 + 570 + static inline void slab_set_stride(struct slab *slab, unsigned int stride) { } 571 + static inline unsigned int slab_get_stride(struct slab *slab) { return 0; } 572 + 594 573 595 574 #endif /* CONFIG_SLAB_OBJ_EXT */ 596 575
+2
mm/slub.c
··· 2206 2206 retry: 2207 2207 old_exts = READ_ONCE(slab->obj_exts); 2208 2208 handle_failed_objexts_alloc(old_exts, vec, objects); 2209 + slab_set_stride(slab, sizeof(struct slabobj_ext)); 2210 + 2209 2211 if (new_slab) { 2210 2212 /* 2211 2213 * If the slab is brand new and nobody can yet access its