All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] mm/slab: only require the requested size when refilling prefilled sheaves
@ 2026-10-23  9:44 Qing Wang
  2026-10-23 14:22 ` Harry Yoo
  0 siblings, 1 reply; 3+ messages in thread
From: Qing Wang @ 2026-10-23  9:44 UTC (permalink / raw)
  To: Vlastimil Babka, Harry Yoo, Andrew Morton, Hao Li,
	Christoph Lameter, David Rientjes, Roman Gushchin
  Cc: linux-mm, linux-kernel, Qing Wang

kmem_cache_prefill_sheaf() and kmem_cache_refill_sheaf() only guarantee
@size objects, but for standard capacity sheaves
__prefill_sheaf_pfmemalloc() uses refill_sheaf(), which actually fills
the sheaf up to s->sheaf_capacity. The call thus fails with -ENOMEM
whenever the sheaf cannot be filled completely, even when @size objects
were already obtained. This leads to needless flushing of the partially
filled sheaf in kmem_cache_prefill_sheaf(), and may use pfmemalloc
reserves to fill the sheaf beyond what was requested.

Pass the @size from kmem_cache_prefill_sheaf() and
kmem_cache_refill_sheaf() down to __prefill_sheaf_pfmemalloc(), and have
it use the newly added refill_sheaf_min(), which returns success once
the sheaf holds @min_size objects while still trying to fill it up to
s->sheaf_capacity.

refill_sheaf() remains the full-capacity variant for
__pcs_replace_empty_main() and kmem_cache_return_sheaf(), because sheaves
on the barn's full list must be full.

Signed-off-by: Qing Wang <wangqing7171@gmail.com>
---
 mm/slub.c | 36 ++++++++++++++++++++++++------------
 1 file changed, 24 insertions(+), 12 deletions(-)

diff --git a/mm/slub.c b/mm/slub.c
index 544cff39762c..4f92b3e30d84 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -2873,28 +2873,39 @@ static unsigned int
 refill_objects(struct kmem_cache *s, void **p, gfp_t gfp, unsigned int min,
 	       unsigned int max);
 
-static int refill_sheaf(struct kmem_cache *s, struct slab_sheaf *sheaf,
-			 gfp_t gfp)
+/*
+ * Refill a sheaf with at least min_size objects, up to the sheaf's capacity.
+ * Returns 0 on success, -ENOMEM if the sheaf could not be filled to min_size.
+ */
+static int refill_sheaf_min(struct kmem_cache *s, struct slab_sheaf *sheaf,
+			    gfp_t gfp, unsigned int min_size)
 {
-	int to_fill = s->sheaf_capacity - sheaf->size;
+	int min_fill = min_size - sheaf->size;
+	int max_fill = s->sheaf_capacity - sheaf->size;
 	int filled;
 
-	if (!to_fill)
+	if (!min_fill)
 		return 0;
 
-	filled = refill_objects(s, &sheaf->objects[sheaf->size], gfp, to_fill,
-				to_fill);
+	filled = refill_objects(s, &sheaf->objects[sheaf->size], gfp, min_fill,
+				max_fill);
 
 	sheaf->size += filled;
 
 	stat_add(s, SHEAF_REFILL, filled);
 
-	if (filled < to_fill)
+	if (filled < min_fill)
 		return -ENOMEM;
 
 	return 0;
 }
 
+static int refill_sheaf(struct kmem_cache *s, struct slab_sheaf *sheaf,
+			 gfp_t gfp)
+{
+	return refill_sheaf_min(s, sheaf, gfp, s->sheaf_capacity);
+}
+
 /*
  * Maximum number of objects freed during a single flush of main pcs sheaf.
  * Translates directly to an on-stack array size.
@@ -5074,7 +5085,8 @@ void *kmem_cache_alloc_node_noprof(struct kmem_cache *s, gfp_t gfpflags, int nod
 EXPORT_SYMBOL(kmem_cache_alloc_node_noprof);
 
 static int __prefill_sheaf_pfmemalloc(struct kmem_cache *s,
-				      struct slab_sheaf *sheaf, gfp_t gfp)
+				      struct slab_sheaf *sheaf, gfp_t gfp,
+				      unsigned int size)
 {
 	gfp_t gfp_nomemalloc;
 	int ret;
@@ -5083,7 +5095,7 @@ static int __prefill_sheaf_pfmemalloc(struct kmem_cache *s,
 	if (gfp_pfmemalloc_allowed(gfp))
 		gfp_nomemalloc |= __GFP_NOWARN;
 
-	ret = refill_sheaf(s, sheaf, gfp_nomemalloc);
+	ret = refill_sheaf_min(s, sheaf, gfp_nomemalloc, size);
 
 	if (likely(!ret || !gfp_pfmemalloc_allowed(gfp)))
 		return ret;
@@ -5092,7 +5104,7 @@ static int __prefill_sheaf_pfmemalloc(struct kmem_cache *s,
 	 * if we are allowed to, refill sheaf with pfmemalloc but then remember
 	 * it for when it's returned
 	 */
-	ret = refill_sheaf(s, sheaf, gfp);
+	ret = refill_sheaf_min(s, sheaf, gfp, size);
 	sheaf->pfmemalloc = true;
 
 	return ret;
@@ -5171,7 +5183,7 @@ kmem_cache_prefill_sheaf(struct kmem_cache *s, gfp_t gfp, unsigned int size)
 		sheaf->pfmemalloc = false;
 
 		if (sheaf->size < size &&
-		    __prefill_sheaf_pfmemalloc(s, sheaf, gfp)) {
+		    __prefill_sheaf_pfmemalloc(s, sheaf, gfp, size)) {
 			sheaf_flush_unused(s, sheaf);
 			free_empty_sheaf(s, sheaf);
 			sheaf = NULL;
@@ -5267,7 +5279,7 @@ int kmem_cache_refill_sheaf(struct kmem_cache *s, gfp_t gfp,
 
 	if (likely(sheaf->capacity >= size)) {
 		if (likely(sheaf->capacity == s->sheaf_capacity))
-			return __prefill_sheaf_pfmemalloc(s, sheaf, gfp);
+			return __prefill_sheaf_pfmemalloc(s, sheaf, gfp, size);
 
 		if (!__kmem_cache_alloc_bulk(s, gfp, sheaf->capacity - sheaf->size,
 					     &sheaf->objects[sheaf->size]))
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] mm/slab: only require the requested size when refilling prefilled sheaves
  2026-10-23  9:44 [PATCH] mm/slab: only require the requested size when refilling prefilled sheaves Qing Wang
@ 2026-10-23 14:22 ` Harry Yoo
  2026-10-26  9:29   ` [PATCH] mm/slab: only require the requested size when refilling Qing Wang
  0 siblings, 1 reply; 3+ messages in thread
From: Harry Yoo @ 2026-10-23 14:22 UTC (permalink / raw)
  To: Qing Wang
  Cc: Vlastimil Babka, Andrew Morton, Hao Li, Christoph Lameter,
	David Rientjes, Roman Gushchin, linux-mm, linux-kernel

On Fri, Oct 23, 2026 at 05:44:01PM +0800, Qing Wang wrote:
> kmem_cache_prefill_sheaf() and kmem_cache_refill_sheaf() only guarantee
> @size objects, but for standard capacity sheaves
> __prefill_sheaf_pfmemalloc() uses refill_sheaf(), which actually fills
> the sheaf up to s->sheaf_capacity.
>
> The call thus fails with -ENOMEM > whenever the sheaf cannot be filled
> completely, even when @size objects were already obtained.

This is extremely rare condition to happen, and so...

> This leads to needless flushing of the partially
> filled sheaf in kmem_cache_prefill_sheaf(),

It doesn't make much sense to micro-optimize slab in low or out of
memory situations.

> and may use pfmemalloc
> reserves to fill the sheaf beyond what was requested.

But the request size itself is a speculation and unused objects will be
returned back to the allocator anyway.

> Pass the @size from kmem_cache_prefill_sheaf() and
> kmem_cache_refill_sheaf() down to __prefill_sheaf_pfmemalloc(), and have
> it use the newly added refill_sheaf_min(), which returns success once
> the sheaf holds @min_size objects while still trying to fill it up to
> s->sheaf_capacity.
> 
> refill_sheaf() remains the full-capacity variant for
> __pcs_replace_empty_main() and kmem_cache_return_sheaf(), because sheaves
> on the barn's full list must be full.
>
> Signed-off-by: Qing Wang <wangqing7171@gmail.com>

-- 
Cheers,
Harry / Hyeonggon


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] mm/slab: only require the requested size when refilling
  2026-10-23 14:22 ` Harry Yoo
