Skip to content

Commit 8235bcf

Browse files
paulmckrcuFrederic Weisbecker
authored andcommitted
srcu: Require special srcu_struct define/init for SRCU-fast readers
This commit adds CONFIG_PROVE_RCU=y checking to enforce the new rule that srcu_struct structures 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 using either DEFINE_SRCU_FAST() or DEFINE_STATIC_SRCU_FAST(). This will enable removal of the non-debug read-side checks from srcu_read_lock_fast() and friends, which on my laptop provides a 25% speedup (which admittedly amounts to about half a nanosecond, but when tracing fastpaths...) Signed-off-by: Paul E. McKenney <paulmck@kernel.org> Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> Cc: Steven Rostedt <rostedt@goodmis.org> Cc: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Cc: <bpf@vger.kernel.org> Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
1 parent e4ed20c commit 8235bcf

2 files changed

Lines changed: 23 additions & 12 deletions

File tree

include/linux/srcu.h

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -271,17 +271,26 @@ static inline int srcu_read_lock(struct srcu_struct *ssp) __acquires(ssp)
271271
* @ssp: srcu_struct in which to register the new reader.
272272
*
273273
* Enter an SRCU read-side critical section, but for a light-weight
274-
* smp_mb()-free reader. See srcu_read_lock() for more information.
275-
*
276-
* If srcu_read_lock_fast() is ever used on an srcu_struct structure,
277-
* then none of the other flavors may be used, whether before, during,
278-
* or after. Note that grace-period auto-expediting is disabled for _fast
279-
* srcu_struct structures because auto-expedited grace periods invoke
280-
* synchronize_rcu_expedited(), IPIs and all.
281-
*
282-
* Note that srcu_read_lock_fast() can be invoked only from those contexts
283-
* where RCU is watching, that is, from contexts where it would be legal
284-
* to invoke rcu_read_lock(). Otherwise, lockdep will complain.
274+
* smp_mb()-free reader. See srcu_read_lock() for more information. This
275+
* function is NMI-safe, in a manner similar to srcu_read_lock_nmisafe().
276+
*
277+
* For srcu_read_lock_fast() to be used on an srcu_struct structure,
278+
* that structure must have been defined using either DEFINE_SRCU_FAST()
279+
* or DEFINE_STATIC_SRCU_FAST() on the one hand or initialized with
280+
* init_srcu_struct_fast() on the other. Such an srcu_struct structure
281+
* cannot be passed to any non-fast variant of srcu_read_{,un}lock() or
282+
* srcu_{down,up}_read(). In kernels built with CONFIG_PROVE_RCU=y,
283+
* __srcu_check_read_flavor() will complain bitterly if you ignore this
284+
* restriction.
285+
*
286+
* Grace-period auto-expediting is disabled for SRCU-fast srcu_struct
287+
* structures because SRCU-fast expedited grace periods invoke
288+
* synchronize_rcu_expedited(), IPIs and all. If you need expedited
289+
* SRCU-fast grace periods, use synchronize_srcu_expedited().
290+
*
291+
* The srcu_read_lock_fast() function can be invoked only from those
292+
* contexts where RCU is watching, that is, from contexts where it would
293+
* be legal to invoke rcu_read_lock(). Otherwise, lockdep will complain.
285294
*/
286295
static inline struct srcu_ctr __percpu *srcu_read_lock_fast(struct srcu_struct *ssp) __acquires(ssp)
287296
{
@@ -317,7 +326,8 @@ static inline struct srcu_ctr __percpu *srcu_read_lock_fast_notrace(struct srcu_
317326
* srcu_down_read() for more information.
318327
*
319328
* The same srcu_struct may be used concurrently by srcu_down_read_fast()
320-
* and srcu_read_lock_fast().
329+
* and srcu_read_lock_fast(). However, the same definition/initialization
330+
* requirements called out for srcu_read_lock_safe() apply.
321331
*/
322332
static inline struct srcu_ctr __percpu *srcu_down_read_fast(struct srcu_struct *ssp) __acquires(ssp)
323333
{

kernel/rcu/srcutree.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -766,6 +766,7 @@ void __srcu_check_read_flavor(struct srcu_struct *ssp, int read_flavor)
766766
WARN_ON_ONCE(ssp->srcu_reader_flavor && read_flavor != ssp->srcu_reader_flavor);
767767
WARN_ON_ONCE(old_read_flavor && ssp->srcu_reader_flavor &&
768768
old_read_flavor != ssp->srcu_reader_flavor);
769+
WARN_ON_ONCE(read_flavor == SRCU_READ_FLAVOR_FAST && !ssp->srcu_reader_flavor);
769770
if (!old_read_flavor) {
770771
old_read_flavor = cmpxchg(&sdp->srcu_reader_flavor, 0, read_flavor);
771772
if (!old_read_flavor)

0 commit comments

Comments
 (0)