.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0 |
---|
1 | 2 | /* |
---|
2 | | - * include/linux/hrtimer.h |
---|
3 | | - * |
---|
4 | 3 | * hrtimers - High-resolution kernel timers |
---|
5 | 4 | * |
---|
6 | 5 | * Copyright(C) 2005, Thomas Gleixner <tglx@linutronix.de> |
---|
.. | .. |
---|
9 | 8 | * data type definitions, declarations, prototypes |
---|
10 | 9 | * |
---|
11 | 10 | * Started by: Thomas Gleixner and Ingo Molnar |
---|
12 | | - * |
---|
13 | | - * For licencing details see kernel-base/COPYING |
---|
14 | 11 | */ |
---|
15 | 12 | #ifndef _LINUX_HRTIMER_H |
---|
16 | 13 | #define _LINUX_HRTIMER_H |
---|
.. | .. |
---|
20 | 17 | #include <linux/init.h> |
---|
21 | 18 | #include <linux/list.h> |
---|
22 | 19 | #include <linux/percpu.h> |
---|
| 20 | +#include <linux/seqlock.h> |
---|
23 | 21 | #include <linux/timer.h> |
---|
24 | 22 | #include <linux/timerqueue.h> |
---|
25 | 23 | #include <linux/android_kabi.h> |
---|
.. | .. |
---|
36 | 34 | * when starting the timer) |
---|
37 | 35 | * HRTIMER_MODE_SOFT - Timer callback function will be executed in |
---|
38 | 36 | * soft irq context |
---|
| 37 | + * HRTIMER_MODE_HARD - Timer callback function will be executed in |
---|
| 38 | + * hard irq context even on PREEMPT_RT. |
---|
39 | 39 | */ |
---|
40 | 40 | enum hrtimer_mode { |
---|
41 | 41 | HRTIMER_MODE_ABS = 0x00, |
---|
42 | 42 | HRTIMER_MODE_REL = 0x01, |
---|
43 | 43 | HRTIMER_MODE_PINNED = 0x02, |
---|
44 | 44 | HRTIMER_MODE_SOFT = 0x04, |
---|
| 45 | + HRTIMER_MODE_HARD = 0x08, |
---|
45 | 46 | |
---|
46 | 47 | HRTIMER_MODE_ABS_PINNED = HRTIMER_MODE_ABS | HRTIMER_MODE_PINNED, |
---|
47 | 48 | HRTIMER_MODE_REL_PINNED = HRTIMER_MODE_REL | HRTIMER_MODE_PINNED, |
---|
.. | .. |
---|
52 | 53 | HRTIMER_MODE_ABS_PINNED_SOFT = HRTIMER_MODE_ABS_PINNED | HRTIMER_MODE_SOFT, |
---|
53 | 54 | HRTIMER_MODE_REL_PINNED_SOFT = HRTIMER_MODE_REL_PINNED | HRTIMER_MODE_SOFT, |
---|
54 | 55 | |
---|
| 56 | + HRTIMER_MODE_ABS_HARD = HRTIMER_MODE_ABS | HRTIMER_MODE_HARD, |
---|
| 57 | + HRTIMER_MODE_REL_HARD = HRTIMER_MODE_REL | HRTIMER_MODE_HARD, |
---|
| 58 | + |
---|
| 59 | + HRTIMER_MODE_ABS_PINNED_HARD = HRTIMER_MODE_ABS_PINNED | HRTIMER_MODE_HARD, |
---|
| 60 | + HRTIMER_MODE_REL_PINNED_HARD = HRTIMER_MODE_REL_PINNED | HRTIMER_MODE_HARD, |
---|
55 | 61 | }; |
---|
56 | 62 | |
---|
57 | 63 | /* |
---|
.. | .. |
---|
105 | 111 | * @state: state information (See bit values above) |
---|
106 | 112 | * @is_rel: Set if the timer was armed relative |
---|
107 | 113 | * @is_soft: Set if hrtimer will be expired in soft interrupt context. |
---|
| 114 | + * @is_hard: Set if hrtimer will be expired in hard interrupt context |
---|
| 115 | + * even on RT. |
---|
108 | 116 | * |
---|
109 | 117 | * The hrtimer structure must be initialized by hrtimer_init() |
---|
110 | 118 | */ |
---|
.. | .. |
---|
116 | 124 | u8 state; |
---|
117 | 125 | u8 is_rel; |
---|
118 | 126 | u8 is_soft; |
---|
| 127 | + u8 is_hard; |
---|
119 | 128 | |
---|
120 | 129 | ANDROID_KABI_RESERVE(1); |
---|
121 | 130 | }; |
---|
.. | .. |
---|
154 | 163 | struct hrtimer_cpu_base *cpu_base; |
---|
155 | 164 | unsigned int index; |
---|
156 | 165 | clockid_t clockid; |
---|
157 | | - seqcount_t seq; |
---|
| 166 | + seqcount_raw_spinlock_t seq; |
---|
158 | 167 | struct hrtimer *running; |
---|
159 | 168 | struct timerqueue_head active; |
---|
160 | 169 | ktime_t (*get_time)(void); |
---|
.. | .. |
---|
189 | 198 | * @nr_retries: Total number of hrtimer interrupt retries |
---|
190 | 199 | * @nr_hangs: Total number of hrtimer interrupt hangs |
---|
191 | 200 | * @max_hang_time: Maximum time spent in hrtimer_interrupt |
---|
| 201 | + * @softirq_expiry_lock: Lock which is taken while softirq based hrtimer are |
---|
| 202 | + * expired |
---|
| 203 | + * @timer_waiters: A hrtimer_cancel() invocation waits for the timer |
---|
| 204 | + * callback to finish. |
---|
192 | 205 | * @expires_next: absolute time of the next event, is required for remote |
---|
193 | 206 | * hrtimer enqueue; it is the total first expiry time (hard |
---|
194 | 207 | * and soft hrtimer are taken into account) |
---|
.. | .. |
---|
215 | 228 | unsigned short nr_retries; |
---|
216 | 229 | unsigned short nr_hangs; |
---|
217 | 230 | unsigned int max_hang_time; |
---|
| 231 | +#endif |
---|
| 232 | +#ifdef CONFIG_PREEMPT_RT |
---|
| 233 | + spinlock_t softirq_expiry_lock; |
---|
| 234 | + atomic_t timer_waiters; |
---|
218 | 235 | #endif |
---|
219 | 236 | ktime_t expires_next; |
---|
220 | 237 | struct hrtimer *next_timer; |
---|
.. | .. |
---|
304 | 321 | |
---|
305 | 322 | extern void hrtimer_interrupt(struct clock_event_device *dev); |
---|
306 | 323 | |
---|
307 | | -extern void clock_was_set_delayed(void); |
---|
308 | | - |
---|
309 | 324 | extern unsigned int hrtimer_resolution; |
---|
310 | 325 | |
---|
311 | 326 | #else |
---|
312 | 327 | |
---|
313 | 328 | #define hrtimer_resolution (unsigned int)LOW_RES_NSEC |
---|
314 | | - |
---|
315 | | -static inline void clock_was_set_delayed(void) { } |
---|
316 | 329 | |
---|
317 | 330 | #endif |
---|
318 | 331 | |
---|
.. | .. |
---|
337 | 350 | timer->base->get_time()); |
---|
338 | 351 | } |
---|
339 | 352 | |
---|
340 | | -extern void clock_was_set(void); |
---|
341 | 353 | #ifdef CONFIG_TIMERFD |
---|
342 | 354 | extern void timerfd_clock_was_set(void); |
---|
343 | 355 | #else |
---|
.. | .. |
---|
347 | 359 | |
---|
348 | 360 | DECLARE_PER_CPU(struct tick_device, tick_cpu_device); |
---|
349 | 361 | |
---|
| 362 | +#ifdef CONFIG_PREEMPT_RT |
---|
| 363 | +void hrtimer_cancel_wait_running(const struct hrtimer *timer); |
---|
| 364 | +#else |
---|
| 365 | +static inline void hrtimer_cancel_wait_running(struct hrtimer *timer) |
---|
| 366 | +{ |
---|
| 367 | + cpu_relax(); |
---|
| 368 | +} |
---|
| 369 | +#endif |
---|
350 | 370 | |
---|
351 | 371 | /* Exported timer functions: */ |
---|
352 | 372 | |
---|
353 | 373 | /* Initialize timers: */ |
---|
354 | 374 | extern void hrtimer_init(struct hrtimer *timer, clockid_t which_clock, |
---|
355 | 375 | enum hrtimer_mode mode); |
---|
| 376 | +extern void hrtimer_init_sleeper(struct hrtimer_sleeper *sl, clockid_t clock_id, |
---|
| 377 | + enum hrtimer_mode mode); |
---|
356 | 378 | |
---|
357 | 379 | #ifdef CONFIG_DEBUG_OBJECTS_TIMERS |
---|
358 | 380 | extern void hrtimer_init_on_stack(struct hrtimer *timer, clockid_t which_clock, |
---|
359 | 381 | enum hrtimer_mode mode); |
---|
| 382 | +extern void hrtimer_init_sleeper_on_stack(struct hrtimer_sleeper *sl, |
---|
| 383 | + clockid_t clock_id, |
---|
| 384 | + enum hrtimer_mode mode); |
---|
360 | 385 | |
---|
361 | 386 | extern void destroy_hrtimer_on_stack(struct hrtimer *timer); |
---|
362 | 387 | #else |
---|
.. | .. |
---|
366 | 391 | { |
---|
367 | 392 | hrtimer_init(timer, which_clock, mode); |
---|
368 | 393 | } |
---|
| 394 | + |
---|
| 395 | +static inline void hrtimer_init_sleeper_on_stack(struct hrtimer_sleeper *sl, |
---|
| 396 | + clockid_t clock_id, |
---|
| 397 | + enum hrtimer_mode mode) |
---|
| 398 | +{ |
---|
| 399 | + hrtimer_init_sleeper(sl, clock_id, mode); |
---|
| 400 | +} |
---|
| 401 | + |
---|
369 | 402 | static inline void destroy_hrtimer_on_stack(struct hrtimer *timer) { } |
---|
370 | 403 | #endif |
---|
371 | 404 | |
---|
.. | .. |
---|
400 | 433 | delta = ktime_to_ns(ktime_sub(hard, soft)); |
---|
401 | 434 | hrtimer_start_range_ns(timer, soft, delta, mode); |
---|
402 | 435 | } |
---|
| 436 | + |
---|
| 437 | +void hrtimer_sleeper_start_expires(struct hrtimer_sleeper *sl, |
---|
| 438 | + enum hrtimer_mode mode); |
---|
403 | 439 | |
---|
404 | 440 | static inline void hrtimer_restart(struct hrtimer *timer) |
---|
405 | 441 | { |
---|
.. | .. |
---|
471 | 507 | /* Precise sleep: */ |
---|
472 | 508 | |
---|
473 | 509 | extern int nanosleep_copyout(struct restart_block *, struct timespec64 *); |
---|
474 | | -extern long hrtimer_nanosleep(const struct timespec64 *rqtp, |
---|
475 | | - const enum hrtimer_mode mode, |
---|
| 510 | +extern long hrtimer_nanosleep(ktime_t rqtp, const enum hrtimer_mode mode, |
---|
476 | 511 | const clockid_t clockid); |
---|
477 | 512 | |
---|
478 | | -extern void hrtimer_init_sleeper(struct hrtimer_sleeper *sl, |
---|
479 | | - struct task_struct *tsk); |
---|
480 | | - |
---|
481 | 513 | extern int schedule_hrtimeout_range(ktime_t *expires, u64 delta, |
---|
482 | | - const enum hrtimer_mode mode); |
---|
| 514 | + const enum hrtimer_mode mode); |
---|
483 | 515 | extern int schedule_hrtimeout_range_clock(ktime_t *expires, |
---|
484 | 516 | u64 delta, |
---|
485 | 517 | const enum hrtimer_mode mode, |
---|