linux/include/linux/tick.h
<<
>>
Prefs
   1/*
   2 * Tick related global functions
   3 */
   4#ifndef _LINUX_TICK_H
   5#define _LINUX_TICK_H
   6
   7#include <linux/clockchips.h>
   8#include <linux/irqflags.h>
   9#include <linux/percpu.h>
  10#include <linux/context_tracking_state.h>
  11#include <linux/cpumask.h>
  12#include <linux/sched.h>
  13
  14#ifdef CONFIG_GENERIC_CLOCKEVENTS
  15extern void __init tick_init(void);
  16/* Should be core only, but ARM BL switcher requires it */
  17extern void tick_suspend_local(void);
  18/* Should be core only, but XEN resume magic and ARM BL switcher require it */
  19extern void tick_resume_local(void);
  20extern void tick_handover_do_timer(void);
  21extern void tick_cleanup_dead_cpu(int cpu);
  22#else /* CONFIG_GENERIC_CLOCKEVENTS */
  23static inline void tick_init(void) { }
  24static inline void tick_suspend_local(void) { }
  25static inline void tick_resume_local(void) { }
  26static inline void tick_handover_do_timer(void) { }
  27static inline void tick_cleanup_dead_cpu(int cpu) { }
  28#endif /* !CONFIG_GENERIC_CLOCKEVENTS */
  29
  30#if defined(CONFIG_GENERIC_CLOCKEVENTS) && defined(CONFIG_SUSPEND)
  31extern void tick_freeze(void);
  32extern void tick_unfreeze(void);
  33#else
  34static inline void tick_freeze(void) { }
  35static inline void tick_unfreeze(void) { }
  36#endif
  37
  38#ifdef CONFIG_TICK_ONESHOT
  39extern void tick_irq_enter(void);
  40#  ifndef arch_needs_cpu
  41#   define arch_needs_cpu() (0)
  42#  endif
  43# else
  44static inline void tick_irq_enter(void) { }
  45#endif
  46
  47#if defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) && defined(CONFIG_TICK_ONESHOT)
  48extern void hotplug_cpu__broadcast_tick_pull(int dead_cpu);
  49#else
  50static inline void hotplug_cpu__broadcast_tick_pull(int dead_cpu) { }
  51#endif
  52
  53enum tick_broadcast_mode {
  54        TICK_BROADCAST_OFF,
  55        TICK_BROADCAST_ON,
  56        TICK_BROADCAST_FORCE,
  57};
  58
  59enum tick_broadcast_state {
  60        TICK_BROADCAST_EXIT,
  61        TICK_BROADCAST_ENTER,
  62};
  63
  64#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
  65extern void tick_broadcast_control(enum tick_broadcast_mode mode);
  66#else
  67static inline void tick_broadcast_control(enum tick_broadcast_mode mode) { }
  68#endif /* BROADCAST */
  69
  70#ifdef CONFIG_GENERIC_CLOCKEVENTS
  71extern int tick_broadcast_oneshot_control(enum tick_broadcast_state state);
  72#else
  73static inline int tick_broadcast_oneshot_control(enum tick_broadcast_state state)
  74{
  75        return 0;
  76}
  77#endif
  78
  79static inline void tick_broadcast_enable(void)
  80{
  81        tick_broadcast_control(TICK_BROADCAST_ON);
  82}
  83static inline void tick_broadcast_disable(void)
  84{
  85        tick_broadcast_control(TICK_BROADCAST_OFF);
  86}
  87static inline void tick_broadcast_force(void)
  88{
  89        tick_broadcast_control(TICK_BROADCAST_FORCE);
  90}
  91static inline int tick_broadcast_enter(void)
  92{
  93        return tick_broadcast_oneshot_control(TICK_BROADCAST_ENTER);
  94}
  95static inline void tick_broadcast_exit(void)
  96{
  97        tick_broadcast_oneshot_control(TICK_BROADCAST_EXIT);
  98}
  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_NONE              0
 108#define TICK_DEP_MASK_POSIX_TIMER       (1 << TICK_DEP_BIT_POSIX_TIMER)
 109#define TICK_DEP_MASK_PERF_EVENTS       (1 << TICK_DEP_BIT_PERF_EVENTS)
 110#define TICK_DEP_MASK_SCHED             (1 << TICK_DEP_BIT_SCHED)
 111#define TICK_DEP_MASK_CLOCK_UNSTABLE    (1 << TICK_DEP_BIT_CLOCK_UNSTABLE)
 112
 113#ifdef CONFIG_NO_HZ_COMMON
 114extern bool tick_nohz_enabled;
 115extern int tick_nohz_tick_stopped(void);
 116extern void tick_nohz_idle_enter(void);
 117extern void tick_nohz_idle_exit(void);
 118extern void tick_nohz_irq_exit(void);
 119extern ktime_t tick_nohz_get_sleep_length(void);
 120extern u64 get_cpu_idle_time_us(int cpu, u64 *last_update_time);
 121extern u64 get_cpu_iowait_time_us(int cpu, u64 *last_update_time);
 122#else /* !CONFIG_NO_HZ_COMMON */
 123#define tick_nohz_enabled (0)
 124static inline int tick_nohz_tick_stopped(void) { return 0; }
 125static inline void tick_nohz_idle_enter(void) { }
 126static inline void tick_nohz_idle_exit(void) { }
 127
 128static inline ktime_t tick_nohz_get_sleep_length(void)
 129{
 130        return NSEC_PER_SEC / HZ;
 131}
 132static inline u64 get_cpu_idle_time_us(int cpu, u64 *unused) { return -1; }
 133static inline u64 get_cpu_iowait_time_us(int cpu, u64 *unused) { return -1; }
 134#endif /* !CONFIG_NO_HZ_COMMON */
 135
 136#ifdef CONFIG_NO_HZ_FULL
 137extern bool tick_nohz_full_running;
 138extern cpumask_var_t tick_nohz_full_mask;
 139extern cpumask_var_t housekeeping_mask;
 140
 141static inline bool tick_nohz_full_enabled(void)
 142{
 143        if (!context_tracking_is_enabled())
 144                return false;
 145
 146        return tick_nohz_full_running;
 147}
 148
 149static inline bool tick_nohz_full_cpu(int cpu)
 150{
 151        if (!tick_nohz_full_enabled())
 152                return false;
 153
 154        return cpumask_test_cpu(cpu, tick_nohz_full_mask);
 155}
 156
 157static inline void tick_nohz_full_add_cpus_to(struct cpumask *mask)
 158{
 159        if (tick_nohz_full_enabled())
 160                cpumask_or(mask, mask, tick_nohz_full_mask);
 161}
 162
 163static inline int housekeeping_any_cpu(void)
 164{
 165        return cpumask_any_and(housekeeping_mask, cpu_online_mask);
 166}
 167
 168extern void tick_nohz_dep_set(enum tick_dep_bits bit);
 169extern void tick_nohz_dep_clear(enum tick_dep_bits bit);
 170extern void tick_nohz_dep_set_cpu(int cpu, enum tick_dep_bits bit);
 171extern void tick_nohz_dep_clear_cpu(int cpu, enum tick_dep_bits bit);
 172extern void tick_nohz_dep_set_task(struct task_struct *tsk,
 173                                   enum tick_dep_bits bit);
 174extern void tick_nohz_dep_clear_task(struct task_struct *tsk,
 175                                     enum tick_dep_bits bit);
 176extern void tick_nohz_dep_set_signal(struct signal_struct *signal,
 177                                     enum tick_dep_bits bit);
 178extern void tick_nohz_dep_clear_signal(struct signal_struct *signal,
 179                                       enum tick_dep_bits bit);
 180
 181/*
 182 * The below are tick_nohz_[set,clear]_dep() wrappers that optimize off-cases
 183 * on top of static keys.
 184 */
 185static inline void tick_dep_set(enum tick_dep_bits bit)
 186{
 187        if (tick_nohz_full_enabled())
 188                tick_nohz_dep_set(bit);
 189}
 190
 191static inline void tick_dep_clear(enum tick_dep_bits bit)
 192{
 193        if (tick_nohz_full_enabled())
 194                tick_nohz_dep_clear(bit);
 195}
 196
 197static inline void tick_dep_set_cpu(int cpu, enum tick_dep_bits bit)
 198{
 199        if (tick_nohz_full_cpu(cpu))
 200                tick_nohz_dep_set_cpu(cpu, bit);
 201}
 202
 203static inline void tick_dep_clear_cpu(int cpu, enum tick_dep_bits bit)
 204{
 205        if (tick_nohz_full_cpu(cpu))
 206                tick_nohz_dep_clear_cpu(cpu, bit);
 207}
 208
 209static inline void tick_dep_set_task(struct task_struct *tsk,
 210                                     enum tick_dep_bits bit)
 211{
 212        if (tick_nohz_full_enabled())
 213                tick_nohz_dep_set_task(tsk, bit);
 214}
 215static inline void tick_dep_clear_task(struct task_struct *tsk,
 216                                       enum tick_dep_bits bit)
 217{
 218        if (tick_nohz_full_enabled())
 219                tick_nohz_dep_clear_task(tsk, bit);
 220}
 221static inline void tick_dep_set_signal(struct signal_struct *signal,
 222                                       enum tick_dep_bits bit)
 223{
 224        if (tick_nohz_full_enabled())
 225                tick_nohz_dep_set_signal(signal, bit);
 226}
 227static inline void tick_dep_clear_signal(struct signal_struct *signal,
 228                                         enum tick_dep_bits bit)
 229{
 230        if (tick_nohz_full_enabled())
 231                tick_nohz_dep_clear_signal(signal, bit);
 232}
 233
 234extern void tick_nohz_full_kick_cpu(int cpu);
 235extern void __tick_nohz_task_switch(void);
 236#else
 237static inline int housekeeping_any_cpu(void)
 238{
 239        return smp_processor_id();
 240}
 241static inline bool tick_nohz_full_enabled(void) { return false; }
 242static inline bool tick_nohz_full_cpu(int cpu) { return false; }
 243static inline void tick_nohz_full_add_cpus_to(struct cpumask *mask) { }
 244
 245static inline void tick_dep_set(enum tick_dep_bits bit) { }
 246static inline void tick_dep_clear(enum tick_dep_bits bit) { }
 247static inline void tick_dep_set_cpu(int cpu, enum tick_dep_bits bit) { }
 248static inline void tick_dep_clear_cpu(int cpu, enum tick_dep_bits bit) { }
 249static inline void tick_dep_set_task(struct task_struct *tsk,
 250                                     enum tick_dep_bits bit) { }
 251static inline void tick_dep_clear_task(struct task_struct *tsk,
 252                                       enum tick_dep_bits bit) { }
 253static inline void tick_dep_set_signal(struct signal_struct *signal,
 254                                       enum tick_dep_bits bit) { }
 255static inline void tick_dep_clear_signal(struct signal_struct *signal,
 256                                         enum tick_dep_bits bit) { }
 257
 258static inline void tick_nohz_full_kick_cpu(int cpu) { }
 259static inline void __tick_nohz_task_switch(void) { }
 260#endif
 261
 262static inline const struct cpumask *housekeeping_cpumask(void)
 263{
 264#ifdef CONFIG_NO_HZ_FULL
 265        if (tick_nohz_full_enabled())
 266                return housekeeping_mask;
 267#endif
 268        return cpu_possible_mask;
 269}
 270
 271static inline bool is_housekeeping_cpu(int cpu)
 272{
 273#ifdef CONFIG_NO_HZ_FULL
 274        if (tick_nohz_full_enabled())
 275                return cpumask_test_cpu(cpu, housekeeping_mask);
 276#endif
 277        return true;
 278}
 279
 280static inline void housekeeping_affine(struct task_struct *t)
 281{
 282#ifdef CONFIG_NO_HZ_FULL
 283        if (tick_nohz_full_enabled())
 284                set_cpus_allowed_ptr(t, housekeeping_mask);
 285
 286#endif
 287}
 288
 289static inline void tick_nohz_task_switch(void)
 290{
 291        if (tick_nohz_full_enabled())
 292                __tick_nohz_task_switch();
 293}
 294
 295#endif
 296