Commit 2b3fc35f6919344e3cf722dde8308f47235c0b70
Committed by
Paul E. McKenney
1 parent
b57f95a382
Exists in
master
and in
4 other branches
rcu: optionally leave lockdep enabled after RCU lockdep splat
There is no need to disable lockdep after an RCU lockdep splat, so remove the debug_lockdeps_off() from lockdep_rcu_dereference(). To avoid repeated lockdep splats, use a static variable in the inlined rcu_dereference_check() and rcu_dereference_protected() macros so that a given instance splats only once, but so that multiple instances can be detected per boot. This is controlled by a new config variable CONFIG_PROVE_RCU_REPEATEDLY, which is disabled by default. This provides the normal lockdep behavior by default, but permits people who want to find multiple RCU-lockdep splats per boot to easily do so. Requested-by: Eric Paris <eparis@redhat.com> Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com> Tested-by: Eric Paris <eparis@redhat.com> Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Showing 3 changed files with 26 additions and 4 deletions Side-by-side Diff
include/linux/rcupdate.h
... | ... | @@ -192,6 +192,15 @@ |
192 | 192 | |
193 | 193 | extern int rcu_my_thread_group_empty(void); |
194 | 194 | |
195 | +#define __do_rcu_dereference_check(c) \ | |
196 | + do { \ | |
197 | + static bool __warned; \ | |
198 | + if (debug_lockdep_rcu_enabled() && !__warned && !(c)) { \ | |
199 | + __warned = true; \ | |
200 | + lockdep_rcu_dereference(__FILE__, __LINE__); \ | |
201 | + } \ | |
202 | + } while (0) | |
203 | + | |
195 | 204 | /** |
196 | 205 | * rcu_dereference_check - rcu_dereference with debug checking |
197 | 206 | * @p: The pointer to read, prior to dereferencing |
... | ... | @@ -221,8 +230,7 @@ |
221 | 230 | */ |
222 | 231 | #define rcu_dereference_check(p, c) \ |
223 | 232 | ({ \ |
224 | - if (debug_lockdep_rcu_enabled() && !(c)) \ | |
225 | - lockdep_rcu_dereference(__FILE__, __LINE__); \ | |
233 | + __do_rcu_dereference_check(c); \ | |
226 | 234 | rcu_dereference_raw(p); \ |
227 | 235 | }) |
228 | 236 | |
... | ... | @@ -239,8 +247,7 @@ |
239 | 247 | */ |
240 | 248 | #define rcu_dereference_protected(p, c) \ |
241 | 249 | ({ \ |
242 | - if (debug_lockdep_rcu_enabled() && !(c)) \ | |
243 | - lockdep_rcu_dereference(__FILE__, __LINE__); \ | |
250 | + __do_rcu_dereference_check(c); \ | |
244 | 251 | (p); \ |
245 | 252 | }) |
246 | 253 |
kernel/lockdep.c
... | ... | @@ -3801,8 +3801,11 @@ |
3801 | 3801 | { |
3802 | 3802 | struct task_struct *curr = current; |
3803 | 3803 | |
3804 | +#ifndef CONFIG_PROVE_RCU_REPEATEDLY | |
3804 | 3805 | if (!debug_locks_off()) |
3805 | 3806 | return; |
3807 | +#endif /* #ifdef CONFIG_PROVE_RCU_REPEATEDLY */ | |
3808 | + /* Note: the following can be executed concurrently, so be careful. */ | |
3806 | 3809 | printk("\n===================================================\n"); |
3807 | 3810 | printk( "[ INFO: suspicious rcu_dereference_check() usage. ]\n"); |
3808 | 3811 | printk( "---------------------------------------------------\n"); |
lib/Kconfig.debug
... | ... | @@ -512,6 +512,18 @@ |
512 | 512 | |
513 | 513 | Say N if you are unsure. |
514 | 514 | |
515 | +config PROVE_RCU_REPEATEDLY | |
516 | + bool "RCU debugging: don't disable PROVE_RCU on first splat" | |
517 | + depends on PROVE_RCU | |
518 | + default n | |
519 | + help | |
520 | + By itself, PROVE_RCU will disable checking upon issuing the | |
521 | + first warning (or "splat"). This feature prevents such | |
522 | + disabling, allowing multiple RCU-lockdep warnings to be printed | |
523 | + on a single reboot. | |
524 | + | |
525 | + Say N if you are unsure. | |
526 | + | |
515 | 527 | config LOCKDEP |
516 | 528 | bool |
517 | 529 | depends on DEBUG_KERNEL && TRACE_IRQFLAGS_SUPPORT && STACKTRACE_SUPPORT && LOCKDEP_SUPPORT |