1*10462d6fSPaul E. McKenney // SPDX-License-Identifier: GPL-2.0+ 2*10462d6fSPaul E. McKenney /* 3*10462d6fSPaul E. McKenney * RCU CPU stall warnings for normal RCU grace periods 4*10462d6fSPaul E. McKenney * 5*10462d6fSPaul E. McKenney * Copyright IBM Corporation, 2019 6*10462d6fSPaul E. McKenney * 7*10462d6fSPaul E. McKenney * Author: Paul E. McKenney <paulmck@linux.ibm.com> 8*10462d6fSPaul E. McKenney */ 9*10462d6fSPaul E. McKenney 10*10462d6fSPaul E. McKenney 11*10462d6fSPaul E. McKenney #ifdef CONFIG_PROVE_RCU 12*10462d6fSPaul E. McKenney #define RCU_STALL_DELAY_DELTA (5 * HZ) 13*10462d6fSPaul E. McKenney #else 14*10462d6fSPaul E. McKenney #define RCU_STALL_DELAY_DELTA 0 15*10462d6fSPaul E. McKenney #endif 16*10462d6fSPaul E. McKenney 17*10462d6fSPaul E. McKenney int rcu_jiffies_till_stall_check(void) 18*10462d6fSPaul E. McKenney { 19*10462d6fSPaul E. McKenney int till_stall_check = READ_ONCE(rcu_cpu_stall_timeout); 20*10462d6fSPaul E. McKenney 21*10462d6fSPaul E. McKenney /* 22*10462d6fSPaul E. McKenney * Limit check must be consistent with the Kconfig limits 23*10462d6fSPaul E. McKenney * for CONFIG_RCU_CPU_STALL_TIMEOUT. 24*10462d6fSPaul E. McKenney */ 25*10462d6fSPaul E. McKenney if (till_stall_check < 3) { 26*10462d6fSPaul E. McKenney WRITE_ONCE(rcu_cpu_stall_timeout, 3); 27*10462d6fSPaul E. McKenney till_stall_check = 3; 28*10462d6fSPaul E. McKenney } else if (till_stall_check > 300) { 29*10462d6fSPaul E. McKenney WRITE_ONCE(rcu_cpu_stall_timeout, 300); 30*10462d6fSPaul E. McKenney till_stall_check = 300; 31*10462d6fSPaul E. McKenney } 32*10462d6fSPaul E. McKenney return till_stall_check * HZ + RCU_STALL_DELAY_DELTA; 33*10462d6fSPaul E. McKenney } 34*10462d6fSPaul E. McKenney EXPORT_SYMBOL_GPL(rcu_jiffies_till_stall_check); 35*10462d6fSPaul E. McKenney 36*10462d6fSPaul E. McKenney void rcu_sysrq_start(void) 37*10462d6fSPaul E. McKenney { 38*10462d6fSPaul E. McKenney if (!rcu_cpu_stall_suppress) 39*10462d6fSPaul E. McKenney rcu_cpu_stall_suppress = 2; 40*10462d6fSPaul E. McKenney } 41*10462d6fSPaul E. McKenney 42*10462d6fSPaul E. McKenney void rcu_sysrq_end(void) 43*10462d6fSPaul E. McKenney { 44*10462d6fSPaul E. McKenney if (rcu_cpu_stall_suppress == 2) 45*10462d6fSPaul E. McKenney rcu_cpu_stall_suppress = 0; 46*10462d6fSPaul E. McKenney } 47*10462d6fSPaul E. McKenney 48*10462d6fSPaul E. McKenney static int rcu_panic(struct notifier_block *this, unsigned long ev, void *ptr) 49*10462d6fSPaul E. McKenney { 50*10462d6fSPaul E. McKenney rcu_cpu_stall_suppress = 1; 51*10462d6fSPaul E. McKenney return NOTIFY_DONE; 52*10462d6fSPaul E. McKenney } 53*10462d6fSPaul E. McKenney 54*10462d6fSPaul E. McKenney static struct notifier_block rcu_panic_block = { 55*10462d6fSPaul E. McKenney .notifier_call = rcu_panic, 56*10462d6fSPaul E. McKenney }; 57*10462d6fSPaul E. McKenney 58*10462d6fSPaul E. McKenney static int __init check_cpu_stall_init(void) 59*10462d6fSPaul E. McKenney { 60*10462d6fSPaul E. McKenney atomic_notifier_chain_register(&panic_notifier_list, &rcu_panic_block); 61*10462d6fSPaul E. McKenney return 0; 62*10462d6fSPaul E. McKenney } 63*10462d6fSPaul E. McKenney early_initcall(check_cpu_stall_init); 64