aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorPaul E. McKenney <paulmck@linux.vnet.ibm.com>2012-01-13 18:32:18 -0500
committerPaul E. McKenney <paulmck@linux.vnet.ibm.com>2012-02-21 12:03:48 -0500
commit13cfcca0e4e2d4cee1d0183c049eb34e54ac976e (patch)
tree2aa48f0db717ae7741602022e4020f22cc3cea7f /kernel
parent27565d64a4e564e72c22d8c91a3cfcb9442383e8 (diff)
rcu: Set RCU CPU stall times via sysfs
The default CONFIG_RCU_CPU_STALL_TIMEOUT value of 60 seconds has served Linux users well for production use for quite some time. However, for debugging, there will be more than three minutes between subsequent stall-warning messages. This can be an annoyingly long wait if you are trying to work out where the offending infinite loop is hiding. Therefore, this commit provides a rcu_cpu_stall_timeout sysfs parameter that may be adjusted at boot time and at runtime to speed up debugging. Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/rcutree.c31
-rw-r--r--kernel/rcutree.h6
2 files changed, 26 insertions, 11 deletions
diff --git a/kernel/rcutree.c b/kernel/rcutree.c
index 61adb351d2c7..cfdab9898e33 100644
--- a/kernel/rcutree.c
+++ b/kernel/rcutree.c
@@ -208,8 +208,11 @@ module_param(blimit, int, 0);
208module_param(qhimark, int, 0); 208module_param(qhimark, int, 0);
209module_param(qlowmark, int, 0); 209module_param(qlowmark, int, 0);
210 210
211int rcu_cpu_stall_suppress __read_mostly; 211int rcu_cpu_stall_suppress __read_mostly; /* 1 = suppress stall warnings. */
212int rcu_cpu_stall_timeout __read_mostly = CONFIG_RCU_CPU_STALL_TIMEOUT;
213
212module_param(rcu_cpu_stall_suppress, int, 0644); 214module_param(rcu_cpu_stall_suppress, int, 0644);
215module_param(rcu_cpu_stall_timeout, int, 0644);
213 216
214static void force_quiescent_state(struct rcu_state *rsp, int relaxed); 217static void force_quiescent_state(struct rcu_state *rsp, int relaxed);
215static int rcu_pending(int cpu); 218static int rcu_pending(int cpu);
@@ -645,10 +648,28 @@ static int rcu_implicit_dynticks_qs(struct rcu_data *rdp)
645 return rcu_implicit_offline_qs(rdp); 648 return rcu_implicit_offline_qs(rdp);
646} 649}
647 650
651static int jiffies_till_stall_check(void)
652{
653 int till_stall_check = ACCESS_ONCE(rcu_cpu_stall_timeout);
654
655 /*
656 * Limit check must be consistent with the Kconfig limits
657 * for CONFIG_RCU_CPU_STALL_TIMEOUT.
658 */
659 if (till_stall_check < 3) {
660 ACCESS_ONCE(rcu_cpu_stall_timeout) = 3;
661 till_stall_check = 3;
662 } else if (till_stall_check > 300) {
663 ACCESS_ONCE(rcu_cpu_stall_timeout) = 300;
664 till_stall_check = 300;
665 }
666 return till_stall_check * HZ + RCU_STALL_DELAY_DELTA;
667}
668
648static void record_gp_stall_check_time(struct rcu_state *rsp) 669static void record_gp_stall_check_time(struct rcu_state *rsp)
649{ 670{
650 rsp->gp_start = jiffies; 671 rsp->gp_start = jiffies;
651 rsp->jiffies_stall = jiffies + RCU_SECONDS_TILL_STALL_CHECK; 672 rsp->jiffies_stall = jiffies + jiffies_till_stall_check();
652} 673}
653 674
654static void print_other_cpu_stall(struct rcu_state *rsp) 675static void print_other_cpu_stall(struct rcu_state *rsp)
@@ -667,7 +688,7 @@ static void print_other_cpu_stall(struct rcu_state *rsp)
667 raw_spin_unlock_irqrestore(&rnp->lock, flags); 688 raw_spin_unlock_irqrestore(&rnp->lock, flags);
668 return; 689 return;
669 } 690 }
670 rsp->jiffies_stall = jiffies + RCU_SECONDS_TILL_STALL_RECHECK; 691 rsp->jiffies_stall = jiffies + 3 * jiffies_till_stall_check() + 3;
671 692
672 /* 693 /*
673 * Now rat on any tasks that got kicked up to the root rcu_node 694 * Now rat on any tasks that got kicked up to the root rcu_node
@@ -726,8 +747,8 @@ static void print_cpu_stall(struct rcu_state *rsp)
726 747
727 raw_spin_lock_irqsave(&rnp->lock, flags); 748 raw_spin_lock_irqsave(&rnp->lock, flags);
728 if (ULONG_CMP_GE(jiffies, rsp->jiffies_stall)) 749 if (ULONG_CMP_GE(jiffies, rsp->jiffies_stall))
729 rsp->jiffies_stall = 750 rsp->jiffies_stall = jiffies +
730 jiffies + RCU_SECONDS_TILL_STALL_RECHECK; 751 3 * jiffies_till_stall_check() + 3;
731 raw_spin_unlock_irqrestore(&rnp->lock, flags); 752 raw_spin_unlock_irqrestore(&rnp->lock, flags);
732 753
733 set_need_resched(); /* kick ourselves to get things going. */ 754 set_need_resched(); /* kick ourselves to get things going. */
diff --git a/kernel/rcutree.h b/kernel/rcutree.h
index 58c9fc3bc820..0328a537846a 100644
--- a/kernel/rcutree.h
+++ b/kernel/rcutree.h
@@ -314,12 +314,6 @@ struct rcu_data {
314#else 314#else
315#define RCU_STALL_DELAY_DELTA 0 315#define RCU_STALL_DELAY_DELTA 0
316#endif 316#endif
317
318#define RCU_SECONDS_TILL_STALL_CHECK (CONFIG_RCU_CPU_STALL_TIMEOUT * HZ + \
319 RCU_STALL_DELAY_DELTA)
320 /* for rsp->jiffies_stall */
321#define RCU_SECONDS_TILL_STALL_RECHECK (3 * RCU_SECONDS_TILL_STALL_CHECK + 30)
322 /* for rsp->jiffies_stall */
323#define RCU_STALL_RAT_DELAY 2 /* Allow other CPUs time */ 317#define RCU_STALL_RAT_DELAY 2 /* Allow other CPUs time */
324 /* to take at least one */ 318 /* to take at least one */
325 /* scheduling clock irq */ 319 /* scheduling clock irq */