135728b82SThomas Gleixner // SPDX-License-Identifier: GPL-2.0 2c0a31329SThomas Gleixner /* 3c0a31329SThomas Gleixner * hrtimers - High-resolution kernel timers 4c0a31329SThomas Gleixner * 5c0a31329SThomas Gleixner * Copyright(C) 2005, Thomas Gleixner <[email protected]> 6c0a31329SThomas Gleixner * Copyright(C) 2005, Red Hat, Inc., Ingo Molnar 7c0a31329SThomas Gleixner * 8c0a31329SThomas Gleixner * data type definitions, declarations, prototypes 9c0a31329SThomas Gleixner * 10c0a31329SThomas Gleixner * Started by: Thomas Gleixner and Ingo Molnar 11c0a31329SThomas Gleixner */ 12c0a31329SThomas Gleixner #ifndef _LINUX_HRTIMER_H 13c0a31329SThomas Gleixner #define _LINUX_HRTIMER_H 14c0a31329SThomas Gleixner 1532e29396SVincenzo Frascino #include <linux/hrtimer_defs.h> 16c0a31329SThomas Gleixner #include <linux/rbtree.h> 17c0a31329SThomas Gleixner #include <linux/init.h> 18c0a31329SThomas Gleixner #include <linux/list.h> 1940b86062SStephen Rothwell #include <linux/percpu.h> 20507e1231SHeiko Carstens #include <linux/timer.h> 21998adc3dSJohn Stultz #include <linux/timerqueue.h> 22c0a31329SThomas Gleixner 233c8aa39dSThomas Gleixner struct hrtimer_clock_base; 243c8aa39dSThomas Gleixner struct hrtimer_cpu_base; 253c8aa39dSThomas Gleixner 26c0a31329SThomas Gleixner /* 27c0a31329SThomas Gleixner * Mode arguments of xxx_hrtimer functions: 2819b51cb5SAnna-Maria Gleixner * 2919b51cb5SAnna-Maria Gleixner * HRTIMER_MODE_ABS - Time value is absolute 3019b51cb5SAnna-Maria Gleixner * HRTIMER_MODE_REL - Time value is relative to now 3119b51cb5SAnna-Maria Gleixner * HRTIMER_MODE_PINNED - Timer is bound to CPU (is only considered 3219b51cb5SAnna-Maria Gleixner * when starting the timer) 3398ecadd4SAnna-Maria Gleixner * HRTIMER_MODE_SOFT - Timer callback function will be executed in 3498ecadd4SAnna-Maria Gleixner * soft irq context 35*a67e4082SSebastian Andrzej Siewior * HRTIMER_MODE_HARD - Timer callback function will be executed in 36*a67e4082SSebastian Andrzej Siewior * hard irq context even on PREEMPT_RT. 37c0a31329SThomas Gleixner */ 38c0a31329SThomas Gleixner enum hrtimer_mode { 3919b51cb5SAnna-Maria Gleixner HRTIMER_MODE_ABS = 0x00, 4019b51cb5SAnna-Maria Gleixner HRTIMER_MODE_REL = 0x01, 4119b51cb5SAnna-Maria Gleixner HRTIMER_MODE_PINNED = 0x02, 4298ecadd4SAnna-Maria Gleixner HRTIMER_MODE_SOFT = 0x04, 43ae6683d8SSebastian Andrzej Siewior HRTIMER_MODE_HARD = 0x08, 4419b51cb5SAnna-Maria Gleixner 4519b51cb5SAnna-Maria Gleixner HRTIMER_MODE_ABS_PINNED = HRTIMER_MODE_ABS | HRTIMER_MODE_PINNED, 4619b51cb5SAnna-Maria Gleixner HRTIMER_MODE_REL_PINNED = HRTIMER_MODE_REL | HRTIMER_MODE_PINNED, 4798ecadd4SAnna-Maria Gleixner 4898ecadd4SAnna-Maria Gleixner HRTIMER_MODE_ABS_SOFT = HRTIMER_MODE_ABS | HRTIMER_MODE_SOFT, 4998ecadd4SAnna-Maria Gleixner HRTIMER_MODE_REL_SOFT = HRTIMER_MODE_REL | HRTIMER_MODE_SOFT, 5098ecadd4SAnna-Maria Gleixner 5198ecadd4SAnna-Maria Gleixner HRTIMER_MODE_ABS_PINNED_SOFT = HRTIMER_MODE_ABS_PINNED | HRTIMER_MODE_SOFT, 5298ecadd4SAnna-Maria Gleixner HRTIMER_MODE_REL_PINNED_SOFT = HRTIMER_MODE_REL_PINNED | HRTIMER_MODE_SOFT, 5398ecadd4SAnna-Maria Gleixner 54ae6683d8SSebastian Andrzej Siewior HRTIMER_MODE_ABS_HARD = HRTIMER_MODE_ABS | HRTIMER_MODE_HARD, 55ae6683d8SSebastian Andrzej Siewior HRTIMER_MODE_REL_HARD = HRTIMER_MODE_REL | HRTIMER_MODE_HARD, 56ae6683d8SSebastian Andrzej Siewior 57ae6683d8SSebastian Andrzej Siewior HRTIMER_MODE_ABS_PINNED_HARD = HRTIMER_MODE_ABS_PINNED | HRTIMER_MODE_HARD, 58ae6683d8SSebastian Andrzej Siewior HRTIMER_MODE_REL_PINNED_HARD = HRTIMER_MODE_REL_PINNED | HRTIMER_MODE_HARD, 59c0a31329SThomas Gleixner }; 60c0a31329SThomas Gleixner 61c9cb2e3dSThomas Gleixner /* 62c9cb2e3dSThomas Gleixner * Return values for the callback function 63c9cb2e3dSThomas Gleixner */ 64c0a31329SThomas Gleixner enum hrtimer_restart { 65c9cb2e3dSThomas Gleixner HRTIMER_NORESTART, /* Timer is not restarted */ 66c9cb2e3dSThomas Gleixner HRTIMER_RESTART, /* Timer must be restarted */ 67c0a31329SThomas Gleixner }; 68c0a31329SThomas Gleixner 69303e967fSThomas Gleixner /* 7054cdfdb4SThomas Gleixner * Values to track state of the timer 71303e967fSThomas Gleixner * 72303e967fSThomas Gleixner * Possible states: 73303e967fSThomas Gleixner * 74303e967fSThomas Gleixner * 0x00 inactive 75303e967fSThomas Gleixner * 0x01 enqueued into rbtree 7654cdfdb4SThomas Gleixner * 77887d9dc9SPeter Zijlstra * The callback state is not part of the timer->state because clearing it would 78887d9dc9SPeter Zijlstra * mean touching the timer after the callback, this makes it impossible to free 79887d9dc9SPeter Zijlstra * the timer from the callback function. 8053370d2eSThomas Gleixner * 81887d9dc9SPeter Zijlstra * Therefore we track the callback state in: 82887d9dc9SPeter Zijlstra * 83887d9dc9SPeter Zijlstra * timer->base->cpu_base->running == timer 84887d9dc9SPeter Zijlstra * 85887d9dc9SPeter Zijlstra * On SMP it is possible to have a "callback function running and enqueued" 86887d9dc9SPeter Zijlstra * status. It happens for example when a posix timer expired and the callback 87303e967fSThomas Gleixner * queued a signal. Between dropping the lock which protects the posix timer 88303e967fSThomas Gleixner * and reacquiring the base lock of the hrtimer, another CPU can deliver the 89887d9dc9SPeter Zijlstra * signal and rearm the timer. 90303e967fSThomas Gleixner * 91303e967fSThomas Gleixner * All state transitions are protected by cpu_base->lock. 92303e967fSThomas Gleixner */ 93303e967fSThomas Gleixner #define HRTIMER_STATE_INACTIVE 0x00 94303e967fSThomas Gleixner #define HRTIMER_STATE_ENQUEUED 0x01 95303e967fSThomas Gleixner 96c0a31329SThomas Gleixner /** 97c0a31329SThomas Gleixner * struct hrtimer - the basic hrtimer structure 98998adc3dSJohn Stultz * @node: timerqueue node, which also manages node.expires, 99998adc3dSJohn Stultz * the absolute expiry time in the hrtimers internal 100c0a31329SThomas Gleixner * representation. The time is related to the clock on 101592aa999SThomas Gleixner * which the timer is based. Is setup by adding 102592aa999SThomas Gleixner * slack to the _softexpires value. For non range timers 103592aa999SThomas Gleixner * identical to _softexpires. 104592aa999SThomas Gleixner * @_softexpires: the absolute earliest expiry time of the hrtimer. 105592aa999SThomas Gleixner * The time which was given as expiry time when the timer 106592aa999SThomas Gleixner * was armed. 107c0a31329SThomas Gleixner * @function: timer expiry callback function 108c0a31329SThomas Gleixner * @base: pointer to the timer base (per cpu and per clock) 109303e967fSThomas Gleixner * @state: state information (See bit values above) 110203cbf77SThomas Gleixner * @is_rel: Set if the timer was armed relative 1115da70160SAnna-Maria Gleixner * @is_soft: Set if hrtimer will be expired in soft interrupt context. 1120ab6a3ddSThomas Gleixner * @is_hard: Set if hrtimer will be expired in hard interrupt context 1130ab6a3ddSThomas Gleixner * even on RT. 114c0a31329SThomas Gleixner * 11554cdfdb4SThomas Gleixner * The hrtimer structure must be initialized by hrtimer_init() 116c0a31329SThomas Gleixner */ 117c0a31329SThomas Gleixner struct hrtimer { 118998adc3dSJohn Stultz struct timerqueue_node node; 119654c8e0bSArjan van de Ven ktime_t _softexpires; 120c9cb2e3dSThomas Gleixner enum hrtimer_restart (*function)(struct hrtimer *); 1213c8aa39dSThomas Gleixner struct hrtimer_clock_base *base; 122203cbf77SThomas Gleixner u8 state; 123203cbf77SThomas Gleixner u8 is_rel; 1245da70160SAnna-Maria Gleixner u8 is_soft; 1250ab6a3ddSThomas Gleixner u8 is_hard; 126c0a31329SThomas Gleixner }; 127c0a31329SThomas Gleixner 128c0a31329SThomas Gleixner /** 12900362e33SThomas Gleixner * struct hrtimer_sleeper - simple sleeper structure 13000362e33SThomas Gleixner * @timer: embedded timer structure 13100362e33SThomas Gleixner * @task: task to wake up 13200362e33SThomas Gleixner * 13300362e33SThomas Gleixner * task is set to NULL, when the timer expires. 13400362e33SThomas Gleixner */ 13500362e33SThomas Gleixner struct hrtimer_sleeper { 13600362e33SThomas Gleixner struct hrtimer timer; 13700362e33SThomas Gleixner struct task_struct *task; 13800362e33SThomas Gleixner }; 13900362e33SThomas Gleixner 140b8e38413SThomas Gleixner #ifdef CONFIG_64BIT 1413f0b9e8eSAnna-Maria Gleixner # define __hrtimer_clock_base_align ____cacheline_aligned 142b8e38413SThomas Gleixner #else 1433f0b9e8eSAnna-Maria Gleixner # define __hrtimer_clock_base_align 144b8e38413SThomas Gleixner #endif 145b8e38413SThomas Gleixner 14600362e33SThomas Gleixner /** 147d1d67174SAndres Salomon * struct hrtimer_clock_base - the timer base for a specific clock 14805fb6bf0SRandy Dunlap * @cpu_base: per cpu clock base 1493c8aa39dSThomas Gleixner * @index: clock type index for per_cpu support when moving a 1503c8aa39dSThomas Gleixner * timer to a base on another cpu. 1514d258b25SVitaliy Ivanov * @clockid: clock id for per_cpu support 1523f0b9e8eSAnna-Maria Gleixner * @seq: seqcount around __run_hrtimer 1533f0b9e8eSAnna-Maria Gleixner * @running: pointer to the currently running hrtimer 154c0a31329SThomas Gleixner * @active: red black tree root node for the active timers 155c0a31329SThomas Gleixner * @get_time: function to retrieve the current time of the clock 15654cdfdb4SThomas Gleixner * @offset: offset of this clock to the monotonic base 157c0a31329SThomas Gleixner */ 1583c8aa39dSThomas Gleixner struct hrtimer_clock_base { 1593c8aa39dSThomas Gleixner struct hrtimer_cpu_base *cpu_base; 1603f0b9e8eSAnna-Maria Gleixner unsigned int index; 161ab8177bcSThomas Gleixner clockid_t clockid; 1623f0b9e8eSAnna-Maria Gleixner seqcount_t seq; 1633f0b9e8eSAnna-Maria Gleixner struct hrtimer *running; 164998adc3dSJohn Stultz struct timerqueue_head active; 165c0a31329SThomas Gleixner ktime_t (*get_time)(void); 16654cdfdb4SThomas Gleixner ktime_t offset; 1673f0b9e8eSAnna-Maria Gleixner } __hrtimer_clock_base_align; 1683c8aa39dSThomas Gleixner 169e06383dbSJohn Stultz enum hrtimer_base_type { 170e06383dbSJohn Stultz HRTIMER_BASE_MONOTONIC, 17168fa61c0SThomas Gleixner HRTIMER_BASE_REALTIME, 172a3ed0e43SThomas Gleixner HRTIMER_BASE_BOOTTIME, 17390adda98SJohn Stultz HRTIMER_BASE_TAI, 17498ecadd4SAnna-Maria Gleixner HRTIMER_BASE_MONOTONIC_SOFT, 17598ecadd4SAnna-Maria Gleixner HRTIMER_BASE_REALTIME_SOFT, 176a3ed0e43SThomas Gleixner HRTIMER_BASE_BOOTTIME_SOFT, 17798ecadd4SAnna-Maria Gleixner HRTIMER_BASE_TAI_SOFT, 178e06383dbSJohn Stultz HRTIMER_MAX_CLOCK_BASES, 179e06383dbSJohn Stultz }; 1803c8aa39dSThomas Gleixner 1811fbc78b3SAnna-Maria Gleixner /** 1823c8aa39dSThomas Gleixner * struct hrtimer_cpu_base - the per cpu clock bases 1833c8aa39dSThomas Gleixner * @lock: lock protecting the base and associated clock bases 1843c8aa39dSThomas Gleixner * and timers 185cddd0248SViresh Kumar * @cpu: cpu number 186ab8177bcSThomas Gleixner * @active_bases: Bitfield to mark bases with active timers 187868a3e91SThomas Gleixner * @clock_was_set_seq: Sequence counter of clock was set events 18854cdfdb4SThomas Gleixner * @hres_active: State of high resolution mode 18928bfd18bSAnna-Maria Gleixner * @in_hrtirq: hrtimer_interrupt() is currently executing 19041d2e494SThomas Gleixner * @hang_detected: The last hrtimer interrupt detected a hang 1915da70160SAnna-Maria Gleixner * @softirq_activated: displays, if the softirq is raised - update of softirq 1925da70160SAnna-Maria Gleixner * related settings is not required then. 19341d2e494SThomas Gleixner * @nr_events: Total number of hrtimer interrupt events 19441d2e494SThomas Gleixner * @nr_retries: Total number of hrtimer interrupt retries 19541d2e494SThomas Gleixner * @nr_hangs: Total number of hrtimer interrupt hangs 19641d2e494SThomas Gleixner * @max_hang_time: Maximum time spent in hrtimer_interrupt 197f61eff83SAnna-Maria Gleixner * @softirq_expiry_lock: Lock which is taken while softirq based hrtimer are 198f61eff83SAnna-Maria Gleixner * expired 199f61eff83SAnna-Maria Gleixner * @timer_waiters: A hrtimer_cancel() invocation waits for the timer 200f61eff83SAnna-Maria Gleixner * callback to finish. 20107a9a7eaSAnna-Maria Gleixner * @expires_next: absolute time of the next event, is required for remote 2025da70160SAnna-Maria Gleixner * hrtimer enqueue; it is the total first expiry time (hard 2035da70160SAnna-Maria Gleixner * and soft hrtimer are taken into account) 204eb27926bSAnna-Maria Gleixner * @next_timer: Pointer to the first expiring timer 2055da70160SAnna-Maria Gleixner * @softirq_expires_next: Time to check, if soft queues needs also to be expired 2065da70160SAnna-Maria Gleixner * @softirq_next_timer: Pointer to the first expiring softirq based timer 207ab8177bcSThomas Gleixner * @clock_base: array of clock bases for this cpu 208895bdfa7SThomas Gleixner * 209895bdfa7SThomas Gleixner * Note: next_timer is just an optimization for __remove_hrtimer(). 210895bdfa7SThomas Gleixner * Do not dereference the pointer because it is not reliable on 211895bdfa7SThomas Gleixner * cross cpu removals. 2123c8aa39dSThomas Gleixner */ 2133c8aa39dSThomas Gleixner struct hrtimer_cpu_base { 214ecb49d1aSThomas Gleixner raw_spinlock_t lock; 215cddd0248SViresh Kumar unsigned int cpu; 216f55a6faaSJohn Stultz unsigned int active_bases; 217868a3e91SThomas Gleixner unsigned int clock_was_set_seq; 21811a9fe06SAnna-Maria Gleixner unsigned int hres_active : 1, 21911a9fe06SAnna-Maria Gleixner in_hrtirq : 1, 2205da70160SAnna-Maria Gleixner hang_detected : 1, 2215da70160SAnna-Maria Gleixner softirq_activated : 1; 22211a9fe06SAnna-Maria Gleixner #ifdef CONFIG_HIGH_RES_TIMERS 223a6ffebceSThomas Gleixner unsigned int nr_events; 224da21c5a5SAnna-Maria Gleixner unsigned short nr_retries; 225da21c5a5SAnna-Maria Gleixner unsigned short nr_hangs; 226a6ffebceSThomas Gleixner unsigned int max_hang_time; 22754cdfdb4SThomas Gleixner #endif 228f61eff83SAnna-Maria Gleixner #ifdef CONFIG_PREEMPT_RT 229f61eff83SAnna-Maria Gleixner spinlock_t softirq_expiry_lock; 230f61eff83SAnna-Maria Gleixner atomic_t timer_waiters; 231f61eff83SAnna-Maria Gleixner #endif 23207a9a7eaSAnna-Maria Gleixner ktime_t expires_next; 233eb27926bSAnna-Maria Gleixner struct hrtimer *next_timer; 2345da70160SAnna-Maria Gleixner ktime_t softirq_expires_next; 2355da70160SAnna-Maria Gleixner struct hrtimer *softirq_next_timer; 236f24444b0SThomas Gleixner struct hrtimer_clock_base clock_base[HRTIMER_MAX_CLOCK_BASES]; 2376d9a1411SThomas Gleixner } ____cacheline_aligned; 238c0a31329SThomas Gleixner 23963ca243bSArjan van de Ven static inline void hrtimer_set_expires(struct hrtimer *timer, ktime_t time) 24063ca243bSArjan van de Ven { 241998adc3dSJohn Stultz timer->node.expires = time; 242654c8e0bSArjan van de Ven timer->_softexpires = time; 24363ca243bSArjan van de Ven } 244654c8e0bSArjan van de Ven 245654c8e0bSArjan van de Ven static inline void hrtimer_set_expires_range(struct hrtimer *timer, ktime_t time, ktime_t delta) 246654c8e0bSArjan van de Ven { 247654c8e0bSArjan van de Ven timer->_softexpires = time; 248998adc3dSJohn Stultz timer->node.expires = ktime_add_safe(time, delta); 249654c8e0bSArjan van de Ven } 250654c8e0bSArjan van de Ven 251da8b44d5SJohn Stultz static inline void hrtimer_set_expires_range_ns(struct hrtimer *timer, ktime_t time, u64 delta) 252654c8e0bSArjan van de Ven { 253654c8e0bSArjan van de Ven timer->_softexpires = time; 254998adc3dSJohn Stultz timer->node.expires = ktime_add_safe(time, ns_to_ktime(delta)); 255654c8e0bSArjan van de Ven } 256654c8e0bSArjan van de Ven 25763ca243bSArjan van de Ven static inline void hrtimer_set_expires_tv64(struct hrtimer *timer, s64 tv64) 25863ca243bSArjan van de Ven { 2592456e855SThomas Gleixner timer->node.expires = tv64; 2602456e855SThomas Gleixner timer->_softexpires = tv64; 26163ca243bSArjan van de Ven } 26263ca243bSArjan van de Ven 26363ca243bSArjan van de Ven static inline void hrtimer_add_expires(struct hrtimer *timer, ktime_t time) 26463ca243bSArjan van de Ven { 265998adc3dSJohn Stultz timer->node.expires = ktime_add_safe(timer->node.expires, time); 266654c8e0bSArjan van de Ven timer->_softexpires = ktime_add_safe(timer->_softexpires, time); 26763ca243bSArjan van de Ven } 26863ca243bSArjan van de Ven 2697597bc94SDavid Howells static inline void hrtimer_add_expires_ns(struct hrtimer *timer, u64 ns) 27063ca243bSArjan van de Ven { 271998adc3dSJohn Stultz timer->node.expires = ktime_add_ns(timer->node.expires, ns); 272654c8e0bSArjan van de Ven timer->_softexpires = ktime_add_ns(timer->_softexpires, ns); 27363ca243bSArjan van de Ven } 27463ca243bSArjan van de Ven 27563ca243bSArjan van de Ven static inline ktime_t hrtimer_get_expires(const struct hrtimer *timer) 27663ca243bSArjan van de Ven { 277998adc3dSJohn Stultz return timer->node.expires; 27863ca243bSArjan van de Ven } 27963ca243bSArjan van de Ven 280654c8e0bSArjan van de Ven static inline ktime_t hrtimer_get_softexpires(const struct hrtimer *timer) 281654c8e0bSArjan van de Ven { 282654c8e0bSArjan van de Ven return timer->_softexpires; 283654c8e0bSArjan van de Ven } 284654c8e0bSArjan van de Ven 28563ca243bSArjan van de Ven static inline s64 hrtimer_get_expires_tv64(const struct hrtimer *timer) 28663ca243bSArjan van de Ven { 2872456e855SThomas Gleixner return timer->node.expires; 28863ca243bSArjan van de Ven } 289654c8e0bSArjan van de Ven static inline s64 hrtimer_get_softexpires_tv64(const struct hrtimer *timer) 290654c8e0bSArjan van de Ven { 2912456e855SThomas Gleixner return timer->_softexpires; 292654c8e0bSArjan van de Ven } 29363ca243bSArjan van de Ven 29463ca243bSArjan van de Ven static inline s64 hrtimer_get_expires_ns(const struct hrtimer *timer) 29563ca243bSArjan van de Ven { 296998adc3dSJohn Stultz return ktime_to_ns(timer->node.expires); 29763ca243bSArjan van de Ven } 29863ca243bSArjan van de Ven 29963ca243bSArjan van de Ven static inline ktime_t hrtimer_expires_remaining(const struct hrtimer *timer) 30063ca243bSArjan van de Ven { 301998adc3dSJohn Stultz return ktime_sub(timer->node.expires, timer->base->get_time()); 30263ca243bSArjan van de Ven } 30363ca243bSArjan van de Ven 30454cdfdb4SThomas Gleixner static inline ktime_t hrtimer_cb_get_time(struct hrtimer *timer) 30554cdfdb4SThomas Gleixner { 30654cdfdb4SThomas Gleixner return timer->base->get_time(); 30754cdfdb4SThomas Gleixner } 30854cdfdb4SThomas Gleixner 30928bfd18bSAnna-Maria Gleixner static inline int hrtimer_is_hres_active(struct hrtimer *timer) 31028bfd18bSAnna-Maria Gleixner { 31128bfd18bSAnna-Maria Gleixner return IS_ENABLED(CONFIG_HIGH_RES_TIMERS) ? 31228bfd18bSAnna-Maria Gleixner timer->base->cpu_base->hres_active : 0; 31328bfd18bSAnna-Maria Gleixner } 31428bfd18bSAnna-Maria Gleixner 31521d6d52aSThomas Gleixner #ifdef CONFIG_HIGH_RES_TIMERS 31621d6d52aSThomas Gleixner struct clock_event_device; 31721d6d52aSThomas Gleixner 31821d6d52aSThomas Gleixner extern void hrtimer_interrupt(struct clock_event_device *dev); 31921d6d52aSThomas Gleixner 320f55a6faaSJohn Stultz extern void clock_was_set_delayed(void); 321f55a6faaSJohn Stultz 322398ca17fSThomas Gleixner extern unsigned int hrtimer_resolution; 323398ca17fSThomas Gleixner 32454cdfdb4SThomas Gleixner #else 32554cdfdb4SThomas Gleixner 326d711b8b3SBorislav Petkov #define hrtimer_resolution (unsigned int)LOW_RES_NSEC 327398ca17fSThomas Gleixner 328f55a6faaSJohn Stultz static inline void clock_was_set_delayed(void) { } 329f55a6faaSJohn Stultz 33054cdfdb4SThomas Gleixner #endif 33154cdfdb4SThomas Gleixner 332203cbf77SThomas Gleixner static inline ktime_t 333203cbf77SThomas Gleixner __hrtimer_expires_remaining_adjusted(const struct hrtimer *timer, ktime_t now) 334203cbf77SThomas Gleixner { 335203cbf77SThomas Gleixner ktime_t rem = ktime_sub(timer->node.expires, now); 336203cbf77SThomas Gleixner 337203cbf77SThomas Gleixner /* 338203cbf77SThomas Gleixner * Adjust relative timers for the extra we added in 339203cbf77SThomas Gleixner * hrtimer_start_range_ns() to prevent short timeouts. 340203cbf77SThomas Gleixner */ 341203cbf77SThomas Gleixner if (IS_ENABLED(CONFIG_TIME_LOW_RES) && timer->is_rel) 3422456e855SThomas Gleixner rem -= hrtimer_resolution; 343203cbf77SThomas Gleixner return rem; 344203cbf77SThomas Gleixner } 345203cbf77SThomas Gleixner 346203cbf77SThomas Gleixner static inline ktime_t 347203cbf77SThomas Gleixner hrtimer_expires_remaining_adjusted(const struct hrtimer *timer) 348203cbf77SThomas Gleixner { 349203cbf77SThomas Gleixner return __hrtimer_expires_remaining_adjusted(timer, 350203cbf77SThomas Gleixner timer->base->get_time()); 351203cbf77SThomas Gleixner } 352203cbf77SThomas Gleixner 353b12a03ceSThomas Gleixner extern void clock_was_set(void); 3549ec26907SThomas Gleixner #ifdef CONFIG_TIMERFD 3559ec26907SThomas Gleixner extern void timerfd_clock_was_set(void); 3569ec26907SThomas Gleixner #else 3579ec26907SThomas Gleixner static inline void timerfd_clock_was_set(void) { } 3589ec26907SThomas Gleixner #endif 359b12a03ceSThomas Gleixner extern void hrtimers_resume(void); 360b12a03ceSThomas Gleixner 3612e94d1f7SArjan van de Ven DECLARE_PER_CPU(struct tick_device, tick_cpu_device); 3622e94d1f7SArjan van de Ven 363f61eff83SAnna-Maria Gleixner #ifdef CONFIG_PREEMPT_RT 364f61eff83SAnna-Maria Gleixner void hrtimer_cancel_wait_running(const struct hrtimer *timer); 365f61eff83SAnna-Maria Gleixner #else 366f61eff83SAnna-Maria Gleixner static inline void hrtimer_cancel_wait_running(struct hrtimer *timer) 367f61eff83SAnna-Maria Gleixner { 368f61eff83SAnna-Maria Gleixner cpu_relax(); 369f61eff83SAnna-Maria Gleixner } 370f61eff83SAnna-Maria Gleixner #endif 3712e94d1f7SArjan van de Ven 372c0a31329SThomas Gleixner /* Exported timer functions: */ 373c0a31329SThomas Gleixner 374c0a31329SThomas Gleixner /* Initialize timers: */ 3757978672cSGeorge Anzinger extern void hrtimer_init(struct hrtimer *timer, clockid_t which_clock, 3767978672cSGeorge Anzinger enum hrtimer_mode mode); 377dbc1625fSSebastian Andrzej Siewior extern void hrtimer_init_sleeper(struct hrtimer_sleeper *sl, clockid_t clock_id, 378dbc1625fSSebastian Andrzej Siewior enum hrtimer_mode mode); 379c0a31329SThomas Gleixner 380237fc6e7SThomas Gleixner #ifdef CONFIG_DEBUG_OBJECTS_TIMERS 381237fc6e7SThomas Gleixner extern void hrtimer_init_on_stack(struct hrtimer *timer, clockid_t which_clock, 382237fc6e7SThomas Gleixner enum hrtimer_mode mode); 383dbc1625fSSebastian Andrzej Siewior extern void hrtimer_init_sleeper_on_stack(struct hrtimer_sleeper *sl, 384dbc1625fSSebastian Andrzej Siewior clockid_t clock_id, 385dbc1625fSSebastian Andrzej Siewior enum hrtimer_mode mode); 386237fc6e7SThomas Gleixner 387237fc6e7SThomas Gleixner extern void destroy_hrtimer_on_stack(struct hrtimer *timer); 388237fc6e7SThomas Gleixner #else 389237fc6e7SThomas Gleixner static inline void hrtimer_init_on_stack(struct hrtimer *timer, 390237fc6e7SThomas Gleixner clockid_t which_clock, 391237fc6e7SThomas Gleixner enum hrtimer_mode mode) 392237fc6e7SThomas Gleixner { 393237fc6e7SThomas Gleixner hrtimer_init(timer, which_clock, mode); 394237fc6e7SThomas Gleixner } 395dbc1625fSSebastian Andrzej Siewior 396dbc1625fSSebastian Andrzej Siewior static inline void hrtimer_init_sleeper_on_stack(struct hrtimer_sleeper *sl, 397dbc1625fSSebastian Andrzej Siewior clockid_t clock_id, 398dbc1625fSSebastian Andrzej Siewior enum hrtimer_mode mode) 399dbc1625fSSebastian Andrzej Siewior { 400dbc1625fSSebastian Andrzej Siewior hrtimer_init_sleeper(sl, clock_id, mode); 401dbc1625fSSebastian Andrzej Siewior } 402dbc1625fSSebastian Andrzej Siewior 403237fc6e7SThomas Gleixner static inline void destroy_hrtimer_on_stack(struct hrtimer *timer) { } 404237fc6e7SThomas Gleixner #endif 405237fc6e7SThomas Gleixner 406c0a31329SThomas Gleixner /* Basic timer operations: */ 40761699e13SThomas Gleixner extern void hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim, 408da8b44d5SJohn Stultz u64 range_ns, const enum hrtimer_mode mode); 4097f1e2ca9SPeter Zijlstra 41002a171afSThomas Gleixner /** 4116de6250cSAnna-Maria Gleixner * hrtimer_start - (re)start an hrtimer 41202a171afSThomas Gleixner * @timer: the timer to be added 41302a171afSThomas Gleixner * @tim: expiry time 4146de6250cSAnna-Maria Gleixner * @mode: timer mode: absolute (HRTIMER_MODE_ABS) or 4155da70160SAnna-Maria Gleixner * relative (HRTIMER_MODE_REL), and pinned (HRTIMER_MODE_PINNED); 4165da70160SAnna-Maria Gleixner * softirq based mode is considered for debug purpose only! 41702a171afSThomas Gleixner */ 41861699e13SThomas Gleixner static inline void hrtimer_start(struct hrtimer *timer, ktime_t tim, 41902a171afSThomas Gleixner const enum hrtimer_mode mode) 42002a171afSThomas Gleixner { 42161699e13SThomas Gleixner hrtimer_start_range_ns(timer, tim, 0, mode); 42202a171afSThomas Gleixner } 42302a171afSThomas Gleixner 424c0a31329SThomas Gleixner extern int hrtimer_cancel(struct hrtimer *timer); 425c0a31329SThomas Gleixner extern int hrtimer_try_to_cancel(struct hrtimer *timer); 426c0a31329SThomas Gleixner 42761699e13SThomas Gleixner static inline void hrtimer_start_expires(struct hrtimer *timer, 42863ca243bSArjan van de Ven enum hrtimer_mode mode) 42963ca243bSArjan van de Ven { 430da8b44d5SJohn Stultz u64 delta; 431da8f2e17SArjan van de Ven ktime_t soft, hard; 432da8f2e17SArjan van de Ven soft = hrtimer_get_softexpires(timer); 433da8f2e17SArjan van de Ven hard = hrtimer_get_expires(timer); 434da8f2e17SArjan van de Ven delta = ktime_to_ns(ktime_sub(hard, soft)); 43561699e13SThomas Gleixner hrtimer_start_range_ns(timer, soft, delta, mode); 43663ca243bSArjan van de Ven } 43763ca243bSArjan van de Ven 43801656464SThomas Gleixner void hrtimer_sleeper_start_expires(struct hrtimer_sleeper *sl, 43901656464SThomas Gleixner enum hrtimer_mode mode); 44001656464SThomas Gleixner 44161699e13SThomas Gleixner static inline void hrtimer_restart(struct hrtimer *timer) 442c9cb2e3dSThomas Gleixner { 44361699e13SThomas Gleixner hrtimer_start_expires(timer, HRTIMER_MODE_ABS); 444c9cb2e3dSThomas Gleixner } 445c0a31329SThomas Gleixner 446c0a31329SThomas Gleixner /* Query timers: */ 447203cbf77SThomas Gleixner extern ktime_t __hrtimer_get_remaining(const struct hrtimer *timer, bool adjust); 448203cbf77SThomas Gleixner 449203cbf77SThomas Gleixner static inline ktime_t hrtimer_get_remaining(const struct hrtimer *timer) 450203cbf77SThomas Gleixner { 451203cbf77SThomas Gleixner return __hrtimer_get_remaining(timer, false); 452203cbf77SThomas Gleixner } 453c0a31329SThomas Gleixner 454c1ad348bSThomas Gleixner extern u64 hrtimer_get_next_event(void); 455a59855cdSRafael J. Wysocki extern u64 hrtimer_next_event_without(const struct hrtimer *exclude); 45669239749STony Lindgren 457887d9dc9SPeter Zijlstra extern bool hrtimer_active(const struct hrtimer *timer); 458c0a31329SThomas Gleixner 45954cdfdb4SThomas Gleixner /* 46054cdfdb4SThomas Gleixner * Helper function to check, whether the timer is on one of the queues 46154cdfdb4SThomas Gleixner */ 46254cdfdb4SThomas Gleixner static inline int hrtimer_is_queued(struct hrtimer *timer) 46354cdfdb4SThomas Gleixner { 464ca109491SPeter Zijlstra return timer->state & HRTIMER_STATE_ENQUEUED; 46554cdfdb4SThomas Gleixner } 46654cdfdb4SThomas Gleixner 4674346f654SOliver Hartkopp /* 4684346f654SOliver Hartkopp * Helper function to check, whether the timer is running the callback 4694346f654SOliver Hartkopp * function 4704346f654SOliver Hartkopp */ 4714346f654SOliver Hartkopp static inline int hrtimer_callback_running(struct hrtimer *timer) 4724346f654SOliver Hartkopp { 4733f0b9e8eSAnna-Maria Gleixner return timer->base->running == timer; 4744346f654SOliver Hartkopp } 4754346f654SOliver Hartkopp 476c0a31329SThomas Gleixner /* Forward a hrtimer so it expires after now: */ 4774d672e7aSDavide Libenzi extern u64 47844f21475SRoman Zippel hrtimer_forward(struct hrtimer *timer, ktime_t now, ktime_t interval); 479c0a31329SThomas Gleixner 48091e5a217SThomas Gleixner /** 48191e5a217SThomas Gleixner * hrtimer_forward_now - forward the timer expiry so it expires after now 48291e5a217SThomas Gleixner * @timer: hrtimer to forward 48391e5a217SThomas Gleixner * @interval: the interval to forward 48491e5a217SThomas Gleixner * 48591e5a217SThomas Gleixner * Forward the timer expiry so it will expire after the current time 48691e5a217SThomas Gleixner * of the hrtimer clock base. Returns the number of overruns. 48791e5a217SThomas Gleixner * 48891e5a217SThomas Gleixner * Can be safely called from the callback function of @timer. If 48991e5a217SThomas Gleixner * called from other contexts @timer must neither be enqueued nor 49091e5a217SThomas Gleixner * running the callback and the caller needs to take care of 49191e5a217SThomas Gleixner * serialization. 49291e5a217SThomas Gleixner * 49391e5a217SThomas Gleixner * Note: This only updates the timer expiry value and does not requeue 49491e5a217SThomas Gleixner * the timer. 49591e5a217SThomas Gleixner */ 4964d672e7aSDavide Libenzi static inline u64 hrtimer_forward_now(struct hrtimer *timer, 4975e05ad7dSDavide Libenzi ktime_t interval) 4985e05ad7dSDavide Libenzi { 4995e05ad7dSDavide Libenzi return hrtimer_forward(timer, timer->base->get_time(), interval); 5005e05ad7dSDavide Libenzi } 5015e05ad7dSDavide Libenzi 50210c94ec1SThomas Gleixner /* Precise sleep: */ 503ce41aaf4SAl Viro 504c0edd7c9SDeepa Dinamani extern int nanosleep_copyout(struct restart_block *, struct timespec64 *); 505938e7cf2SThomas Gleixner extern long hrtimer_nanosleep(const struct timespec64 *rqtp, 50610c94ec1SThomas Gleixner const enum hrtimer_mode mode, 50710c94ec1SThomas Gleixner const clockid_t clockid); 50810c94ec1SThomas Gleixner 509da8b44d5SJohn Stultz extern int schedule_hrtimeout_range(ktime_t *expires, u64 delta, 510654c8e0bSArjan van de Ven const enum hrtimer_mode mode); 511351b3f7aSCarsten Emde extern int schedule_hrtimeout_range_clock(ktime_t *expires, 512da8b44d5SJohn Stultz u64 delta, 513da8b44d5SJohn Stultz const enum hrtimer_mode mode, 51490777713SAnna-Maria Gleixner clockid_t clock_id); 5157bb67439SArjan van de Ven extern int schedule_hrtimeout(ktime_t *expires, const enum hrtimer_mode mode); 5167bb67439SArjan van de Ven 517c0a31329SThomas Gleixner /* Soft interrupt function to run the hrtimer queues: */ 518c0a31329SThomas Gleixner extern void hrtimer_run_queues(void); 519c0a31329SThomas Gleixner 520c0a31329SThomas Gleixner /* Bootup initialization: */ 521c0a31329SThomas Gleixner extern void __init hrtimers_init(void); 522c0a31329SThomas Gleixner 52388ad0bf6SIngo Molnar /* Show pending timers: */ 52488ad0bf6SIngo Molnar extern void sysrq_timer_list_show(void); 52588ad0bf6SIngo Molnar 52627590dc1SThomas Gleixner int hrtimers_prepare_cpu(unsigned int cpu); 52727590dc1SThomas Gleixner #ifdef CONFIG_HOTPLUG_CPU 52827590dc1SThomas Gleixner int hrtimers_dead_cpu(unsigned int cpu); 52927590dc1SThomas Gleixner #else 53027590dc1SThomas Gleixner #define hrtimers_dead_cpu NULL 53127590dc1SThomas Gleixner #endif 53227590dc1SThomas Gleixner 533c0a31329SThomas Gleixner #endif 534