Commit 851a67b825540a8e00c0be3ee25e4627ba8b133b
1 parent
34a3d1e837
lockdep: annotate rcu_read_{,un}lock{,_bh}
lockdep annotate rcu_read_{,un}lock{,_bh} in order to catch imbalanced usage. Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl> Signed-off-by: Ingo Molnar <mingo@elte.hu> Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Showing 3 changed files with 29 additions and 0 deletions Side-by-side Diff
include/linux/lockdep.h
... | ... | @@ -253,6 +253,13 @@ |
253 | 253 | struct lock_class_key *key, int subclass); |
254 | 254 | |
255 | 255 | /* |
256 | + * To initialize a lockdep_map statically use this macro. | |
257 | + * Note that _name must not be NULL. | |
258 | + */ | |
259 | +#define STATIC_LOCKDEP_MAP_INIT(_name, _key) \ | |
260 | + { .name = (_name), .key = (void *)(_key), } | |
261 | + | |
262 | +/* | |
256 | 263 | * Reinitialize a lock key - for cases where there is special locking or |
257 | 264 | * special initialization of locks so that the validator gets the scope |
258 | 265 | * of dependencies wrong: they are either too broad (they need a class-split) |
include/linux/rcupdate.h
... | ... | @@ -41,6 +41,7 @@ |
41 | 41 | #include <linux/percpu.h> |
42 | 42 | #include <linux/cpumask.h> |
43 | 43 | #include <linux/seqlock.h> |
44 | +#include <linux/lockdep.h> | |
44 | 45 | |
45 | 46 | /** |
46 | 47 | * struct rcu_head - callback structure for use with RCU |
... | ... | @@ -133,6 +134,15 @@ |
133 | 134 | extern int rcu_pending(int cpu); |
134 | 135 | extern int rcu_needs_cpu(int cpu); |
135 | 136 | |
137 | +#ifdef CONFIG_DEBUG_LOCK_ALLOC | |
138 | +extern struct lockdep_map rcu_lock_map; | |
139 | +# define rcu_read_acquire() lock_acquire(&rcu_lock_map, 0, 0, 2, 1, _THIS_IP_) | |
140 | +# define rcu_read_release() lock_release(&rcu_lock_map, 1, _THIS_IP_) | |
141 | +#else | |
142 | +# define rcu_read_acquire() do { } while (0) | |
143 | +# define rcu_read_release() do { } while (0) | |
144 | +#endif | |
145 | + | |
136 | 146 | /** |
137 | 147 | * rcu_read_lock - mark the beginning of an RCU read-side critical section. |
138 | 148 | * |
... | ... | @@ -166,6 +176,7 @@ |
166 | 176 | do { \ |
167 | 177 | preempt_disable(); \ |
168 | 178 | __acquire(RCU); \ |
179 | + rcu_read_acquire(); \ | |
169 | 180 | } while(0) |
170 | 181 | |
171 | 182 | /** |
... | ... | @@ -175,6 +186,7 @@ |
175 | 186 | */ |
176 | 187 | #define rcu_read_unlock() \ |
177 | 188 | do { \ |
189 | + rcu_read_release(); \ | |
178 | 190 | __release(RCU); \ |
179 | 191 | preempt_enable(); \ |
180 | 192 | } while(0) |
... | ... | @@ -204,6 +216,7 @@ |
204 | 216 | do { \ |
205 | 217 | local_bh_disable(); \ |
206 | 218 | __acquire(RCU_BH); \ |
219 | + rcu_read_acquire(); \ | |
207 | 220 | } while(0) |
208 | 221 | |
209 | 222 | /* |
... | ... | @@ -213,6 +226,7 @@ |
213 | 226 | */ |
214 | 227 | #define rcu_read_unlock_bh() \ |
215 | 228 | do { \ |
229 | + rcu_read_release(); \ | |
216 | 230 | __release(RCU_BH); \ |
217 | 231 | local_bh_enable(); \ |
218 | 232 | } while(0) |
kernel/rcupdate.c
... | ... | @@ -49,6 +49,14 @@ |
49 | 49 | #include <linux/cpu.h> |
50 | 50 | #include <linux/mutex.h> |
51 | 51 | |
52 | +#ifdef CONFIG_DEBUG_LOCK_ALLOC | |
53 | +static struct lock_class_key rcu_lock_key; | |
54 | +struct lockdep_map rcu_lock_map = | |
55 | + STATIC_LOCKDEP_MAP_INIT("rcu_read_lock", &rcu_lock_key); | |
56 | + | |
57 | +EXPORT_SYMBOL_GPL(rcu_lock_map); | |
58 | +#endif | |
59 | + | |
52 | 60 | /* Definition for rcupdate control block. */ |
53 | 61 | static struct rcu_ctrlblk rcu_ctrlblk = { |
54 | 62 | .cur = -300, |