Skip to content

Commit e562904

Browse files
HSM6236Vlastimil Babka (SUSE)
authored andcommitted
mm/slub: use empty sheaf helpers for oversized sheaves
Oversized prefilled sheaves are allocated separately because their capacity can be larger than the cache's regular sheaf capacity. After they are flushed, however, they are empty sheaves as well, and should be released through the same empty-sheaf helper. Allocate oversized prefilled sheaves with __alloc_empty_sheaf() and free them with free_empty_sheaf() after a failed prefill or after they are returned and flushed. This keeps the oversized and pfmemalloc return paths consistent, including the SLAB_KMALLOC-specific __GFP_NO_OBJ_EXT and mark_obj_codetag_empty() handling. Keep the caller-GFP filtering in alloc_empty_sheaf() instead of __alloc_empty_sheaf(). In particular, do not clear OBJCGS_CLEAR_MASK in the raw helper, so the oversized prefill path does not unexpectedly drop caller-provided flags such as __GFP_NOFAIL. The SLAB_KMALLOC-specific addition of __GFP_NO_OBJ_EXT remains in __alloc_empty_sheaf(), matching the free_empty_sheaf() assumption. Since oversized sheaves are now allocated and freed through the empty sheaf helpers, SHEAF_ALLOC and SHEAF_FREE also account for oversized sheaves. Update the stat comments accordingly. Keep the capacity initialization in the oversized prefill path, since capacity is currently only used for prefilled sheaves Signed-off-by: Shengming Hu <hu.shengming@zte.com.cn> Link: https://patch.msgid.link/20260528193537623nAo-xYBNYBysGKSBjREuO@zte.com.cn Reviewed-by: Harry Yoo (Oracle) <harry@kernel.org> Reviewed-by: Hao Li <hao.li@linux.dev> Signed-off-by: Vlastimil Babka (SUSE) <vbabka@kernel.org>
1 parent c996bad commit e562904

1 file changed

Lines changed: 10 additions & 11 deletions

File tree

mm/slub.c

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -362,8 +362,8 @@ enum stat_item {
362362
CMPXCHG_DOUBLE_FAIL, /* Failures of slab freelist update */
363363
SHEAF_FLUSH, /* Objects flushed from a sheaf */
364364
SHEAF_REFILL, /* Objects refilled to a sheaf */
365-
SHEAF_ALLOC, /* Allocation of an empty sheaf */
366-
SHEAF_FREE, /* Freeing of an empty sheaf */
365+
SHEAF_ALLOC, /* Allocation of an empty sheaf including oversized ones */
366+
SHEAF_FREE, /* Freeing of an empty sheaf including oversized ones */
367367
BARN_GET, /* Got full sheaf from barn */
368368
BARN_GET_FAIL, /* Failed to get full sheaf from barn */
369369
BARN_PUT, /* Put full sheaf to barn */
@@ -2762,11 +2762,6 @@ static struct slab_sheaf *__alloc_empty_sheaf(struct kmem_cache *s, gfp_t gfp,
27622762
struct slab_sheaf *sheaf;
27632763
size_t sheaf_size;
27642764

2765-
if (gfp & __GFP_NO_OBJ_EXT)
2766-
return NULL;
2767-
2768-
gfp &= ~OBJCGS_CLEAR_MASK;
2769-
27702765
/*
27712766
* Prevent recursion to the same cache, or a deep stack of kmallocs of
27722767
* varying sizes (sheaf capacity might differ for each kmalloc size
@@ -2791,6 +2786,11 @@ static struct slab_sheaf *__alloc_empty_sheaf(struct kmem_cache *s, gfp_t gfp,
27912786
static inline struct slab_sheaf *alloc_empty_sheaf(struct kmem_cache *s,
27922787
gfp_t gfp)
27932788
{
2789+
if (gfp & __GFP_NO_OBJ_EXT)
2790+
return NULL;
2791+
2792+
gfp &= ~OBJCGS_CLEAR_MASK;
2793+
27942794
return __alloc_empty_sheaf(s, gfp, s->sheaf_capacity);
27952795
}
27962796

@@ -5014,12 +5014,11 @@ kmem_cache_prefill_sheaf(struct kmem_cache *s, gfp_t gfp, unsigned int size)
50145014

50155015
if (unlikely(size > s->sheaf_capacity)) {
50165016

5017-
sheaf = kzalloc_flex(*sheaf, objects, size, gfp);
5017+
sheaf = __alloc_empty_sheaf(s, gfp, size);
50185018
if (!sheaf)
50195019
return NULL;
50205020

50215021
stat(s, SHEAF_PREFILL_OVERSIZE);
5022-
sheaf->cache = s;
50235022
sheaf->capacity = size;
50245023

50255024
/*
@@ -5028,7 +5027,7 @@ kmem_cache_prefill_sheaf(struct kmem_cache *s, gfp_t gfp, unsigned int size)
50285027
*/
50295028
if (!__kmem_cache_alloc_bulk(s, gfp, size,
50305029
&sheaf->objects[0])) {
5031-
kfree(sheaf);
5030+
free_empty_sheaf(s, sheaf);
50325031
return NULL;
50335032
}
50345033

@@ -5096,7 +5095,7 @@ void kmem_cache_return_sheaf(struct kmem_cache *s, gfp_t gfp,
50965095
if (unlikely((sheaf->capacity != s->sheaf_capacity)
50975096
|| sheaf->pfmemalloc)) {
50985097
sheaf_flush_unused(s, sheaf);
5099-
kfree(sheaf);
5098+
free_empty_sheaf(s, sheaf);
51005099
return;
51015100
}
51025101

0 commit comments

Comments
 (0)