@@ -47,7 +47,13 @@ int init_srcu_struct(struct srcu_struct *ssp);
47
47
#define SRCU_READ_FLAVOR_NORMAL 0x1 // srcu_read_lock().
48
48
#define SRCU_READ_FLAVOR_NMI 0x2 // srcu_read_lock_nmisafe().
49
49
#define SRCU_READ_FLAVOR_LITE 0x4 // srcu_read_lock_lite().
50
- #define SRCU_READ_FLAVOR_ALL 0x7 // All of the above.
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_LITE | SRCU_READ_FLAVOR_FAST) // All of the above.
53
+ #define SRCU_READ_FLAVOR_SLOWGP (SRCU_READ_FLAVOR_LITE | SRCU_READ_FLAVOR_FAST)
54
+ // Flavors requiring synchronize_rcu()
55
+ // instead of smp_mb().
56
+ void __srcu_read_unlock (struct srcu_struct * ssp , int idx ) __releases (ssp );
51
57
52
58
#ifdef CONFIG_TINY_SRCU
53
59
#include <linux/srcutiny.h>
@@ -60,15 +66,6 @@ int init_srcu_struct(struct srcu_struct *ssp);
60
66
void call_srcu (struct srcu_struct * ssp , struct rcu_head * head ,
61
67
void (* func )(struct rcu_head * head ));
62
68
void cleanup_srcu_struct (struct srcu_struct * ssp );
63
- int __srcu_read_lock (struct srcu_struct * ssp ) __acquires (ssp );
64
- void __srcu_read_unlock (struct srcu_struct * ssp , int idx ) __releases (ssp );
65
- #ifdef CONFIG_TINY_SRCU
66
- #define __srcu_read_lock_lite __srcu_read_lock
67
- #define __srcu_read_unlock_lite __srcu_read_unlock
68
- #else // #ifdef CONFIG_TINY_SRCU
69
- int __srcu_read_lock_lite (struct srcu_struct * ssp ) __acquires (ssp );
70
- void __srcu_read_unlock_lite (struct srcu_struct * ssp , int idx ) __releases (ssp );
71
- #endif // #else // #ifdef CONFIG_TINY_SRCU
72
69
void synchronize_srcu (struct srcu_struct * ssp );
73
70
74
71
#define SRCU_GET_STATE_COMPLETED 0x1
@@ -257,6 +254,51 @@ static inline int srcu_read_lock(struct srcu_struct *ssp) __acquires(ssp)
257
254
return retval ;
258
255
}
259
256
257
+ /**
258
+ * srcu_read_lock_fast - register a new reader for an SRCU-protected structure.
259
+ * @ssp: srcu_struct in which to register the new reader.
260
+ *
261
+ * 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.
273
+ */
274
+ static inline struct srcu_ctr __percpu * srcu_read_lock_fast (struct srcu_struct * ssp ) __acquires (ssp )
275
+ {
276
+ struct srcu_ctr __percpu * retval ;
277
+
278
+ srcu_check_read_flavor_force (ssp , SRCU_READ_FLAVOR_FAST );
279
+ retval = __srcu_read_lock_fast (ssp );
280
+ rcu_try_lock_acquire (& ssp -> dep_map );
281
+ return retval ;
282
+ }
283
+
284
+ /**
285
+ * srcu_down_read_fast - register a new reader for an SRCU-protected structure.
286
+ * @ssp: srcu_struct in which to register the new reader.
287
+ *
288
+ * Enter a semaphore-like SRCU read-side critical section, but for
289
+ * a light-weight smp_mb()-free reader. See srcu_read_lock_fast() and
290
+ * srcu_down_read() for more information.
291
+ *
292
+ * The same srcu_struct may be used concurrently by srcu_down_read_fast()
293
+ * and srcu_read_lock_fast().
294
+ */
295
+ static inline struct srcu_ctr __percpu * srcu_down_read_fast (struct srcu_struct * ssp ) __acquires (ssp )
296
+ {
297
+ WARN_ON_ONCE (IS_ENABLED (CONFIG_PROVE_RCU ) && in_nmi ());
298
+ srcu_check_read_flavor_force (ssp , SRCU_READ_FLAVOR_FAST );
299
+ return __srcu_read_lock_fast (ssp );
300
+ }
301
+
260
302
/**
261
303
* srcu_read_lock_lite - register a new reader for an SRCU-protected structure.
262
304
* @ssp: srcu_struct in which to register the new reader.
@@ -278,7 +320,7 @@ static inline int srcu_read_lock_lite(struct srcu_struct *ssp) __acquires(ssp)
278
320
{
279
321
int retval ;
280
322
281
- srcu_check_read_flavor_lite (ssp );
323
+ srcu_check_read_flavor_force (ssp , SRCU_READ_FLAVOR_LITE );
282
324
retval = __srcu_read_lock_lite (ssp );
283
325
rcu_try_lock_acquire (& ssp -> dep_map );
284
326
return retval ;
@@ -335,7 +377,8 @@ srcu_read_lock_notrace(struct srcu_struct *ssp) __acquires(ssp)
335
377
* srcu_down_read() nor srcu_up_read() may be invoked from an NMI handler.
336
378
*
337
379
* Calls to srcu_down_read() may be nested, similar to the manner in
338
- * which calls to down_read() may be nested.
380
+ * which calls to down_read() may be nested. The same srcu_struct may be
381
+ * used concurrently by srcu_down_read() and srcu_read_lock().
339
382
*/
340
383
static inline int srcu_down_read (struct srcu_struct * ssp ) __acquires (ssp )
341
384
{
@@ -360,10 +403,41 @@ static inline void srcu_read_unlock(struct srcu_struct *ssp, int idx)
360
403
__srcu_read_unlock (ssp , idx );
361
404
}
362
405
406
+ /**
407
+ * srcu_read_unlock_fast - unregister a old reader from an SRCU-protected structure.
408
+ * @ssp: srcu_struct in which to unregister the old reader.
409
+ * @scp: return value from corresponding srcu_read_lock_fast().
410
+ *
411
+ * Exit a light-weight SRCU read-side critical section.
412
+ */
413
+ static inline void srcu_read_unlock_fast (struct srcu_struct * ssp , struct srcu_ctr __percpu * scp )
414
+ __releases (ssp )
415
+ {
416
+ srcu_check_read_flavor (ssp , SRCU_READ_FLAVOR_FAST );
417
+ srcu_lock_release (& ssp -> dep_map );
418
+ __srcu_read_unlock_fast (ssp , scp );
419
+ }
420
+
421
+ /**
422
+ * srcu_up_read_fast - unregister a old reader from an SRCU-protected structure.
423
+ * @ssp: srcu_struct in which to unregister the old reader.
424
+ * @scp: return value from corresponding srcu_read_lock_fast().
425
+ *
426
+ * Exit an SRCU read-side critical section, but not necessarily from
427
+ * the same context as the maching srcu_down_read_fast().
428
+ */
429
+ static inline void srcu_up_read_fast (struct srcu_struct * ssp , struct srcu_ctr __percpu * scp )
430
+ __releases (ssp )
431
+ {
432
+ WARN_ON_ONCE (IS_ENABLED (CONFIG_PROVE_RCU ) && in_nmi ());
433
+ srcu_check_read_flavor (ssp , SRCU_READ_FLAVOR_FAST );
434
+ __srcu_read_unlock_fast (ssp , scp );
435
+ }
436
+
363
437
/**
364
438
* srcu_read_unlock_lite - unregister a old reader from an SRCU-protected structure.
365
439
* @ssp: srcu_struct in which to unregister the old reader.
366
- * @idx: return value from corresponding srcu_read_lock ().
440
+ * @idx: return value from corresponding srcu_read_lock_lite ().
367
441
*
368
442
* Exit a light-weight SRCU read-side critical section.
369
443
*/
@@ -379,7 +453,7 @@ static inline void srcu_read_unlock_lite(struct srcu_struct *ssp, int idx)
379
453
/**
380
454
* srcu_read_unlock_nmisafe - unregister a old reader from an SRCU-protected structure.
381
455
* @ssp: srcu_struct in which to unregister the old reader.
382
- * @idx: return value from corresponding srcu_read_lock ().
456
+ * @idx: return value from corresponding srcu_read_lock_nmisafe ().
383
457
*
384
458
* Exit an SRCU read-side critical section, but in an NMI-safe manner.
385
459
*/
0 commit comments