1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */ 2c1797bafSThomas Gleixner #ifndef _TICK_SCHED_H 3c1797bafSThomas Gleixner #define _TICK_SCHED_H 4c1797bafSThomas Gleixner 5c1797bafSThomas Gleixner #include <linux/hrtimer.h> 6c1797bafSThomas Gleixner 77270d11cSThomas Gleixner enum tick_device_mode { 87270d11cSThomas Gleixner TICKDEV_MODE_PERIODIC, 97270d11cSThomas Gleixner TICKDEV_MODE_ONESHOT, 107270d11cSThomas Gleixner }; 117270d11cSThomas Gleixner 127270d11cSThomas Gleixner struct tick_device { 137270d11cSThomas Gleixner struct clock_event_device *evtdev; 147270d11cSThomas Gleixner enum tick_device_mode mode; 157270d11cSThomas Gleixner }; 167270d11cSThomas Gleixner 17a478ffb2SFrederic Weisbecker /* The CPU is in the tick idle mode */ 18a478ffb2SFrederic Weisbecker #define TS_FLAG_INIDLE BIT(0) 19a478ffb2SFrederic Weisbecker /* The idle tick has been stopped */ 20a478ffb2SFrederic Weisbecker #define TS_FLAG_STOPPED BIT(1) 21a478ffb2SFrederic Weisbecker /* 22a478ffb2SFrederic Weisbecker * Indicator that the CPU is actively in the tick idle mode; 23a478ffb2SFrederic Weisbecker * it is reset during irq handling phases. 24a478ffb2SFrederic Weisbecker */ 25a478ffb2SFrederic Weisbecker #define TS_FLAG_IDLE_ACTIVE BIT(2) 26a478ffb2SFrederic Weisbecker /* CPU was the last one doing do_timer before going idle */ 27a478ffb2SFrederic Weisbecker #define TS_FLAG_DO_TIMER_LAST BIT(3) 287988e5aeSFrederic Weisbecker /* NO_HZ is enabled */ 297988e5aeSFrederic Weisbecker #define TS_FLAG_NOHZ BIT(4) 307988e5aeSFrederic Weisbecker /* High resolution tick mode */ 317988e5aeSFrederic Weisbecker #define TS_FLAG_HIGHRES BIT(5) 32a478ffb2SFrederic Weisbecker 33c1797bafSThomas Gleixner /** 34c1797bafSThomas Gleixner * struct tick_sched - sched tick emulation and no idle tick control/stats 35605da849SFrederic Weisbecker * 36a478ffb2SFrederic Weisbecker * @flags: State flags gathering the TS_FLAG_* features 37d6b87eafSAnna-Maria Gleixner * @got_idle_tick: Tick timer function has run with @inidle set 38605da849SFrederic Weisbecker * @stalled_jiffies: Number of stalled jiffies detected across ticks 39605da849SFrederic Weisbecker * @last_tick_jiffies: Value of jiffies seen on last tick 40605da849SFrederic Weisbecker * @sched_timer: hrtimer to schedule the periodic tick in high 41605da849SFrederic Weisbecker * resolution mode 42c1797bafSThomas Gleixner * @last_tick: Store the last tick expiry time when the tick 43c1797bafSThomas Gleixner * timer is modified for nohz sleeps. This is necessary 44c1797bafSThomas Gleixner * to resume the tick timer operation in the timeline 45c1797bafSThomas Gleixner * when the CPU returns from nohz sleep. 46411fe24eSFrederic Weisbecker * @next_tick: Next tick to be fired when in dynticks mode. 47c1797bafSThomas Gleixner * @idle_jiffies: jiffies at the entry to idle for idle time accounting 48605da849SFrederic Weisbecker * @idle_waketime: Time when the idle was interrupted 49605da849SFrederic Weisbecker * @idle_sleeptime_seq: sequence counter for data consistency 50605da849SFrederic Weisbecker * @idle_entrytime: Time when the idle call was entered 51605da849SFrederic Weisbecker * @last_jiffies: Base jiffies snapshot when next event was last computed 52605da849SFrederic Weisbecker * @timer_expires_base: Base time clock monotonic for @timer_expires 53605da849SFrederic Weisbecker * @timer_expires: Anticipated timer expiration time (in case sched tick is stopped) 54605da849SFrederic Weisbecker * @next_timer: Expiry time of next expiring timer for debugging purpose only 55605da849SFrederic Weisbecker * @idle_expires: Next tick in idle, for debugging purpose only 56c1797bafSThomas Gleixner * @idle_calls: Total number of idle calls 57c1797bafSThomas Gleixner * @idle_sleeps: Number of idle calls, where the sched tick was stopped 58c1797bafSThomas Gleixner * @idle_exittime: Time when the idle state was left 59c1797bafSThomas Gleixner * @idle_sleeptime: Sum of the time slept in idle with sched tick stopped 60c1797bafSThomas Gleixner * @iowait_sleeptime: Sum of the time slept in idle with sched tick stopped, with IO outstanding 61d6b87eafSAnna-Maria Gleixner * @tick_dep_mask: Tick dependency mask - is set, if someone needs the tick 62605da849SFrederic Weisbecker * @check_clocks: Notification mechanism about clocksource changes 63c1797bafSThomas Gleixner */ 64c1797bafSThomas Gleixner struct tick_sched { 65605da849SFrederic Weisbecker /* Common flags */ 66a478ffb2SFrederic Weisbecker unsigned long flags; 672bc629a6SFrederic Weisbecker 68605da849SFrederic Weisbecker /* Tick handling: jiffies stall check */ 69605da849SFrederic Weisbecker unsigned int stalled_jiffies; 70605da849SFrederic Weisbecker unsigned long last_tick_jiffies; 71605da849SFrederic Weisbecker 72605da849SFrederic Weisbecker /* Tick handling */ 73605da849SFrederic Weisbecker struct hrtimer sched_timer; 74c1797bafSThomas Gleixner ktime_t last_tick; 75411fe24eSFrederic Weisbecker ktime_t next_tick; 76c1797bafSThomas Gleixner unsigned long idle_jiffies; 77605da849SFrederic Weisbecker ktime_t idle_waketime; 783ce74f1aSFrederic Weisbecker unsigned int got_idle_tick; 79605da849SFrederic Weisbecker 80605da849SFrederic Weisbecker /* Idle entry */ 81620a30faSFrederic Weisbecker seqcount_t idle_sleeptime_seq; 82605da849SFrederic Weisbecker ktime_t idle_entrytime; 83605da849SFrederic Weisbecker 84605da849SFrederic Weisbecker /* Tick stop */ 85605da849SFrederic Weisbecker unsigned long last_jiffies; 86605da849SFrederic Weisbecker u64 timer_expires_base; 87605da849SFrederic Weisbecker u64 timer_expires; 88605da849SFrederic Weisbecker u64 next_timer; 89605da849SFrederic Weisbecker ktime_t idle_expires; 90c1797bafSThomas Gleixner unsigned long idle_calls; 91c1797bafSThomas Gleixner unsigned long idle_sleeps; 92605da849SFrederic Weisbecker 93605da849SFrederic Weisbecker /* Idle exit */ 94c1797bafSThomas Gleixner ktime_t idle_exittime; 95c1797bafSThomas Gleixner ktime_t idle_sleeptime; 96c1797bafSThomas Gleixner ktime_t iowait_sleeptime; 97605da849SFrederic Weisbecker 98605da849SFrederic Weisbecker /* Full dynticks handling */ 99f009a7a7SFrederic Weisbecker atomic_t tick_dep_mask; 100605da849SFrederic Weisbecker 101605da849SFrederic Weisbecker /* Clocksource changes */ 102605da849SFrederic Weisbecker unsigned long check_clocks; 103c1797bafSThomas Gleixner }; 104c1797bafSThomas Gleixner 105c1797bafSThomas Gleixner extern struct tick_sched *tick_get_tick_sched(int cpu); 106c1797bafSThomas Gleixner 1077988e5aeSFrederic Weisbecker extern void tick_setup_sched_timer(bool hrtimer); 108*a184d983SArnd Bergmann #if defined CONFIG_TICK_ONESHOT 1093f69d04eSFrederic Weisbecker extern void tick_sched_timer_dying(int cpu); 110c1797bafSThomas Gleixner #else tick_sched_timer_dying(int cpu)1113f69d04eSFrederic Weisbeckerstatic inline void tick_sched_timer_dying(int cpu) { } 112c1797bafSThomas Gleixner #endif 113c1797bafSThomas Gleixner 114f32dd117SThomas Gleixner #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST 115f32dd117SThomas Gleixner extern int __tick_broadcast_oneshot_control(enum tick_broadcast_state state); 116f32dd117SThomas Gleixner #else 117f32dd117SThomas Gleixner static inline int __tick_broadcast_oneshot_control(enum tick_broadcast_state state)118f32dd117SThomas Gleixner__tick_broadcast_oneshot_control(enum tick_broadcast_state state) 119f32dd117SThomas Gleixner { 120f32dd117SThomas Gleixner return -EBUSY; 121f32dd117SThomas Gleixner } 122f32dd117SThomas Gleixner #endif 123f32dd117SThomas Gleixner 124c1797bafSThomas Gleixner #endif 125