diff options
author | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2010-02-22 20:04:46 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2010-02-25 03:41:00 -0500 |
commit | c26d34a5858f96a564c45048bf5f09319d2abad1 (patch) | |
tree | 644941c0005b8ecda4f5af3fd9f9c385f911f146 | |
parent | 632ee200130899252508c478ad0e808222573fbc (diff) |
rcu: Add lockdep-enabled variants of rcu_dereference()
Make rcu_dereference() check for being in an RCU read-side
critical section, and create rcu_dereference_bh(),
rcu_dereference_sched(), and srcu_dereference() to check for the
other flavors of RCU. Also create rcu_dereference_raw() to
avoid checking, and make rcu_dereference_check() use
rcu_dereference_raw().
Acked-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: laijs@cn.fujitsu.com
Cc: dipankar@in.ibm.com
Cc: mathieu.desnoyers@polymtl.ca
Cc: josh@joshtriplett.org
Cc: dvhltc@us.ibm.com
Cc: niv@us.ibm.com
Cc: peterz@infradead.org
Cc: rostedt@goodmis.org
Cc: Valdis.Kletnieks@vt.edu
Cc: dhowells@redhat.com
LKML-Reference: <1266887105-1528-2-git-send-email-paulmck@linux.vnet.ibm.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r-- | include/linux/rcupdate.h | 41 | ||||
-rw-r--r-- | include/linux/srcu.h | 8 |
2 files changed, 42 insertions, 7 deletions
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index e3d37efe2703..839d296a7ac0 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h | |||
@@ -184,12 +184,12 @@ static inline int rcu_read_lock_sched_held(void) | |||
184 | ({ \ | 184 | ({ \ |
185 | if (debug_locks) \ | 185 | if (debug_locks) \ |
186 | WARN_ON_ONCE(!(c)); \ | 186 | WARN_ON_ONCE(!(c)); \ |
187 | rcu_dereference(p); \ | 187 | rcu_dereference_raw(p); \ |
188 | }) | 188 | }) |
189 | 189 | ||
190 | #else /* #ifdef CONFIG_PROVE_RCU */ | 190 | #else /* #ifdef CONFIG_PROVE_RCU */ |
191 | 191 | ||
192 | #define rcu_dereference_check(p, c) rcu_dereference(p) | 192 | #define rcu_dereference_check(p, c) rcu_dereference_raw(p) |
193 | 193 | ||
194 | #endif /* #else #ifdef CONFIG_PROVE_RCU */ | 194 | #endif /* #else #ifdef CONFIG_PROVE_RCU */ |
195 | 195 | ||
@@ -325,22 +325,49 @@ static inline notrace void rcu_read_unlock_sched_notrace(void) | |||
325 | 325 | ||
326 | 326 | ||
327 | /** | 327 | /** |
328 | * rcu_dereference - fetch an RCU-protected pointer in an | 328 | * rcu_dereference_raw - fetch an RCU-protected pointer |
329 | * RCU read-side critical section. This pointer may later | 329 | * |
330 | * be safely dereferenced. | 330 | * The caller must be within some flavor of RCU read-side critical |
331 | * section, or must be otherwise preventing the pointer from changing, | ||
332 | * for example, by holding an appropriate lock. This pointer may later | ||
333 | * be safely dereferenced. It is the caller's responsibility to have | ||
334 | * done the right thing, as this primitive does no checking of any kind. | ||
331 | * | 335 | * |
332 | * Inserts memory barriers on architectures that require them | 336 | * Inserts memory barriers on architectures that require them |
333 | * (currently only the Alpha), and, more importantly, documents | 337 | * (currently only the Alpha), and, more importantly, documents |
334 | * exactly which pointers are protected by RCU. | 338 | * exactly which pointers are protected by RCU. |
335 | */ | 339 | */ |
336 | 340 | #define rcu_dereference_raw(p) ({ \ | |
337 | #define rcu_dereference(p) ({ \ | ||
338 | typeof(p) _________p1 = ACCESS_ONCE(p); \ | 341 | typeof(p) _________p1 = ACCESS_ONCE(p); \ |
339 | smp_read_barrier_depends(); \ | 342 | smp_read_barrier_depends(); \ |
340 | (_________p1); \ | 343 | (_________p1); \ |
341 | }) | 344 | }) |
342 | 345 | ||
343 | /** | 346 | /** |
347 | * rcu_dereference - fetch an RCU-protected pointer, checking for RCU | ||
348 | * | ||
349 | * Makes rcu_dereference_check() do the dirty work. | ||
350 | */ | ||
351 | #define rcu_dereference(p) \ | ||
352 | rcu_dereference_check(p, rcu_read_lock_held()) | ||
353 | |||
354 | /** | ||
355 | * rcu_dereference_bh - fetch an RCU-protected pointer, checking for RCU-bh | ||
356 | * | ||
357 | * Makes rcu_dereference_check() do the dirty work. | ||
358 | */ | ||
359 | #define rcu_dereference_bh(p) \ | ||
360 | rcu_dereference_check(p, rcu_read_lock_bh_held()) | ||
361 | |||
362 | /** | ||
363 | * rcu_dereference_sched - fetch RCU-protected pointer, checking for RCU-sched | ||
364 | * | ||
365 | * Makes rcu_dereference_check() do the dirty work. | ||
366 | */ | ||
367 | #define rcu_dereference_sched(p) \ | ||
368 | rcu_dereference_check(p, rcu_read_lock_sched_held()) | ||
369 | |||
370 | /** | ||
344 | * rcu_assign_pointer - assign (publicize) a pointer to a newly | 371 | * rcu_assign_pointer - assign (publicize) a pointer to a newly |
345 | * initialized structure that will be dereferenced by RCU read-side | 372 | * initialized structure that will be dereferenced by RCU read-side |
346 | * critical sections. Returns the value assigned. | 373 | * critical sections. Returns the value assigned. |
diff --git a/include/linux/srcu.h b/include/linux/srcu.h index adbe1670b366..3084f80909cd 100644 --- a/include/linux/srcu.h +++ b/include/linux/srcu.h | |||
@@ -106,6 +106,14 @@ static inline int srcu_read_lock_held(struct srcu_struct *sp) | |||
106 | #endif /* #else #ifdef CONFIG_DEBUG_LOCK_ALLOC */ | 106 | #endif /* #else #ifdef CONFIG_DEBUG_LOCK_ALLOC */ |
107 | 107 | ||
108 | /** | 108 | /** |
109 | * srcu_dereference - fetch SRCU-protected pointer with checking | ||
110 | * | ||
111 | * Makes rcu_dereference_check() do the dirty work. | ||
112 | */ | ||
113 | #define srcu_dereference(p, sp) \ | ||
114 | rcu_dereference_check(p, srcu_read_lock_held(sp)) | ||
115 | |||
116 | /** | ||
109 | * srcu_read_lock - register a new reader for an SRCU-protected structure. | 117 | * srcu_read_lock - register a new reader for an SRCU-protected structure. |
110 | * @sp: srcu_struct in which to register the new reader. | 118 | * @sp: srcu_struct in which to register the new reader. |
111 | * | 119 | * |