aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/tick.h
diff options
context:
space:
mode:
authorFrederic Weisbecker <fweisbec@gmail.com>2015-06-07 09:54:30 -0400
committerFrederic Weisbecker <fweisbec@gmail.com>2016-03-02 10:41:39 -0500
commitd027d45d8a17a4145eab2d841140e9acbb7feb59 (patch)
tree492d0ffe0b6e2bc548266c382b8c5c41cb5ef3b8 /include/linux/tick.h
parent8537bb95a63e4be330359721f0ecd422f4a4c0ca (diff)
nohz: New tick dependency mask
The tick dependency is evaluated on every IRQ and context switch. This consists is a batch of checks which determine whether it is safe to stop the tick or not. These checks are often split in many details: posix cpu timers, scheduler, sched clock, perf events.... each of which are made of smaller details: posix cpu timer involves checking process wide timers then thread wide timers. Perf involves checking freq events then more per cpu details. Checking these informations asynchronously every time we update the full dynticks state bring avoidable overhead and a messy layout. Let's introduce instead tick dependency masks: one for system wide dependency (unstable sched clock, freq based perf events), one for CPU wide dependency (sched, throttling perf events), and task/signal level dependencies (posix cpu timers). The subsystems are responsible for setting and clearing their dependency through a set of APIs that will take care of concurrent dependency mask modifications and kick targets to restart the relevant CPU tick whenever needed. This new dependency engine stays beside the old one until all subsystems having a tick dependency are converted to it. Suggested-by: Thomas Gleixner <tglx@linutronix.de> Suggested-by: Peter Zijlstra <peterz@infradead.org> Reviewed-by: Chris Metcalf <cmetcalf@ezchip.com> Cc: Christoph Lameter <cl@linux.com> Cc: Chris Metcalf <cmetcalf@ezchip.com> Cc: Ingo Molnar <mingo@kernel.org> Cc: Luiz Capitulino <lcapitulino@redhat.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Rik van Riel <riel@redhat.com> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Viresh Kumar <viresh.kumar@linaro.org> Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Diffstat (limited to 'include/linux/tick.h')
-rw-r--r--include/linux/tick.h92
1 files changed, 92 insertions, 0 deletions
diff --git a/include/linux/tick.h b/include/linux/tick.h
index 97fd4e543846..d60e5df8ec28 100644
--- a/include/linux/tick.h
+++ b/include/linux/tick.h
@@ -97,6 +97,18 @@ static inline void tick_broadcast_exit(void)
97 tick_broadcast_oneshot_control(TICK_BROADCAST_EXIT); 97 tick_broadcast_oneshot_control(TICK_BROADCAST_EXIT);
98} 98}
99 99
100enum tick_dep_bits {
101 TICK_DEP_BIT_POSIX_TIMER = 0,
102 TICK_DEP_BIT_PERF_EVENTS = 1,
103 TICK_DEP_BIT_SCHED = 2,
104 TICK_DEP_BIT_CLOCK_UNSTABLE = 3
105};
106
107#define TICK_DEP_MASK_POSIX_TIMER (1 << TICK_DEP_BIT_POSIX_TIMER)
108#define TICK_DEP_MASK_PERF_EVENTS (1 << TICK_DEP_BIT_PERF_EVENTS)
109#define TICK_DEP_MASK_SCHED (1 << TICK_DEP_BIT_SCHED)
110#define TICK_DEP_MASK_CLOCK_UNSTABLE (1 << TICK_DEP_BIT_CLOCK_UNSTABLE)
111
100#ifdef CONFIG_NO_HZ_COMMON 112#ifdef CONFIG_NO_HZ_COMMON
101extern int tick_nohz_enabled; 113extern int tick_nohz_enabled;
102extern int tick_nohz_tick_stopped(void); 114extern int tick_nohz_tick_stopped(void);
@@ -154,6 +166,72 @@ static inline int housekeeping_any_cpu(void)
154 return cpumask_any_and(housekeeping_mask, cpu_online_mask); 166 return cpumask_any_and(housekeeping_mask, cpu_online_mask);
155} 167}
156 168
169extern void tick_nohz_dep_set(enum tick_dep_bits bit);
170extern void tick_nohz_dep_clear(enum tick_dep_bits bit);
171extern void tick_nohz_dep_set_cpu(int cpu, enum tick_dep_bits bit);
172extern void tick_nohz_dep_clear_cpu(int cpu, enum tick_dep_bits bit);
173extern void tick_nohz_dep_set_task(struct task_struct *tsk,
174 enum tick_dep_bits bit);
175extern void tick_nohz_dep_clear_task(struct task_struct *tsk,
176 enum tick_dep_bits bit);
177extern void tick_nohz_dep_set_signal(struct signal_struct *signal,
178 enum tick_dep_bits bit);
179extern void tick_nohz_dep_clear_signal(struct signal_struct *signal,
180 enum tick_dep_bits bit);
181
182/*
183 * The below are tick_nohz_[set,clear]_dep() wrappers that optimize off-cases
184 * on top of static keys.
185 */
186static inline void tick_dep_set(enum tick_dep_bits bit)
187{
188 if (tick_nohz_full_enabled())
189 tick_nohz_dep_set(bit);
190}
191
192static inline void tick_dep_clear(enum tick_dep_bits bit)
193{
194 if (tick_nohz_full_enabled())
195 tick_nohz_dep_clear(bit);
196}
197
198static inline void tick_dep_set_cpu(int cpu, enum tick_dep_bits bit)
199{
200 if (tick_nohz_full_cpu(cpu))
201 tick_nohz_dep_set_cpu(cpu, bit);
202}
203
204static inline void tick_dep_clear_cpu(int cpu, enum tick_dep_bits bit)
205{
206 if (tick_nohz_full_cpu(cpu))
207 tick_nohz_dep_clear_cpu(cpu, bit);
208}
209
210static inline void tick_dep_set_task(struct task_struct *tsk,
211 enum tick_dep_bits bit)
212{
213 if (tick_nohz_full_enabled())
214 tick_nohz_dep_set_task(tsk, bit);
215}
216static inline void tick_dep_clear_task(struct task_struct *tsk,
217 enum tick_dep_bits bit)
218{
219 if (tick_nohz_full_enabled())
220 tick_nohz_dep_clear_task(tsk, bit);
221}
222static inline void tick_dep_set_signal(struct signal_struct *signal,
223 enum tick_dep_bits bit)
224{
225 if (tick_nohz_full_enabled())
226 tick_nohz_dep_set_signal(signal, bit);
227}
228static inline void tick_dep_clear_signal(struct signal_struct *signal,
229 enum tick_dep_bits bit)
230{
231 if (tick_nohz_full_enabled())
232 tick_nohz_dep_clear_signal(signal, bit);
233}
234
157extern void tick_nohz_full_kick(void); 235extern void tick_nohz_full_kick(void);
158extern void tick_nohz_full_kick_cpu(int cpu); 236extern void tick_nohz_full_kick_cpu(int cpu);
159extern void tick_nohz_full_kick_all(void); 237extern void tick_nohz_full_kick_all(void);
@@ -166,6 +244,20 @@ static inline int housekeeping_any_cpu(void)
166static inline bool tick_nohz_full_enabled(void) { return false; } 244static inline bool tick_nohz_full_enabled(void) { return false; }
167static inline bool tick_nohz_full_cpu(int cpu) { return false; } 245static inline bool tick_nohz_full_cpu(int cpu) { return false; }
168static inline void tick_nohz_full_add_cpus_to(struct cpumask *mask) { } 246static inline void tick_nohz_full_add_cpus_to(struct cpumask *mask) { }
247
248static inline void tick_dep_set(enum tick_dep_bits bit) { }
249static inline void tick_dep_clear(enum tick_dep_bits bit) { }
250static inline void tick_dep_set_cpu(int cpu, enum tick_dep_bits bit) { }
251static inline void tick_dep_clear_cpu(int cpu, enum tick_dep_bits bit) { }
252static inline void tick_dep_set_task(struct task_struct *tsk,
253 enum tick_dep_bits bit) { }
254static inline void tick_dep_clear_task(struct task_struct *tsk,
255 enum tick_dep_bits bit) { }
256static inline void tick_dep_set_signal(struct signal_struct *signal,
257 enum tick_dep_bits bit) { }
258static inline void tick_dep_clear_signal(struct signal_struct *signal,
259 enum tick_dep_bits bit) { }
260
169static inline void tick_nohz_full_kick_cpu(int cpu) { } 261static inline void tick_nohz_full_kick_cpu(int cpu) { }
170static inline void tick_nohz_full_kick(void) { } 262static inline void tick_nohz_full_kick(void) { }
171static inline void tick_nohz_full_kick_all(void) { } 263static inline void tick_nohz_full_kick_all(void) { }