aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/hrtimer.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/hrtimer.h')
-rw-r--r--include/linux/hrtimer.h48
1 files changed, 44 insertions, 4 deletions
diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h
index 4971100a8cab..1b9a51a1bccb 100644
--- a/include/linux/hrtimer.h
+++ b/include/linux/hrtimer.h
@@ -32,12 +32,15 @@ struct hrtimer_cpu_base;
32 * when starting the timer) 32 * when starting the timer)
33 * HRTIMER_MODE_SOFT - Timer callback function will be executed in 33 * HRTIMER_MODE_SOFT - Timer callback function will be executed in
34 * soft irq context 34 * soft irq context
35 * HRTIMER_MODE_HARD - Timer callback function will be executed in
36 * hard irq context even on PREEMPT_RT.
35 */ 37 */
36enum hrtimer_mode { 38enum hrtimer_mode {
37 HRTIMER_MODE_ABS = 0x00, 39 HRTIMER_MODE_ABS = 0x00,
38 HRTIMER_MODE_REL = 0x01, 40 HRTIMER_MODE_REL = 0x01,
39 HRTIMER_MODE_PINNED = 0x02, 41 HRTIMER_MODE_PINNED = 0x02,
40 HRTIMER_MODE_SOFT = 0x04, 42 HRTIMER_MODE_SOFT = 0x04,
43 HRTIMER_MODE_HARD = 0x08,
41 44
42 HRTIMER_MODE_ABS_PINNED = HRTIMER_MODE_ABS | HRTIMER_MODE_PINNED, 45 HRTIMER_MODE_ABS_PINNED = HRTIMER_MODE_ABS | HRTIMER_MODE_PINNED,
43 HRTIMER_MODE_REL_PINNED = HRTIMER_MODE_REL | HRTIMER_MODE_PINNED, 46 HRTIMER_MODE_REL_PINNED = HRTIMER_MODE_REL | HRTIMER_MODE_PINNED,
@@ -48,6 +51,11 @@ enum hrtimer_mode {
48 HRTIMER_MODE_ABS_PINNED_SOFT = HRTIMER_MODE_ABS_PINNED | HRTIMER_MODE_SOFT, 51 HRTIMER_MODE_ABS_PINNED_SOFT = HRTIMER_MODE_ABS_PINNED | HRTIMER_MODE_SOFT,
49 HRTIMER_MODE_REL_PINNED_SOFT = HRTIMER_MODE_REL_PINNED | HRTIMER_MODE_SOFT, 52 HRTIMER_MODE_REL_PINNED_SOFT = HRTIMER_MODE_REL_PINNED | HRTIMER_MODE_SOFT,
50 53
54 HRTIMER_MODE_ABS_HARD = HRTIMER_MODE_ABS | HRTIMER_MODE_HARD,
55 HRTIMER_MODE_REL_HARD = HRTIMER_MODE_REL | HRTIMER_MODE_HARD,
56
57 HRTIMER_MODE_ABS_PINNED_HARD = HRTIMER_MODE_ABS_PINNED | HRTIMER_MODE_HARD,
58 HRTIMER_MODE_REL_PINNED_HARD = HRTIMER_MODE_REL_PINNED | HRTIMER_MODE_HARD,
51}; 59};
52 60
53/* 61/*
@@ -101,6 +109,8 @@ enum hrtimer_restart {
101 * @state: state information (See bit values above) 109 * @state: state information (See bit values above)
102 * @is_rel: Set if the timer was armed relative 110 * @is_rel: Set if the timer was armed relative
103 * @is_soft: Set if hrtimer will be expired in soft interrupt context. 111 * @is_soft: Set if hrtimer will be expired in soft interrupt context.
112 * @is_hard: Set if hrtimer will be expired in hard interrupt context
113 * even on RT.
104 * 114 *
105 * The hrtimer structure must be initialized by hrtimer_init() 115 * The hrtimer structure must be initialized by hrtimer_init()
106 */ 116 */
@@ -112,6 +122,7 @@ struct hrtimer {
112 u8 state; 122 u8 state;
113 u8 is_rel; 123 u8 is_rel;
114 u8 is_soft; 124 u8 is_soft;
125 u8 is_hard;
115}; 126};
116 127
117/** 128/**
@@ -183,6 +194,10 @@ enum hrtimer_base_type {
183 * @nr_retries: Total number of hrtimer interrupt retries 194 * @nr_retries: Total number of hrtimer interrupt retries
184 * @nr_hangs: Total number of hrtimer interrupt hangs 195 * @nr_hangs: Total number of hrtimer interrupt hangs
185 * @max_hang_time: Maximum time spent in hrtimer_interrupt 196 * @max_hang_time: Maximum time spent in hrtimer_interrupt
197 * @softirq_expiry_lock: Lock which is taken while softirq based hrtimer are
198 * expired
199 * @timer_waiters: A hrtimer_cancel() invocation waits for the timer
200 * callback to finish.
186 * @expires_next: absolute time of the next event, is required for remote 201 * @expires_next: absolute time of the next event, is required for remote
187 * hrtimer enqueue; it is the total first expiry time (hard 202 * hrtimer enqueue; it is the total first expiry time (hard
188 * and soft hrtimer are taken into account) 203 * and soft hrtimer are taken into account)
@@ -210,6 +225,10 @@ struct hrtimer_cpu_base {
210 unsigned short nr_hangs; 225 unsigned short nr_hangs;
211 unsigned int max_hang_time; 226 unsigned int max_hang_time;
212#endif 227#endif
228#ifdef CONFIG_PREEMPT_RT
229 spinlock_t softirq_expiry_lock;
230 atomic_t timer_waiters;
231#endif
213 ktime_t expires_next; 232 ktime_t expires_next;
214 struct hrtimer *next_timer; 233 struct hrtimer *next_timer;
215 ktime_t softirq_expires_next; 234 ktime_t softirq_expires_next;
@@ -341,16 +360,29 @@ extern void hrtimers_resume(void);
341 360
342DECLARE_PER_CPU(struct tick_device, tick_cpu_device); 361DECLARE_PER_CPU(struct tick_device, tick_cpu_device);
343 362
363#ifdef CONFIG_PREEMPT_RT
364void hrtimer_cancel_wait_running(const struct hrtimer *timer);
365#else
366static inline void hrtimer_cancel_wait_running(struct hrtimer *timer)
367{
368 cpu_relax();
369}
370#endif
344 371
345/* Exported timer functions: */ 372/* Exported timer functions: */
346 373
347/* Initialize timers: */ 374/* Initialize timers: */
348extern void hrtimer_init(struct hrtimer *timer, clockid_t which_clock, 375extern void hrtimer_init(struct hrtimer *timer, clockid_t which_clock,
349 enum hrtimer_mode mode); 376 enum hrtimer_mode mode);
377extern void hrtimer_init_sleeper(struct hrtimer_sleeper *sl, clockid_t clock_id,
378 enum hrtimer_mode mode);
350 379
351#ifdef CONFIG_DEBUG_OBJECTS_TIMERS 380#ifdef CONFIG_DEBUG_OBJECTS_TIMERS
352extern void hrtimer_init_on_stack(struct hrtimer *timer, clockid_t which_clock, 381extern void hrtimer_init_on_stack(struct hrtimer *timer, clockid_t which_clock,
353 enum hrtimer_mode mode); 382 enum hrtimer_mode mode);
383extern void hrtimer_init_sleeper_on_stack(struct hrtimer_sleeper *sl,
384 clockid_t clock_id,
385 enum hrtimer_mode mode);
354 386
355extern void destroy_hrtimer_on_stack(struct hrtimer *timer); 387extern void destroy_hrtimer_on_stack(struct hrtimer *timer);
356#else 388#else
@@ -360,6 +392,14 @@ static inline void hrtimer_init_on_stack(struct hrtimer *timer,
360{ 392{
361 hrtimer_init(timer, which_clock, mode); 393 hrtimer_init(timer, which_clock, mode);
362} 394}
395
396static inline void hrtimer_init_sleeper_on_stack(struct hrtimer_sleeper *sl,
397 clockid_t clock_id,
398 enum hrtimer_mode mode)
399{
400 hrtimer_init_sleeper(sl, clock_id, mode);
401}
402
363static inline void destroy_hrtimer_on_stack(struct hrtimer *timer) { } 403static inline void destroy_hrtimer_on_stack(struct hrtimer *timer) { }
364#endif 404#endif
365 405
@@ -395,6 +435,9 @@ static inline void hrtimer_start_expires(struct hrtimer *timer,
395 hrtimer_start_range_ns(timer, soft, delta, mode); 435 hrtimer_start_range_ns(timer, soft, delta, mode);
396} 436}
397 437
438void hrtimer_sleeper_start_expires(struct hrtimer_sleeper *sl,
439 enum hrtimer_mode mode);
440
398static inline void hrtimer_restart(struct hrtimer *timer) 441static inline void hrtimer_restart(struct hrtimer *timer)
399{ 442{
400 hrtimer_start_expires(timer, HRTIMER_MODE_ABS); 443 hrtimer_start_expires(timer, HRTIMER_MODE_ABS);
@@ -463,11 +506,8 @@ extern long hrtimer_nanosleep(const struct timespec64 *rqtp,
463 const enum hrtimer_mode mode, 506 const enum hrtimer_mode mode,
464 const clockid_t clockid); 507 const clockid_t clockid);
465 508
466extern void hrtimer_init_sleeper(struct hrtimer_sleeper *sl,
467 struct task_struct *tsk);
468
469extern int schedule_hrtimeout_range(ktime_t *expires, u64 delta, 509extern int schedule_hrtimeout_range(ktime_t *expires, u64 delta,
470 const enum hrtimer_mode mode); 510 const enum hrtimer_mode mode);
471extern int schedule_hrtimeout_range_clock(ktime_t *expires, 511extern int schedule_hrtimeout_range_clock(ktime_t *expires,
472 u64 delta, 512 u64 delta,
473 const enum hrtimer_mode mode, 513 const enum hrtimer_mode mode,