1
2
3
4
5
6
7
8
9
10
11
12
13
14
15#ifndef _LINUX_HRTIMER_H
16#define _LINUX_HRTIMER_H
17
18#include <linux/rbtree.h>
19#include <linux/ktime.h>
20#include <linux/init.h>
21#include <linux/list.h>
22#include <linux/percpu.h>
23#include <linux/timer.h>
24#include <linux/timerqueue.h>
25
26struct hrtimer_clock_base;
27struct hrtimer_cpu_base;
28
29
30
31
32
33
34
35
36
37
38
39enum hrtimer_mode {
40 HRTIMER_MODE_ABS = 0x00,
41 HRTIMER_MODE_REL = 0x01,
42 HRTIMER_MODE_PINNED = 0x02,
43 HRTIMER_MODE_SOFT = 0x04,
44
45 HRTIMER_MODE_ABS_PINNED = HRTIMER_MODE_ABS | HRTIMER_MODE_PINNED,
46 HRTIMER_MODE_REL_PINNED = HRTIMER_MODE_REL | HRTIMER_MODE_PINNED,
47
48 HRTIMER_MODE_ABS_SOFT = HRTIMER_MODE_ABS | HRTIMER_MODE_SOFT,
49 HRTIMER_MODE_REL_SOFT = HRTIMER_MODE_REL | HRTIMER_MODE_SOFT,
50
51 HRTIMER_MODE_ABS_PINNED_SOFT = HRTIMER_MODE_ABS_PINNED | HRTIMER_MODE_SOFT,
52 HRTIMER_MODE_REL_PINNED_SOFT = HRTIMER_MODE_REL_PINNED | HRTIMER_MODE_SOFT,
53
54};
55
56
57
58
59enum hrtimer_restart {
60 HRTIMER_NORESTART,
61 HRTIMER_RESTART,
62};
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88#define HRTIMER_STATE_INACTIVE 0x00
89#define HRTIMER_STATE_ENQUEUED 0x01
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110struct hrtimer {
111 struct timerqueue_node node;
112 ktime_t _softexpires;
113 enum hrtimer_restart (*function)(struct hrtimer *);
114 struct hrtimer_clock_base *base;
115 u8 state;
116 u8 is_rel;
117 u8 is_soft;
118};
119
120
121
122
123
124
125
126
127struct hrtimer_sleeper {
128 struct hrtimer timer;
129 struct task_struct *task;
130};
131
132#ifdef CONFIG_64BIT
133# define __hrtimer_clock_base_align ____cacheline_aligned
134#else
135# define __hrtimer_clock_base_align
136#endif
137
138
139
140
141
142
143
144
145
146
147
148
149
150struct hrtimer_clock_base {
151 struct hrtimer_cpu_base *cpu_base;
152 unsigned int index;
153 clockid_t clockid;
154 seqcount_t seq;
155 struct hrtimer *running;
156 struct timerqueue_head active;
157 ktime_t (*get_time)(void);
158 ktime_t offset;
159} __hrtimer_clock_base_align;
160
161enum hrtimer_base_type {
162 HRTIMER_BASE_MONOTONIC,
163 HRTIMER_BASE_REALTIME,
164 HRTIMER_BASE_BOOTTIME,
165 HRTIMER_BASE_TAI,
166 HRTIMER_BASE_MONOTONIC_SOFT,
167 HRTIMER_BASE_REALTIME_SOFT,
168 HRTIMER_BASE_BOOTTIME_SOFT,
169 HRTIMER_BASE_TAI_SOFT,
170 HRTIMER_MAX_CLOCK_BASES,
171};
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201struct hrtimer_cpu_base {
202 raw_spinlock_t lock;
203 unsigned int cpu;
204 unsigned int active_bases;
205 unsigned int clock_was_set_seq;
206 unsigned int hres_active : 1,
207 in_hrtirq : 1,
208 hang_detected : 1,
209 softirq_activated : 1;
210#ifdef CONFIG_HIGH_RES_TIMERS
211 unsigned int nr_events;
212 unsigned short nr_retries;
213 unsigned short nr_hangs;
214 unsigned int max_hang_time;
215#endif
216 ktime_t expires_next;
217 struct hrtimer *next_timer;
218 ktime_t softirq_expires_next;
219 struct hrtimer *softirq_next_timer;
220 struct hrtimer_clock_base clock_base[HRTIMER_MAX_CLOCK_BASES];
221} ____cacheline_aligned;
222
223static inline void hrtimer_set_expires(struct hrtimer *timer, ktime_t time)
224{
225 timer->node.expires = time;
226 timer->_softexpires = time;
227}
228
229static inline void hrtimer_set_expires_range(struct hrtimer *timer, ktime_t time, ktime_t delta)
230{
231 timer->_softexpires = time;
232 timer->node.expires = ktime_add_safe(time, delta);
233}
234
235static inline void hrtimer_set_expires_range_ns(struct hrtimer *timer, ktime_t time, u64 delta)
236{
237 timer->_softexpires = time;
238 timer->node.expires = ktime_add_safe(time, ns_to_ktime(delta));
239}
240
241static inline void hrtimer_set_expires_tv64(struct hrtimer *timer, s64 tv64)
242{
243 timer->node.expires = tv64;
244 timer->_softexpires = tv64;
245}
246
247static inline void hrtimer_add_expires(struct hrtimer *timer, ktime_t time)
248{
249 timer->node.expires = ktime_add_safe(timer->node.expires, time);
250 timer->_softexpires = ktime_add_safe(timer->_softexpires, time);
251}
252
253static inline void hrtimer_add_expires_ns(struct hrtimer *timer, u64 ns)
254{
255 timer->node.expires = ktime_add_ns(timer->node.expires, ns);
256 timer->_softexpires = ktime_add_ns(timer->_softexpires, ns);
257}
258
259static inline ktime_t hrtimer_get_expires(const struct hrtimer *timer)
260{
261 return timer->node.expires;
262}
263
264static inline ktime_t hrtimer_get_softexpires(const struct hrtimer *timer)
265{
266 return timer->_softexpires;
267}
268
269static inline s64 hrtimer_get_expires_tv64(const struct hrtimer *timer)
270{
271 return timer->node.expires;
272}
273static inline s64 hrtimer_get_softexpires_tv64(const struct hrtimer *timer)
274{
275 return timer->_softexpires;
276}
277
278static inline s64 hrtimer_get_expires_ns(const struct hrtimer *timer)
279{
280 return ktime_to_ns(timer->node.expires);
281}
282
283static inline ktime_t hrtimer_expires_remaining(const struct hrtimer *timer)
284{
285 return ktime_sub(timer->node.expires, timer->base->get_time());
286}
287
288static inline ktime_t hrtimer_cb_get_time(struct hrtimer *timer)
289{
290 return timer->base->get_time();
291}
292
293static inline int hrtimer_is_hres_active(struct hrtimer *timer)
294{
295 return IS_ENABLED(CONFIG_HIGH_RES_TIMERS) ?
296 timer->base->cpu_base->hres_active : 0;
297}
298
299#ifdef CONFIG_HIGH_RES_TIMERS
300struct clock_event_device;
301
302extern void hrtimer_interrupt(struct clock_event_device *dev);
303
304
305
306
307
308
309
310# define HIGH_RES_NSEC 1
311# define KTIME_HIGH_RES (HIGH_RES_NSEC)
312# define MONOTONIC_RES_NSEC HIGH_RES_NSEC
313# define KTIME_MONOTONIC_RES KTIME_HIGH_RES
314
315extern void clock_was_set_delayed(void);
316
317extern unsigned int hrtimer_resolution;
318
319#else
320
321# define MONOTONIC_RES_NSEC LOW_RES_NSEC
322# define KTIME_MONOTONIC_RES KTIME_LOW_RES
323
324#define hrtimer_resolution (unsigned int)LOW_RES_NSEC
325
326static inline void clock_was_set_delayed(void) { }
327
328#endif
329
330static inline ktime_t
331__hrtimer_expires_remaining_adjusted(const struct hrtimer *timer, ktime_t now)
332{
333 ktime_t rem = ktime_sub(timer->node.expires, now);
334
335
336
337
338
339 if (IS_ENABLED(CONFIG_TIME_LOW_RES) && timer->is_rel)
340 rem -= hrtimer_resolution;
341 return rem;
342}
343
344static inline ktime_t
345hrtimer_expires_remaining_adjusted(const struct hrtimer *timer)
346{
347 return __hrtimer_expires_remaining_adjusted(timer,
348 timer->base->get_time());
349}
350
351extern void clock_was_set(void);
352#ifdef CONFIG_TIMERFD
353extern void timerfd_clock_was_set(void);
354#else
355static inline void timerfd_clock_was_set(void) { }
356#endif
357extern void hrtimers_resume(void);
358
359DECLARE_PER_CPU(struct tick_device, tick_cpu_device);
360
361
362
363
364
365extern void hrtimer_init(struct hrtimer *timer, clockid_t which_clock,
366 enum hrtimer_mode mode);
367
368#ifdef CONFIG_DEBUG_OBJECTS_TIMERS
369extern void hrtimer_init_on_stack(struct hrtimer *timer, clockid_t which_clock,
370 enum hrtimer_mode mode);
371
372extern void destroy_hrtimer_on_stack(struct hrtimer *timer);
373#else
374static inline void hrtimer_init_on_stack(struct hrtimer *timer,
375 clockid_t which_clock,
376 enum hrtimer_mode mode)
377{
378 hrtimer_init(timer, which_clock, mode);
379}
380static inline void destroy_hrtimer_on_stack(struct hrtimer *timer) { }
381#endif
382
383
384extern void hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim,
385 u64 range_ns, const enum hrtimer_mode mode);
386
387
388
389
390
391
392
393
394
395static inline void hrtimer_start(struct hrtimer *timer, ktime_t tim,
396 const enum hrtimer_mode mode)
397{
398 hrtimer_start_range_ns(timer, tim, 0, mode);
399}
400
401extern int hrtimer_cancel(struct hrtimer *timer);
402extern int hrtimer_try_to_cancel(struct hrtimer *timer);
403
404static inline void hrtimer_start_expires(struct hrtimer *timer,
405 enum hrtimer_mode mode)
406{
407 u64 delta;
408 ktime_t soft, hard;
409 soft = hrtimer_get_softexpires(timer);
410 hard = hrtimer_get_expires(timer);
411 delta = ktime_to_ns(ktime_sub(hard, soft));
412 hrtimer_start_range_ns(timer, soft, delta, mode);
413}
414
415static inline void hrtimer_restart(struct hrtimer *timer)
416{
417 hrtimer_start_expires(timer, HRTIMER_MODE_ABS);
418}
419
420
421extern ktime_t __hrtimer_get_remaining(const struct hrtimer *timer, bool adjust);
422
423static inline ktime_t hrtimer_get_remaining(const struct hrtimer *timer)
424{
425 return __hrtimer_get_remaining(timer, false);
426}
427
428extern u64 hrtimer_get_next_event(void);
429
430extern bool hrtimer_active(const struct hrtimer *timer);
431
432
433
434
435static inline int hrtimer_is_queued(struct hrtimer *timer)
436{
437 return timer->state & HRTIMER_STATE_ENQUEUED;
438}
439
440
441
442
443
444static inline int hrtimer_callback_running(struct hrtimer *timer)
445{
446 return timer->base->running == timer;
447}
448
449
450extern u64
451hrtimer_forward(struct hrtimer *timer, ktime_t now, ktime_t interval);
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469static inline u64 hrtimer_forward_now(struct hrtimer *timer,
470 ktime_t interval)
471{
472 return hrtimer_forward(timer, timer->base->get_time(), interval);
473}
474
475
476
477extern int nanosleep_copyout(struct restart_block *, struct timespec64 *);
478extern long hrtimer_nanosleep(const struct timespec64 *rqtp,
479 const enum hrtimer_mode mode,
480 const clockid_t clockid);
481
482extern void hrtimer_init_sleeper(struct hrtimer_sleeper *sl,
483 struct task_struct *tsk);
484
485extern int schedule_hrtimeout_range(ktime_t *expires, u64 delta,
486 const enum hrtimer_mode mode);
487extern int schedule_hrtimeout_range_clock(ktime_t *expires,
488 u64 delta,
489 const enum hrtimer_mode mode,
490 clockid_t clock_id);
491extern int schedule_hrtimeout(ktime_t *expires, const enum hrtimer_mode mode);
492
493
494extern void hrtimer_run_queues(void);
495
496
497extern void __init hrtimers_init(void);
498
499
500extern void sysrq_timer_list_show(void);
501
502int hrtimers_prepare_cpu(unsigned int cpu);
503#ifdef CONFIG_HOTPLUG_CPU
504int hrtimers_dead_cpu(unsigned int cpu);
505#else
506#define hrtimers_dead_cpu NULL
507#endif
508
509#endif
510