[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250923142036.112290-33-paulmck@kernel.org>
Date: Tue, 23 Sep 2025 07:20:35 -0700
From: "Paul E. McKenney" <paulmck@...nel.org>
To: rcu@...r.kernel.org
Cc: linux-kernel@...r.kernel.org,
kernel-team@...a.com,
rostedt@...dmis.org,
"Paul E. McKenney" <paulmck@...nel.org>,
Mathieu Desnoyers <mathieu.desnoyers@...icios.com>,
Sebastian Andrzej Siewior <bigeasy@...utronix.de>,
bpf@...r.kernel.org
Subject: [PATCH 33/34] srcu: Make SRCU-fast readers enforce use of SRCU-fast definition/init
This commit makes CONFIG_PROVE_RCU=y kernels enforce the new rule
that srcu_struct structures that are passed to srcu_read_lock_fast()
and other SRCU-fast read-side markers be either initialized with
init_srcu_struct_fast() on the one hand or defined with DEFINE_SRCU_FAST()
or DEFINE_STATIC_SRCU_FAST() on the other.
This eliminates the read-side test that was formerly included in
srcu_read_lock_fast() and friends, speeding these primitives up by
about 25% (admittedly only about half of a nanosecond, but when tracing
on fastpaths...)
Signed-off-by: Paul E. McKenney <paulmck@...nel.org>
Cc: Mathieu Desnoyers <mathieu.desnoyers@...icios.com>
Cc: Steven Rostedt <rostedt@...dmis.org>
Cc: Sebastian Andrzej Siewior <bigeasy@...utronix.de>
Cc: <bpf@...r.kernel.org>
---
include/linux/srcu.h | 6 +++---
include/linux/srcutiny.h | 1 -
include/linux/srcutree.h | 16 +---------------
kernel/rcu/tasks.h | 5 -----
4 files changed, 4 insertions(+), 24 deletions(-)
diff --git a/include/linux/srcu.h b/include/linux/srcu.h
index 2982b5a6930fa6..41e27c1d917d3e 100644
--- a/include/linux/srcu.h
+++ b/include/linux/srcu.h
@@ -297,7 +297,7 @@ static inline struct srcu_ctr __percpu *srcu_read_lock_fast(struct srcu_struct *
struct srcu_ctr __percpu *retval;
RCU_LOCKDEP_WARN(!rcu_is_watching(), "RCU must be watching srcu_read_lock_fast().");
- srcu_check_read_flavor_force(ssp, SRCU_READ_FLAVOR_FAST);
+ srcu_check_read_flavor(ssp, SRCU_READ_FLAVOR_FAST);
retval = __srcu_read_lock_fast(ssp);
rcu_try_lock_acquire(&ssp->dep_map);
return retval;
@@ -312,7 +312,7 @@ static inline struct srcu_ctr __percpu *srcu_read_lock_fast_notrace(struct srcu_
{
struct srcu_ctr __percpu *retval;
- srcu_check_read_flavor_force(ssp, SRCU_READ_FLAVOR_FAST);
+ srcu_check_read_flavor(ssp, SRCU_READ_FLAVOR_FAST);
retval = __srcu_read_lock_fast(ssp);
return retval;
}
@@ -333,7 +333,7 @@ static inline struct srcu_ctr __percpu *srcu_down_read_fast(struct srcu_struct *
{
WARN_ON_ONCE(IS_ENABLED(CONFIG_PROVE_RCU) && in_nmi());
RCU_LOCKDEP_WARN(!rcu_is_watching(), "RCU must be watching srcu_down_read_fast().");
- srcu_check_read_flavor_force(ssp, SRCU_READ_FLAVOR_FAST);
+ srcu_check_read_flavor(ssp, SRCU_READ_FLAVOR_FAST);
return __srcu_read_lock_fast(ssp);
}
diff --git a/include/linux/srcutiny.h b/include/linux/srcutiny.h
index 92e6ab53398fc0..1ecc3393fb26be 100644
--- a/include/linux/srcutiny.h
+++ b/include/linux/srcutiny.h
@@ -112,7 +112,6 @@ static inline void srcu_barrier(struct srcu_struct *ssp)
static inline void srcu_expedite_current(struct srcu_struct *ssp) { }
#define srcu_check_read_flavor(ssp, read_flavor) do { } while (0)
-#define srcu_check_read_flavor_force(ssp, read_flavor) do { } while (0)
/* Defined here to avoid size increase for non-torture kernels. */
static inline void srcu_torture_stats_print(struct srcu_struct *ssp,
diff --git a/include/linux/srcutree.h b/include/linux/srcutree.h
index 05400f70baa40a..fd24ec146af614 100644
--- a/include/linux/srcutree.h
+++ b/include/linux/srcutree.h
@@ -311,21 +311,7 @@ __srcu_read_unlock_fast(struct srcu_struct *ssp, struct srcu_ctr __percpu *scp)
void __srcu_check_read_flavor(struct srcu_struct *ssp, int read_flavor);
-// Record reader usage even for CONFIG_PROVE_RCU=n kernels. This is
-// needed only for flavors that require grace-period smp_mb() calls to be
-// promoted to synchronize_rcu().
-static inline void srcu_check_read_flavor_force(struct srcu_struct *ssp, int read_flavor)
-{
- struct srcu_data *sdp = raw_cpu_ptr(ssp->sda);
-
- if (likely(READ_ONCE(sdp->srcu_reader_flavor) & read_flavor))
- return;
-
- // Note that the cmpxchg() in __srcu_check_read_flavor() is fully ordered.
- __srcu_check_read_flavor(ssp, read_flavor);
-}
-
-// Record non-_lite() usage only for CONFIG_PROVE_RCU=y kernels.
+// Record SRCU-reader usage type only for CONFIG_PROVE_RCU=y kernels.
static inline void srcu_check_read_flavor(struct srcu_struct *ssp, int read_flavor)
{
if (IS_ENABLED(CONFIG_PROVE_RCU))
diff --git a/kernel/rcu/tasks.h b/kernel/rcu/tasks.h
index bf1226834c9423..76f952196a2921 100644
--- a/kernel/rcu/tasks.h
+++ b/kernel/rcu/tasks.h
@@ -1600,11 +1600,6 @@ static inline void rcu_tasks_bootup_oddness(void) {}
// Tracing variant of Tasks RCU. This variant is designed to be used
// to protect tracing hooks, including those of BPF. This variant
// is implemented via a straightforward mapping onto SRCU-fast.
-// DEFINE_SRCU_FAST() is required because rcu_read_lock_trace() must
-// use __srcu_read_lock_fast() in order to bypass the rcu_is_watching()
-// checks in kernels built with CONFIG_TASKS_TRACE_RCU_NO_MB=n, which also
-// bypasses the srcu_check_read_flavor_force() that would otherwise mark
-// rcu_tasks_trace_srcu_struct as needing SRCU-fast readers.
DEFINE_SRCU_FAST(rcu_tasks_trace_srcu_struct);
EXPORT_SYMBOL_GPL(rcu_tasks_trace_srcu_struct);
--
2.40.1
Powered by blists - more mailing lists