aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrederic Weisbecker <fweisbec@gmail.com>2013-04-17 18:15:40 -0400
committerFrederic Weisbecker <fweisbec@gmail.com>2013-04-18 12:53:34 -0400
commit76c24fb054b52b34af4dcde589cbb9e2b98fc74c (patch)
treebbce968d4f057dce3b028ca5c5b894e68255db02
parent65d798f0f9339ae2c4ebe9480e3260b33382a584 (diff)
nohz: New APIs to re-evaluate the tick on full dynticks CPUs
Provide two new helpers in order to notify the full dynticks CPUs about some internal system changes against which they may reconsider the state of their tick. Some practical examples include: posix cpu timers, perf tick and sched clock tick. For now the notifying handler, implemented through IPIs, is a stub that will be implemented when we get the tick stop/restart infrastructure in. 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>
-rw-r--r--include/linux/tick.h4
-rw-r--r--kernel/time/Kconfig1
-rw-r--r--kernel/time/tick-sched.c51
3 files changed, 56 insertions, 0 deletions
diff --git a/include/linux/tick.h b/include/linux/tick.h
index b4e3b0c9639e..c2dcfb18f65b 100644
--- a/include/linux/tick.h
+++ b/include/linux/tick.h
@@ -159,8 +159,12 @@ static inline u64 get_cpu_iowait_time_us(int cpu, u64 *unused) { return -1; }
159 159
160#ifdef CONFIG_NO_HZ_FULL 160#ifdef CONFIG_NO_HZ_FULL
161extern int tick_nohz_full_cpu(int cpu); 161extern int tick_nohz_full_cpu(int cpu);
162extern void tick_nohz_full_kick(void);
163extern void tick_nohz_full_kick_all(void);
162#else 164#else
163static inline int tick_nohz_full_cpu(int cpu) { return 0; } 165static inline int tick_nohz_full_cpu(int cpu) { return 0; }
166static inline void tick_nohz_full_kick(void) { }
167static inline void tick_nohz_full_kick_all(void) { }
164#endif 168#endif
165 169
166 170
diff --git a/kernel/time/Kconfig b/kernel/time/Kconfig
index 358d601a4fec..fbb4c7eb92a0 100644
--- a/kernel/time/Kconfig
+++ b/kernel/time/Kconfig
@@ -111,6 +111,7 @@ config NO_HZ_FULL
111 select RCU_USER_QS 111 select RCU_USER_QS
112 select RCU_NOCB_CPU 112 select RCU_NOCB_CPU
113 select CONTEXT_TRACKING_FORCE 113 select CONTEXT_TRACKING_FORCE
114 select IRQ_WORK
114 help 115 help
115 Adaptively try to shutdown the tick whenever possible, even when 116 Adaptively try to shutdown the tick whenever possible, even when
116 the CPU is running tasks. Typically this requires running a single 117 the CPU is running tasks. Typically this requires running a single
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index 369b5769fc97..2bcad5b904d8 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -147,6 +147,57 @@ static void tick_sched_handle(struct tick_sched *ts, struct pt_regs *regs)
147static cpumask_var_t nohz_full_mask; 147static cpumask_var_t nohz_full_mask;
148bool have_nohz_full_mask; 148bool have_nohz_full_mask;
149 149
150/*
151 * Re-evaluate the need for the tick on the current CPU
152 * and restart it if necessary.
153 */
154static void tick_nohz_full_check(void)
155{
156 /*
157 * STUB for now, will be filled with the full tick stop/restart
158 * infrastructure patches
159 */
160}
161
162static void nohz_full_kick_work_func(struct irq_work *work)
163{
164 tick_nohz_full_check();
165}
166
167static DEFINE_PER_CPU(struct irq_work, nohz_full_kick_work) = {
168 .func = nohz_full_kick_work_func,
169};
170
171/*
172 * Kick the current CPU if it's full dynticks in order to force it to
173 * re-evaluate its dependency on the tick and restart it if necessary.
174 */
175void tick_nohz_full_kick(void)
176{
177 if (tick_nohz_full_cpu(smp_processor_id()))
178 irq_work_queue(&__get_cpu_var(nohz_full_kick_work));
179}
180
181static void nohz_full_kick_ipi(void *info)
182{
183 tick_nohz_full_check();
184}
185
186/*
187 * Kick all full dynticks CPUs in order to force these to re-evaluate
188 * their dependency on the tick and restart it if necessary.
189 */
190void tick_nohz_full_kick_all(void)
191{
192 if (!have_nohz_full_mask)
193 return;
194
195 preempt_disable();
196 smp_call_function_many(nohz_full_mask,
197 nohz_full_kick_ipi, NULL, false);
198 preempt_enable();
199}
200
150int tick_nohz_full_cpu(int cpu) 201int tick_nohz_full_cpu(int cpu)
151{ 202{
152 if (!have_nohz_full_mask) 203 if (!have_nohz_full_mask)