aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul E. McKenney <paulmck@linux.vnet.ibm.com>2010-04-09 18:39:10 -0400
committerIngo Molnar <mingo@elte.hu>2010-04-14 06:19:51 -0400
commitb62730baea32f86fe91a7930e4b7ee8d82778b79 (patch)
tree97910bcb8a0790b10ff687dad901e158a2da63f4
parent2ba3abd8186f24c7fb418927025b4e2120e3a362 (diff)
rcu: Add rcu_access_pointer and rcu_dereference_protected
This patch adds variants of rcu_dereference() that handle situations where the RCU-protected data structure cannot change, perhaps due to our holding the update-side lock, or where the RCU-protected pointer is only to be fetched, not dereferenced. These are needed due to some performance concerns with using rcu_dereference() where it is not required, aside from the need for lockdep/sparse checking. The new rcu_access_pointer() primitive is for the case where the pointer is be fetch and not dereferenced. This primitive may be used without protection, RCU or otherwise, due to the fact that it uses ACCESS_ONCE(). The new rcu_dereference_protected() primitive is for the case where updates are prevented, for example, due to holding the update-side lock. This primitive does neither ACCESS_ONCE() nor smp_read_barrier_depends(), so can only be used when updates are somehow prevented. Suggested-by: David Howells <dhowells@redhat.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 Cc: eric.dumazet@gmail.com LKML-Reference: <1270852752-25278-1-git-send-email-paulmck@linux.vnet.ibm.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r--include/linux/rcupdate.h32
1 files changed, 32 insertions, 0 deletions
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index 872a98e13d6a..8fe86609441f 100644
--- a/include/linux/rcupdate.h
+++ b/include/linux/rcupdate.h
@@ -209,13 +209,45 @@ static inline int rcu_read_lock_sched_held(void)
209 rcu_dereference_raw(p); \ 209 rcu_dereference_raw(p); \
210 }) 210 })
211 211
212/**
213 * rcu_dereference_protected - fetch RCU pointer when updates prevented
214 *
215 * Return the value of the specified RCU-protected pointer, but omit
216 * both the smp_read_barrier_depends() and the ACCESS_ONCE(). This
217 * is useful in cases where update-side locks prevent the value of the
218 * pointer from changing. Please note that this primitive does -not-
219 * prevent the compiler from repeating this reference or combining it
220 * with other references, so it should not be used without protection
221 * of appropriate locks.
222 */
223#define rcu_dereference_protected(p, c) \
224 ({ \
225 if (debug_lockdep_rcu_enabled() && !(c)) \
226 lockdep_rcu_dereference(__FILE__, __LINE__); \
227 (p); \
228 })
229
212#else /* #ifdef CONFIG_PROVE_RCU */ 230#else /* #ifdef CONFIG_PROVE_RCU */
213 231
214#define rcu_dereference_check(p, c) rcu_dereference_raw(p) 232#define rcu_dereference_check(p, c) rcu_dereference_raw(p)
233#define rcu_dereference_protected(p, c) (p)
215 234
216#endif /* #else #ifdef CONFIG_PROVE_RCU */ 235#endif /* #else #ifdef CONFIG_PROVE_RCU */
217 236
218/** 237/**
238 * rcu_access_pointer - fetch RCU pointer with no dereferencing
239 *
240 * Return the value of the specified RCU-protected pointer, but omit the
241 * smp_read_barrier_depends() and keep the ACCESS_ONCE(). This is useful
242 * when the value of this pointer is accessed, but the pointer is not
243 * dereferenced, for example, when testing an RCU-protected pointer against
244 * NULL. This may also be used in cases where update-side locks prevent
245 * the value of the pointer from changing, but rcu_dereference_protected()
246 * is a lighter-weight primitive for this use case.
247 */
248#define rcu_access_pointer(p) ACCESS_ONCE(p)
249
250/**
219 * rcu_read_lock - mark the beginning of an RCU read-side critical section. 251 * rcu_read_lock - mark the beginning of an RCU read-side critical section.
220 * 252 *
221 * When synchronize_rcu() is invoked on one CPU while other CPUs 253 * When synchronize_rcu() is invoked on one CPU while other CPUs