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>
1650d91c76SKent Overstreet #include <linux/hrtimer_types.h>
17c0a31329SThomas Gleixner #include <linux/init.h>
18c0a31329SThomas Gleixner #include <linux/list.h>
196060ef31SKent Overstreet #include <linux/percpu-defs.h>
2050d91c76SKent Overstreet #include <linux/rbtree.h>
21507e1231SHeiko Carstens #include <linux/timer.h>
22c0a31329SThomas Gleixner
23c0a31329SThomas Gleixner /*
24c0a31329SThomas Gleixner * Mode arguments of xxx_hrtimer functions:
2519b51cb5SAnna-Maria Gleixner *
2619b51cb5SAnna-Maria Gleixner * HRTIMER_MODE_ABS - Time value is absolute
2719b51cb5SAnna-Maria Gleixner * HRTIMER_MODE_REL - Time value is relative to now
2819b51cb5SAnna-Maria Gleixner * HRTIMER_MODE_PINNED - Timer is bound to CPU (is only considered
2919b51cb5SAnna-Maria Gleixner * when starting the timer)
3098ecadd4SAnna-Maria Gleixner * HRTIMER_MODE_SOFT - Timer callback function will be executed in
3198ecadd4SAnna-Maria Gleixner * soft irq context
32a67e4082SSebastian Andrzej Siewior * HRTIMER_MODE_HARD - Timer callback function will be executed in
33a67e4082SSebastian Andrzej Siewior * hard irq context even on PREEMPT_RT.
34c0a31329SThomas Gleixner */
35c0a31329SThomas Gleixner enum hrtimer_mode {
3619b51cb5SAnna-Maria Gleixner HRTIMER_MODE_ABS = 0x00,
3719b51cb5SAnna-Maria Gleixner HRTIMER_MODE_REL = 0x01,
3819b51cb5SAnna-Maria Gleixner HRTIMER_MODE_PINNED = 0x02,
3998ecadd4SAnna-Maria Gleixner HRTIMER_MODE_SOFT = 0x04,
40ae6683d8SSebastian Andrzej Siewior HRTIMER_MODE_HARD = 0x08,
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
51ae6683d8SSebastian Andrzej Siewior HRTIMER_MODE_ABS_HARD = HRTIMER_MODE_ABS | HRTIMER_MODE_HARD,
52ae6683d8SSebastian Andrzej Siewior HRTIMER_MODE_REL_HARD = HRTIMER_MODE_REL | HRTIMER_MODE_HARD,
53ae6683d8SSebastian Andrzej Siewior
54ae6683d8SSebastian Andrzej Siewior HRTIMER_MODE_ABS_PINNED_HARD = HRTIMER_MODE_ABS_PINNED | HRTIMER_MODE_HARD,
55ae6683d8SSebastian Andrzej Siewior HRTIMER_MODE_REL_PINNED_HARD = HRTIMER_MODE_REL_PINNED | HRTIMER_MODE_HARD,
56c0a31329SThomas Gleixner };
57c0a31329SThomas Gleixner
58c9cb2e3dSThomas Gleixner /*
5954cdfdb4SThomas Gleixner * Values to track state of the timer
60303e967fSThomas Gleixner *
61303e967fSThomas Gleixner * Possible states:
62303e967fSThomas Gleixner *
63303e967fSThomas Gleixner * 0x00 inactive
64303e967fSThomas Gleixner * 0x01 enqueued into rbtree
6554cdfdb4SThomas Gleixner *
66887d9dc9SPeter Zijlstra * The callback state is not part of the timer->state because clearing it would
67887d9dc9SPeter Zijlstra * mean touching the timer after the callback, this makes it impossible to free
68887d9dc9SPeter Zijlstra * the timer from the callback function.
6953370d2eSThomas Gleixner *
70887d9dc9SPeter Zijlstra * Therefore we track the callback state in:
71887d9dc9SPeter Zijlstra *
72887d9dc9SPeter Zijlstra * timer->base->cpu_base->running == timer
73887d9dc9SPeter Zijlstra *
74887d9dc9SPeter Zijlstra * On SMP it is possible to have a "callback function running and enqueued"
75887d9dc9SPeter Zijlstra * status. It happens for example when a posix timer expired and the callback
76303e967fSThomas Gleixner * queued a signal. Between dropping the lock which protects the posix timer
77303e967fSThomas Gleixner * and reacquiring the base lock of the hrtimer, another CPU can deliver the
78887d9dc9SPeter Zijlstra * signal and rearm the timer.
79303e967fSThomas Gleixner *
80303e967fSThomas Gleixner * All state transitions are protected by cpu_base->lock.
81303e967fSThomas Gleixner */
82303e967fSThomas Gleixner #define HRTIMER_STATE_INACTIVE 0x00
83303e967fSThomas Gleixner #define HRTIMER_STATE_ENQUEUED 0x01
84303e967fSThomas Gleixner
85c0a31329SThomas Gleixner /**
8600362e33SThomas Gleixner * struct hrtimer_sleeper - simple sleeper structure
8700362e33SThomas Gleixner * @timer: embedded timer structure
8800362e33SThomas Gleixner * @task: task to wake up
8900362e33SThomas Gleixner *
9000362e33SThomas Gleixner * task is set to NULL, when the timer expires.
9100362e33SThomas Gleixner */
9200362e33SThomas Gleixner struct hrtimer_sleeper {
9300362e33SThomas Gleixner struct hrtimer timer;
9400362e33SThomas Gleixner struct task_struct *task;
9500362e33SThomas Gleixner };
9600362e33SThomas Gleixner
hrtimer_set_expires(struct hrtimer * timer,ktime_t time)9763ca243bSArjan van de Ven static inline void hrtimer_set_expires(struct hrtimer *timer, ktime_t time)
9863ca243bSArjan van de Ven {
99998adc3dSJohn Stultz timer->node.expires = time;
100654c8e0bSArjan van de Ven timer->_softexpires = time;
10163ca243bSArjan van de Ven }
102654c8e0bSArjan van de Ven
hrtimer_set_expires_range(struct hrtimer * timer,ktime_t time,ktime_t delta)103654c8e0bSArjan van de Ven static inline void hrtimer_set_expires_range(struct hrtimer *timer, ktime_t time, ktime_t delta)
104654c8e0bSArjan van de Ven {
105654c8e0bSArjan van de Ven timer->_softexpires = time;
106998adc3dSJohn Stultz timer->node.expires = ktime_add_safe(time, delta);
107654c8e0bSArjan van de Ven }
108654c8e0bSArjan van de Ven
hrtimer_set_expires_range_ns(struct hrtimer * timer,ktime_t time,u64 delta)109da8b44d5SJohn Stultz static inline void hrtimer_set_expires_range_ns(struct hrtimer *timer, ktime_t time, u64 delta)
110654c8e0bSArjan van de Ven {
111654c8e0bSArjan van de Ven timer->_softexpires = time;
112998adc3dSJohn Stultz timer->node.expires = ktime_add_safe(time, ns_to_ktime(delta));
113654c8e0bSArjan van de Ven }
114654c8e0bSArjan van de Ven
hrtimer_set_expires_tv64(struct hrtimer * timer,s64 tv64)11563ca243bSArjan van de Ven static inline void hrtimer_set_expires_tv64(struct hrtimer *timer, s64 tv64)
11663ca243bSArjan van de Ven {
1172456e855SThomas Gleixner timer->node.expires = tv64;
1182456e855SThomas Gleixner timer->_softexpires = tv64;
11963ca243bSArjan van de Ven }
12063ca243bSArjan van de Ven
hrtimer_add_expires(struct hrtimer * timer,ktime_t time)12163ca243bSArjan van de Ven static inline void hrtimer_add_expires(struct hrtimer *timer, ktime_t time)
12263ca243bSArjan van de Ven {
123998adc3dSJohn Stultz timer->node.expires = ktime_add_safe(timer->node.expires, time);
124654c8e0bSArjan van de Ven timer->_softexpires = ktime_add_safe(timer->_softexpires, time);
12563ca243bSArjan van de Ven }
12663ca243bSArjan van de Ven
hrtimer_add_expires_ns(struct hrtimer * timer,u64 ns)1277597bc94SDavid Howells static inline void hrtimer_add_expires_ns(struct hrtimer *timer, u64 ns)
12863ca243bSArjan van de Ven {
129998adc3dSJohn Stultz timer->node.expires = ktime_add_ns(timer->node.expires, ns);
130654c8e0bSArjan van de Ven timer->_softexpires = ktime_add_ns(timer->_softexpires, ns);
13163ca243bSArjan van de Ven }
13263ca243bSArjan van de Ven
hrtimer_get_expires(const struct hrtimer * timer)13363ca243bSArjan van de Ven static inline ktime_t hrtimer_get_expires(const struct hrtimer *timer)
13463ca243bSArjan van de Ven {
135998adc3dSJohn Stultz return timer->node.expires;
13663ca243bSArjan van de Ven }
13763ca243bSArjan van de Ven
hrtimer_get_softexpires(const struct hrtimer * timer)138654c8e0bSArjan van de Ven static inline ktime_t hrtimer_get_softexpires(const struct hrtimer *timer)
139654c8e0bSArjan van de Ven {
140654c8e0bSArjan van de Ven return timer->_softexpires;
141654c8e0bSArjan van de Ven }
142654c8e0bSArjan van de Ven
hrtimer_get_expires_tv64(const struct hrtimer * timer)14363ca243bSArjan van de Ven static inline s64 hrtimer_get_expires_tv64(const struct hrtimer *timer)
14463ca243bSArjan van de Ven {
1452456e855SThomas Gleixner return timer->node.expires;
14663ca243bSArjan van de Ven }
hrtimer_get_softexpires_tv64(const struct hrtimer * timer)147654c8e0bSArjan van de Ven static inline s64 hrtimer_get_softexpires_tv64(const struct hrtimer *timer)
148654c8e0bSArjan van de Ven {
1492456e855SThomas Gleixner return timer->_softexpires;
150654c8e0bSArjan van de Ven }
15163ca243bSArjan van de Ven
hrtimer_get_expires_ns(const struct hrtimer * timer)15263ca243bSArjan van de Ven static inline s64 hrtimer_get_expires_ns(const struct hrtimer *timer)
15363ca243bSArjan van de Ven {
154998adc3dSJohn Stultz return ktime_to_ns(timer->node.expires);
15563ca243bSArjan van de Ven }
15663ca243bSArjan van de Ven
hrtimer_expires_remaining(const struct hrtimer * timer)15763ca243bSArjan van de Ven static inline ktime_t hrtimer_expires_remaining(const struct hrtimer *timer)
15863ca243bSArjan van de Ven {
159998adc3dSJohn Stultz return ktime_sub(timer->node.expires, timer->base->get_time());
16063ca243bSArjan van de Ven }
16163ca243bSArjan van de Ven
hrtimer_cb_get_time(struct hrtimer * timer)16254cdfdb4SThomas Gleixner static inline ktime_t hrtimer_cb_get_time(struct hrtimer *timer)
16354cdfdb4SThomas Gleixner {
16454cdfdb4SThomas Gleixner return timer->base->get_time();
16554cdfdb4SThomas Gleixner }
16654cdfdb4SThomas Gleixner
hrtimer_is_hres_active(struct hrtimer * timer)16728bfd18bSAnna-Maria Gleixner static inline int hrtimer_is_hres_active(struct hrtimer *timer)
16828bfd18bSAnna-Maria Gleixner {
16928bfd18bSAnna-Maria Gleixner return IS_ENABLED(CONFIG_HIGH_RES_TIMERS) ?
17028bfd18bSAnna-Maria Gleixner timer->base->cpu_base->hres_active : 0;
17128bfd18bSAnna-Maria Gleixner }
17228bfd18bSAnna-Maria Gleixner
17321d6d52aSThomas Gleixner #ifdef CONFIG_HIGH_RES_TIMERS
17421d6d52aSThomas Gleixner struct clock_event_device;
17521d6d52aSThomas Gleixner
17621d6d52aSThomas Gleixner extern void hrtimer_interrupt(struct clock_event_device *dev);
17721d6d52aSThomas Gleixner
178398ca17fSThomas Gleixner extern unsigned int hrtimer_resolution;
179398ca17fSThomas Gleixner
18054cdfdb4SThomas Gleixner #else
18154cdfdb4SThomas Gleixner
182d711b8b3SBorislav Petkov #define hrtimer_resolution (unsigned int)LOW_RES_NSEC
183398ca17fSThomas Gleixner
18454cdfdb4SThomas Gleixner #endif
18554cdfdb4SThomas Gleixner
186203cbf77SThomas Gleixner static inline ktime_t
__hrtimer_expires_remaining_adjusted(const struct hrtimer * timer,ktime_t now)187203cbf77SThomas Gleixner __hrtimer_expires_remaining_adjusted(const struct hrtimer *timer, ktime_t now)
188203cbf77SThomas Gleixner {
189203cbf77SThomas Gleixner ktime_t rem = ktime_sub(timer->node.expires, now);
190203cbf77SThomas Gleixner
191203cbf77SThomas Gleixner /*
192203cbf77SThomas Gleixner * Adjust relative timers for the extra we added in
193203cbf77SThomas Gleixner * hrtimer_start_range_ns() to prevent short timeouts.
194203cbf77SThomas Gleixner */
195203cbf77SThomas Gleixner if (IS_ENABLED(CONFIG_TIME_LOW_RES) && timer->is_rel)
1962456e855SThomas Gleixner rem -= hrtimer_resolution;
197203cbf77SThomas Gleixner return rem;
198203cbf77SThomas Gleixner }
199203cbf77SThomas Gleixner
200203cbf77SThomas Gleixner static inline ktime_t
hrtimer_expires_remaining_adjusted(const struct hrtimer * timer)201203cbf77SThomas Gleixner hrtimer_expires_remaining_adjusted(const struct hrtimer *timer)
202203cbf77SThomas Gleixner {
203203cbf77SThomas Gleixner return __hrtimer_expires_remaining_adjusted(timer,
204203cbf77SThomas Gleixner timer->base->get_time());
205203cbf77SThomas Gleixner }
206203cbf77SThomas Gleixner
2079ec26907SThomas Gleixner #ifdef CONFIG_TIMERFD
2089ec26907SThomas Gleixner extern void timerfd_clock_was_set(void);
20966f7b0c8SThomas Gleixner extern void timerfd_resume(void);
2109ec26907SThomas Gleixner #else
timerfd_clock_was_set(void)2119ec26907SThomas Gleixner static inline void timerfd_clock_was_set(void) { }
timerfd_resume(void)21266f7b0c8SThomas Gleixner static inline void timerfd_resume(void) { }
2139ec26907SThomas Gleixner #endif
214b12a03ceSThomas Gleixner
2152e94d1f7SArjan van de Ven DECLARE_PER_CPU(struct tick_device, tick_cpu_device);
2162e94d1f7SArjan van de Ven
217f61eff83SAnna-Maria Gleixner #ifdef CONFIG_PREEMPT_RT
218f61eff83SAnna-Maria Gleixner void hrtimer_cancel_wait_running(const struct hrtimer *timer);
219f61eff83SAnna-Maria Gleixner #else
hrtimer_cancel_wait_running(struct hrtimer * timer)220f61eff83SAnna-Maria Gleixner static inline void hrtimer_cancel_wait_running(struct hrtimer *timer)
221f61eff83SAnna-Maria Gleixner {
222f61eff83SAnna-Maria Gleixner cpu_relax();
223f61eff83SAnna-Maria Gleixner }
224f61eff83SAnna-Maria Gleixner #endif
2252e94d1f7SArjan van de Ven
hrtimer_dummy_timeout(struct hrtimer * unused)226806e3224SNam Cao static inline enum hrtimer_restart hrtimer_dummy_timeout(struct hrtimer *unused)
227806e3224SNam Cao {
228806e3224SNam Cao return HRTIMER_NORESTART;
229806e3224SNam Cao }
230806e3224SNam Cao
231c0a31329SThomas Gleixner /* Exported timer functions: */
232c0a31329SThomas Gleixner
233c0a31329SThomas Gleixner /* Initialize timers: */
234908a1d77SNam Cao extern void hrtimer_setup(struct hrtimer *timer, enum hrtimer_restart (*function)(struct hrtimer *),
235908a1d77SNam Cao clockid_t clock_id, enum hrtimer_mode mode);
236444cb7dbSNam Cao extern void hrtimer_setup_on_stack(struct hrtimer *timer,
237444cb7dbSNam Cao enum hrtimer_restart (*function)(struct hrtimer *),
238444cb7dbSNam Cao clockid_t clock_id, enum hrtimer_mode mode);
239c9bd83abSNam Cao extern void hrtimer_setup_sleeper_on_stack(struct hrtimer_sleeper *sl, clockid_t clock_id,
240c9bd83abSNam Cao enum hrtimer_mode mode);
241237fc6e7SThomas Gleixner
242fbf920f2SNam Cao #ifdef CONFIG_DEBUG_OBJECTS_TIMERS
243237fc6e7SThomas Gleixner extern void destroy_hrtimer_on_stack(struct hrtimer *timer);
244237fc6e7SThomas Gleixner #else
destroy_hrtimer_on_stack(struct hrtimer * timer)245237fc6e7SThomas Gleixner static inline void destroy_hrtimer_on_stack(struct hrtimer *timer) { }
246237fc6e7SThomas Gleixner #endif
247237fc6e7SThomas Gleixner
248c0a31329SThomas Gleixner /* Basic timer operations: */
24961699e13SThomas Gleixner extern void hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim,
250da8b44d5SJohn Stultz u64 range_ns, const enum hrtimer_mode mode);
2517f1e2ca9SPeter Zijlstra
25202a171afSThomas Gleixner /**
2536de6250cSAnna-Maria Gleixner * hrtimer_start - (re)start an hrtimer
25402a171afSThomas Gleixner * @timer: the timer to be added
25502a171afSThomas Gleixner * @tim: expiry time
2566de6250cSAnna-Maria Gleixner * @mode: timer mode: absolute (HRTIMER_MODE_ABS) or
2575da70160SAnna-Maria Gleixner * relative (HRTIMER_MODE_REL), and pinned (HRTIMER_MODE_PINNED);
2585da70160SAnna-Maria Gleixner * softirq based mode is considered for debug purpose only!
25902a171afSThomas Gleixner */
hrtimer_start(struct hrtimer * timer,ktime_t tim,const enum hrtimer_mode mode)26061699e13SThomas Gleixner static inline void hrtimer_start(struct hrtimer *timer, ktime_t tim,
26102a171afSThomas Gleixner const enum hrtimer_mode mode)
26202a171afSThomas Gleixner {
26361699e13SThomas Gleixner hrtimer_start_range_ns(timer, tim, 0, mode);
26402a171afSThomas Gleixner }
26502a171afSThomas Gleixner
266c0a31329SThomas Gleixner extern int hrtimer_cancel(struct hrtimer *timer);
267c0a31329SThomas Gleixner extern int hrtimer_try_to_cancel(struct hrtimer *timer);
268c0a31329SThomas Gleixner
hrtimer_start_expires(struct hrtimer * timer,enum hrtimer_mode mode)26961699e13SThomas Gleixner static inline void hrtimer_start_expires(struct hrtimer *timer,
27063ca243bSArjan van de Ven enum hrtimer_mode mode)
27163ca243bSArjan van de Ven {
272da8b44d5SJohn Stultz u64 delta;
273da8f2e17SArjan van de Ven ktime_t soft, hard;
274da8f2e17SArjan van de Ven soft = hrtimer_get_softexpires(timer);
275da8f2e17SArjan van de Ven hard = hrtimer_get_expires(timer);
276da8f2e17SArjan van de Ven delta = ktime_to_ns(ktime_sub(hard, soft));
27761699e13SThomas Gleixner hrtimer_start_range_ns(timer, soft, delta, mode);
27863ca243bSArjan van de Ven }
27963ca243bSArjan van de Ven
28001656464SThomas Gleixner void hrtimer_sleeper_start_expires(struct hrtimer_sleeper *sl,
28101656464SThomas Gleixner enum hrtimer_mode mode);
28201656464SThomas Gleixner
hrtimer_restart(struct hrtimer * timer)28361699e13SThomas Gleixner static inline void hrtimer_restart(struct hrtimer *timer)
284c9cb2e3dSThomas Gleixner {
28561699e13SThomas Gleixner hrtimer_start_expires(timer, HRTIMER_MODE_ABS);
286c9cb2e3dSThomas Gleixner }
287c0a31329SThomas Gleixner
288c0a31329SThomas Gleixner /* Query timers: */
289203cbf77SThomas Gleixner extern ktime_t __hrtimer_get_remaining(const struct hrtimer *timer, bool adjust);
290203cbf77SThomas Gleixner
29166981c37SMauro Carvalho Chehab /**
29266981c37SMauro Carvalho Chehab * hrtimer_get_remaining - get remaining time for the timer
29366981c37SMauro Carvalho Chehab * @timer: the timer to read
29466981c37SMauro Carvalho Chehab */
hrtimer_get_remaining(const struct hrtimer * timer)295203cbf77SThomas Gleixner static inline ktime_t hrtimer_get_remaining(const struct hrtimer *timer)
296203cbf77SThomas Gleixner {
297203cbf77SThomas Gleixner return __hrtimer_get_remaining(timer, false);
298203cbf77SThomas Gleixner }
299c0a31329SThomas Gleixner
300c1ad348bSThomas Gleixner extern u64 hrtimer_get_next_event(void);
301a59855cdSRafael J. Wysocki extern u64 hrtimer_next_event_without(const struct hrtimer *exclude);
30269239749STony Lindgren
303887d9dc9SPeter Zijlstra extern bool hrtimer_active(const struct hrtimer *timer);
304c0a31329SThomas Gleixner
30556144737SEric Dumazet /**
30666981c37SMauro Carvalho Chehab * hrtimer_is_queued - check, whether the timer is on one of the queues
30756144737SEric Dumazet * @timer: Timer to check
30856144737SEric Dumazet *
30956144737SEric Dumazet * Returns: True if the timer is queued, false otherwise
31056144737SEric Dumazet *
31156144737SEric Dumazet * The function can be used lockless, but it gives only a current snapshot.
31254cdfdb4SThomas Gleixner */
hrtimer_is_queued(struct hrtimer * timer)31356144737SEric Dumazet static inline bool hrtimer_is_queued(struct hrtimer *timer)
31454cdfdb4SThomas Gleixner {
31556144737SEric Dumazet /* The READ_ONCE pairs with the update functions of timer->state */
31656144737SEric Dumazet return !!(READ_ONCE(timer->state) & HRTIMER_STATE_ENQUEUED);
31754cdfdb4SThomas Gleixner }
31854cdfdb4SThomas Gleixner
3194346f654SOliver Hartkopp /*
3204346f654SOliver Hartkopp * Helper function to check, whether the timer is running the callback
3214346f654SOliver Hartkopp * function
3224346f654SOliver Hartkopp */
hrtimer_callback_running(struct hrtimer * timer)3234346f654SOliver Hartkopp static inline int hrtimer_callback_running(struct hrtimer *timer)
3244346f654SOliver Hartkopp {
3253f0b9e8eSAnna-Maria Gleixner return timer->base->running == timer;
3264346f654SOliver Hartkopp }
3274346f654SOliver Hartkopp
3288f02e356SNam Cao /**
3298f02e356SNam Cao * hrtimer_update_function - Update the timer's callback function
3308f02e356SNam Cao * @timer: Timer to update
3318f02e356SNam Cao * @function: New callback function
3328f02e356SNam Cao *
3338f02e356SNam Cao * Only safe to call if the timer is not enqueued. Can be called in the callback function if the
3348f02e356SNam Cao * timer is not enqueued at the same time (see the comments above HRTIMER_STATE_ENQUEUED).
3358f02e356SNam Cao */
hrtimer_update_function(struct hrtimer * timer,enum hrtimer_restart (* function)(struct hrtimer *))3368f02e356SNam Cao static inline void hrtimer_update_function(struct hrtimer *timer,
3378f02e356SNam Cao enum hrtimer_restart (*function)(struct hrtimer *))
3388f02e356SNam Cao {
3392ea97b76SThomas Gleixner #ifdef CONFIG_PROVE_LOCKING
3408f02e356SNam Cao guard(raw_spinlock_irqsave)(&timer->base->cpu_base->lock);
3418f02e356SNam Cao
3428f02e356SNam Cao if (WARN_ON_ONCE(hrtimer_is_queued(timer)))
3438f02e356SNam Cao return;
3448f02e356SNam Cao
3458f02e356SNam Cao if (WARN_ON_ONCE(!function))
3468f02e356SNam Cao return;
3472ea97b76SThomas Gleixner #endif
348*2424e146SNam Cao ACCESS_PRIVATE(timer, function) = function;
3498f02e356SNam Cao }
3508f02e356SNam Cao
351c0a31329SThomas Gleixner /* Forward a hrtimer so it expires after now: */
3524d672e7aSDavide Libenzi extern u64
35344f21475SRoman Zippel hrtimer_forward(struct hrtimer *timer, ktime_t now, ktime_t interval);
354c0a31329SThomas Gleixner
35591e5a217SThomas Gleixner /**
356ca2768bbSAnna-Maria Behnsen * hrtimer_forward_now() - forward the timer expiry so it expires after now
35791e5a217SThomas Gleixner * @timer: hrtimer to forward
35891e5a217SThomas Gleixner * @interval: the interval to forward
35991e5a217SThomas Gleixner *
360ca2768bbSAnna-Maria Behnsen * It is a variant of hrtimer_forward(). The timer will expire after the current
361ca2768bbSAnna-Maria Behnsen * time of the hrtimer clock base. See hrtimer_forward() for details.
36291e5a217SThomas Gleixner */
hrtimer_forward_now(struct hrtimer * timer,ktime_t interval)3634d672e7aSDavide Libenzi static inline u64 hrtimer_forward_now(struct hrtimer *timer,
3645e05ad7dSDavide Libenzi ktime_t interval)
3655e05ad7dSDavide Libenzi {
3665e05ad7dSDavide Libenzi return hrtimer_forward(timer, timer->base->get_time(), interval);
3675e05ad7dSDavide Libenzi }
3685e05ad7dSDavide Libenzi
36910c94ec1SThomas Gleixner /* Precise sleep: */
370ce41aaf4SAl Viro
371c0edd7c9SDeepa Dinamani extern int nanosleep_copyout(struct restart_block *, struct timespec64 *);
372ea2d1f7fSAndrei Vagin extern long hrtimer_nanosleep(ktime_t rqtp, const enum hrtimer_mode mode,
37310c94ec1SThomas Gleixner const clockid_t clockid);
37410c94ec1SThomas Gleixner
375da8b44d5SJohn Stultz extern int schedule_hrtimeout_range(ktime_t *expires, u64 delta,
376654c8e0bSArjan van de Ven const enum hrtimer_mode mode);
377351b3f7aSCarsten Emde extern int schedule_hrtimeout_range_clock(ktime_t *expires,
378da8b44d5SJohn Stultz u64 delta,
379da8b44d5SJohn Stultz const enum hrtimer_mode mode,
38090777713SAnna-Maria Gleixner clockid_t clock_id);
3817bb67439SArjan van de Ven extern int schedule_hrtimeout(ktime_t *expires, const enum hrtimer_mode mode);
3827bb67439SArjan van de Ven
383c0a31329SThomas Gleixner /* Soft interrupt function to run the hrtimer queues: */
384c0a31329SThomas Gleixner extern void hrtimer_run_queues(void);
385c0a31329SThomas Gleixner
386c0a31329SThomas Gleixner /* Bootup initialization: */
387c0a31329SThomas Gleixner extern void __init hrtimers_init(void);
388c0a31329SThomas Gleixner
38988ad0bf6SIngo Molnar /* Show pending timers: */
39088ad0bf6SIngo Molnar extern void sysrq_timer_list_show(void);
39188ad0bf6SIngo Molnar
39227590dc1SThomas Gleixner int hrtimers_prepare_cpu(unsigned int cpu);
3932f8dea16SKoichiro Den int hrtimers_cpu_starting(unsigned int cpu);
39427590dc1SThomas Gleixner #ifdef CONFIG_HOTPLUG_CPU
3955c0930ccSThomas Gleixner int hrtimers_cpu_dying(unsigned int cpu);
39627590dc1SThomas Gleixner #else
3975c0930ccSThomas Gleixner #define hrtimers_cpu_dying NULL
39827590dc1SThomas Gleixner #endif
39927590dc1SThomas Gleixner
400c0a31329SThomas Gleixner #endif
401