Commit 13cfcca0 authored by Paul E. McKenney's avatar Paul E. McKenney

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: default avatarPaul E. McKenney <paulmck@linux.vnet.ibm.com>
parent 27565d64
...@@ -208,8 +208,11 @@ module_param(blimit, int, 0); ...@@ -208,8 +208,11 @@ module_param(blimit, int, 0);
module_param(qhimark, int, 0); module_param(qhimark, int, 0);
module_param(qlowmark, int, 0); module_param(qlowmark, int, 0);
int rcu_cpu_stall_suppress __read_mostly; int rcu_cpu_stall_suppress __read_mostly; /* 1 = suppress stall warnings. */
int rcu_cpu_stall_timeout __read_mostly = CONFIG_RCU_CPU_STALL_TIMEOUT;
module_param(rcu_cpu_stall_suppress, int, 0644); module_param(rcu_cpu_stall_suppress, int, 0644);
module_param(rcu_cpu_stall_timeout, int, 0644);
static void force_quiescent_state(struct rcu_state *rsp, int relaxed); static void force_quiescent_state(struct rcu_state *rsp, int relaxed);
static int rcu_pending(int cpu); static int rcu_pending(int cpu);
...@@ -645,10 +648,28 @@ static int rcu_implicit_dynticks_qs(struct rcu_data *rdp) ...@@ -645,10 +648,28 @@ static int rcu_implicit_dynticks_qs(struct rcu_data *rdp)
return rcu_implicit_offline_qs(rdp); return rcu_implicit_offline_qs(rdp);
} }
static int jiffies_till_stall_check(void)
{
int till_stall_check = ACCESS_ONCE(rcu_cpu_stall_timeout);
/*
* Limit check must be consistent with the Kconfig limits
* for CONFIG_RCU_CPU_STALL_TIMEOUT.
*/
if (till_stall_check < 3) {
ACCESS_ONCE(rcu_cpu_stall_timeout) = 3;
till_stall_check = 3;
} else if (till_stall_check > 300) {
ACCESS_ONCE(rcu_cpu_stall_timeout) = 300;
till_stall_check = 300;
}
return till_stall_check * HZ + RCU_STALL_DELAY_DELTA;
}
static void record_gp_stall_check_time(struct rcu_state *rsp) static void record_gp_stall_check_time(struct rcu_state *rsp)
{ {
rsp->gp_start = jiffies; rsp->gp_start = jiffies;
rsp->jiffies_stall = jiffies + RCU_SECONDS_TILL_STALL_CHECK; rsp->jiffies_stall = jiffies + jiffies_till_stall_check();
} }
static void print_other_cpu_stall(struct rcu_state *rsp) static void print_other_cpu_stall(struct rcu_state *rsp)
...@@ -667,7 +688,7 @@ static void print_other_cpu_stall(struct rcu_state *rsp) ...@@ -667,7 +688,7 @@ static void print_other_cpu_stall(struct rcu_state *rsp)
raw_spin_unlock_irqrestore(&rnp->lock, flags); raw_spin_unlock_irqrestore(&rnp->lock, flags);
return; return;
} }
rsp->jiffies_stall = jiffies + RCU_SECONDS_TILL_STALL_RECHECK; rsp->jiffies_stall = jiffies + 3 * jiffies_till_stall_check() + 3;
/* /*
* Now rat on any tasks that got kicked up to the root rcu_node * 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,8 +747,8 @@ static void print_cpu_stall(struct rcu_state *rsp)
raw_spin_lock_irqsave(&rnp->lock, flags); raw_spin_lock_irqsave(&rnp->lock, flags);
if (ULONG_CMP_GE(jiffies, rsp->jiffies_stall)) if (ULONG_CMP_GE(jiffies, rsp->jiffies_stall))
rsp->jiffies_stall = rsp->jiffies_stall = jiffies +
jiffies + RCU_SECONDS_TILL_STALL_RECHECK; 3 * jiffies_till_stall_check() + 3;
raw_spin_unlock_irqrestore(&rnp->lock, flags); raw_spin_unlock_irqrestore(&rnp->lock, flags);
set_need_resched(); /* kick ourselves to get things going. */ set_need_resched(); /* kick ourselves to get things going. */
......
...@@ -314,12 +314,6 @@ struct rcu_data { ...@@ -314,12 +314,6 @@ struct rcu_data {
#else #else
#define RCU_STALL_DELAY_DELTA 0 #define RCU_STALL_DELAY_DELTA 0
#endif #endif
#define RCU_SECONDS_TILL_STALL_CHECK (CONFIG_RCU_CPU_STALL_TIMEOUT * HZ + \
RCU_STALL_DELAY_DELTA)
/* for rsp->jiffies_stall */
#define RCU_SECONDS_TILL_STALL_RECHECK (3 * RCU_SECONDS_TILL_STALL_CHECK + 30)
/* for rsp->jiffies_stall */
#define RCU_STALL_RAT_DELAY 2 /* Allow other CPUs time */ #define RCU_STALL_RAT_DELAY 2 /* Allow other CPUs time */
/* to take at least one */ /* to take at least one */
/* scheduling clock irq */ /* scheduling clock irq */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment