* [PATCH v2] mm/slub: free prefilled empty sheaves consistently @ 2026-05-22 6:59 hu.shengming 2026-05-25 6:38 ` Hao Li 0 siblings, 1 reply; 3+ messages in thread From: hu.shengming @ 2026-05-22 6:59 UTC (permalink / raw) To: vbabka, harry, akpm Cc: hao.li, cl, rientjes, roman.gushchin, linux-mm, linux-kernel, zhang.run, cai.qu From: Shengming Hu <hu.shengming@zte.com.cn> Empty sheaves allocated by alloc_empty_sheaf() should be released with free_empty_sheaf(). Move the common empty-sheaf initialization into __alloc_empty_sheaf(), including the capacity and default pfmemalloc state, and use it for oversized prefilled sheaves as well. This keeps the prefill paths consistent: after flushing an oversized or pfmemalloc sheaf, release the now-empty sheaf through free_empty_sheaf() instead of kfree(). Signed-off-by: Shengming Hu <hu.shengming@zte.com.cn> --- Changes in v2: - Rework the change as suggested by Harry. - Teach __alloc_empty_sheaf() to initialize capacity and pfmemalloc. - Allocate oversized prefilled sheaves through __alloc_empty_sheaf(). - Free flushed oversized and pfmemalloc sheaves through free_empty_sheaf(). - Link to v1: https://lore.kernel.org/all/20260521195015105Y4zvKHj0TfPZEujixy9Vo@zte.com.cn/ --- mm/slub.c | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/mm/slub.c b/mm/slub.c index 04692a6f9128..bbe8351f1bfa 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -2782,6 +2782,8 @@ static struct slab_sheaf *__alloc_empty_sheaf(struct kmem_cache *s, gfp_t gfp, return NULL; sheaf->cache = s; + sheaf->capacity = capacity; + sheaf->pfmemalloc = false; stat(s, SHEAF_ALLOC); @@ -5015,21 +5017,15 @@ kmem_cache_prefill_sheaf(struct kmem_cache *s, gfp_t gfp, unsigned int size) if (unlikely(size > s->sheaf_capacity)) { - sheaf = kzalloc_flex(*sheaf, objects, size, gfp); + sheaf = __alloc_empty_sheaf(s, gfp, size); if (!sheaf) return NULL; stat(s, SHEAF_PREFILL_OVERSIZE); - sheaf->cache = s; - sheaf->capacity = size; - /* - * we do not need to care about pfmemalloc here because oversize - * sheaves area always flushed and freed when returned - */ if (!__kmem_cache_alloc_bulk(s, gfp, size, &sheaf->objects[0])) { - kfree(sheaf); + free_empty_sheaf(s, sheaf); return NULL; } @@ -5064,9 +5060,6 @@ kmem_cache_prefill_sheaf(struct kmem_cache *s, gfp_t gfp, unsigned int size) sheaf = alloc_empty_sheaf(s, gfp); if (sheaf) { - sheaf->capacity = s->sheaf_capacity; - sheaf->pfmemalloc = false; - if (sheaf->size < size && __prefill_sheaf_pfmemalloc(s, sheaf, gfp)) { sheaf_flush_unused(s, sheaf); @@ -5097,7 +5090,7 @@ void kmem_cache_return_sheaf(struct kmem_cache *s, gfp_t gfp, if (unlikely((sheaf->capacity != s->sheaf_capacity) || sheaf->pfmemalloc)) { sheaf_flush_unused(s, sheaf); - kfree(sheaf); + free_empty_sheaf(s, sheaf); return; } -- 2.25.1 ^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH v2] mm/slub: free prefilled empty sheaves consistently 2026-05-22 6:59 [PATCH v2] mm/slub: free prefilled empty sheaves consistently hu.shengming @ 2026-05-25 6:38 ` Hao Li 2026-05-25 7:39 ` hu.shengming 0 siblings, 1 reply; 3+ messages in thread From: Hao Li @ 2026-05-25 6:38 UTC (permalink / raw) To: hu.shengming Cc: vbabka, harry, akpm, cl, rientjes, roman.gushchin, linux-mm, linux-kernel, zhang.run, cai.qu On Fri, May 22, 2026 at 02:59:00PM +0800, hu.shengming@zte.com.cn wrote: > From: Shengming Hu <hu.shengming@zte.com.cn> > > Empty sheaves allocated by alloc_empty_sheaf() should be released with > free_empty_sheaf(). > > Move the common empty-sheaf initialization into __alloc_empty_sheaf(), > including the capacity and default pfmemalloc state, and use it for > oversized prefilled sheaves as well. > > This keeps the prefill paths consistent: after flushing an oversized or > pfmemalloc sheaf, release the now-empty sheaf through free_empty_sheaf() > instead of kfree(). > > Signed-off-by: Shengming Hu <hu.shengming@zte.com.cn> > --- > Changes in v2: > - Rework the change as suggested by Harry. > - Teach __alloc_empty_sheaf() to initialize capacity and pfmemalloc. > - Allocate oversized prefilled sheaves through __alloc_empty_sheaf(). > - Free flushed oversized and pfmemalloc sheaves through free_empty_sheaf(). > - Link to v1: https://lore.kernel.org/all/20260521195015105Y4zvKHj0TfPZEujixy9Vo@zte.com.cn/ > > --- > mm/slub.c | 17 +++++------------ > 1 file changed, 5 insertions(+), 12 deletions(-) > > diff --git a/mm/slub.c b/mm/slub.c > index 04692a6f9128..bbe8351f1bfa 100644 > --- a/mm/slub.c > +++ b/mm/slub.c > @@ -2782,6 +2782,8 @@ static struct slab_sheaf *__alloc_empty_sheaf(struct kmem_cache *s, gfp_t gfp, > return NULL; > > sheaf->cache = s; > + sheaf->capacity = capacity; > + sheaf->pfmemalloc = false; we could eliminate `sheaf->pfmemalloc = false;` because the allocation use kzalloc. > > stat(s, SHEAF_ALLOC); > > @@ -5015,21 +5017,15 @@ kmem_cache_prefill_sheaf(struct kmem_cache *s, gfp_t gfp, unsigned int size) > > if (unlikely(size > s->sheaf_capacity)) { > > - sheaf = kzalloc_flex(*sheaf, objects, size, gfp); > + sheaf = __alloc_empty_sheaf(s, gfp, size); > if (!sheaf) > return NULL; > > stat(s, SHEAF_PREFILL_OVERSIZE); > - sheaf->cache = s; > - sheaf->capacity = size; > > - /* > - * we do not need to care about pfmemalloc here because oversize > - * sheaves area always flushed and freed when returned > - */ > if (!__kmem_cache_alloc_bulk(s, gfp, size, > &sheaf->objects[0])) { > - kfree(sheaf); > + free_empty_sheaf(s, sheaf); > return NULL; > } > > @@ -5064,9 +5060,6 @@ kmem_cache_prefill_sheaf(struct kmem_cache *s, gfp_t gfp, unsigned int size) > sheaf = alloc_empty_sheaf(s, gfp); > > if (sheaf) { > - sheaf->capacity = s->sheaf_capacity; > - sheaf->pfmemalloc = false; I think we couldn't delete 'sheaf->pfmemalloc = false;', because the 'sheaf' pointer here could points to a normal size sheaf via the `if (pcs->spare) {} else {}` statements above. > - > if (sheaf->size < size && > __prefill_sheaf_pfmemalloc(s, sheaf, gfp)) { > sheaf_flush_unused(s, sheaf); > @@ -5097,7 +5090,7 @@ void kmem_cache_return_sheaf(struct kmem_cache *s, gfp_t gfp, > if (unlikely((sheaf->capacity != s->sheaf_capacity) > || sheaf->pfmemalloc)) { > sheaf_flush_unused(s, sheaf); > - kfree(sheaf); > + free_empty_sheaf(s, sheaf); > return; > } > > -- > 2.25.1 -- Thanks, Hao ^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH v2] mm/slub: free prefilled empty sheaves consistently 2026-05-25 6:38 ` Hao Li @ 2026-05-25 7:39 ` hu.shengming 0 siblings, 0 replies; 3+ messages in thread From: hu.shengming @ 2026-05-25 7:39 UTC (permalink / raw) To: hao.li Cc: vbabka, harry, akpm, cl, rientjes, roman.gushchin, linux-mm, linux-kernel, zhang.run, cai.qu Hao wrote: > On Fri, May 22, 2026 at 02:59:00PM +0800, hu.shengming@zte.com.cn wrote: > > From: Shengming Hu <hu.shengming@zte.com.cn> > > > > Empty sheaves allocated by alloc_empty_sheaf() should be released with > > free_empty_sheaf(). > > > > Move the common empty-sheaf initialization into __alloc_empty_sheaf(), > > including the capacity and default pfmemalloc state, and use it for > > oversized prefilled sheaves as well. > > > > This keeps the prefill paths consistent: after flushing an oversized or > > pfmemalloc sheaf, release the now-empty sheaf through free_empty_sheaf() > > instead of kfree(). > > > > Signed-off-by: Shengming Hu <hu.shengming@zte.com.cn> > > --- > > Changes in v2: > > - Rework the change as suggested by Harry. > > - Teach __alloc_empty_sheaf() to initialize capacity and pfmemalloc. > > - Allocate oversized prefilled sheaves through __alloc_empty_sheaf(). > > - Free flushed oversized and pfmemalloc sheaves through free_empty_sheaf(). > > - Link to v1: https://lore.kernel.org/all/20260521195015105Y4zvKHj0TfPZEujixy9Vo@zte.com.cn/ > > > > --- > > mm/slub.c | 17 +++++------------ > > 1 file changed, 5 insertions(+), 12 deletions(-) > > > > diff --git a/mm/slub.c b/mm/slub.c > > index 04692a6f9128..bbe8351f1bfa 100644 > > --- a/mm/slub.c > > +++ b/mm/slub.c > > @@ -2782,6 +2782,8 @@ static struct slab_sheaf *__alloc_empty_sheaf(struct kmem_cache *s, gfp_t gfp, > > return NULL; > > > > sheaf->cache = s; > > + sheaf->capacity = capacity; > > + sheaf->pfmemalloc = false; > > we could eliminate `sheaf->pfmemalloc = false;` because the allocation use > kzalloc. > Hi Hao, Thanks for the review. Yes, I agree that `sheaf->pfmemalloc = false` in __alloc_empty_sheaf() is redundant, as the sheaf is allocated through kzalloc(). > > > > stat(s, SHEAF_ALLOC); > > > > @@ -5015,21 +5017,15 @@ kmem_cache_prefill_sheaf(struct kmem_cache *s, gfp_t gfp, unsigned int size) > > > > if (unlikely(size > s->sheaf_capacity)) { > > > > - sheaf = kzalloc_flex(*sheaf, objects, size, gfp); > > + sheaf = __alloc_empty_sheaf(s, gfp, size); > > if (!sheaf) > > return NULL; > > > > stat(s, SHEAF_PREFILL_OVERSIZE); > > - sheaf->cache = s; > > - sheaf->capacity = size; > > > > - /* > > - * we do not need to care about pfmemalloc here because oversize > > - * sheaves area always flushed and freed when returned > > - */ > > if (!__kmem_cache_alloc_bulk(s, gfp, size, > > &sheaf->objects[0])) { > > - kfree(sheaf); > > + free_empty_sheaf(s, sheaf); > > return NULL; > > } > > > > @@ -5064,9 +5060,6 @@ kmem_cache_prefill_sheaf(struct kmem_cache *s, gfp_t gfp, unsigned int size) > > sheaf = alloc_empty_sheaf(s, gfp); > > > > if (sheaf) { > > - sheaf->capacity = s->sheaf_capacity; > > - sheaf->pfmemalloc = false; > > I think we couldn't delete 'sheaf->pfmemalloc = false;', because the 'sheaf' > pointer here could points to a normal size sheaf via the `if (pcs->spare) {} > else {}` statements above. > You are also right that sheaf in the normal-sized prefill path may come from pcs->spare or the barn rather than from a fresh __alloc_empty_sheaf() allocation. Therefore, the pfmemalloc state cannot rely on the zeroed allocation there, and I will restore the explicit initialization in kmem_cache_prefill_sheaf(). Also, after looking at this again, I found that capacity needs the same treatment.`capacity` and `pfmemalloc` share storage with `rcu_head`/`barn_list`, so the prefill-specific fields need to be reinitialized whenever a normal-sized sheaf is reused as a prefilled sheaf. I will restore both assignments in v3. > > - > > if (sheaf->size < size && > > __prefill_sheaf_pfmemalloc(s, sheaf, gfp)) { > > sheaf_flush_unused(s, sheaf); > > @@ -5097,7 +5090,7 @@ void kmem_cache_return_sheaf(struct kmem_cache *s, gfp_t gfp, > > if (unlikely((sheaf->capacity != s->sheaf_capacity) > > || sheaf->pfmemalloc)) { > > sheaf_flush_unused(s, sheaf); > > - kfree(sheaf); > > + free_empty_sheaf(s, sheaf); > > return; > > } > > > > -- > > 2.25.1 > > -- > Thanks, > Hao -- With Best Regards, Shengming ^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-05-25 7:40 UTC | newest] Thread overview: 3+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-05-22 6:59 [PATCH v2] mm/slub: free prefilled empty sheaves consistently hu.shengming 2026-05-25 6:38 ` Hao Li 2026-05-25 7:39 ` hu.shengming
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox