From: "Paul E. McKenney" <paulmck@kernel.org>
To: rcu@vger.kernel.org
Cc: linux-kernel@vger.kernel.org, kernel-team@meta.com,
rostedt@goodmis.org, Kunwu Chan <kunwu.chan@gmail.com>,
"Paul E . McKenney" <paulmck@kernel.org>,
David Woodhouse <dwmw2@infradead.org>
Subject: [PATCH 13/19] srcutree: Add reader-free fastpath to synchronize_srcu_atomic()
Date: Fri, 18 Sep 2026 17:35:15 -0700 [thread overview]
Message-ID: <20260919003521.3134552-13-paulmck@kernel.org> (raw)
In-Reply-To: <13d6be93-8d9d-47a2-beb0-99c8a90938d4@paulmck-laptop>
From: Kunwu Chan <kunwu.chan@gmail.com>
synchronize_srcu_atomic() is restricted to srcu_read_lock_atomic() and
srcu_read_unlock_atomic(), whose read-side critical sections disable
preemption. In the common case where there are no readers at all, the
grace period therefore need not do the index flip. Add a fastpath
that sums both ranks of the per-CPU ->srcu_ctrs[] counters and, if the
lock counts match the unlock counts on both ranks, ends the grace
period immediately, skipping the srcu_advance_state() scans, mirroring
the similar Tiny SRCU fastpath.
Correctness requires the counter-sum proof to follow the grace-period
anchor written by srcu_gp_start(); placing it before the anchor could
let this grace period miss a pre-existing reader and return without
waiting for it. The smp_mb() between the unlock and lock sums pairs
with the smp_mb() in __srcu_read_lock(). The grace period is ended
manually under ->lock and ->srcu_atomic_gp_flag.
In theory, this is slower than David Woodhouse's earlier patch, but
David's measurements showed that the performance was close enough
that it makes sense to keep the get_state_synchronize_srcu() and
poll_state_synchronize_srcu semantics.
Link: https://lore.kernel.org/all/20260907075829.2073224-4-kunwu.chan@linux.dev/
Link: https://lore.kernel.org/all/0f4dea21bac43685d3286df329401177e4452b36.camel@infradead.org/
Link: https://lore.kernel.org/all/0d4af6318ac67486858be1df8d436147b444a2d2.camel@infradead.org/
Signed-off-by: Kunwu Chan <kunwu.chan@gmail.com>
Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
Cc: David Woodhouse <dwmw2@infradead.org>
---
kernel/rcu/srcutree.c | 48 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 48 insertions(+)
diff --git a/kernel/rcu/srcutree.c b/kernel/rcu/srcutree.c
index 64081c8eacc8..93b8d1088abe 100644
--- a/kernel/rcu/srcutree.c
+++ b/kernel/rcu/srcutree.c
@@ -2119,6 +2119,8 @@ void synchronize_srcu_atomic(struct srcu_struct *ssp)
{
unsigned long srcu_state;
struct srcu_usage *sup = ssp->srcu_sup;
+ unsigned long rdm0, rdm1;
+ unsigned long unlocks0, unlocks1;
// Initialize. Either init_srcu_struct() was invoked or
// DEFINE_SRCU() or similar was used. Therefore, no allocation
@@ -2154,6 +2156,52 @@ void synchronize_srcu_atomic(struct srcu_struct *ssp)
srcu_gp_start(ssp);
raw_spin_unlock_irq_rcu_node(sup);
+ //
+ // Fastpath: If there are no readers at all, neither grace-period
+ // scan need wait, so both can be satisfied at once without doing
+ // the index flip. The counter-sum proof is the same as that of
+ // srcu_readers_active_idx_check(), but spanning both indices.
+ // Atomic SRCU guarantees that all readers are of
+ // SRCU_READ_FLAVOR_ATOMIC, so the SLOWGP check never triggers and
+ // the ->srcu_reader_flavor masks returned by
+ // srcu_readers_unlock_idx() are unused.
+ //
+ // This proof must follow the grace-period anchor written by the
+ // srcu_gp_start() above, never precede it. With the anchor first,
+ // a reader whose lock increment is missed by the sums below cannot
+ // have incremented its lock counter before the anchor, and therefore
+ // cannot be a pre-existing reader of this grace period. Placing the
+ // proof before the anchor would let this grace period miss a
+ // pre-existing reader and return without waiting for it.
+ //
+ // The smp_mb() pairs with the smp_mb() in __srcu_read_lock()
+ // (store-buffering pattern), which guarantees that a lock is always
+ // counted if the corresponding unlock is counted, the same
+ // memory-ordering guarantee as is provided by
+ // srcu_readers_active_idx_check().
+ //
+ unlocks0 = srcu_readers_unlock_idx(ssp, 0, &rdm0);
+ unlocks1 = srcu_readers_unlock_idx(ssp, 1, &rdm1);
+ smp_mb(); /* A */
+ if (srcu_readers_lock_idx(ssp, 0, false, unlocks0) &&
+ srcu_readers_lock_idx(ssp, 1, false, unlocks1)) {
+ // No readers, so end this grace period manually, skipping
+ // the index flip. Advancing the sequence number via
+ // rcu_seq_start() in srcu_gp_start() above and rcu_seq_end()
+ // below keeps get_state_synchronize_srcu() and
+ // poll_state_synchronize_srcu() working, all under ->lock
+ // and ->srcu_atomic_gp_flag, which excludes concurrent
+ // sequence-number updates.
+ raw_spin_lock_irq_rcu_node(sup);
+ rcu_seq_end(&sup->srcu_gp_seq);
+ raw_spin_unlock_irq_rcu_node(sup);
+ WARN_ON_ONCE(!poll_state_synchronize_srcu(ssp, srcu_state));
+ atomic_set_release(&sup->srcu_atomic_gp_flag, 0);
+ preempt_enable();
+ non_block_end();
+ return;
+ }
+
// Wait for it to complete, helping it along.
while (!poll_state_synchronize_srcu(ssp, srcu_state)) {
cpu_relax();
--
2.40.1
next prev parent reply other threads:[~2026-09-19 0:35 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-19 0:35 [PATCH 0/19] Add atomic SRCU Paul E. McKenney
2026-09-19 0:35 ` [PATCH 01/19] srcutiny: Make a Tiny SRCU grace period imply an RCU grace period Paul E. McKenney
2026-09-19 0:35 ` [PATCH 02/19] srcutree: Suppress srcu_advance_state() mutex_lock in atomic Paul E. McKenney
2026-09-19 0:35 ` [PATCH 03/19] srcutree: Suppress to-big transition for atomic SRCU Paul E. McKenney
2026-09-19 0:35 ` [PATCH 04/19] srcutree: Add an atomic Tree SRCU Paul E. McKenney
2026-09-19 0:35 ` [PATCH 05/19] srcutiny: Add an atomic Tiny SRCU Paul E. McKenney
2026-09-19 0:35 ` [PATCH 06/19] rcutorture: Add support for testing synchronize_srcu_atomic() Paul E. McKenney
2026-09-19 0:35 ` [PATCH 07/19] srcutree: Disable preemption across synchronize_srcu_atomic() Paul E. McKenney
2026-09-19 0:35 ` [PATCH 08/19] srcu: Use IRQ_WORK_INIT_HARD for srcu's irq_work Paul E. McKenney
2026-09-19 0:35 ` [PATCH 09/19] srcu: Fix WARN_ON() for rcu_segcblist_n_cbs() in cleanup_srcu_struct() Paul E. McKenney
2026-09-19 0:35 ` [PATCH 10/19] srcutree: Warn if Tiny SRCU readers are preempted Paul E. McKenney
2026-09-19 0:35 ` [PATCH 11/19] srcutree: Explicitly note DEFINE_SRCU() needs for srcu_barrier() Paul E. McKenney
2026-09-19 0:35 ` [PATCH 12/19] rcutorture: Add atomic-SRCU support to torture.sh Paul E. McKenney
2026-09-19 0:35 ` Paul E. McKenney [this message]
2026-09-19 0:35 ` [PATCH 14/19] srcutree: Skip callback scheduling for atomic SRCU grace periods Paul E. McKenney
2026-09-19 0:35 ` [PATCH 15/19] srcutree: Remove srcu_barrier() sleep for atomic SRCU Paul E. McKenney
2026-09-19 0:35 ` [PATCH 16/19] srcu: Restrict atomic-SRCU non_block annotation to task context Paul E. McKenney
2026-09-19 0:35 ` [PATCH 17/19] srcutree: Make init_srcu_struct_atomic() prevent transition to big Paul E. McKenney
2026-09-19 0:35 ` [PATCH 18/19] srcutree: Don't transition atomic SRCU to big in srcu_gp_end() Paul E. McKenney
2026-09-19 0:35 ` [PATCH 19/19] srcutree: Skip torture to-big transition for atomic SRCU Paul E. McKenney
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=20260919003521.3134552-13-paulmck@kernel.org \
--to=paulmck@kernel.org \
--cc=dwmw2@infradead.org \
--cc=kernel-team@meta.com \
--cc=kunwu.chan@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=rcu@vger.kernel.org \
--cc=rostedt@goodmis.org \
/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
all inboxes | Powered by JetHome®