tick.h 8.4 KB
Newer Older
1 2
/*
 * Tick related global functions
3 4 5 6 7
 */
#ifndef _LINUX_TICK_H
#define _LINUX_TICK_H

#include <linux/clockchips.h>
8
#include <linux/irqflags.h>
9
#include <linux/percpu.h>
10 11
#include <linux/context_tracking_state.h>
#include <linux/cpumask.h>
12
#include <linux/sched.h>
13

14 15
#ifdef CONFIG_GENERIC_CLOCKEVENTS
extern void __init tick_init(void);
16 17 18
/* Should be core only, but ARM BL switcher requires it */
extern void tick_suspend_local(void);
/* Should be core only, but XEN resume magic and ARM BL switcher require it */
19
extern void tick_resume_local(void);
20
extern void tick_handover_do_timer(void);
21
extern void tick_cleanup_dead_cpu(int cpu);
22 23
#else /* CONFIG_GENERIC_CLOCKEVENTS */
static inline void tick_init(void) { }
24
static inline void tick_suspend_local(void) { }
25
static inline void tick_resume_local(void) { }
26
static inline void tick_handover_do_timer(void) { }
27
static inline void tick_cleanup_dead_cpu(int cpu) { }
28
#endif /* !CONFIG_GENERIC_CLOCKEVENTS */
29

30 31 32 33 34 35 36 37
#if defined(CONFIG_GENERIC_CLOCKEVENTS) && defined(CONFIG_SUSPEND)
extern void tick_freeze(void);
extern void tick_unfreeze(void);
#else
static inline void tick_freeze(void) { }
static inline void tick_unfreeze(void) { }
#endif

38
#ifdef CONFIG_TICK_ONESHOT
39
extern void tick_irq_enter(void);
40
#  ifndef arch_needs_cpu
41
#   define arch_needs_cpu() (0)
42
#  endif
43
# else
44
static inline void tick_irq_enter(void) { }
45
#endif
46

47 48 49 50 51 52
#if defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) && defined(CONFIG_TICK_ONESHOT)
extern void hotplug_cpu__broadcast_tick_pull(int dead_cpu);
#else
static inline void hotplug_cpu__broadcast_tick_pull(int dead_cpu) { }
#endif

53 54 55 56 57 58
enum tick_broadcast_mode {
	TICK_BROADCAST_OFF,
	TICK_BROADCAST_ON,
	TICK_BROADCAST_FORCE,
};

59 60 61 62 63
enum tick_broadcast_state {
	TICK_BROADCAST_EXIT,
	TICK_BROADCAST_ENTER,
};

64 65 66 67 68 69
#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
extern void tick_broadcast_control(enum tick_broadcast_mode mode);
#else
static inline void tick_broadcast_control(enum tick_broadcast_mode mode) { }
#endif /* BROADCAST */

70
#ifdef CONFIG_GENERIC_CLOCKEVENTS
71
extern int tick_broadcast_oneshot_control(enum tick_broadcast_state state);
72 73 74 75 76 77
#else
static inline int tick_broadcast_oneshot_control(enum tick_broadcast_state state)
{
	return 0;
}
#endif
78

79 80 81 82 83 84 85 86 87 88 89 90
static inline void tick_broadcast_enable(void)
{
	tick_broadcast_control(TICK_BROADCAST_ON);
}
static inline void tick_broadcast_disable(void)
{
	tick_broadcast_control(TICK_BROADCAST_OFF);
}
static inline void tick_broadcast_force(void)
{
	tick_broadcast_control(TICK_BROADCAST_FORCE);
}
91 92 93 94 95 96 97 98
static inline int tick_broadcast_enter(void)
{
	return tick_broadcast_oneshot_control(TICK_BROADCAST_ENTER);
}
static inline void tick_broadcast_exit(void)
{
	tick_broadcast_oneshot_control(TICK_BROADCAST_EXIT);
}
99

100 101 102 103 104 105 106
enum tick_dep_bits {
	TICK_DEP_BIT_POSIX_TIMER	= 0,
	TICK_DEP_BIT_PERF_EVENTS	= 1,
	TICK_DEP_BIT_SCHED		= 2,
	TICK_DEP_BIT_CLOCK_UNSTABLE	= 3
};

