From: Vlastimil Babka <vbabka@suse.cz>
To: Suren Baghdasaryan <surenb@google.com>,
"Liam R. Howlett" <Liam.Howlett@oracle.com>,
Christoph Lameter <cl@linux.com>,
David Rientjes <rientjes@google.com>
Cc: Roman Gushchin <roman.gushchin@linux.dev>,
Hyeonggon Yoo <42.hyeyoo@gmail.com>,
Uladzislau Rezki <urezki@gmail.com>,
linux-mm@kvack.org, linux-kernel@vger.kernel.org,
rcu@vger.kernel.org, maple-tree@lists.infradead.org,
Vlastimil Babka <vbabka@suse.cz>
Subject: [PATCH RFC v2 07/10] slab: determine barn status racily outside of lock
Date: Fri, 14 Feb 2025 17:27:43 +0100 [thread overview]
Message-ID: <20250214-slub-percpu-caches-v2-7-88592ee0966a@suse.cz> (raw)
In-Reply-To: <20250214-slub-percpu-caches-v2-0-88592ee0966a@suse.cz>
The possibility of many barn operations is determined by the current
number of full or empty sheaves. Taking the barn->lock just to find out
that e.g. there are no empty sheaves results in unnecessary overhead and
lock contention. Thus perform these checks outside of the lock with a
data_race() annotated variable read and fail quickly without taking the
lock.
Checks for sheaf availability that racily succeed have to be obviously
repeated under the lock for correctness, but we can skip repeating
checks if there are too many sheaves on the given list as the limits
don't need to be strict.
Signed-off-by: Vlastimil Babka <vbabka@suse.cz>
---
mm/slub.c | 57 ++++++++++++++++++++++++++++++++++-----------------------
1 file changed, 34 insertions(+), 23 deletions(-)
diff --git a/mm/slub.c b/mm/slub.c
index c1df7cf22267f28f743404531bef921e25fac086..72e6437f1d74bfacbb1cd7642af42929c48cc66a 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -2685,9 +2685,12 @@ static struct slab_sheaf *barn_get_empty_sheaf(struct node_barn *barn)
struct slab_sheaf *empty = NULL;
unsigned long flags;
+ if (!data_race(barn->nr_empty))
+ return NULL;
+
spin_lock_irqsave(&barn->lock, flags);
- if (barn->nr_empty) {
+ if (likely(barn->nr_empty)) {
empty = list_first_entry(&barn->sheaves_empty,
struct slab_sheaf, barn_list);
list_del(&empty->barn_list);
@@ -2703,38 +2706,36 @@ static int barn_put_empty_sheaf(struct node_barn *barn,
struct slab_sheaf *sheaf, bool ignore_limit)
{
unsigned long flags;
- int ret = 0;
+
+ /* we don't repeat the check under barn->lock as it's not critical */
+ if (!ignore_limit && data_race(barn->nr_empty) >= MAX_EMPTY_SHEAVES)
+ return -E2BIG;
spin_lock_irqsave(&barn->lock, flags);
- if (!ignore_limit && barn->nr_empty >= MAX_EMPTY_SHEAVES) {
- ret = -E2BIG;
- } else {
- list_add(&sheaf->barn_list, &barn->sheaves_empty);
- barn->nr_empty++;
- }
+ list_add(&sheaf->barn_list, &barn->sheaves_empty);
+ barn->nr_empty++;
spin_unlock_irqrestore(&barn->lock, flags);
- return ret;
+ return 0;
}
static int barn_put_full_sheaf(struct node_barn *barn, struct slab_sheaf *sheaf,
bool ignore_limit)
{
unsigned long flags;
- int ret = 0;
+
+ /* we don't repeat the check under barn->lock as it's not critical */
+ if (!ignore_limit && data_race(barn->nr_full) >= MAX_FULL_SHEAVES)
+ return -E2BIG;
spin_lock_irqsave(&barn->lock, flags);
- if (!ignore_limit && barn->nr_full >= MAX_FULL_SHEAVES) {
- ret = -E2BIG;
- } else {
- list_add(&sheaf->barn_list, &barn->sheaves_full);
- barn->nr_full++;
- }
+ list_add(&sheaf->barn_list, &barn->sheaves_full);
+ barn->nr_full++;
spin_unlock_irqrestore(&barn->lock, flags);
- return ret;
+ return 0;
}
static struct slab_sheaf *barn_get_full_or_empty_sheaf(struct node_barn *barn)
@@ -2742,6 +2743,9 @@ static struct slab_sheaf *barn_get_full_or_empty_sheaf(struct node_barn *barn)
struct slab_sheaf *sheaf = NULL;
unsigned long flags;
+ if (!data_race(barn->nr_full) && !data_race(barn->nr_empty))
+ return NULL;
+
spin_lock_irqsave(&barn->lock, flags);
if (barn->nr_full) {
@@ -2772,9 +2776,12 @@ barn_replace_empty_sheaf(struct node_barn *barn, struct slab_sheaf *empty)
struct slab_sheaf *full = NULL;
unsigned long flags;
+ if (!data_race(barn->nr_full))
+ return NULL;
+
spin_lock_irqsave(&barn->lock, flags);
- if (barn->nr_full) {
+ if (likely(barn->nr_full)) {
full = list_first_entry(&barn->sheaves_full, struct slab_sheaf,
barn_list);
list_del(&full->barn_list);
@@ -2797,19 +2804,23 @@ barn_replace_full_sheaf(struct node_barn *barn, struct slab_sheaf *full)
struct slab_sheaf *empty;
unsigned long flags;
+ /* we don't repeat this check under barn->lock as it's not critical */
+ if (data_race(barn->nr_full) >= MAX_FULL_SHEAVES)
+ return ERR_PTR(-E2BIG);
+ if (!data_race(barn->nr_empty))
+ return ERR_PTR(-ENOMEM);
+
spin_lock_irqsave(&barn->lock, flags);
- if (barn->nr_full >= MAX_FULL_SHEAVES) {
- empty = ERR_PTR(-E2BIG);
- } else if (!barn->nr_empty) {
- empty = ERR_PTR(-ENOMEM);
- } else {
+ if (likely(barn->nr_empty)) {
empty = list_first_entry(&barn->sheaves_empty, struct slab_sheaf,
barn_list);
list_del(&empty->barn_list);
list_add(&full->barn_list, &barn->sheaves_full);
barn->nr_empty--;
barn->nr_full++;
+ } else {
+ empty = ERR_PTR(-ENOMEM);
}
spin_unlock_irqrestore(&barn->lock, flags);
--
2.48.1
next prev parent reply other threads:[~2025-02-14 16:28 UTC|newest]
Thread overview: 55+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-02-14 16:27 [PATCH RFC v2 00/10] SLUB percpu sheaves Vlastimil Babka
2025-02-14 16:27 ` [PATCH RFC v2 01/10] slab: add opt-in caching layer of " Vlastimil Babka
2025-02-22 22:46 ` Suren Baghdasaryan
2025-02-22 22:56 ` Suren Baghdasaryan
2025-03-12 14:57 ` Vlastimil Babka
2025-03-12 15:14 ` Suren Baghdasaryan
2025-03-17 10:09 ` Vlastimil Babka
2025-02-24 8:04 ` Harry Yoo
2025-03-12 14:59 ` Vlastimil Babka
2025-02-14 16:27 ` [PATCH RFC v2 02/10] slab: add sheaf support for batching kfree_rcu() operations Vlastimil Babka
2025-02-22 23:08 ` Suren Baghdasaryan
2025-03-12 16:19 ` Vlastimil Babka
2025-02-24 8:40 ` Harry Yoo
2025-03-12 16:16 ` Vlastimil Babka
2025-02-14 16:27 ` [PATCH RFC v2 03/10] locking/local_lock: Introduce localtry_lock_t Vlastimil Babka
2025-02-17 14:19 ` Sebastian Andrzej Siewior
2025-02-17 14:35 ` Vlastimil Babka
2025-02-17 15:07 ` Sebastian Andrzej Siewior
2025-02-18 18:41 ` Alexei Starovoitov
2025-02-26 17:00 ` Davidlohr Bueso
2025-02-26 17:15 ` Alexei Starovoitov
2025-02-26 19:28 ` Davidlohr Bueso
2025-02-14 16:27 ` [PATCH RFC v2 04/10] locking/local_lock: add localtry_trylock() Vlastimil Babka
2025-02-14 16:27 ` [PATCH RFC v2 05/10] slab: switch percpu sheaves locking to localtry_lock Vlastimil Babka
2025-02-23 2:33 ` Suren Baghdasaryan
2025-02-24 13:08 ` Harry Yoo
2025-02-14 16:27 ` [PATCH RFC v2 06/10] slab: sheaf prefilling for guaranteed allocations Vlastimil Babka
2025-02-23 3:54 ` Suren Baghdasaryan
2025-02-25 7:30 ` Harry Yoo
2025-03-12 17:09 ` Vlastimil Babka
2025-02-25 8:00 ` Harry Yoo
2025-03-12 18:16 ` Vlastimil Babka
2025-02-14 16:27 ` Vlastimil Babka [this message]
2025-02-23 4:00 ` [PATCH RFC v2 07/10] slab: determine barn status racily outside of lock Suren Baghdasaryan
2025-02-25 8:54 ` Harry Yoo
2025-03-12 18:23 ` Vlastimil Babka
2025-02-14 16:27 ` [PATCH RFC v2 08/10] tools: Add testing support for changes to rcu and slab for sheaves Vlastimil Babka
2025-02-23 4:24 ` Suren Baghdasaryan
2025-02-14 16:27 ` [PATCH RFC v2 09/10] tools: Add sheafs support to testing infrastructure Vlastimil Babka
2025-02-14 16:27 ` [PATCH RFC v2 10/10] maple_tree: use percpu sheaves for maple_node_cache Vlastimil Babka
2025-02-23 4:27 ` Suren Baghdasaryan
2025-02-14 18:28 ` [PATCH RFC v2 00/10] SLUB percpu sheaves Christoph Lameter (Ampere)
2025-02-23 0:19 ` Kent Overstreet
2025-02-23 4:44 ` Suren Baghdasaryan
2025-02-24 1:36 ` Suren Baghdasaryan
2025-02-24 1:43 ` Suren Baghdasaryan
2025-02-24 20:53 ` Vlastimil Babka
2025-02-24 21:12 ` Suren Baghdasaryan
2025-02-25 20:26 ` Suren Baghdasaryan
2025-03-04 10:54 ` Vlastimil Babka
2025-03-04 18:35 ` Suren Baghdasaryan
2025-03-04 19:08 ` Liam R. Howlett
2025-03-14 17:10 ` Suren Baghdasaryan
2025-03-17 11:08 ` Vlastimil Babka
2025-03-17 18:56 ` Suren Baghdasaryan
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=20250214-slub-percpu-caches-v2-7-88592ee0966a@suse.cz \
--to=vbabka@suse.cz \
--cc=42.hyeyoo@gmail.com \
--cc=Liam.Howlett@oracle.com \
--cc=cl@linux.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=maple-tree@lists.infradead.org \
--cc=rcu@vger.kernel.org \
--cc=rientjes@google.com \
--cc=roman.gushchin@linux.dev \
--cc=surenb@google.com \
--cc=urezki@gmail.com \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox