aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/rcutree_plugin.h
diff options
context:
space:
mode:
authorPaul E. McKenney <paul.mckenney@linaro.org>2012-01-10 17:13:24 -0500
committerPaul E. McKenney <paulmck@linux.vnet.ibm.com>2012-02-21 12:03:36 -0500
commit778d250a29224795e6320b58928bafa6b6104a06 (patch)
tree51eaa45a16731b22797ed88d34584c8b6d55cc01 /kernel/rcutree_plugin.h
parent091541bbdb9906349481a504e7d8e7fa89f6b6bb (diff)
rcu: Limit lazy-callback duration
Currently, a given CPU is permitted to remain in dyntick-idle mode indefinitely if it has only lazy RCU callbacks queued. This is vulnerable to corner cases in NUMA systems, so limit the time to six seconds by default. (Currently controlled by a cpp macro.) Signed-off-by: Paul E. McKenney <paul.mckenney@linaro.org> Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Diffstat (limited to 'kernel/rcutree_plugin.h')
-rw-r--r--kernel/rcutree_plugin.h12
1 files changed, 11 insertions, 1 deletions
diff --git a/kernel/rcutree_plugin.h b/kernel/rcutree_plugin.h
index eeb2cc6b8657..f8e6dcc91860 100644
--- a/kernel/rcutree_plugin.h
+++ b/kernel/rcutree_plugin.h
@@ -2050,6 +2050,9 @@ static void rcu_prepare_for_idle(int cpu)
2050 * number, be warned: Setting RCU_IDLE_GP_DELAY too high can hang your 2050 * number, be warned: Setting RCU_IDLE_GP_DELAY too high can hang your
2051 * system. And if you are -that- concerned about energy efficiency, 2051 * system. And if you are -that- concerned about energy efficiency,
2052 * just power the system down and be done with it! 2052 * just power the system down and be done with it!
2053 * RCU_IDLE_LAZY_GP_DELAY gives the number of jiffies that a CPU is
2054 * permitted to sleep in dyntick-idle mode with only lazy RCU
2055 * callbacks pending. Setting this too high can OOM your system.
2053 * 2056 *
2054 * The values below work well in practice. If future workloads require 2057 * The values below work well in practice. If future workloads require
2055 * adjustment, they can be converted into kernel config parameters, though 2058 * adjustment, they can be converted into kernel config parameters, though
@@ -2058,11 +2061,13 @@ static void rcu_prepare_for_idle(int cpu)
2058#define RCU_IDLE_FLUSHES 5 /* Number of dyntick-idle tries. */ 2061#define RCU_IDLE_FLUSHES 5 /* Number of dyntick-idle tries. */
2059#define RCU_IDLE_OPT_FLUSHES 3 /* Optional dyntick-idle tries. */ 2062#define RCU_IDLE_OPT_FLUSHES 3 /* Optional dyntick-idle tries. */
2060#define RCU_IDLE_GP_DELAY 6 /* Roughly one grace period. */ 2063#define RCU_IDLE_GP_DELAY 6 /* Roughly one grace period. */
2064#define RCU_IDLE_LAZY_GP_DELAY (6 * HZ) /* Roughly six seconds. */
2061 2065
2062static DEFINE_PER_CPU(int, rcu_dyntick_drain); 2066static DEFINE_PER_CPU(int, rcu_dyntick_drain);
2063static DEFINE_PER_CPU(unsigned long, rcu_dyntick_holdoff); 2067static DEFINE_PER_CPU(unsigned long, rcu_dyntick_holdoff);
2064static DEFINE_PER_CPU(struct hrtimer, rcu_idle_gp_timer); 2068static DEFINE_PER_CPU(struct hrtimer, rcu_idle_gp_timer);
2065static ktime_t rcu_idle_gp_wait; 2069static ktime_t rcu_idle_gp_wait; /* If some non-lazy callbacks. */
2070static ktime_t rcu_idle_lazy_gp_wait; /* If only lazy callbacks. */
2066 2071
2067/* 2072/*
2068 * Allow the CPU to enter dyntick-idle mode if either: (1) There are no 2073 * Allow the CPU to enter dyntick-idle mode if either: (1) There are no
@@ -2151,6 +2156,8 @@ static void rcu_prepare_for_idle_init(int cpu)
2151 unsigned int upj = jiffies_to_usecs(RCU_IDLE_GP_DELAY); 2156 unsigned int upj = jiffies_to_usecs(RCU_IDLE_GP_DELAY);
2152 2157
2153 rcu_idle_gp_wait = ns_to_ktime(upj * (u64)1000); 2158 rcu_idle_gp_wait = ns_to_ktime(upj * (u64)1000);
2159 upj = jiffies_to_usecs(RCU_IDLE_LAZY_GP_DELAY);
2160 rcu_idle_lazy_gp_wait = ns_to_ktime(upj * (u64)1000);
2154 firsttime = 0; 2161 firsttime = 0;
2155 } 2162 }
2156} 2163}
@@ -2225,6 +2232,9 @@ static void rcu_prepare_for_idle(int cpu)
2225 if (rcu_cpu_has_nonlazy_callbacks(cpu)) 2232 if (rcu_cpu_has_nonlazy_callbacks(cpu))
2226 hrtimer_start(&per_cpu(rcu_idle_gp_timer, cpu), 2233 hrtimer_start(&per_cpu(rcu_idle_gp_timer, cpu),
2227 rcu_idle_gp_wait, HRTIMER_MODE_REL); 2234 rcu_idle_gp_wait, HRTIMER_MODE_REL);
2235 else
2236 hrtimer_start(&per_cpu(rcu_idle_gp_timer, cpu),
2237 rcu_idle_lazy_gp_wait, HRTIMER_MODE_REL);
2228 return; /* Nothing more to do immediately. */ 2238 return; /* Nothing more to do immediately. */
2229 } else if (--per_cpu(rcu_dyntick_drain, cpu) <= 0) { 2239 } else if (--per_cpu(rcu_dyntick_drain, cpu) <= 0) {
2230 /* We have hit the limit, so time to give up. */ 2240 /* We have hit the limit, so time to give up. */