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.

slab: prevent recursive kmalloc() in alloc_empty_sheaf()

We want to expand usage of sheaves to all non-boot caches, including
kmalloc caches. Since sheaves themselves are also allocated by
kmalloc(), we need to prevent excessive or infinite recursion -
depending on sheaf size, the sheaf can be allocated from smaller, same
or larger kmalloc size bucket, there's no particular constraint.

This is similar to allocating the objext arrays so let's just reuse the
existing mechanisms for those. __GFP_NO_OBJ_EXT in alloc_empty_sheaf()
will prevent a nested kmalloc() from allocating a sheaf itself - it will
either have sheaves already, or fallback to a non-sheaf-cached
allocation (so bootstrap of sheaves in a kmalloc cache that allocates
sheaves from its own size bucket is possible). Additionally, reuse
OBJCGS_CLEAR_MASK to clear unwanted gfp flags from the nested
allocation.

Link: https://patch.msgid.link/20251105-sheaves-cleanups-v1-5-b8218e1ac7ef@suse.cz
Reviewed-by: Harry Yoo <harry.yoo@oracle.com>
Signed-off-by: Vlastimil Babka <vbabka@suse.cz>

+26 -16
-6
include/linux/gfp_types.h
··· 55 55 #ifdef CONFIG_LOCKDEP 56 56 ___GFP_NOLOCKDEP_BIT, 57 57 #endif 58 - #ifdef CONFIG_SLAB_OBJ_EXT 59 58 ___GFP_NO_OBJ_EXT_BIT, 60 - #endif 61 59 ___GFP_LAST_BIT 62 60 }; 63 61 ··· 96 98 #else 97 99 #define ___GFP_NOLOCKDEP 0 98 100 #endif 99 - #ifdef CONFIG_SLAB_OBJ_EXT 100 101 #define ___GFP_NO_OBJ_EXT BIT(___GFP_NO_OBJ_EXT_BIT) 101 - #else 102 - #define ___GFP_NO_OBJ_EXT 0 103 - #endif 104 102 105 103 /* 106 104 * Physical address zone modifiers (see linux/mmzone.h - low four bits)
+26 -10
mm/slub.c
··· 2031 2031 } 2032 2032 #endif /* CONFIG_SLUB_DEBUG */ 2033 2033 2034 + /* 2035 + * The allocated objcg pointers array is not accounted directly. 2036 + * Moreover, it should not come from DMA buffer and is not readily 2037 + * reclaimable. So those GFP bits should be masked off. 2038 + */ 2039 + #define OBJCGS_CLEAR_MASK (__GFP_DMA | __GFP_RECLAIMABLE | \ 2040 + __GFP_ACCOUNT | __GFP_NOFAIL) 2041 + 2034 2042 #ifdef CONFIG_SLAB_OBJ_EXT 2035 2043 2036 2044 #ifdef CONFIG_MEM_ALLOC_PROFILING_DEBUG ··· 2088 2080 struct slabobj_ext *vec, unsigned int objects) {} 2089 2081 2090 2082 #endif /* CONFIG_MEM_ALLOC_PROFILING_DEBUG */ 2091 - 2092 - /* 2093 - * The allocated objcg pointers array is not accounted directly. 2094 - * Moreover, it should not come from DMA buffer and is not readily 2095 - * reclaimable. So those GFP bits should be masked off. 2096 - */ 2097 - #define OBJCGS_CLEAR_MASK (__GFP_DMA | __GFP_RECLAIMABLE | \ 2098 - __GFP_ACCOUNT | __GFP_NOFAIL) 2099 2083 2100 2084 static inline void init_slab_obj_exts(struct slab *slab) 2101 2085 { ··· 2596 2596 2597 2597 static struct slab_sheaf *alloc_empty_sheaf(struct kmem_cache *s, gfp_t gfp) 2598 2598 { 2599 - struct slab_sheaf *sheaf = kzalloc(struct_size(sheaf, objects, 2600 - s->sheaf_capacity), gfp); 2599 + struct slab_sheaf *sheaf; 2600 + size_t sheaf_size; 2601 + 2602 + if (gfp & __GFP_NO_OBJ_EXT) 2603 + return NULL; 2604 + 2605 + gfp &= ~OBJCGS_CLEAR_MASK; 2606 + 2607 + /* 2608 + * Prevent recursion to the same cache, or a deep stack of kmallocs of 2609 + * varying sizes (sheaf capacity might differ for each kmalloc size 2610 + * bucket) 2611 + */ 2612 + if (s->flags & SLAB_KMALLOC) 2613 + gfp |= __GFP_NO_OBJ_EXT; 2614 + 2615 + sheaf_size = struct_size(sheaf, objects, s->sheaf_capacity); 2616 + sheaf = kzalloc(sheaf_size, gfp); 2601 2617 2602 2618 if (unlikely(!sheaf)) 2603 2619 return NULL;