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 35c0a31329SThomas Gleixner */ 36c0a31329SThomas Gleixner enum hrtimer_mode { 3719b51cb5SAnna-Maria Gleixner HRTIMER_MODE_ABS = 0x00, 3819b51cb5SAnna-Maria Gleixner HRTIMER_MODE_REL = 0x01, 3919b51cb5SAnna-Maria Gleixner HRTIMER_MODE_PINNED = 0x02, 4098ecadd4SAnna-Maria Gleixner HRTIMER_MODE_SOFT = 0x04, 4119b51cb5SAnna-Maria Gleixner 4219b51cb5SAnna-Maria Gleixner HRTIMER_MODE_ABS_PINNED = HRTIMER_MODE_ABS | HRTIMER_MODE_PINNED, 4319b51cb5SAnna-Maria Gleixner HRTIMER_MODE_REL_PINNED = HRTIMER_MODE_REL | HRTIMER_MODE_PINNED, 4498ecadd4SAnna-Maria Gleixner 4598ecadd4SAnna-Maria Gleixner HRTIMER_MODE_ABS_SOFT = HRTIMER_MODE_ABS | HRTIMER_MODE_SOFT, 4698ecadd4SAnna-Maria Gleixner HRTIMER_MODE_REL_SOFT = HRTIMER_MODE_REL | HRTIMER_MODE_SOFT, 4798ecadd4SAnna-Maria Gleixner 4898ecadd4SAnna-Maria Gleixner HRTIMER_MODE_ABS_PINNED_SOFT = HRTIMER_MODE_ABS_PINNED | HRTIMER_MODE_SOFT, 4998ecadd4SAnna-Maria Gleixner HRTIMER_MODE_REL_PINNED_SOFT = HRTIMER_MODE_REL_PINNED | HRTIMER_MODE_SOFT, 5098ecadd4SAnna-Maria Gleixner 51c0a31329SThomas Gleixner }; 52c0a31329SThomas Gleixner 53c9cb2e3dSThomas Gleixner /* 54c9cb2e3dSThomas Gleixner * Return values for the callback function 55c9cb2e3dSThomas Gleixner */ 56c0a31329SThomas Gleixner enum hrtimer_restart { 57c9cb2e3dSThomas Gleixner HRTIMER_NORESTART, /* Timer is not restarted */ 58c9cb2e3dSThomas Gleixner HRTIMER_RESTART, /* Timer must be restarted */ 59c0a31329SThomas Gleixner }; 60c0a31329SThomas Gleixner 61303e967fSThomas Gleixner /* 6254cdfdb4SThomas Gleixner * Values to track state of the timer 63303e967fSThomas Gleixner * 64303e967fSThomas Gleixner * Possible states: 65303e967fSThomas Gleixner * 66303e967fSThomas Gleixner * 0x00 inactive 67303e967fSThomas Gleixner * 0x01 enqueued into rbtree 6854cdfdb4SThomas Gleixner * 69887d9dc9SPeter Zijlstra * The callback state is not part of the timer->state because clearing it would 70887d9dc9SPeter Zijlstra * mean touching the timer after the callback, this makes it impossible to free 71887d9dc9SPeter Zijlstra * the timer from the callback function. 7253370d2eSThomas Gleixner * 73887d9dc9SPeter Zijlstra * Therefore we track the callback state in: 74887d9dc9SPeter Zijlstra * 75887d9dc9SPeter Zijlstra * timer->base->cpu_base->running == timer 76887d9dc9SPeter Zijlstra * 77887d9dc9SPeter Zijlstra * On SMP it is possible to have a "callback function running and enqueued" 78887d9dc9SPeter Zijlstra * status. It happens for example when a posix timer expired and the callback 79303e967fSThomas Gleixner * queued a signal. Between dropping the lock which protects the posix timer 80303e967fSThomas Gleixner * and reacquiring the base lock of the hrtimer, another CPU can deliver the 81887d9dc9SPeter Zijlstra * signal and rearm the timer. 82303e967fSThomas Gleixner * 83303e967fSThomas Gleixner * All state transitions are protected by cpu_base->lock. 84303e967fSThomas Gleixner */ 85303e967fSThomas Gleixner #define HRTIMER_STATE_INACTIVE 0x00 86303e967fSThomas Gleixner #define HRTIMER_STATE_ENQUEUED 0x01 87303e967fSThomas Gleixner 88c0a31329SThomas Gleixner /** 89c0a31329SThomas Gleixner * struct hrtimer - the basic hrtimer structure 90998adc3dSJohn Stultz * @node: timerqueue node, which also manages node.expires, 91998adc3dSJohn Stultz * the absolute expiry time in the hrtimers internal 92c0a31329SThomas Gleixner * representation. The time is related to the clock on 93592aa999SThomas Gleixner * which the timer is based. Is setup by adding 94592aa999SThomas Gleixner * slack to the _softexpires value. For non range timers 95592aa999SThomas Gleixner * identical to _softexpires. 96592aa999SThomas Gleixner * @_softexpires: the absolute earliest expiry time of the hrtimer. 97592aa999SThomas Gleixner * The time which was given as expiry time when the timer 98592aa999SThomas Gleixner * was armed. 99c0a31329SThomas Gleixner * @function: timer expiry callback function 100c0a31329SThomas Gleixner * @base: pointer to the timer base (per cpu and per clock) 101303e967fSThomas Gleixner * @state: state information (See bit values above) 102203cbf77SThomas Gleixner * @is_rel: Set if the timer was armed relative 1035da70160SAnna-Maria Gleixner * @is_soft: Set if hrtimer will be expired in soft interrupt context. 104c0a31329SThomas Gleixner * 10554cdfdb4SThomas Gleixner * The hrtimer structure must be initialized by hrtimer_init() 106c0a31329SThomas Gleixner */ 107c0a31329SThomas Gleixner struct hrtimer { 108998adc3dSJohn Stultz struct timerqueue_node node; 109654c8e0bSArjan van de Ven ktime_t _softexpires; 110c9cb2e3dSThomas Gleixner enum hrtimer_restart (*function)(struct hrtimer *); 1113c8aa39dSThomas Gleixner struct hrtimer_clock_base *base; 112203cbf77SThomas Gleixner u8 state; 113203cbf77SThomas Gleixner u8 is_rel; 1145da70160SAnna-Maria Gleixner u8 is_soft; 115c0a31329SThomas Gleixner }; 116c0a31329SThomas Gleixner 117c0a31329SThomas Gleixner /** 11800362e33SThomas Gleixner * struct hrtimer_sleeper - simple sleeper structure 11900362e33SThomas Gleixner * @timer: embedded timer structure 12000362e33SThomas Gleixner * @task: task to wake up 12100362e33SThomas Gleixner * 12200362e33SThomas Gleixner * task is set to NULL, when the timer expires. 12300362e33SThomas Gleixner */ 12400362e33SThomas Gleixner struct hrtimer_sleeper { 12500362e33SThomas Gleixner struct hrtimer timer; 12600362e33SThomas Gleixner struct task_struct *task; 12700362e33SThomas Gleixner }; 12800362e33SThomas Gleixner 129b8e38413SThomas Gleixner #ifdef CONFIG_64BIT 1303f0b9e8eSAnna-Maria Gleixner # define __hrtimer_clock_base_align ____cacheline_aligned 131b8e38413SThomas Gleixner #else 1323f0b9e8eSAnna-Maria Gleixner # define __hrtimer_clock_base_align 133b8e38413SThomas Gleixner #endif 134b8e38413SThomas Gleixner 13500362e33SThomas Gleixner /** 136d1d67174SAndres Salomon * struct hrtimer_clock_base - the timer base for a specific clock 13705fb6bf0SRandy Dunlap * @cpu_base: per cpu clock base 1383c8aa39dSThomas Gleixner * @index: clock type index for per_cpu support when moving a 1393c8aa39dSThomas Gleixner * timer to a base on another cpu. 1404d258b25SVitaliy Ivanov * @clockid: clock id for per_cpu support 1413f0b9e8eSAnna-Maria Gleixner * @seq: seqcount around __run_hrtimer 1423f0b9e8eSAnna-Maria Gleixner * @running: pointer to the currently running hrtimer 143c0a31329SThomas Gleixner * @active: red black tree root node for the active timers 144c0a31329SThomas Gleixner * @get_time: function to retrieve the current time of the clock 14554cdfdb4SThomas Gleixner * @offset: offset of this clock to the monotonic base 146c0a31329SThomas Gleixner */ 1473c8aa39dSThomas Gleixner struct hrtimer_clock_base { 1483c8aa39dSThomas Gleixner struct hrtimer_cpu_base *cpu_base; 1493f0b9e8eSAnna-Maria Gleixner unsigned int index; 150ab8177bcSThomas Gleixner clockid_t clockid; 1513f0b9e8eSAnna-Maria Gleixner seqcount_t seq; 1523f0b9e8eSAnna-Maria Gleixner struct hrtimer *running; 153998adc3dSJohn Stultz struct timerqueue_head active; 154c0a31329SThomas Gleixner ktime_t (*get_time)(void); 15554cdfdb4SThomas Gleixner ktime_t offset; 1563f0b9e8eSAnna-Maria Gleixner } __hrtimer_clock_base_align; 1573c8aa39dSThomas Gleixner 158e06383dbSJohn Stultz enum hrtimer_base_type { 159e06383dbSJohn Stultz HRTIMER_BASE_MONOTONIC, 16068fa61c0SThomas Gleixner HRTIMER_BASE_REALTIME, 161a3ed0e43SThomas Gleixner HRTIMER_BASE_BOOTTIME, 16290adda98SJohn Stultz HRTIMER_BASE_TAI, 16398ecadd4SAnna-Maria Gleixner HRTIMER_BASE_MONOTONIC_SOFT, 16498ecadd4SAnna-Maria Gleixner HRTIMER_BASE_REALTIME_SOFT, 165a3ed0e43SThomas Gleixner HRTIMER_BASE_BOOTTIME_SOFT, 16698ecadd4SAnna-Maria Gleixner HRTIMER_BASE_TAI_SOFT, 167e06383dbSJohn Stultz HRTIMER_MAX_CLOCK_BASES, 168e06383dbSJohn Stultz }; 1693c8aa39dSThomas Gleixner 1701fbc78b3SAnna-Maria Gleixner /** 1713c8aa39dSThomas Gleixner * struct hrtimer_cpu_base - the per cpu clock bases 1723c8aa39dSThomas Gleixner * @lock: lock protecting the base and associated clock bases 1733c8aa39dSThomas Gleixner * and timers 174cddd0248SViresh Kumar * @cpu: cpu number 175ab8177bcSThomas Gleixner * @active_bases: Bitfield to mark bases with active timers 176868a3e91SThomas Gleixner * @clock_was_set_seq: Sequence counter of clock was set events 17754cdfdb4SThomas Gleixner * @hres_active: State of high resolution mode 17828bfd18bSAnna-Maria Gleixner * @in_hrtirq: hrtimer_interrupt() is currently executing 17941d2e494SThomas Gleixner * @hang_detected: The last hrtimer interrupt detected a hang 1805da70160SAnna-Maria Gleixner * @softirq_activated: displays, if the softirq is raised - update of softirq 1815da70160SAnna-Maria Gleixner * related settings is not required then. 18241d2e494SThomas Gleixner * @nr_events: Total number of hrtimer interrupt events 18341d2e494SThomas Gleixner * @nr_retries: Total number of hrtimer interrupt retries 18441d2e494SThomas Gleixner * @nr_hangs: Total number of hrtimer interrupt hangs 18541d2e494SThomas Gleixner * @max_hang_time: Maximum time spent in hrtimer_interrupt 18607a9a7eaSAnna-Maria Gleixner * @expires_next: absolute time of the next event, is required for remote 1875da70160SAnna-Maria Gleixner * hrtimer enqueue; it is the total first expiry time (hard 1885da70160SAnna-Maria Gleixner * and soft hrtimer are taken into account) 189eb27926bSAnna-Maria Gleixner * @next_timer: Pointer to the first expiring timer 1905da70160SAnna-Maria Gleixner * @softirq_expires_next: Time to check, if soft queues needs also to be expired 1915da70160SAnna-Maria Gleixner * @softirq_next_timer: Pointer to the first expiring softirq based timer 192ab8177bcSThomas Gleixner * @clock_base: array of clock bases for this cpu 193895bdfa7SThomas Gleixner * 194895bdfa7SThomas Gleixner * Note: next_timer is just an optimization for __remove_hrtimer(). 195895bdfa7SThomas Gleixner * Do not dereference the pointer because it is not reliable on 196895bdfa7SThomas Gleixner * cross cpu removals. 1973c8aa39dSThomas Gleixner */ 1983c8aa39dSThomas Gleixner struct hrtimer_cpu_base { 199ecb49d1aSThomas Gleixner raw_spinlock_t lock; 200cddd0248SViresh Kumar unsigned int cpu; 201f55a6faaSJohn Stultz unsigned int active_bases; 202868a3e91SThomas Gleixner unsigned int clock_was_set_seq; 20311a9fe06SAnna-Maria Gleixner unsigned int hres_active : 1, 20411a9fe06SAnna-Maria Gleixner in_hrtirq : 1, 2055da70160SAnna-Maria Gleixner hang_detected : 1, 2065da70160SAnna-Maria Gleixner softirq_activated : 1; 20711a9fe06SAnna-Maria Gleixner #ifdef CONFIG_HIGH_RES_TIMERS 208a6ffebceSThomas Gleixner unsigned int nr_events; 209da21c5a5SAnna-Maria Gleixner unsigned short nr_retries; 210da21c5a5SAnna-Maria Gleixner unsigned short nr_hangs; 211a6ffebceSThomas Gleixner unsigned int max_hang_time; 21254cdfdb4SThomas Gleixner #endif 21307a9a7eaSAnna-Maria Gleixner ktime_t expires_next; 214eb27926bSAnna-Maria Gleixner struct hrtimer *next_timer; 2155da70160SAnna-Maria Gleixner ktime_t softirq_expires_next; 2165da70160SAnna-Maria Gleixner struct hrtimer *softirq_next_timer; 217f24444b0SThomas Gleixner struct hrtimer_clock_base clock_base[HRTIMER_MAX_CLOCK_BASES]; 2186d9a1411SThomas Gleixner } ____cacheline_aligned; 219c0a31329SThomas Gleixner 22063ca243bSArjan van de Ven static inline void hrtimer_set_expires(struct hrtimer *timer, ktime_t time) 22163ca243bSArjan van de Ven { 222998adc3dSJohn Stultz timer->node.expires = time; 223654c8e0bSArjan van de Ven timer->_softexpires = time; 22463ca243bSArjan van de Ven } 225654c8e0bSArjan van de Ven 226654c8e0bSArjan van de Ven static inline void hrtimer_set_expires_range(struct hrtimer *timer, ktime_t time, ktime_t delta) 227654c8e0bSArjan van de Ven { 228654c8e0bSArjan van de Ven timer->_softexpires = time; 229998adc3dSJohn Stultz timer->node.expires = ktime_add_safe(time, delta); 230654c8e0bSArjan van de Ven } 231654c8e0bSArjan van de Ven 232da8b44d5SJohn Stultz static inline void hrtimer_set_expires_range_ns(struct hrtimer *timer, ktime_t time, u64 delta) 233654c8e0bSArjan van de Ven { 234654c8e0bSArjan van de Ven timer->_softexpires = time; 235998adc3dSJohn Stultz timer->node.expires = ktime_add_safe(time, ns_to_ktime(delta)); 236654c8e0bSArjan van de Ven } 237654c8e0bSArjan van de Ven 23863ca243bSArjan van de Ven static inline void hrtimer_set_expires_tv64(struct hrtimer *timer, s64 tv64) 23963ca243bSArjan van de Ven { 2402456e855SThomas Gleixner timer->node.expires = tv64; 2412456e855SThomas Gleixner timer->_softexpires = tv64; 24263ca243bSArjan van de Ven } 24363ca243bSArjan van de Ven 24463ca243bSArjan van de Ven static inline void hrtimer_add_expires(struct hrtimer *timer, ktime_t time) 24563ca243bSArjan van de Ven { 246998adc3dSJohn Stultz timer->node.expires = ktime_add_safe(timer->node.expires, time); 247654c8e0bSArjan van de Ven timer->_softexpires = ktime_add_safe(timer->_softexpires, time); 24863ca243bSArjan van de Ven } 24963ca243bSArjan van de Ven 2507597bc94SDavid Howells static inline void hrtimer_add_expires_ns(struct hrtimer *timer, u64 ns) 25163ca243bSArjan van de Ven { 252998adc3dSJohn Stultz timer->node.expires = ktime_add_ns(timer->node.expires, ns); 253654c8e0bSArjan van de Ven timer->_softexpires = ktime_add_ns(timer->_softexpires, ns); 25463ca243bSArjan van de Ven } 25563ca243bSArjan van de Ven 25663ca243bSArjan van de Ven static inline ktime_t hrtimer_get_expires(const struct hrtimer *timer) 25763ca243bSArjan van de Ven { 258998adc3dSJohn Stultz return timer->node.expires; 25963ca243bSArjan van de Ven } 26063ca243bSArjan van de Ven 261654c8e0bSArjan van de Ven static inline ktime_t hrtimer_get_softexpires(const struct hrtimer *timer) 262654c8e0bSArjan van de Ven { 263654c8e0bSArjan van de Ven return timer->_softexpires; 264654c8e0bSArjan van de Ven } 265654c8e0bSArjan van de Ven 26663ca243bSArjan van de Ven static inline s64 hrtimer_get_expires_tv64(const struct hrtimer *timer) 26763ca243bSArjan van de Ven { 2682456e855SThomas Gleixner return timer->node.expires; 26963ca243bSArjan van de Ven } 270654c8e0bSArjan van de Ven static inline s64 hrtimer_get_softexpires_tv64(const struct hrtimer *timer) 271654c8e0bSArjan van de Ven { 2722456e855SThomas Gleixner return timer->_softexpires; 273654c8e0bSArjan van de Ven } 27463ca243bSArjan van de Ven 27563ca243bSArjan van de Ven static inline s64 hrtimer_get_expires_ns(const struct hrtimer *timer) 27663ca243bSArjan van de Ven { 277998adc3dSJohn Stultz return ktime_to_ns(timer->node.expires); 27863ca243bSArjan van de Ven } 27963ca243bSArjan van de Ven 28063ca243bSArjan van de Ven static inline ktime_t hrtimer_expires_remaining(const struct hrtimer *timer) 28163ca243bSArjan van de Ven { 282998adc3dSJohn Stultz return ktime_sub(timer->node.expires, timer->base->get_time()); 28363ca243bSArjan van de Ven } 28463ca243bSArjan van de Ven 28554cdfdb4SThomas Gleixner static inline ktime_t hrtimer_cb_get_time(struct hrtimer *timer) 28654cdfdb4SThomas Gleixner { 28754cdfdb4SThomas Gleixner return timer->base->get_time(); 28854cdfdb4SThomas Gleixner } 28954cdfdb4SThomas Gleixner 29028bfd18bSAnna-Maria Gleixner static inline int hrtimer_is_hres_active(struct hrtimer *timer) 29128bfd18bSAnna-Maria Gleixner { 29228bfd18bSAnna-Maria Gleixner return IS_ENABLED(CONFIG_HIGH_RES_TIMERS) ? 29328bfd18bSAnna-Maria Gleixner timer->base->cpu_base->hres_active : 0; 29428bfd18bSAnna-Maria Gleixner } 29528bfd18bSAnna-Maria Gleixner 29621d6d52aSThomas Gleixner #ifdef CONFIG_HIGH_RES_TIMERS 29721d6d52aSThomas Gleixner struct clock_event_device; 29821d6d52aSThomas Gleixner 29921d6d52aSThomas Gleixner extern void hrtimer_interrupt(struct clock_event_device *dev); 30021d6d52aSThomas Gleixner 301f55a6faaSJohn Stultz extern void clock_was_set_delayed(void); 302f55a6faaSJohn Stultz 303398ca17fSThomas Gleixner extern unsigned int hrtimer_resolution; 304398ca17fSThomas Gleixner 30554cdfdb4SThomas Gleixner #else 30654cdfdb4SThomas Gleixner 307d711b8b3SBorislav Petkov #define hrtimer_resolution (unsigned int)LOW_RES_NSEC 308398ca17fSThomas Gleixner 309f55a6faaSJohn Stultz static inline void clock_was_set_delayed(void) { } 310f55a6faaSJohn Stultz 31154cdfdb4SThomas Gleixner #endif 31254cdfdb4SThomas Gleixner 313203cbf77SThomas Gleixner static inline ktime_t 314203cbf77SThomas Gleixner __hrtimer_expires_remaining_adjusted(const struct hrtimer *timer, ktime_t now) 315203cbf77SThomas Gleixner { 316203cbf77SThomas Gleixner ktime_t rem = ktime_sub(timer->node.expires, now); 317203cbf77SThomas Gleixner 318203cbf77SThomas Gleixner /* 319203cbf77SThomas Gleixner * Adjust relative timers for the extra we added in 320203cbf77SThomas Gleixner * hrtimer_start_range_ns() to prevent short timeouts. 321203cbf77SThomas Gleixner */ 322203cbf77SThomas Gleixner if (IS_ENABLED(CONFIG_TIME_LOW_RES) && timer->is_rel) 3232456e855SThomas Gleixner rem -= hrtimer_resolution; 324203cbf77SThomas Gleixner return rem; 325203cbf77SThomas Gleixner } 326203cbf77SThomas Gleixner 327203cbf77SThomas Gleixner static inline ktime_t 328203cbf77SThomas Gleixner hrtimer_expires_remaining_adjusted(const struct hrtimer *timer) 329203cbf77SThomas Gleixner { 330203cbf77SThomas Gleixner return __hrtimer_expires_remaining_adjusted(timer, 331203cbf77SThomas Gleixner timer->base->get_time()); 332203cbf77SThomas Gleixner } 333203cbf77SThomas Gleixner 334b12a03ceSThomas Gleixner extern void clock_was_set(void); 3359ec26907SThomas Gleixner #ifdef CONFIG_TIMERFD 3369ec26907SThomas Gleixner extern void timerfd_clock_was_set(void); 3379ec26907SThomas Gleixner #else 3389ec26907SThomas Gleixner static inline void timerfd_clock_was_set(void) { } 3399ec26907SThomas Gleixner #endif 340b12a03ceSThomas Gleixner extern void hrtimers_resume(void); 341b12a03ceSThomas Gleixner 3422e94d1f7SArjan van de Ven DECLARE_PER_CPU(struct tick_device, tick_cpu_device); 3432e94d1f7SArjan van de Ven 3442e94d1f7SArjan van de Ven 345c0a31329SThomas Gleixner /* Exported timer functions: */ 346c0a31329SThomas Gleixner 347c0a31329SThomas Gleixner /* Initialize timers: */ 3487978672cSGeorge Anzinger extern void hrtimer_init(struct hrtimer *timer, clockid_t which_clock, 3497978672cSGeorge Anzinger enum hrtimer_mode mode); 350*dbc1625fSSebastian Andrzej Siewior extern void hrtimer_init_sleeper(struct hrtimer_sleeper *sl, clockid_t clock_id, 351*dbc1625fSSebastian Andrzej Siewior enum hrtimer_mode mode); 352c0a31329SThomas Gleixner 353237fc6e7SThomas Gleixner #ifdef CONFIG_DEBUG_OBJECTS_TIMERS 354237fc6e7SThomas Gleixner extern void hrtimer_init_on_stack(struct hrtimer *timer, clockid_t which_clock, 355237fc6e7SThomas Gleixner enum hrtimer_mode mode); 356*dbc1625fSSebastian Andrzej Siewior extern void hrtimer_init_sleeper_on_stack(struct hrtimer_sleeper *sl, 357*dbc1625fSSebastian Andrzej Siewior clockid_t clock_id, 358*dbc1625fSSebastian Andrzej Siewior enum hrtimer_mode mode); 359237fc6e7SThomas Gleixner 360237fc6e7SThomas Gleixner extern void destroy_hrtimer_on_stack(struct hrtimer *timer); 361237fc6e7SThomas Gleixner #else 362237fc6e7SThomas Gleixner static inline void hrtimer_init_on_stack(struct hrtimer *timer, 363237fc6e7SThomas Gleixner clockid_t which_clock, 364237fc6e7SThomas Gleixner enum hrtimer_mode mode) 365237fc6e7SThomas Gleixner { 366237fc6e7SThomas Gleixner hrtimer_init(timer, which_clock, mode); 367237fc6e7SThomas Gleixner } 368*dbc1625fSSebastian Andrzej Siewior 369*dbc1625fSSebastian Andrzej Siewior static inline void hrtimer_init_sleeper_on_stack(struct hrtimer_sleeper *sl, 370*dbc1625fSSebastian Andrzej Siewior clockid_t clock_id, 371*dbc1625fSSebastian Andrzej Siewior enum hrtimer_mode mode) 372*dbc1625fSSebastian Andrzej Siewior { 373*dbc1625fSSebastian Andrzej Siewior hrtimer_init_sleeper(sl, clock_id, mode); 374*dbc1625fSSebastian Andrzej Siewior } 375*dbc1625fSSebastian Andrzej Siewior 376237fc6e7SThomas Gleixner static inline void destroy_hrtimer_on_stack(struct hrtimer *timer) { } 377237fc6e7SThomas Gleixner #endif 378237fc6e7SThomas Gleixner 379c0a31329SThomas Gleixner /* Basic timer operations: */ 38061699e13SThomas Gleixner extern void hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim, 381da8b44d5SJohn Stultz u64 range_ns, const enum hrtimer_mode mode); 3827f1e2ca9SPeter Zijlstra 38302a171afSThomas Gleixner /** 3846de6250cSAnna-Maria Gleixner * hrtimer_start - (re)start an hrtimer 38502a171afSThomas Gleixner * @timer: the timer to be added 38602a171afSThomas Gleixner * @tim: expiry time 3876de6250cSAnna-Maria Gleixner * @mode: timer mode: absolute (HRTIMER_MODE_ABS) or 3885da70160SAnna-Maria Gleixner * relative (HRTIMER_MODE_REL), and pinned (HRTIMER_MODE_PINNED); 3895da70160SAnna-Maria Gleixner * softirq based mode is considered for debug purpose only! 39002a171afSThomas Gleixner */ 39161699e13SThomas Gleixner static inline void hrtimer_start(struct hrtimer *timer, ktime_t tim, 39202a171afSThomas Gleixner const enum hrtimer_mode mode) 39302a171afSThomas Gleixner { 39461699e13SThomas Gleixner hrtimer_start_range_ns(timer, tim, 0, mode); 39502a171afSThomas Gleixner } 39602a171afSThomas Gleixner 397c0a31329SThomas Gleixner extern int hrtimer_cancel(struct hrtimer *timer); 398c0a31329SThomas Gleixner extern int hrtimer_try_to_cancel(struct hrtimer *timer); 399c0a31329SThomas Gleixner 40061699e13SThomas Gleixner static inline void hrtimer_start_expires(struct hrtimer *timer, 40163ca243bSArjan van de Ven enum hrtimer_mode mode) 40263ca243bSArjan van de Ven { 403da8b44d5SJohn Stultz u64 delta; 404da8f2e17SArjan van de Ven ktime_t soft, hard; 405da8f2e17SArjan van de Ven soft = hrtimer_get_softexpires(timer); 406da8f2e17SArjan van de Ven hard = hrtimer_get_expires(timer); 407da8f2e17SArjan van de Ven delta = ktime_to_ns(ktime_sub(hard, soft)); 40861699e13SThomas Gleixner hrtimer_start_range_ns(timer, soft, delta, mode); 40963ca243bSArjan van de Ven } 41063ca243bSArjan van de Ven 41161699e13SThomas Gleixner static inline void hrtimer_restart(struct hrtimer *timer) 412c9cb2e3dSThomas Gleixner { 41361699e13SThomas Gleixner hrtimer_start_expires(timer, HRTIMER_MODE_ABS); 414c9cb2e3dSThomas Gleixner } 415c0a31329SThomas Gleixner 416c0a31329SThomas Gleixner /* Query timers: */ 417203cbf77SThomas Gleixner extern ktime_t __hrtimer_get_remaining(const struct hrtimer *timer, bool adjust); 418203cbf77SThomas Gleixner 419203cbf77SThomas Gleixner static inline ktime_t hrtimer_get_remaining(const struct hrtimer *timer) 420203cbf77SThomas Gleixner { 421203cbf77SThomas Gleixner return __hrtimer_get_remaining(timer, false); 422203cbf77SThomas Gleixner } 423c0a31329SThomas Gleixner 424c1ad348bSThomas Gleixner extern u64 hrtimer_get_next_event(void); 425a59855cdSRafael J. Wysocki extern u64 hrtimer_next_event_without(const struct hrtimer *exclude); 42669239749STony Lindgren 427887d9dc9SPeter Zijlstra extern bool hrtimer_active(const struct hrtimer *timer); 428c0a31329SThomas Gleixner 42954cdfdb4SThomas Gleixner /* 43054cdfdb4SThomas Gleixner * Helper function to check, whether the timer is on one of the queues 43154cdfdb4SThomas Gleixner */ 43254cdfdb4SThomas Gleixner static inline int hrtimer_is_queued(struct hrtimer *timer) 43354cdfdb4SThomas Gleixner { 434ca109491SPeter Zijlstra return timer->state & HRTIMER_STATE_ENQUEUED; 43554cdfdb4SThomas Gleixner } 43654cdfdb4SThomas Gleixner 4374346f654SOliver Hartkopp /* 4384346f654SOliver Hartkopp * Helper function to check, whether the timer is running the callback 4394346f654SOliver Hartkopp * function 4404346f654SOliver Hartkopp */ 4414346f654SOliver Hartkopp static inline int hrtimer_callback_running(struct hrtimer *timer) 4424346f654SOliver Hartkopp { 4433f0b9e8eSAnna-Maria Gleixner return timer->base->running == timer; 4444346f654SOliver Hartkopp } 4454346f654SOliver Hartkopp 446c0a31329SThomas Gleixner /* Forward a hrtimer so it expires after now: */ 4474d672e7aSDavide Libenzi extern u64 44844f21475SRoman Zippel hrtimer_forward(struct hrtimer *timer, ktime_t now, ktime_t interval); 449c0a31329SThomas Gleixner 45091e5a217SThomas Gleixner /** 45191e5a217SThomas Gleixner * hrtimer_forward_now - forward the timer expiry so it expires after now 45291e5a217SThomas Gleixner * @timer: hrtimer to forward 45391e5a217SThomas Gleixner * @interval: the interval to forward 45491e5a217SThomas Gleixner * 45591e5a217SThomas Gleixner * Forward the timer expiry so it will expire after the current time 45691e5a217SThomas Gleixner * of the hrtimer clock base. Returns the number of overruns. 45791e5a217SThomas Gleixner * 45891e5a217SThomas Gleixner * Can be safely called from the callback function of @timer. If 45991e5a217SThomas Gleixner * called from other contexts @timer must neither be enqueued nor 46091e5a217SThomas Gleixner * running the callback and the caller needs to take care of 46191e5a217SThomas Gleixner * serialization. 46291e5a217SThomas Gleixner * 46391e5a217SThomas Gleixner * Note: This only updates the timer expiry value and does not requeue 46491e5a217SThomas Gleixner * the timer. 46591e5a217SThomas Gleixner */ 4664d672e7aSDavide Libenzi static inline u64 hrtimer_forward_now(struct hrtimer *timer, 4675e05ad7dSDavide Libenzi ktime_t interval) 4685e05ad7dSDavide Libenzi { 4695e05ad7dSDavide Libenzi return hrtimer_forward(timer, timer->base->get_time(), interval); 4705e05ad7dSDavide Libenzi } 4715e05ad7dSDavide Libenzi 47210c94ec1SThomas Gleixner /* Precise sleep: */ 473ce41aaf4SAl Viro 474c0edd7c9SDeepa Dinamani extern int nanosleep_copyout(struct restart_block *, struct timespec64 *); 475938e7cf2SThomas Gleixner extern long hrtimer_nanosleep(const struct timespec64 *rqtp, 47610c94ec1SThomas Gleixner const enum hrtimer_mode mode, 47710c94ec1SThomas Gleixner const clockid_t clockid); 47810c94ec1SThomas Gleixner 479da8b44d5SJohn Stultz extern int schedule_hrtimeout_range(ktime_t *expires, u64 delta, 480654c8e0bSArjan van de Ven const enum hrtimer_mode mode); 481351b3f7aSCarsten Emde extern int schedule_hrtimeout_range_clock(ktime_t *expires, 482da8b44d5SJohn Stultz u64 delta, 483da8b44d5SJohn Stultz const enum hrtimer_mode mode, 48490777713SAnna-Maria Gleixner clockid_t clock_id); 4857bb67439SArjan van de Ven extern int schedule_hrtimeout(ktime_t *expires, const enum hrtimer_mode mode); 4867bb67439SArjan van de Ven 487c0a31329SThomas Gleixner /* Soft interrupt function to run the hrtimer queues: */ 488c0a31329SThomas Gleixner extern void hrtimer_run_queues(void); 489c0a31329SThomas Gleixner 490c0a31329SThomas Gleixner /* Bootup initialization: */ 491c0a31329SThomas Gleixner extern void __init hrtimers_init(void); 492c0a31329SThomas Gleixner 49388ad0bf6SIngo Molnar /* Show pending timers: */ 49488ad0bf6SIngo Molnar extern void sysrq_timer_list_show(void); 49588ad0bf6SIngo Molnar 49627590dc1SThomas Gleixner int hrtimers_prepare_cpu(unsigned int cpu); 49727590dc1SThomas Gleixner #ifdef CONFIG_HOTPLUG_CPU 49827590dc1SThomas Gleixner int hrtimers_dead_cpu(unsigned int cpu); 49927590dc1SThomas Gleixner #else 50027590dc1SThomas Gleixner #define hrtimers_dead_cpu NULL 50127590dc1SThomas Gleixner #endif 50227590dc1SThomas Gleixner 503c0a31329SThomas Gleixner #endif 504