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        ktime_t len = { .tv64 = NSEC_PER_SEC/HZ };
 131
 132        return len;
 133}
 134static inline u64 get_cpu_idle_time_us(int cpu, u64 *unused) { return -1; }
 135static 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
 139extern bool tick_nohz_full_running;
 140extern cpumask_var_t tick_nohz_full_mask;
 141extern cpumask_var_t housekeeping_mask;
 142
 143static inline bool tick_nohz_full_enabled(void)
 144{
 145        if (!context_tracking_is_enabled())
 146                return false;
 147
 148        return tick_nohz_full_running;
 149}
 150
 151static inline bool tick_nohz_full_cpu(int cpu)
 152{
 153        if (!tick_nohz_full_enabled())
 154                return false;
 155
 156        return cpumask_test_cpu(cpu, tick_nohz_full_mask);
 157}
 158
 159static inline void tick_nohz_full_add_cpus_to(struct cpumask *mask)
 160{
 161        if (tick_nohz_full_enabled())
 162                cpumask_or(mask, mask, tick_nohz_full_mask);
 163}
 164
 165static inline int housekeeping_any_cpu(void)
 166{
 167        return cpumask_any_and(housekeeping_mask, cpu_online_mask);
 168}
 169
 170extern void tick_nohz_dep_set(enum tick_dep_bits bit);
 171extern void tick_nohz_dep_clear(enum tick_dep_bits bit);
 172extern void tick_nohz_dep_set_cpu(int cpu, enum tick_dep_bits bit);
 173extern void tick_nohz_dep_clear_cpu(int cpu, enum tick_dep_bits bit);
 174extern void tick_nohz_dep_set_task(struct task_struct *tsk,
 175                                   enum tick_dep_bits bit);
 176extern void tick_nohz_dep_clear_task(struct task_struct *tsk,
 177                                     enum tick_dep_bits bit);
 178extern void tick_nohz_dep_set_signal(struct signal_struct *signal,
 179                                     enum tick_dep_bits bit);
 180extern void tick_nohz_dep_clear_signal(struct signal_struct *signal,
 181                                       enum tick_dep_bits bit);
 182
 183/*
 184 * The below are tick_nohz_[set,clear]_dep() wrappers that optimize off-cases
 185 * on top of static keys.
 186 */
 187static inline void tick_dep_set(enum tick_dep_bits bit)
 188{
 189        if (tick_nohz_full_enabled())
 190                tick_nohz_dep_set(bit);
 191}
 192
 193static inline void tick_dep_clear(enum tick_dep_bits bit)
 194{
 195        if (tick_nohz_full_enabled())
 196                tick_nohz_dep_clear(bit);
 197}
 198
 199static inline void tick_dep_set_cpu(int cpu, enum tick_dep_bits bit)
 200{
 201        if (tick_nohz_full_cpu(cpu))
 202                tick_nohz_dep_set_cpu(cpu, bit);
 203}
 204
 205static inline void tick_dep_clear_cpu(int cpu, enum tick_dep_bits bit)
 206{
 207        if (tick_nohz_full_cpu(cpu))
 208                tick_nohz_dep_clear_cpu(cpu, bit);
 209}
 210
 211static inline void tick_dep_set_task(struct task_struct *tsk,
 212                                     enum tick_dep_bits bit)
 213{
 214        if (tick_nohz_full_enabled())
 215                tick_nohz_dep_set_task(tsk, bit);
 216}
 217static inline void tick_dep_clear_task(struct task_struct *tsk,
 218                                       enum tick_dep_bits bit)
 219{
 220        if (tick_nohz_full_enabled())
 221                tick_nohz_dep_clear_task(tsk, bit);
 222}
 223static inline void tick_dep_set_signal(struct signal_struct *signal,
 224                                       enum tick_dep_bits bit)
 225{
 226        if (tick_nohz_full_enabled())
 227                tick_nohz_dep_set_signal(signal, bit);
 228}
 229static inline void tick_dep_clear_signal(struct signal_struct *signal,
 230                                         enum tick_dep_bits bit)
 231{
 232        if (tick_nohz_full_enabled())
 233                tick_nohz_dep_clear_signal(signal, bit);
 234}
 235
 236extern void tick_nohz_full_kick_cpu(int cpu);
 237extern void __tick_nohz_task_switch(void);
 238#else
 239static inline int housekeeping_any_cpu(void)
 240{
 241        return smp_processor_id();
 242}
 243static inline bool tick_nohz_full_enabled(void) { return false; }
 244static inline bool tick_nohz_full_cpu(int cpu) { return false; }
 245static inline void tick_nohz_full_add_cpus_to(struct cpumask *mask) { }
 246
 247static inline void tick_dep_set(enum tick_dep_bits bit) { }
 248static inline void tick_dep_clear(enum tick_dep_bits bit) { }
 249static inline void tick_dep_set_cpu(int cpu, enum tick_dep_bits bit) { }
 250static inline void tick_dep_clear_cpu(int cpu, enum tick_dep_bits bit) { }
 251static inline void tick_dep_set_task(struct task_struct *tsk,
 252                                     enum tick_dep_bits bit) { }
 253static inline void tick_dep_clear_task(struct task_struct *tsk,
 254                                       enum tick_dep_bits bit) { }
 255static inline void tick_dep_set_signal(struct signal_struct *signal,
 256                                       enum tick_dep_bits bit) { }
 257static inline void tick_dep_clear_signal(struct signal_struct *signal,
 258                                         enum tick_dep_bits bit) { }
 259
 260static inline void tick_nohz_full_kick_cpu(int cpu) { }
 261static inline void __tick_nohz_task_switch(void) { }
 262#endif
 263
 264static inline const struct cpumask *housekeeping_cpumask(void)
 265{
 266#ifdef CONFIG_NO_HZ_FULL
 267        if (tick_nohz_full_enabled())
 268                return housekeeping_mask;
 269#endif
 270        return cpu_possible_mask;
 271}
 272
 273static inline bool is_housekeeping_cpu(int cpu)
 274{
 275#ifdef CONFIG_NO_HZ_FULL
 276        if (tick_nohz_full_enabled())
 277                return cpumask_test_cpu(cpu, housekeeping_mask);
 278#endif
 279        return true;
 280}
 281
 282static inline void housekeeping_affine(struct task_struct *t)
 283{
 284#ifdef CONFIG_NO_HZ_FULL
 285        if (tick_nohz_full_enabled())
 286                set_cpus_allowed_ptr(t, housekeeping_mask);
 287
 288#endif
 289}
 290
 291static inline void tick_nohz_task_switch(void)
 292{
 293        if (tick_nohz_full_enabled())
 294                __tick_nohz_task_switch();
 295}
 296
 297#endif
 298