aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/rcupdate.h15
-rw-r--r--kernel/lockdep.c3
-rw-r--r--lib/Kconfig.debug12
3 files changed, 26 insertions, 4 deletions
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index db266bbed23f..4dca2752cfde 100644
--- a/include/linux/rcupdate.h
+++ b/include/linux/rcupdate.h
@@ -192,6 +192,15 @@ static inline int rcu_read_lock_sched_held(void)
192 192
193extern int rcu_my_thread_group_empty(void); 193extern 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 * rcu_dereference_check - rcu_dereference with debug checking 205 * rcu_dereference_check - rcu_dereference with debug checking
197 * @p: The pointer to read, prior to dereferencing 206 * @p: The pointer to read, prior to dereferencing
@@ -221,8 +230,7 @@ extern int rcu_my_thread_group_empty(void);
221 */ 230 */
222#define rcu_dereference_check(p, c) \ 231#define rcu_dereference_check(p, c) \
223 ({ \ 232 ({ \
224 if (debug_lockdep_rcu_enabled() && !(c)) \ 233 __do_rcu_dereference_check(c); \
225 lockdep_rcu_dereference(__FILE__, __LINE__); \
226 rcu_dereference_raw(p); \ 234 rcu_dereference_raw(p); \
227 }) 235 })
228 236
@@ -239,8 +247,7 @@ extern int rcu_my_thread_group_empty(void);
239 */ 247 */
240#define rcu_dereference_protected(p, c) \ 248#define rcu_dereference_protected(p, c) \
241 ({ \ 249 ({ \
242 if (debug_lockdep_rcu_enabled() && !(c)) \ 250 __do_rcu_dereference_check(c); \
243 lockdep_rcu_dereference(__FILE__, __LINE__); \
244 (p); \ 251 (p); \
245 }) 252 })
246 253
diff --git a/kernel/lockdep.c b/kernel/lockdep.c
index 2594e1ce41cb..3a756ba8d5d8 100644
--- a/kernel/lockdep.c
+++ b/kernel/lockdep.c
@@ -3801,8 +3801,11 @@ void lockdep_rcu_dereference(const char *file, const int line)
3801{ 3801{
3802 struct task_struct *curr = current; 3802 struct task_struct *curr = current;
3803 3803
3804#ifndef CONFIG_PROVE_RCU_REPEATEDLY
3804 if (!debug_locks_off()) 3805 if (!debug_locks_off())
3805 return; 3806 return;
3807#endif /* #ifdef CONFIG_PROVE_RCU_REPEATEDLY */
3808 /* Note: the following can be executed concurrently, so be careful. */
3806 printk("\n===================================================\n"); 3809 printk("\n===================================================\n");
3807 printk( "[ INFO: suspicious rcu_dereference_check() usage. ]\n"); 3810 printk( "[ INFO: suspicious rcu_dereference_check() usage. ]\n");
3808 printk( "---------------------------------------------------\n"); 3811 printk( "---------------------------------------------------\n");
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 935248bdbc47..94090b4bb7d2 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -512,6 +512,18 @@ config PROVE_RCU
512 512
513 Say N if you are unsure. 513 Say N if you are unsure.
514 514
515config 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
515config LOCKDEP 527config LOCKDEP
516 bool 528 bool
517 depends on DEBUG_KERNEL && TRACE_IRQFLAGS_SUPPORT && STACKTRACE_SUPPORT && LOCKDEP_SUPPORT 529 depends on DEBUG_KERNEL && TRACE_IRQFLAGS_SUPPORT && STACKTRACE_SUPPORT && LOCKDEP_SUPPORT