| .. | .. |
|---|
| 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, |
|---|