diff options
Diffstat (limited to 'kernel/rcupdate.c')
-rw-r--r-- | kernel/rcupdate.c | 60 |
1 files changed, 57 insertions, 3 deletions
diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c index a2cf76177b44..48ab70384a4c 100644 --- a/kernel/rcupdate.c +++ b/kernel/rcupdate.c | |||
@@ -404,11 +404,65 @@ EXPORT_SYMBOL_GPL(rcuhead_debug_descr); | |||
404 | #endif /* #ifdef CONFIG_DEBUG_OBJECTS_RCU_HEAD */ | 404 | #endif /* #ifdef CONFIG_DEBUG_OBJECTS_RCU_HEAD */ |
405 | 405 | ||
406 | #if defined(CONFIG_TREE_RCU) || defined(CONFIG_TREE_PREEMPT_RCU) || defined(CONFIG_RCU_TRACE) | 406 | #if defined(CONFIG_TREE_RCU) || defined(CONFIG_TREE_PREEMPT_RCU) || defined(CONFIG_RCU_TRACE) |
407 | void do_trace_rcu_torture_read(char *rcutorturename, struct rcu_head *rhp) | 407 | void do_trace_rcu_torture_read(char *rcutorturename, struct rcu_head *rhp, |
408 | unsigned long secs, | ||
409 | unsigned long c_old, unsigned long c) | ||
408 | { | 410 | { |
409 | trace_rcu_torture_read(rcutorturename, rhp); | 411 | trace_rcu_torture_read(rcutorturename, rhp, secs, c_old, c); |
410 | } | 412 | } |
411 | EXPORT_SYMBOL_GPL(do_trace_rcu_torture_read); | 413 | EXPORT_SYMBOL_GPL(do_trace_rcu_torture_read); |
412 | #else | 414 | #else |
413 | #define do_trace_rcu_torture_read(rcutorturename, rhp) do { } while (0) | 415 | #define do_trace_rcu_torture_read(rcutorturename, rhp, secs, c_old, c) \ |
416 | do { } while (0) | ||
414 | #endif | 417 | #endif |
418 | |||
419 | #ifdef CONFIG_RCU_STALL_COMMON | ||
420 | |||
421 | #ifdef CONFIG_PROVE_RCU | ||
422 | #define RCU_STALL_DELAY_DELTA (5 * HZ) | ||
423 | #else | ||
424 | #define RCU_STALL_DELAY_DELTA 0 | ||
425 | #endif | ||
426 | |||
427 | int rcu_cpu_stall_suppress __read_mostly; /* 1 = suppress stall warnings. */ | ||
428 | int rcu_cpu_stall_timeout __read_mostly = CONFIG_RCU_CPU_STALL_TIMEOUT; | ||
429 | |||
430 | module_param(rcu_cpu_stall_suppress, int, 0644); | ||
431 | module_param(rcu_cpu_stall_timeout, int, 0644); | ||
432 | |||
433 | int rcu_jiffies_till_stall_check(void) | ||
434 | { | ||
435 | int till_stall_check = ACCESS_ONCE(rcu_cpu_stall_timeout); | ||
436 | |||
437 | /* | ||
438 | * Limit check must be consistent with the Kconfig limits | ||
439 | * for CONFIG_RCU_CPU_STALL_TIMEOUT. | ||
440 | */ | ||
441 | if (till_stall_check < 3) { | ||
442 | ACCESS_ONCE(rcu_cpu_stall_timeout) = 3; | ||
443 | till_stall_check = 3; | ||
444 | } else if (till_stall_check > 300) { | ||
445 | ACCESS_ONCE(rcu_cpu_stall_timeout) = 300; | ||
446 | till_stall_check = 300; | ||
447 | } | ||
448 | return till_stall_check * HZ + RCU_STALL_DELAY_DELTA; | ||
449 | } | ||
450 | |||
451 | static int rcu_panic(struct notifier_block *this, unsigned long ev, void *ptr) | ||
452 | { | ||
453 | rcu_cpu_stall_suppress = 1; | ||
454 | return NOTIFY_DONE; | ||
455 | } | ||
456 | |||
457 | static struct notifier_block rcu_panic_block = { | ||
458 | .notifier_call = rcu_panic, | ||
459 | }; | ||
460 | |||
461 | static int __init check_cpu_stall_init(void) | ||
462 | { | ||
463 | atomic_notifier_chain_register(&panic_notifier_list, &rcu_panic_block); | ||
464 | return 0; | ||
465 | } | ||
466 | early_initcall(check_cpu_stall_init); | ||
467 | |||
468 | #endif /* #ifdef CONFIG_RCU_STALL_COMMON */ | ||