[PATCH v4] mm/slub: use empty sheaf helpers for oversized sheaves

hu.shengming@zte.com.cn posted 1 patch 1 week, 6 days ago
There is a newer version of this series
mm/slub.c | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
[PATCH v4] mm/slub: use empty sheaf helpers for oversized sheaves
Posted by hu.shengming@zte.com.cn 1 week, 6 days ago
From: Shengming Hu <hu.shengming@zte.com.cn>

Oversized prefilled sheaves are allocated separately, but after they are
flushed they are empty sheaves as well. Release them through
free_empty_sheaf() instead of calling kfree() directly.

Use __alloc_empty_sheaf() for oversized prefilled sheaves as well, so
that they are allocated through the same helper as regular empty sheaves
and released through the matching helper.

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.

This keeps the oversized and pfmemalloc prefill paths consistent after
flushing.

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/

Changes in v3:
- Address Hao's comments:
- Drop the redundant `pfmemalloc` initialization in
  __alloc_empty_sheaf().
- Keep initializing `capacity` and `pfmemalloc` in the normal-sized
  prefill path, since the sheaf may be reused rather than freshly
  allocated.
- Link to v2: https://lore.kernel.org/all/20260522145900248m-nBcy07_SCDk2ATDWfmg@zte.com.cn/

Changes in v4:
- Address comments from Hao and Harry:
- Keep capacity initialization in the oversized prefill path.
- Update SHEAF_ALLOC and SHEAF_FREE comments to mention oversized sheaves.
- Restore the oversized sheaf pfmemalloc comment.
- Link to v3: https://lore.kernel.org/all/20260525211000387LYqTHmxYL900XIB8qwV3h@zte.com.cn/

---
 mm/slub.c | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/mm/slub.c b/mm/slub.c
