.. | .. |
---|
| 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, |
---|
.. | .. |
---|
111 | 111 | * @state: state information (See bit values above) |
---|
112 | 112 | * @is_rel: Set if the timer was armed relative |
---|
113 | 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. |
---|
114 | 116 | * |
---|
115 | 117 | * The hrtimer structure must be initialized by hrtimer_init() |
---|
116 | 118 | */ |
---|
.. | .. |
---|
122 | 124 | u8 state; |
---|
123 | 125 | u8 is_rel; |
---|
124 | 126 | u8 is_soft; |
---|
| 127 | + u8 is_hard; |
---|
125 | 128 | |
---|
126 | 129 | ANDROID_KABI_RESERVE(1); |
---|
127 | 130 | }; |
---|
.. | .. |
---|
160 | 163 | struct hrtimer_cpu_base *cpu_base; |
---|
161 | 164 | unsigned int index; |
---|
162 | 165 | clockid_t clockid; |
---|
163 | | - seqcount_t seq; |
---|
| 166 | + seqcount_raw_spinlock_t seq; |
---|
164 | 167 | struct hrtimer *running; |
---|
165 | 168 | struct timerqueue_head active; |
---|
166 | 169 | ktime_t (*get_time)(void); |
---|
.. | .. |
---|
197 | 200 | * @max_hang_time: Maximum time spent in hrtimer_interrupt |
---|
198 | 201 | * @softirq_expiry_lock: Lock which is taken while softirq based hrtimer are |
---|
199 | 202 | * expired |
---|
| 203 | + * @timer_waiters: A hrtimer_cancel() invocation waits for the timer |
---|
| 204 | + * callback to finish. |
---|
200 | 205 | * @expires_next: absolute time of the next event, is required for remote |
---|
201 | 206 | * hrtimer enqueue; it is the total first expiry time (hard |
---|
202 | 207 | * and soft hrtimer are taken into account) |
---|
.. | .. |
---|
224 | 229 | unsigned short nr_hangs; |
---|
225 | 230 | unsigned int max_hang_time; |
---|
226 | 231 | #endif |
---|
| 232 | +#ifdef CONFIG_PREEMPT_RT |
---|
227 | 233 | spinlock_t softirq_expiry_lock; |
---|
| 234 | + atomic_t timer_waiters; |
---|
| 235 | +#endif |
---|
228 | 236 | ktime_t expires_next; |
---|
229 | 237 | struct hrtimer *next_timer; |
---|
230 | 238 | ktime_t softirq_expires_next; |
---|
.. | .. |
---|
313 | 321 | |
---|
314 | 322 | extern void hrtimer_interrupt(struct clock_event_device *dev); |
---|
315 | 323 | |
---|
316 | | -extern void clock_was_set_delayed(void); |
---|
317 | | - |
---|
318 | 324 | extern unsigned int hrtimer_resolution; |
---|
319 | 325 | |
---|
320 | 326 | #else |
---|
321 | 327 | |
---|
322 | 328 | #define hrtimer_resolution (unsigned int)LOW_RES_NSEC |
---|
323 | | - |
---|
324 | | -static inline void clock_was_set_delayed(void) { } |
---|
325 | 329 | |
---|
326 | 330 | #endif |
---|
327 | 331 | |
---|
.. | .. |
---|
346 | 350 | timer->base->get_time()); |
---|
347 | 351 | } |
---|
348 | 352 | |
---|
349 | | -extern void clock_was_set(void); |
---|
350 | 353 | #ifdef CONFIG_TIMERFD |
---|
351 | 354 | extern void timerfd_clock_was_set(void); |
---|
352 | 355 | #else |
---|
.. | .. |
---|
356 | 359 | |
---|
357 | 360 | DECLARE_PER_CPU(struct tick_device, tick_cpu_device); |
---|
358 | 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 |
---|
359 | 370 | |
---|
360 | 371 | /* Exported timer functions: */ |
---|
361 | 372 | |
---|
.. | .. |
---|
363 | 374 | extern void hrtimer_init(struct hrtimer *timer, clockid_t which_clock, |
---|
364 | 375 | enum hrtimer_mode mode); |
---|
365 | 376 | extern void hrtimer_init_sleeper(struct hrtimer_sleeper *sl, clockid_t clock_id, |
---|
366 | | - enum hrtimer_mode mode, |
---|
367 | | - struct task_struct *task); |
---|
| 377 | + enum hrtimer_mode mode); |
---|
368 | 378 | |
---|
369 | 379 | #ifdef CONFIG_DEBUG_OBJECTS_TIMERS |
---|
370 | 380 | extern void hrtimer_init_on_stack(struct hrtimer *timer, clockid_t which_clock, |
---|
371 | 381 | enum hrtimer_mode mode); |
---|
372 | 382 | extern void hrtimer_init_sleeper_on_stack(struct hrtimer_sleeper *sl, |
---|
373 | 383 | clockid_t clock_id, |
---|
374 | | - enum hrtimer_mode mode, |
---|
375 | | - struct task_struct *task); |
---|
| 384 | + enum hrtimer_mode mode); |
---|
376 | 385 | |
---|
377 | 386 | extern void destroy_hrtimer_on_stack(struct hrtimer *timer); |
---|
378 | 387 | #else |
---|
.. | .. |
---|
384 | 393 | } |
---|
385 | 394 | |
---|
386 | 395 | static inline void hrtimer_init_sleeper_on_stack(struct hrtimer_sleeper *sl, |
---|
387 | | - clockid_t clock_id, |
---|
388 | | - enum hrtimer_mode mode, |
---|
389 | | - struct task_struct *task) |
---|
| 396 | + clockid_t clock_id, |
---|
| 397 | + enum hrtimer_mode mode) |
---|
390 | 398 | { |
---|
391 | | - hrtimer_init_sleeper(sl, clock_id, mode, task); |
---|
| 399 | + hrtimer_init_sleeper(sl, clock_id, mode); |
---|
392 | 400 | } |
---|
393 | 401 | |
---|
394 | 402 | static inline void destroy_hrtimer_on_stack(struct hrtimer *timer) { } |
---|
.. | .. |
---|
414 | 422 | |
---|
415 | 423 | extern int hrtimer_cancel(struct hrtimer *timer); |
---|
416 | 424 | extern int hrtimer_try_to_cancel(struct hrtimer *timer); |
---|
417 | | -extern void hrtimer_grab_expiry_lock(const struct hrtimer *timer); |
---|
418 | 425 | |
---|
419 | 426 | static inline void hrtimer_start_expires(struct hrtimer *timer, |
---|
420 | 427 | enum hrtimer_mode mode) |
---|
.. | .. |
---|
426 | 433 | delta = ktime_to_ns(ktime_sub(hard, soft)); |
---|
427 | 434 | hrtimer_start_range_ns(timer, soft, delta, mode); |
---|
428 | 435 | } |
---|
| 436 | + |
---|
| 437 | +void hrtimer_sleeper_start_expires(struct hrtimer_sleeper *sl, |
---|
| 438 | + enum hrtimer_mode mode); |
---|
429 | 439 | |
---|
430 | 440 | static inline void hrtimer_restart(struct hrtimer *timer) |
---|
431 | 441 | { |
---|
.. | .. |
---|
497 | 507 | /* Precise sleep: */ |
---|
498 | 508 | |
---|
499 | 509 | extern int nanosleep_copyout(struct restart_block *, struct timespec64 *); |
---|
500 | | -extern long hrtimer_nanosleep(const struct timespec64 *rqtp, |
---|
501 | | - const enum hrtimer_mode mode, |
---|
| 510 | +extern long hrtimer_nanosleep(ktime_t rqtp, const enum hrtimer_mode mode, |
---|
502 | 511 | const clockid_t clockid); |
---|
503 | 512 | |
---|
504 | 513 | extern int schedule_hrtimeout_range(ktime_t *expires, u64 delta, |
---|
505 | | - const enum hrtimer_mode mode); |
---|
| 514 | + const enum hrtimer_mode mode); |
---|
506 | 515 | extern int schedule_hrtimeout_range_clock(ktime_t *expires, |
---|
507 | 516 | u64 delta, |
---|
508 | 517 | const enum hrtimer_mode mode, |
---|