@@ -25,8 +25,12 @@ struct srcu_struct;
2525
2626#ifdef CONFIG_DEBUG_LOCK_ALLOC
2727
28- int __init_srcu_struct (struct srcu_struct * ssp , const char * name ,
29- struct lock_class_key * key );
28+ int __init_srcu_struct (struct srcu_struct * ssp , const char * name , struct lock_class_key * key );
29+ #ifndef CONFIG_TINY_SRCU
30+ int __init_srcu_struct_fast (struct srcu_struct * ssp , const char * name , struct lock_class_key * key );
31+ int __init_srcu_struct_fast_updown (struct srcu_struct * ssp , const char * name ,
32+ struct lock_class_key * key );
33+ #endif // #ifndef CONFIG_TINY_SRCU
3034
3135#define init_srcu_struct (ssp ) \
3236({ \
@@ -35,22 +39,42 @@ int __init_srcu_struct(struct srcu_struct *ssp, const char *name,
3539 __init_srcu_struct((ssp), #ssp, &__srcu_key); \
3640})
3741
42+ #define init_srcu_struct_fast (ssp ) \
43+ ({ \
44+ static struct lock_class_key __srcu_key; \
45+ \
46+ __init_srcu_struct_fast((ssp), #ssp, &__srcu_key); \
47+ })
48+
49+ #define init_srcu_struct_fast_updown (ssp ) \
50+ ({ \
51+ static struct lock_class_key __srcu_key; \
52+ \
53+ __init_srcu_struct_fast_updown((ssp), #ssp, &__srcu_key); \
54+ })
55+
3856#define __SRCU_DEP_MAP_INIT (srcu_name ) .dep_map = { .name = #srcu_name },
3957#else /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */
4058
4159int init_srcu_struct (struct srcu_struct * ssp );
60+ #ifndef CONFIG_TINY_SRCU
61+ int init_srcu_struct_fast (struct srcu_struct * ssp );
62+ int init_srcu_struct_fast_updown (struct srcu_struct * ssp );
63+ #endif // #ifndef CONFIG_TINY_SRCU
4264
4365#define __SRCU_DEP_MAP_INIT (srcu_name )
4466#endif /* #else #ifdef CONFIG_DEBUG_LOCK_ALLOC */
4567
4668/* Values for SRCU Tree srcu_data ->srcu_reader_flavor, but also used by rcutorture. */
47- #define SRCU_READ_FLAVOR_NORMAL 0x1 // srcu_read_lock().
48- #define SRCU_READ_FLAVOR_NMI 0x2 // srcu_read_lock_nmisafe().
49- // 0x4 // SRCU-lite is no longer with us.
50- #define SRCU_READ_FLAVOR_FAST 0x8 // srcu_read_lock_fast().
51- #define SRCU_READ_FLAVOR_ALL (SRCU_READ_FLAVOR_NORMAL | SRCU_READ_FLAVOR_NMI | \
52- SRCU_READ_FLAVOR_FAST) // All of the above.
53- #define SRCU_READ_FLAVOR_SLOWGP SRCU_READ_FLAVOR_FAST
69+ #define SRCU_READ_FLAVOR_NORMAL 0x1 // srcu_read_lock().
70+ #define SRCU_READ_FLAVOR_NMI 0x2 // srcu_read_lock_nmisafe().
71+ // 0x4 // SRCU-lite is no longer with us.
72+ #define SRCU_READ_FLAVOR_FAST 0x4 // srcu_read_lock_fast().
73+ #define SRCU_READ_FLAVOR_FAST_UPDOWN 0x8 // srcu_read_lock_fast().
74+ #define SRCU_READ_FLAVOR_ALL (SRCU_READ_FLAVOR_NORMAL | SRCU_READ_FLAVOR_NMI | \
75+ SRCU_READ_FLAVOR_FAST | SRCU_READ_FLAVOR_FAST_UPDOWN)
76+ // All of the above.
77+ #define SRCU_READ_FLAVOR_SLOWGP (SRCU_READ_FLAVOR_FAST | SRCU_READ_FLAVOR_FAST_UPDOWN)
5478 // Flavors requiring synchronize_rcu()
5579 // instead of smp_mb().
5680void __srcu_read_unlock (struct srcu_struct * ssp , int idx ) __releases (ssp );
@@ -259,29 +283,78 @@ static inline int srcu_read_lock(struct srcu_struct *ssp) __acquires(ssp)
259283 * @ssp: srcu_struct in which to register the new reader.
260284 *
261285 * Enter an SRCU read-side critical section, but for a light-weight
262- * smp_mb()-free reader. See srcu_read_lock() for more information.
263- *
264- * If srcu_read_lock_fast() is ever used on an srcu_struct structure,
265- * then none of the other flavors may be used, whether before, during,
266- * or after. Note that grace-period auto-expediting is disabled for _fast
267- * srcu_struct structures because auto-expedited grace periods invoke
268- * synchronize_rcu_expedited(), IPIs and all.
269- *
270- * Note that srcu_read_lock_fast() can be invoked only from those contexts
271- * where RCU is watching, that is, from contexts where it would be legal
272- * to invoke rcu_read_lock(). Otherwise, lockdep will complain.
286+ * smp_mb()-free reader. See srcu_read_lock() for more information. This
287+ * function is NMI-safe, in a manner similar to srcu_read_lock_nmisafe().
288+ *
289+ * For srcu_read_lock_fast() to be used on an srcu_struct structure,
290+ * that structure must have been defined using either DEFINE_SRCU_FAST()
291+ * or DEFINE_STATIC_SRCU_FAST() on the one hand or initialized with
292+ * init_srcu_struct_fast() on the other. Such an srcu_struct structure
293+ * cannot be passed to any non-fast variant of srcu_read_{,un}lock() or
294+ * srcu_{down,up}_read(). In kernels built with CONFIG_PROVE_RCU=y,
295+ * __srcu_check_read_flavor() will complain bitterly if you ignore this
296+ * restriction.
297+ *
298+ * Grace-period auto-expediting is disabled for SRCU-fast srcu_struct
299+ * structures because SRCU-fast expedited grace periods invoke
300+ * synchronize_rcu_expedited(), IPIs and all. If you need expedited
301+ * SRCU-fast grace periods, use synchronize_srcu_expedited().
302+ *
303+ * The srcu_read_lock_fast() function can be invoked only from those
304+ * contexts where RCU is watching, that is, from contexts where it would
305+ * be legal to invoke rcu_read_lock(). Otherwise, lockdep will complain.
273306 */
274307static inline struct srcu_ctr __percpu * srcu_read_lock_fast (struct srcu_struct * ssp ) __acquires (ssp )
275308{
276309 struct srcu_ctr __percpu * retval ;
277310
278311 RCU_LOCKDEP_WARN (!rcu_is_watching (), "RCU must be watching srcu_read_lock_fast()." );
279- srcu_check_read_flavor_force (ssp , SRCU_READ_FLAVOR_FAST );
312+ srcu_check_read_flavor (ssp , SRCU_READ_FLAVOR_FAST );
280313 retval = __srcu_read_lock_fast (ssp );
281314 rcu_try_lock_acquire (& ssp -> dep_map );
282315 return retval ;
283316}
284317
318+ /**
319+ * srcu_read_lock_fast_updown - register a new reader for an SRCU-fast-updown structure.
320+ * @ssp: srcu_struct in which to register the new reader.
321+ *
322+ * Enter an SRCU read-side critical section, but for a light-weight
323+ * smp_mb()-free reader. See srcu_read_lock() for more information.
324+ * This function is compatible with srcu_down_read_fast(), but is not
325+ * NMI-safe.
326+ *
327+ * For srcu_read_lock_fast_updown() to be used on an srcu_struct
328+ * structure, that structure must have been defined using either
329+ * DEFINE_SRCU_FAST_UPDOWN() or DEFINE_STATIC_SRCU_FAST_UPDOWN() on the one
330+ * hand or initialized with init_srcu_struct_fast_updown() on the other.
331+ * Such an srcu_struct structure cannot be passed to any non-fast-updown
332+ * variant of srcu_read_{,un}lock() or srcu_{down,up}_read(). In kernels
333+ * built with CONFIG_PROVE_RCU=y, __srcu_check_read_flavor() will complain
334+ * bitterly if you ignore this * restriction.
335+ *
336+ * Grace-period auto-expediting is disabled for SRCU-fast-updown
337+ * srcu_struct structures because SRCU-fast-updown expedited grace periods
338+ * invoke synchronize_rcu_expedited(), IPIs and all. If you need expedited
339+ * SRCU-fast-updown grace periods, use synchronize_srcu_expedited().
340+ *
341+ * The srcu_read_lock_fast_updown() function can be invoked only from
342+ * those contexts where RCU is watching, that is, from contexts where
343+ * it would be legal to invoke rcu_read_lock(). Otherwise, lockdep will
344+ * complain.
345+ */
346+ static inline struct srcu_ctr __percpu * srcu_read_lock_fast_updown (struct srcu_struct * ssp )
347+ __acquires (ssp )
348+ {
349+ struct srcu_ctr __percpu * retval ;
350+
351+ RCU_LOCKDEP_WARN (!rcu_is_watching (), "RCU must be watching srcu_read_lock_fast_updown()." );
352+ srcu_check_read_flavor (ssp , SRCU_READ_FLAVOR_FAST_UPDOWN );
353+ retval = __srcu_read_lock_fast_updown (ssp );
354+ rcu_try_lock_acquire (& ssp -> dep_map );
355+ return retval ;
356+ }
357+
285358/*
286359 * Used by tracing, cannot be traced and cannot call lockdep.
287360 * See srcu_read_lock_fast() for more information.
@@ -291,7 +364,7 @@ static inline struct srcu_ctr __percpu *srcu_read_lock_fast_notrace(struct srcu_
291364{
292365 struct srcu_ctr __percpu * retval ;
293366
294- srcu_check_read_flavor_force (ssp , SRCU_READ_FLAVOR_FAST );
367+ srcu_check_read_flavor (ssp , SRCU_READ_FLAVOR_FAST );
295368 retval = __srcu_read_lock_fast (ssp );
296369 return retval ;
297370}
@@ -305,14 +378,15 @@ static inline struct srcu_ctr __percpu *srcu_read_lock_fast_notrace(struct srcu_
305378 * srcu_down_read() for more information.
306379 *
307380 * The same srcu_struct may be used concurrently by srcu_down_read_fast()
308- * and srcu_read_lock_fast().
381+ * and srcu_read_lock_fast(). However, the same definition/initialization
382+ * requirements called out for srcu_read_lock_safe() apply.
309383 */
310384static inline struct srcu_ctr __percpu * srcu_down_read_fast (struct srcu_struct * ssp ) __acquires (ssp )
311385{
312386 WARN_ON_ONCE (IS_ENABLED (CONFIG_PROVE_RCU ) && in_nmi ());
313387 RCU_LOCKDEP_WARN (!rcu_is_watching (), "RCU must be watching srcu_down_read_fast()." );
314- srcu_check_read_flavor_force (ssp , SRCU_READ_FLAVOR_FAST );
315- return __srcu_read_lock_fast (ssp );
388+ srcu_check_read_flavor (ssp , SRCU_READ_FLAVOR_FAST_UPDOWN );
389+ return __srcu_read_lock_fast_updown (ssp );
316390}
317391
318392/**
@@ -408,6 +482,23 @@ static inline void srcu_read_unlock_fast(struct srcu_struct *ssp, struct srcu_ct
408482 RCU_LOCKDEP_WARN (!rcu_is_watching (), "RCU must be watching srcu_read_unlock_fast()." );
409483}
410484
485+ /**
486+ * srcu_read_unlock_fast_updown - unregister a old reader from an SRCU-fast-updown structure.
487+ * @ssp: srcu_struct in which to unregister the old reader.
488+ * @scp: return value from corresponding srcu_read_lock_fast_updown().
489+ *
490+ * Exit an SRCU-fast-updown read-side critical section.
491+ */
492+ static inline void
493+ srcu_read_unlock_fast_updown (struct srcu_struct * ssp , struct srcu_ctr __percpu * scp ) __releases (ssp )
494+ {
495+ srcu_check_read_flavor (ssp , SRCU_READ_FLAVOR_FAST_UPDOWN );
496+ srcu_lock_release (& ssp -> dep_map );
497+ __srcu_read_unlock_fast_updown (ssp , scp );
498+ RCU_LOCKDEP_WARN (!rcu_is_watching (),
499+ "RCU must be watching srcu_read_unlock_fast_updown()." );
500+ }
501+
411502/*
412503 * Used by tracing, cannot be traced and cannot call lockdep.
413504 * See srcu_read_unlock_fast() for more information.
@@ -431,9 +522,9 @@ static inline void srcu_up_read_fast(struct srcu_struct *ssp, struct srcu_ctr __
431522 __releases (ssp )
432523{
433524 WARN_ON_ONCE (IS_ENABLED (CONFIG_PROVE_RCU ) && in_nmi ());
434- srcu_check_read_flavor (ssp , SRCU_READ_FLAVOR_FAST );
435- __srcu_read_unlock_fast (ssp , scp );
436- RCU_LOCKDEP_WARN (!rcu_is_watching (), "RCU must be watching srcu_up_read_fast ()." );
525+ srcu_check_read_flavor (ssp , SRCU_READ_FLAVOR_FAST_UPDOWN );
526+ __srcu_read_unlock_fast_updown (ssp , scp );
527+ RCU_LOCKDEP_WARN (!rcu_is_watching (), "RCU must be watching srcu_up_read_fast_updown ()." );
437528}
438529
439530/**
0 commit comments