index 04692a6f9128..08812de7a8b5 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -362,8 +362,8 @@ enum stat_item {
 	CMPXCHG_DOUBLE_FAIL,	/* Failures of slab freelist update */
 	SHEAF_FLUSH,		/* Objects flushed from a sheaf */
 	SHEAF_REFILL,		/* Objects refilled to a sheaf */
-	SHEAF_ALLOC,		/* Allocation of an empty sheaf */
-	SHEAF_FREE,		/* Freeing of an empty sheaf */
+	SHEAF_ALLOC,		/* Allocation of an empty sheaf including oversized ones */
+	SHEAF_FREE,		/* Freeing of an empty sheaf including oversized ones */
 	BARN_GET,		/* Got full sheaf from barn */
 	BARN_GET_FAIL,		/* Failed to get full sheaf from barn */
 	BARN_PUT,		/* Put full sheaf to barn */
@@ -5015,12 +5015,11 @@ 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;

 		/*
@@ -5029,7 +5028,7 @@ kmem_cache_prefill_sheaf(struct kmem_cache *s, gfp_t gfp, unsigned int size)
 		 */
 		if (!__kmem_cache_alloc_bulk(s, gfp, size,
 					     &sheaf->objects[0])) {
-			kfree(sheaf);
+			free_empty_sheaf(s, sheaf);
 			return NULL;
 		}

@@ -5097,7 +5096,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
Re: [PATCH v4] mm/slub: use empty sheaf helpers for oversized sheaves
Posted by Vlastimil Babka (SUSE) 1 week, 5 days ago
On 5/26/26 17:24, hu.shengming@zte.com.cn wrote:
> From: Shengming Hu <hu.shengming@zte.com.cn>
> 
> Oversized prefilled sheaves are allocated separately, but after they are
> flushed they are empty sheaves as well. Release them through
> free_empty_sheaf() instead of calling kfree() directly.
> 
> Use __alloc_empty_sheaf() for oversized prefilled sheaves as well, so
> that they are allocated through the same helper as regular empty sheaves
> and released through the matching helper.
> 
> 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.
> 
> This keeps the oversized and pfmemalloc prefill paths consistent after
> flushing.
> 
> Signed-off-by: Shengming Hu <hu.shengming@zte.com.cn>

Hmm, __alloc_empty_sheaf() does "gfp &= ~OBJCGS_CLEAR_MASK" which includes
__GFP_NOFAIL. A caller of kmem_cache_prefill_sheaf() with __GFP_NOFAIL might
not expect failure. The __GFP_NO_OBJ_EXT handling is also not necessary for
prefilled sheaves.

Well maybe all the gfp handling could be simply moved to
alloc_empty_sheaf()? The other caller of __alloc_empty_sheaf() is
bootstrap_cache_sheaves() and I think it doesn't need it either.

> ---
> 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/
> 
> Changes in v3:
> - Address Hao's comments:
> - Drop the redundant `pfmemalloc` initialization in
>   __alloc_empty_sheaf().
> - Keep initializing `capacity` and `pfmemalloc` in the normal-sized
>   prefill path, since the sheaf may be reused rather than freshly
>   allocated.
> - Link to v2: https://lore.kernel.org/all/20260522145900248m-nBcy07_SCDk2ATDWfmg@zte.com.cn/
> 
> Changes in v4:
> - Address comments from Hao and Harry:
> - Keep capacity initialization in the oversized prefill path.
> - Update SHEAF_ALLOC and SHEAF_FREE comments to mention oversized sheaves.
> - Restore the oversized sheaf pfmemalloc comment.
> - Link to v3: https://lore.kernel.org/all/20260525211000387LYqTHmxYL900XIB8qwV3h@zte.com.cn/
> 
> ---
>  mm/slub.c | 11 +++++------
>  1 file changed, 5 insertions(+), 6 deletions(-)
> 
> diff --git a/mm/slub.c b/mm/slub.c
> index 04692a6f9128..08812de7a8b5 100644
> --- a/mm/slub.c
> +++ b/mm/slub.c
> @@ -362,8 +362,8 @@ enum stat_item {
>  	CMPXCHG_DOUBLE_FAIL,	/* Failures of slab freelist update */
>  	SHEAF_FLUSH,		/* Objects flushed from a sheaf */
>  	SHEAF_REFILL,		/* Objects refilled to a sheaf */
> -	SHEAF_ALLOC,		/* Allocation of an empty sheaf */
> -	SHEAF_FREE,		/* Freeing of an empty sheaf */
> +	SHEAF_ALLOC,		/* Allocation of an empty sheaf including oversized ones */
> +	SHEAF_FREE,		/* Freeing of an empty sheaf including oversized ones */
>  	BARN_GET,		/* Got full sheaf from barn */
>  	BARN_GET_FAIL,		/* Failed to get full sheaf from barn */
>  	BARN_PUT,		/* Put full sheaf to barn */
> @@ -5015,12 +5015,11 @@ 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;
> 
>  		/*
> @@ -5029,7 +5028,7 @@ kmem_cache_prefill_sheaf(struct kmem_cache *s, gfp_t gfp, unsigned int size)
>  		 */
>  		if (!__kmem_cache_alloc_bulk(s, gfp, size,
>  					     &sheaf->objects[0])) {
> -			kfree(sheaf);
> +			free_empty_sheaf(s, sheaf);
>  			return NULL;
>  		}
> 
> @@ -5097,7 +5096,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;
>  	}
>
Re: [PATCH v4] mm/slub: use empty sheaf helpers for oversized sheaves
Posted by hu.shengming@zte.com.cn 1 week, 5 days ago
VlastimilBabka(SUSE)<vbabka@kernel.org> wrote:
> On 5/26/26 17:24, hu.shengming@zte.com.cn wrote:
> > From: Shengming Hu <hu.shengming@zte.com.cn>
> > 
> > Oversized prefilled sheaves are allocated separately, but after they are
> > flushed they are empty sheaves as well. Release them through
> > free_empty_sheaf() instead of calling kfree() directly.
> > 
> > Use __alloc_empty_sheaf() for oversized prefilled sheaves as well, so
> > that they are allocated through the same helper as regular empty sheaves
> > and released through the matching helper.
> > 
> > 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.
> > 
> > This keeps the oversized and pfmemalloc prefill paths consistent after
> > flushing.
> > 
> > Signed-off-by: Shengming Hu <hu.shengming@zte.com.cn>
> 
> Hmm, __alloc_empty_sheaf() does "gfp &= ~OBJCGS_CLEAR_MASK" which includes
> __GFP_NOFAIL. A caller of kmem_cache_prefill_sheaf() with __GFP_NOFAIL might
> not expect failure. The __GFP_NO_OBJ_EXT handling is also not necessary for
> prefilled sheaves.
> 
> Well maybe all the gfp handling could be simply moved to
> alloc_empty_sheaf()? The other caller of __alloc_empty_sheaf() is
> bootstrap_cache_sheaves() and I think it doesn't need it either.
> 

Thanks for the review!

I agree that clearing OBJCGS_CLEAR_MASK in __alloc_empty_sheaf()
is not right for the oversized prefill path. In particular, it changes
the caller-provided GFP flags and can drop __GFP_NOFAIL. I will move that
part out of __alloc_empty_sheaf().

I am less sure about moving the __GFP_NO_OBJ_EXT handling out of
__alloc_empty_sheaf() as well, because that seems to make the free side
more complicated.

Currently free_empty_sheaf() assumes that sheaves for SLAB_KMALLOC caches
were allocated with __GFP_NO_OBJ_EXT, and therefore calls
mark_obj_codetag_empty() before kfree(). If __GFP_NO_OBJ_EXT is moved out
of __alloc_empty_sheaf(), then oversized prefilled sheaves allocated by
the raw helper would not have that flag anymore, while regular sheaves
allocated through alloc_empty_sheaf() would still have it.

In that case, the return path could no longer use one free helper for both
oversized and pfmemalloc sheaves after flushing. It would need to split
the two cases, for example:

        if (unlikely(sheaf->capacity != s->sheaf_capacity)) {
                sheaf_flush_unused(s, sheaf);
                __free_empty_sheaf(s, sheaf);
                return;
        }

        if (unlikely(sheaf->pfmemalloc)) {
                sheaf_flush_unused(s, sheaf);
                free_empty_sheaf(s, sheaf);
                return;
        }

There is also the bootstrap_cache_sheaves() case. The sheaves allocated
there are regular-sized sheaves. If such a sheaf later reaches
kmem_cache_return_sheaf(), it could not safely be released through
free_empty_sheaf() unless it was also allocated with __GFP_NO_OBJ_EXT,
because free_empty_sheaf() currently assumes that SLAB_KMALLOC sheaves
were allocated with __GFP_NO_OBJ_EXT and calls mark_obj_codetag_empty().
Unlike oversized sheaves, these bootstrap-created sheaves have the regular
capacity, so the return path cannot distinguish them by
sheaf->capacity != s->sheaf_capacity.

So I wonder if it would be better to move only the OBJCGS_CLEAR_MASK
clearing out of __alloc_empty_sheaf(), but keep the __GFP_NO_OBJ_EXT
handling there. That would fix the __GFP_NOFAIL issue for oversized
prefilled sheaves, while still keeping the allocation/free assumptions
consistent and allowing flushed oversized and pfmemalloc sheaves to use
the same free_empty_sheaf() path.

Would this approach be acceptable, or did I misunderstand your suggestion?

--
With Best Regards,
Shengming
Re: [PATCH v4] mm/slub: use empty sheaf helpers for oversized sheaves
Posted by Vlastimil Babka (SUSE) 1 week, 5 days ago
On 5/27/26 15:48, hu.shengming@zte.com.cn wrote:
> VlastimilBabka(SUSE)<vbabka@kernel.org> wrote:
>> On 5/26/26 17:24, hu.shengming@zte.com.cn wrote:
>> > From: Shengming Hu <hu.shengming@zte.com.cn>
>> > 
>> > Oversized prefilled sheaves are allocated separately, but after they are
>> > flushed they are empty sheaves as well. Release them through
>> > free_empty_sheaf() instead of calling kfree() directly.
>> > 
>> > Use __alloc_empty_sheaf() for oversized prefilled sheaves as well, so
>> > that they are allocated through the same helper as regular empty sheaves
>> > and released through the matching helper.
>> > 
>> > 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.
>> > 
>> > This keeps the oversized and pfmemalloc prefill paths consistent after
>> > flushing.
>> > 
>> > Signed-off-by: Shengming Hu <hu.shengming@zte.com.cn>
>> 
>> Hmm, __alloc_empty_sheaf() does "gfp &= ~OBJCGS_CLEAR_MASK" which includes
>> __GFP_NOFAIL. A caller of kmem_cache_prefill_sheaf() with __GFP_NOFAIL might
>> not expect failure. The __GFP_NO_OBJ_EXT handling is also not necessary for
>> prefilled sheaves.
>> 
>> Well maybe all the gfp handling could be simply moved to
>> alloc_empty_sheaf()? The other caller of __alloc_empty_sheaf() is
>> bootstrap_cache_sheaves() and I think it doesn't need it either.
>> 
> 
> Thanks for the review!
> 
> I agree that clearing OBJCGS_CLEAR_MASK in __alloc_empty_sheaf()
> is not right for the oversized prefill path. In particular, it changes
> the caller-provided GFP flags and can drop __GFP_NOFAIL. I will move that
> part out of __alloc_empty_sheaf().
> 
> I am less sure about moving the __GFP_NO_OBJ_EXT handling out of
> __alloc_empty_sheaf() as well, because that seems to make the free side
> more complicated.
> 
> Currently free_empty_sheaf() assumes that sheaves for SLAB_KMALLOC caches
> were allocated with __GFP_NO_OBJ_EXT, and therefore calls
> mark_obj_codetag_empty() before kfree(). If __GFP_NO_OBJ_EXT is moved out
> of __alloc_empty_sheaf(), then oversized prefilled sheaves allocated by
> the raw helper would not have that flag anymore, while regular sheaves
> allocated through alloc_empty_sheaf() would still have it.
> 
> In that case, the return path could no longer use one free helper for both
> oversized and pfmemalloc sheaves after flushing. It would need to split
> the two cases, for example:
> 
>         if (unlikely(sheaf->capacity != s->sheaf_capacity)) {
>                 sheaf_flush_unused(s, sheaf);
>                 __free_empty_sheaf(s, sheaf);
>                 return;
>         }
> 
>         if (unlikely(sheaf->pfmemalloc)) {
>                 sheaf_flush_unused(s, sheaf);
>                 free_empty_sheaf(s, sheaf);
>                 return;
>         }
> 
> There is also the bootstrap_cache_sheaves() case. The sheaves allocated
> there are regular-sized sheaves. If such a sheaf later reaches
> kmem_cache_return_sheaf(), it could not safely be released through
> free_empty_sheaf() unless it was also allocated with __GFP_NO_OBJ_EXT,
> because free_empty_sheaf() currently assumes that SLAB_KMALLOC sheaves
> were allocated with __GFP_NO_OBJ_EXT and calls mark_obj_codetag_empty().
> Unlike oversized sheaves, these bootstrap-created sheaves have the regular
> capacity, so the return path cannot distinguish them by
> sheaf->capacity != s->sheaf_capacity.
> 
> So I wonder if it would be better to move only the OBJCGS_CLEAR_MASK
> clearing out of __alloc_empty_sheaf(), but keep the __GFP_NO_OBJ_EXT
> handling there. That would fix the __GFP_NOFAIL issue for oversized
> prefilled sheaves, while still keeping the allocation/free assumptions
> consistent and allowing flushed oversized and pfmemalloc sheaves to use
> the same free_empty_sheaf() path.
> 
> Would this approach be acceptable, or did I misunderstand your suggestion?

I see, thanks. Could we perhaps move the mark_obj_codetag_empty() code to
alloc_empty_sheaf()? If not, then do as you suggest?

> 
> --
> With Best Regards,
> Shengming
Re: [PATCH v4] mm/slub: use empty sheaf helpers for oversized sheaves
Posted by hu.shengming@zte.com.cn 1 week, 4 days ago
VlastimilBabka(SUSE)<vbabka@kernel.org> wrote:
>On 5/27/26 15:48, hu.shengming@zte.com.cn wrote:
>> VlastimilBabka(SUSE)<vbabka@kernel.org> wrote:
>>> On 5/26/26 17:24, hu.shengming@zte.com.cn wrote:
>>> > From: Shengming Hu <hu.shengming@zte.com.cn>
>>> > 
>>> > Oversized prefilled sheaves are allocated separately, but after they are
>>> > flushed they are empty sheaves as well. Release them through
>>> > free_empty_sheaf() instead of calling kfree() directly.
>>> > 
>>> > Use __alloc_empty_sheaf() for oversized prefilled sheaves as well, so
>>> > that they are allocated through the same helper as regular empty sheaves
>>> > and released through the matching helper.
>>> > 
>>> > 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.
>>> > 
>>> > This keeps the oversized and pfmemalloc prefill paths consistent after
>>> > flushing.
>>> > 
>>> > Signed-off-by: Shengming Hu <hu.shengming@zte.com.cn>
>>> 
>>> Hmm, __alloc_empty_sheaf() does "gfp &= ~OBJCGS_CLEAR_MASK" which includes
>>> __GFP_NOFAIL. A caller of kmem_cache_prefill_sheaf() with __GFP_NOFAIL might
>>> not expect failure. The __GFP_NO_OBJ_EXT handling is also not necessary for
>>> prefilled sheaves.
>>> 
>>> Well maybe all the gfp handling could be simply moved to
>>> alloc_empty_sheaf()? The other caller of __alloc_empty_sheaf() is
>>> bootstrap_cache_sheaves() and I think it doesn't need it either.
>>> 
>> 
>> Thanks for the review!
>> 
>> I agree that clearing OBJCGS_CLEAR_MASK in __alloc_empty_sheaf()
>> is not right for the oversized prefill path. In particular, it changes
>> the caller-provided GFP flags and can drop __GFP_NOFAIL. I will move that
>> part out of __alloc_empty_sheaf().
>> 
>> I am less sure about moving the __GFP_NO_OBJ_EXT handling out of
>> __alloc_empty_sheaf() as well, because that seems to make the free side
>> more complicated.
>> 
>> Currently free_empty_sheaf() assumes that sheaves for SLAB_KMALLOC caches
>> were allocated with __GFP_NO_OBJ_EXT, and therefore calls
>> mark_obj_codetag_empty() before kfree(). If __GFP_NO_OBJ_EXT is moved out
>> of __alloc_empty_sheaf(), then oversized prefilled sheaves allocated by
>> the raw helper would not have that flag anymore, while regular sheaves
>> allocated through alloc_empty_sheaf() would still have it.
>> 
>> In that case, the return path could no longer use one free helper for both
>> oversized and pfmemalloc sheaves after flushing. It would need to split
>> the two cases, for example:
>> 
>>         if (unlikely(sheaf->capacity != s->sheaf_capacity)) {
>>                 sheaf_flush_unused(s, sheaf);
>>                 __free_empty_sheaf(s, sheaf);
>>                 return;
>>         }
>> 
>>         if (unlikely(sheaf->pfmemalloc)) {
>>                 sheaf_flush_unused(s, sheaf);
>>                 free_empty_sheaf(s, sheaf);
>>                 return;
>>         }
>> 
>> There is also the bootstrap_cache_sheaves() case. The sheaves allocated
>> there are regular-sized sheaves. If such a sheaf later reaches
>> kmem_cache_return_sheaf(), it could not safely be released through
>> free_empty_sheaf() unless it was also allocated with __GFP_NO_OBJ_EXT,
>> because free_empty_sheaf() currently assumes that SLAB_KMALLOC sheaves
>> were allocated with __GFP_NO_OBJ_EXT and calls mark_obj_codetag_empty().
>> Unlike oversized sheaves, these bootstrap-created sheaves have the regular
>> capacity, so the return path cannot distinguish them by
>> sheaf->capacity != s->sheaf_capacity.
>> 
>> So I wonder if it would be better to move only the OBJCGS_CLEAR_MASK
>> clearing out of __alloc_empty_sheaf(), but keep the __GFP_NO_OBJ_EXT
>> handling there. That would fix the __GFP_NOFAIL issue for oversized
>> prefilled sheaves, while still keeping the allocation/free assumptions
>> consistent and allowing flushed oversized and pfmemalloc sheaves to use
>> the same free_empty_sheaf() path.
>> 
>> Would this approach be acceptable, or did I misunderstand your suggestion?
>
> I see, thanks. Could we perhaps move the mark_obj_codetag_empty() code to
> alloc_empty_sheaf()? If not, then do as you suggest?
>

I looked at moving mark_obj_codetag_empty() to alloc_empty_sheaf(), but I
don't think it is equivalent to doing it on the free path.

mark_obj_codetag_empty() only marks an entry if the slab already has
slabobj_exts. For sheaf metadata allocated with __GFP_NO_OBJ_EXT, the
allocation hook will not create the object extension. So if the slab has
no obj_exts at allocation time, an allocation-time mark would be a no-op.
A slabobj_ext can still be created later for the same kmalloc slab by
another allocation, and then freeing the sheaf without marking it on the
free path can still leave the sheaf entry with a NULL tag.

So I think the marking should stay in free_empty_sheaf(). I can still
move the caller-GFP filtering out of __alloc_empty_sheaf(). That includes
both clearing OBJCGS_CLEAR_MASK and handling the early rejection of
caller-supplied __GFP_NO_OBJ_EXT:

	if (gfp & __GFP_NO_OBJ_EXT)
		return NULL;

Moving this filtering to the caller would let the oversized prefill path
avoid losing __GFP_NOFAIL.But I would keep the SLAB_KMALLOC-specific
__GFP_NO_OBJ_EXT allocation and the matching free-time mark together.

Please let me know if you have a better suggestion.

--
With Best Regards,
Shengming
Re: [PATCH v4] mm/slub: use empty sheaf helpers for oversized sheaves
Posted by Vlastimil Babka (SUSE) 1 week, 4 days ago
On 5/28/26 08:37, hu.shengming@zte.com.cn wrote:
> VlastimilBabka(SUSE)<vbabka@kernel.org> wrote:
>>On 5/27/26 15:48, hu.shengming@zte.com.cn wrote:
>>
>> I see, thanks. Could we perhaps move the mark_obj_codetag_empty() code to
>> alloc_empty_sheaf()? If not, then do as you suggest?
>>
> 
> I looked at moving mark_obj_codetag_empty() to alloc_empty_sheaf(), but I
> don't think it is equivalent to doing it on the free path.
> 
> mark_obj_codetag_empty() only marks an entry if the slab already has
> slabobj_exts. For sheaf metadata allocated with __GFP_NO_OBJ_EXT, the
> allocation hook will not create the object extension. So if the slab has
> no obj_exts at allocation time, an allocation-time mark would be a no-op.
> A slabobj_ext can still be created later for the same kmalloc slab by
> another allocation, and then freeing the sheaf without marking it on the
> free path can still leave the sheaf entry with a NULL tag.

Ah right, makes sense.

> So I think the marking should stay in free_empty_sheaf(). I can still
> move the caller-GFP filtering out of __alloc_empty_sheaf(). That includes
> both clearing OBJCGS_CLEAR_MASK and handling the early rejection of
> caller-supplied __GFP_NO_OBJ_EXT:
> 
> 	if (gfp & __GFP_NO_OBJ_EXT)
> 		return NULL;
> 
> Moving this filtering to the caller would let the oversized prefill path
> avoid losing __GFP_NOFAIL.But I would keep the SLAB_KMALLOC-specific
> __GFP_NO_OBJ_EXT allocation and the matching free-time mark together.

Sounds good! Thanks!

> Please let me know if you have a better suggestion.
> 
> --
> With Best Regards,
> Shengming