107
#define TICK_DEP_MASK_NONE		0
108 109 110 111 112
#define TICK_DEP_MASK_POSIX_TIMER	(1 << TICK_DEP_BIT_POSIX_TIMER)
#define TICK_DEP_MASK_PERF_EVENTS	(1 << TICK_DEP_BIT_PERF_EVENTS)
#define TICK_DEP_MASK_SCHED		(1 << TICK_DEP_BIT_SCHED)
#define TICK_DEP_MASK_CLOCK_UNSTABLE	(1 << TICK_DEP_BIT_CLOCK_UNSTABLE)

113
#ifdef CONFIG_NO_HZ_COMMON
114
extern int tick_nohz_enabled;
115
extern int tick_nohz_tick_stopped(void);
116
extern void tick_nohz_idle_enter(void);
117 118
extern void tick_nohz_idle_exit(void);
extern void tick_nohz_irq_exit(void);
119
extern ktime_t tick_nohz_get_sleep_length(void);
120
extern u64 get_cpu_idle_time_us(int cpu, u64 *last_update_time);
121
extern u64 get_cpu_iowait_time_us(int cpu, u64 *last_update_time);
122
#else /* !CONFIG_NO_HZ_COMMON */
123
#define tick_nohz_enabled (0)
124
static inline int tick_nohz_tick_stopped(void) { return 0; }
125 126
static inline void tick_nohz_idle_enter(void) { }
static inline void tick_nohz_idle_exit(void) { }
127

128 129 130 131 132 133
static inline ktime_t tick_nohz_get_sleep_length(void)
{
	ktime_t len = { .tv64 = NSEC_PER_SEC/HZ };

	return len;
}
134
static inline u64 get_cpu_idle_time_us(int cpu, u64 *unused) { return -1; }
135
static inline u64 get_cpu_iowait_time_us(int cpu, u64 *unused) { return -1; }
136
#endif /* !CONFIG_NO_HZ_COMMON */
137

138
#ifdef CONFIG_NO_HZ_FULL
139 140
extern bool tick_nohz_full_running;
extern cpumask_var_t tick_nohz_full_mask;
141
extern cpumask_var_t housekeeping_mask;
142 143 144

static inline bool tick_nohz_full_enabled(void)
{
145
	if (!context_tracking_is_enabled())
146 147 148 149 150 151 152 153 154 155 156 157 158
		return false;

	return tick_nohz_full_running;
}

static inline bool tick_nohz_full_cpu(int cpu)
{
	if (!tick_nohz_full_enabled())
		return false;

	return cpumask_test_cpu(cpu, tick_nohz_full_mask);
}

159 160 161 162 163 164
static inline void tick_nohz_full_add_cpus_to(struct cpumask *mask)
{
	if (tick_nohz_full_enabled())
		cpumask_or(mask, mask, tick_nohz_full_mask);
}

165 166 167 168 169
static inline int housekeeping_any_cpu(void)
{
	return cpumask_any_and(housekeeping_mask, cpu_online_mask);
}

170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235
extern void tick_nohz_dep_set(enum tick_dep_bits bit);
extern void tick_nohz_dep_clear(enum tick_dep_bits bit);
extern void tick_nohz_dep_set_cpu(int cpu, enum tick_dep_bits bit);
extern void tick_nohz_dep_clear_cpu(int cpu, enum tick_dep_bits bit);
extern void tick_nohz_dep_set_task(struct task_struct *tsk,
				   enum tick_dep_bits bit);
extern void tick_nohz_dep_clear_task(struct task_struct *tsk,
				     enum tick_dep_bits bit);
extern void tick_nohz_dep_set_signal(struct signal_struct *signal,
				     enum tick_dep_bits bit);
extern void tick_nohz_dep_clear_signal(struct signal_struct *signal,
				       enum tick_dep_bits bit);

/*
 * The below are tick_nohz_[set,clear]_dep() wrappers that optimize off-cases
 * on top of static keys.
 */
