aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/time
diff options
context:
space:
mode:
authorFrederic Weisbecker <fweisbec@gmail.com>2013-04-20 09:43:57 -0400
committerFrederic Weisbecker <fweisbec@gmail.com>2013-04-22 14:28:04 -0400
commit9014c45d9e2dbb935498a5f1d106e220e8624643 (patch)
tree2db8ead01d05d5a2a85904b251b2966b2c56dfca /kernel/time
parentff442c51f6543378cf23107c75b7949dc64a9119 (diff)
nohz: Implement full dynticks kick
Implement the full dynticks kick that is performed from IPIs sent by various subsystems (scheduler, posix timers, ...) when they want to notify about a new event that may reconsider the dependency on the tick. Most of the time, such an event end up restarting the tick. (Part of the design with subsystems providing *_can_stop_tick() helpers suggested by Peter Zijlstra a while ago). Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com> Cc: Chris Metcalf <cmetcalf@tilera.com> Cc: Christoph Lameter <cl@linux.com> Cc: Geoff Levand <geoff@infradead.org> Cc: Gilad Ben Yossef <gilad@benyossef.com> Cc: Hakan Akkan <hakanakkan@gmail.com> Cc: Ingo Molnar <mingo@kernel.org> Cc: Kevin Hilman <khilman@linaro.org> Cc: Li Zhong <zhong@linux.vnet.ibm.com> Cc: Oleg Nesterov <oleg@redhat.com> Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com> Cc: Paul Gortmaker <paul.gortmaker@windriver.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Steven Rostedt <rostedt@goodmis.org> Cc: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'kernel/time')
-rw-r--r--kernel/time/tick-sched.c42
1 files changed, 38 insertions, 4 deletions
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index 4d74a68b2c34..95d79aeb3e27 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -21,6 +21,8 @@
21#include <linux/sched.h> 21#include <linux/sched.h>
22#include <linux/module.h> 22#include <linux/module.h>
23#include <linux/irq_work.h> 23#include <linux/irq_work.h>
24#include <linux/posix-timers.h>
25#include <linux/perf_event.h>
24 26
25#include <asm/irq_regs.h> 27#include <asm/irq_regs.h>
26 28
@@ -147,16 +149,48 @@ static void tick_sched_handle(struct tick_sched *ts, struct pt_regs *regs)
147static cpumask_var_t nohz_full_mask; 149static cpumask_var_t nohz_full_mask;
148bool have_nohz_full_mask; 150bool have_nohz_full_mask;
149 151
152static bool can_stop_full_tick(void)
153{
154 WARN_ON_ONCE(!irqs_disabled());
155
156 if (!sched_can_stop_tick())
157 return false;
158
159 if (!posix_cpu_timers_can_stop_tick(current))
160 return false;
161
162 if (!perf_event_can_stop_tick())
163 return false;
164
165 /* sched_clock_tick() needs us? */
166#ifdef CONFIG_HAVE_UNSTABLE_SCHED_CLOCK
167 /*
168 * TODO: kick full dynticks CPUs when
169 * sched_clock_stable is set.
170 */
171 if (!sched_clock_stable)
172 return false;
173#endif
174
175 return true;
176}
177
178static void tick_nohz_restart_sched_tick(struct tick_sched *ts, ktime_t now);
179
150/* 180/*
151 * Re-evaluate the need for the tick on the current CPU 181 * Re-evaluate the need for the tick on the current CPU
152 * and restart it if necessary. 182 * and restart it if necessary.
153 */ 183 */
154void tick_nohz_full_check(void) 184void tick_nohz_full_check(void)
155{ 185{
156 /* 186 struct tick_sched *ts = &__get_cpu_var(tick_cpu_sched);
157 * STUB for now, will be filled with the full tick stop/restart 187
158 * infrastructure patches 188 if (tick_nohz_full_cpu(smp_processor_id())) {
159 */ 189 if (ts->tick_stopped && !is_idle_task(current)) {
190 if (!can_stop_full_tick())
191 tick_nohz_restart_sched_tick(ts, ktime_get());
192 }
193 }
160} 194}
161 195
162static void nohz_full_kick_work_func(struct irq_work *work) 196static void nohz_full_kick_work_func(struct irq_work *work)