From: "Vlastimil Babka (SUSE)" <vbabka@kernel.org>
To: Hao Li <hao.li@linux.dev>, harry@kernel.org, akpm@linux-foundation.org
Cc: cl@gentwo.org, rientjes@google.com, roman.gushchin@linux.dev,
linux-mm@kvack.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH v2] mm/slub: refill prefilled sheaves from the barn
Date: Tue, 22 Sep 2026 16:50:41 +0200 [thread overview]
Message-ID: <2b064cfd-25af-4934-ab85-1018140b76e6@kernel.org> (raw)
In-Reply-To: <20260921094521.141665-1-hao.li@linux.dev>
On 9/21/26 11:41, Hao Li wrote:
> Currently, when the prefill API refills a non-full sheaf, it takes the
> objects from partial slabs and never from the full sheaves in the barn,
> so once the barn's full list becomes saturated, it stays saturated.
>
> For objects freed via kfree_rcu(), every RCU sheaf then has to be
> flushed to slabs because the barn's full list has no room.
>
> To fix this, let the sheaf refill from the barn first, and introduce a
> partial sheaf in the barn, which holds the leftover objects [1].
>
> Only the prefill path needs the partial sheaf. The generic allocation
> path (__pcs_replace_empty_main()) exchanges an empty sheaf for a full
> one from the barn, so nothing is left over. The prefill path refills a
> sheaf that is not necessarily empty, so taking objects from the barn
> usually leaves leftovers, and the partial sheaf is where they are
> kept. refill_sheaf() only takes objects from partial slabs and never
> involves the partial sheaf.
>
> The sheaf is refilled by copying objects from the partial sheaf, and
> then from a full sheaf taken from the barn if it is still not full. A
> sheaf that objects were copied from stays in the barn as the partial
> sheaf if it still holds objects, or goes on the empty list if it is
> empty. The sheaf being refilled is never replaced.
>
> The gain comes from two sides: every full sheaf taken out makes room on
> the barn's full list for a future RCU sheaf, and refilling from the
> barn is cheaper than refilling from partial slabs under list_lock.
>
> Note that putting the sheaf with the leftover objects on the full list
> instead would not work: it would occupy room on the full list, so the
> list would stay saturated and rcu_free_sheaf() would still keep
> flushing.
>
> An earlier version of this patch swapped sheaves instead, to minimize
> the memcpy overhead. As Harry Yoo pointed out [2], replacing the
> caller's sheaf loses cache affinity, filling it directly is more
> straightforward, and testing showed no measurable difference between
> the two approaches, so the approach he suggested is used.
Yep, a memcpy of a small array isn't a big deal.
> Tested with will-it-scale mmap1 (192 processes, one-minute runs) on the
> maple_node cache.
>
> throughput: 27778727 -> 34500556 (+24.2%)
>
> metric baseline patched change
> =====================================================================
> alloc_fastpath 54,124 56,696 +4.75%
> alloc_slab 7,100,651 159,739 -97.75%
> barn_get 849 194,460,392 +22904539.81%
> barn_get_fail 2 217 +10750.00%
> barn_put 851 182,306,701 +21422544.07%
> barn_put_fail 260,400,484 145,522,675 -44.12%
> cmpxchg_double_fail 1,029,204 334,228 -67.53%
> free_add_partial 326,694,687 181,935,790 -44.31%
> free_fastpath 13,297 15,611 +17.40%
> free_rcu_sheaf 8,332,839,104 10,490,535,227 +25.89%
> free_remove_partial 7,099,788 158,297 -97.77%
> free_slab 7,099,788 158,297 -97.77%
> free_slowpath 10,969,156 782,851 -92.86%
> objects 15,295 14,849 -2.92%
> objects_partial 15,295 14,849 -2.92%
> partial 1,604 2,336 +45.64%
> sheaf_alloc 137,757,895 141,208,076 +2.50%
> sheaf_flush 8,332,823,922 4,656,725,764 -44.12%
> sheaf_free 137,757,883 141,208,072 +2.50%
> sheaf_prefill_fast 3,337,502,163 4,196,506,116 +25.74%
> sheaf_prefill_slow 685 400 -41.61%
> sheaf_refill 8,343,794,364 4,657,509,724 -44.18%
> sheaf_return_fast 3,337,502,411 4,196,506,382 +25.74%
> sheaf_return_slow 437 134 -69.34%
> slabs 1,604 2,336 +45.64%
> total_objects 102,656 149,504 +45.64%
>
> Here is what the important metric changes mean.
>
> barn_get and barn_put: refills now take full sheaves out of the barn,
> and RCU sheaves are put into the barn again. Before, the barn's full
> list was saturated once and hardly ever consumed.
>
> barn_put_fail: more than half of the RCU sheaves are now put into the
> barn instead of being flushed. The rest are still flushed because they
> arrive while the barn's full list is at its limit.
>
> sheaf_refill and free_add_partial: fewer objects are taken from partial
> slabs to refill sheaves, and fewer slabs are added to the partial list,
> by the same percentage.
>
> alloc_slab and free_slab: the partial list is almost never empty when a
> refill looks at it, so slabs are almost never allocated and freed again
> only to serve refills.
>
> After the test, the maple_node cache holds 1604 slabs without the patch
> and 2336 with it. After a manual shrink
> (echo 1 > /sys/kernel/slab/maple_node/shrink), it holds 485 without
> the patch and 563 with it. So most of the extra slabs are held only by
> objects sitting in sheaves and are returned by a shrink, and what
> remains is a small difference, because objects handed out from the barn
> come from many more slabs than a refill from partial slabs would use.
>
> Link: https://lore.kernel.org/linux-mm/aqPlMzUIw-4g2iOX@fedora/ [1]
> Link: https://lore.kernel.org/linux-mm/aq0ylDidEHa2kg4X@thinkstation/ [2]
> Signed-off-by: Hao Li <hao.li@linux.dev>
Very cool!
Reviewed-by: Vlastimil Babka (SUSE) <vbabka@kernel.org>
prev parent reply other threads:[~2026-09-22 14:50 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-21 9:41 [PATCH v2] mm/slub: refill prefilled sheaves from the barn Hao Li
2026-09-22 12:46 ` Harry Yoo
2026-09-22 13:11 ` Harry Yoo (Meta)
2026-09-22 14:50 ` Vlastimil Babka (SUSE) [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=2b064cfd-25af-4934-ab85-1018140b76e6@kernel.org \
--to=vbabka@kernel.org \
--cc=akpm@linux-foundation.org \
--cc=cl@gentwo.org \
--cc=hao.li@linux.dev \
--cc=harry@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=rientjes@google.com \
--cc=roman.gushchin@linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.