static inline void tick_dep_set(enum tick_dep_bits bit)
{
	if (tick_nohz_full_enabled())
		tick_nohz_dep_set(bit);
}

static inline void tick_dep_clear(enum tick_dep_bits bit)
{
	if (tick_nohz_full_enabled())
		tick_nohz_dep_clear(bit);
}

static inline void tick_dep_set_cpu(int cpu, enum tick_dep_bits bit)
{
	if (tick_nohz_full_cpu(cpu))
		tick_nohz_dep_set_cpu(cpu, bit);
}

static inline void tick_dep_clear_cpu(int cpu, enum tick_dep_bits bit)
{
	if (tick_nohz_full_cpu(cpu))
		tick_nohz_dep_clear_cpu(cpu, bit);
}

static inline void tick_dep_set_task(struct task_struct *tsk,
				     enum tick_dep_bits bit)
{
	if (tick_nohz_full_enabled())
		tick_nohz_dep_set_task(tsk, bit);
}
static inline void tick_dep_clear_task(struct task_struct *tsk,
				       enum tick_dep_bits bit)
{
	if (tick_nohz_full_enabled())
		tick_nohz_dep_clear_task(tsk, bit);
}
static inline void tick_dep_set_signal(struct signal_struct *signal,
				       enum tick_dep_bits bit)
{
	if (tick_nohz_full_enabled())
		tick_nohz_dep_set_signal(signal, bit);
}
static inline void tick_dep_clear_signal(struct signal_struct *signal,
					 enum tick_dep_bits bit)
{
	if (tick_nohz_full_enabled())
		tick_nohz_dep_clear_signal(signal, bit);
}

236
extern void tick_nohz_full_kick_cpu(int cpu);
237
extern void __tick_nohz_task_switch(void);
238
#else
239 240 241 242
static inline int housekeeping_any_cpu(void)
{
	return smp_processor_id();
}
243 244
static inline bool tick_nohz_full_enabled(void) { return false; }
static inline bool tick_nohz_full_cpu(int cpu) { return false; }
245
static inline void tick_nohz_full_add_cpus_to(struct cpumask *mask) { }
246 247 248 249 250 251 252 253 254 255 256 257 258 259

static inline void tick_dep_set(enum tick_dep_bits bit) { }
static inline void tick_dep_clear(enum tick_dep_bits bit) { }
static inline void tick_dep_set_cpu(int cpu, enum tick_dep_bits bit) { }
static inline void tick_dep_clear_cpu(int cpu, enum tick_dep_bits bit) { }
static inline void tick_dep_set_task(struct task_struct *tsk,
				     enum tick_dep_bits bit) { }
static inline void tick_dep_clear_task(struct task_struct *tsk,
				       enum tick_dep_bits bit) { }
static inline void tick_dep_set_signal(struct signal_struct *signal,
				       enum tick_dep_bits bit) { }
static inline void tick_dep_clear_signal(struct signal_struct *signal,
					 enum tick_dep_bits bit) { }

260
static inline void tick_nohz_full_kick_cpu(int cpu) { }
261
static inline void __tick_nohz_task_switch(void) { }
262 263
#endif

264 265 266 267 268 269 270 271 272
static inline const struct cpumask *housekeeping_cpumask(void)
{
#ifdef CONFIG_NO_HZ_FULL
	if (tick_nohz_full_enabled())
		return housekeeping_mask;
#endif
	return cpu_possible_mask;
}

273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290
static inline bool is_housekeeping_cpu(int cpu)
{
#ifdef CONFIG_NO_HZ_FULL
	if (tick_nohz_full_enabled())
		return cpumask_test_cpu(cpu, housekeeping_mask);
#endif
	return true;
}

static inline void housekeeping_affine(struct task_struct *t)
{
#ifdef CONFIG_NO_HZ_FULL
	if (tick_nohz_full_enabled())
		set_cpus_allowed_ptr(t, housekeeping_mask);

#endif
}

291
static inline void tick_nohz_task_switch(void)
292 293
{
	if (tick_nohz_full_enabled())
294
		__tick_nohz_task_switch();
295 296
}

297
#endif