@ 2026-10-26  9:29   ` Qing Wang
  0 siblings, 0 replies; 3+ messages in thread
From: Qing Wang @ 2026-10-26  9:29 UTC (permalink / raw)
  To: harry
  Cc: akpm, cl, hao.li, linux-kernel, linux-mm, rientjes,
	roman.gushchin, vbabka, wangqing7171

On Fri, 23 Oct 2026 at 22:22, Harry Yoo <harry@kernel.org> wrote:
> On Fri, Oct 23, 2026 at 05:44:01PM +0800, Qing Wang wrote:
> > kmem_cache_prefill_sheaf() and kmem_cache_refill_sheaf() only guarantee
> > @size objects, but for standard capacity sheaves
> > __prefill_sheaf_pfmemalloc() uses refill_sheaf(), which actually fills
> > the sheaf up to s->sheaf_capacity.
> >
> > The call thus fails with -ENOMEM > whenever the sheaf cannot be filled
> > completely, even when @size objects were already obtained.
> 
> This is extremely rare condition to happen, and so...

Yes, I went to measure the number of times of
kmem_cache_prefill_sheaf() and kmem_cache_refill_sheaf() in qemu. It's also
very low.

> 
> > This leads to needless flushing of the partially
> > filled sheaf in kmem_cache_prefill_sheaf(),
> 
> It doesn't make much sense to micro-optimize slab in low or out of
> memory situations.

I agree with you. Because it's so rare.

Thanks for your careful review.

--
Best regards,
Qing


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-10-26  9:30 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-23  9:44 [PATCH] mm/slab: only require the requested size when refilling prefilled sheaves Qing Wang
2026-10-23 14:22 ` Harry Yoo
2026-10-26  9:29   ` [PATCH] mm/slab: only require the requested size when refilling Qing Wang

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.