xref: /linux-6.15/include/linux/hrtimer.h (revision dbc1625f)
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