aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/rcutree.c
diff options
context:
space:
mode:
authorPaul E. McKenney <paul.mckenney@linaro.org>2012-06-26 23:45:57 -0400
committerPaul E. McKenney <paulmck@linux.vnet.ibm.com>2012-09-23 10:41:54 -0400
commitd40011f601b450396104de42c631981502946cf0 (patch)
tree62205b755bca9391c6924764387d4417e91014d3 /kernel/rcutree.c
parent394f2769aa0dbcf027bae6fb52835e25e05d332e (diff)
rcu: Control grace-period duration from sysfs
Although almost everyone is well-served by the defaults, some uses of RCU benefit from shorter grace periods, while others benefit more from the greater efficiency provided by longer grace periods. Situations requiring a large number of grace periods to elapse (and wireshark startup has been called out as an example of this) are helped by lower-latency grace periods. Furthermore, in some embedded applications, people are willing to accept a small degradation in update efficiency (due to there being more of the shorter grace-period operations) in order to gain the lower latency. In contrast, those few systems with thousands of CPUs need longer grace periods because the CPU overhead of a grace period rises roughly linearly with the number of CPUs. Such systems normally do not make much use of facilities that require large numbers of grace periods to elapse, so this is a good tradeoff. Therefore, this commit allows the durations to be controlled from sysfs. There are two sysfs parameters, one named "jiffies_till_first_fqs" that specifies the delay in jiffies from the end of grace-period initialization until the first attempt to force quiescent states, and the other named "jiffies_till_next_fqs" that specifies the delay (again in jiffies) between subsequent attempts to force quiescent states. They both default to three jiffies, which is compatible with the old hard-coded behavior. At some future time, it may be possible to automatically increase the grace-period length with the number of CPUs, but we do not yet have sufficient data to do a good job. Preliminary data indicates that we should add an addiitonal jiffy to each of the delays for every 200 CPUs in the system, but more experimentation is needed. For now, the number of systems with more than 1,000 CPUs is small enough that this can be relegated to boot-time hand tuning. Signed-off-by: Paul E. McKenney <paul.mckenney@linaro.org> Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com> Reviewed-by: Josh Triplett <josh@joshtriplett.org>
Diffstat (limited to 'kernel/rcutree.c')
-rw-r--r--kernel/rcutree.c25
1 files changed, 22 insertions, 3 deletions
diff --git a/kernel/rcutree.c b/kernel/rcutree.c
index 43d57a17fcc5..c0d3d56f0404 100644
--- a/kernel/rcutree.c
+++ b/kernel/rcutree.c
@@ -226,6 +226,12 @@ int rcu_cpu_stall_timeout __read_mostly = CONFIG_RCU_CPU_STALL_TIMEOUT;
226module_param(rcu_cpu_stall_suppress, int, 0644); 226module_param(rcu_cpu_stall_suppress, int, 0644);
227module_param(rcu_cpu_stall_timeout, int, 0644); 227module_param(rcu_cpu_stall_timeout, int, 0644);
228 228
229static ulong jiffies_till_first_fqs = RCU_JIFFIES_TILL_FORCE_QS;
230static ulong jiffies_till_next_fqs = RCU_JIFFIES_TILL_FORCE_QS;
231
232module_param(jiffies_till_first_fqs, ulong, 0644);
233module_param(jiffies_till_next_fqs, ulong, 0644);
234
229static void force_qs_rnp(struct rcu_state *rsp, int (*f)(struct rcu_data *)); 235static void force_qs_rnp(struct rcu_state *rsp, int (*f)(struct rcu_data *));
230static void force_quiescent_state(struct rcu_state *rsp); 236static void force_quiescent_state(struct rcu_state *rsp);
231static int rcu_pending(int cpu); 237static int rcu_pending(int cpu);
@@ -1177,6 +1183,7 @@ static void rcu_gp_cleanup(struct rcu_state *rsp)
1177static int __noreturn rcu_gp_kthread(void *arg) 1183static int __noreturn rcu_gp_kthread(void *arg)
1178{ 1184{
1179 int fqs_state; 1185 int fqs_state;
1186 unsigned long j;
1180 int ret; 1187 int ret;
1181 struct rcu_state *rsp = arg; 1188 struct rcu_state *rsp = arg;
1182 struct rcu_node *rnp = rcu_get_root(rsp); 1189 struct rcu_node *rnp = rcu_get_root(rsp);
@@ -1197,14 +1204,18 @@ static int __noreturn rcu_gp_kthread(void *arg)
1197 1204
1198 /* Handle quiescent-state forcing. */ 1205 /* Handle quiescent-state forcing. */
1199 fqs_state = RCU_SAVE_DYNTICK; 1206 fqs_state = RCU_SAVE_DYNTICK;
1207 j = jiffies_till_first_fqs;
1208 if (j > HZ) {
1209 j = HZ;
1210 jiffies_till_first_fqs = HZ;
1211 }
1200 for (;;) { 1212 for (;;) {
1201 rsp->jiffies_force_qs = jiffies + 1213 rsp->jiffies_force_qs = jiffies + j;
1202 RCU_JIFFIES_TILL_FORCE_QS;
1203 ret = wait_event_interruptible_timeout(rsp->gp_wq, 1214 ret = wait_event_interruptible_timeout(rsp->gp_wq,
1204 (rsp->gp_flags & RCU_GP_FLAG_FQS) || 1215 (rsp->gp_flags & RCU_GP_FLAG_FQS) ||
1205 (!ACCESS_ONCE(rnp->qsmask) && 1216 (!ACCESS_ONCE(rnp->qsmask) &&
1206 !rcu_preempt_blocked_readers_cgp(rnp)), 1217 !rcu_preempt_blocked_readers_cgp(rnp)),
1207 RCU_JIFFIES_TILL_FORCE_QS); 1218 j);
1208 /* If grace period done, leave loop. */ 1219 /* If grace period done, leave loop. */
1209 if (!ACCESS_ONCE(rnp->qsmask) && 1220 if (!ACCESS_ONCE(rnp->qsmask) &&
1210 !rcu_preempt_blocked_readers_cgp(rnp)) 1221 !rcu_preempt_blocked_readers_cgp(rnp))
@@ -1218,6 +1229,14 @@ static int __noreturn rcu_gp_kthread(void *arg)
1218 cond_resched(); 1229 cond_resched();
1219 flush_signals(current); 1230 flush_signals(current);
1220 } 1231 }
1232 j = jiffies_till_next_fqs;
1233 if (j > HZ) {
1234 j = HZ;
1235 jiffies_till_next_fqs = HZ;
1236 } else if (j < 1) {
1237 j = 1;
1238 jiffies_till_next_fqs = 1;
1239 }
1221 } 1240 }
1222 1241
1223 /* Handle grace-period end. */ 1242 /* Handle grace-period end. */