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.h113
1 files changed, 67 insertions, 46 deletions
diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h
index 012c37fdb688..c7902ca7c9f4 100644
--- a/include/linux/hrtimer.h
+++ b/include/linux/hrtimer.h
@@ -28,13 +28,29 @@ struct hrtimer_cpu_base;
28 28
29/* 29/*
30 * Mode arguments of xxx_hrtimer functions: 30 * Mode arguments of xxx_hrtimer functions:
31 *
32 * HRTIMER_MODE_ABS - Time value is absolute
33 * HRTIMER_MODE_REL - Time value is relative to now
34 * HRTIMER_MODE_PINNED - Timer is bound to CPU (is only considered
35 * when starting the timer)
36 * HRTIMER_MODE_SOFT - Timer callback function will be executed in
37 * soft irq context
31 */ 38 */
32enum hrtimer_mode { 39enum hrtimer_mode {
33 HRTIMER_MODE_ABS = 0x0, /* Time value is absolute */ 40 HRTIMER_MODE_ABS = 0x00,
34 HRTIMER_MODE_REL = 0x1, /* Time value is relative to now */ 41 HRTIMER_MODE_REL = 0x01,
35 HRTIMER_MODE_PINNED = 0x02, /* Timer is bound to CPU */ 42 HRTIMER_MODE_PINNED = 0x02,
36 HRTIMER_MODE_ABS_PINNED = 0x02, 43 HRTIMER_MODE_SOFT = 0x04,
37 HRTIMER_MODE_REL_PINNED = 0x03, 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
38}; 54};
39 55
40/* 56/*
@@ -87,6 +103,7 @@ enum hrtimer_restart {
87 * @base: pointer to the timer base (per cpu and per clock) 103 * @base: pointer to the timer base (per cpu and per clock)
88 * @state: state information (See bit values above) 104 * @state: state information (See bit values above)
89 * @is_rel: Set if the timer was armed relative 105 * @is_rel: Set if the timer was armed relative
106 * @is_soft: Set if hrtimer will be expired in soft interrupt context.
90 * 107 *
91 * The hrtimer structure must be initialized by hrtimer_init() 108 * The hrtimer structure must be initialized by hrtimer_init()
92 */ 109 */
@@ -97,6 +114,7 @@ struct hrtimer {
97 struct hrtimer_clock_base *base; 114 struct hrtimer_clock_base *base;
98 u8 state; 115 u8 state;
99 u8 is_rel; 116 u8 is_rel;
117 u8 is_soft;
100}; 118};
101 119
102/** 120/**
@@ -112,9 +130,9 @@ struct hrtimer_sleeper {
112}; 130};
113 131
114#ifdef CONFIG_64BIT 132#ifdef CONFIG_64BIT
115# define HRTIMER_CLOCK_BASE_ALIGN 64 133# define __hrtimer_clock_base_align ____cacheline_aligned
116#else 134#else
117# define HRTIMER_CLOCK_BASE_ALIGN 32 135# define __hrtimer_clock_base_align
118#endif 136#endif
119 137
120/** 138/**
@@ -123,48 +141,57 @@ struct hrtimer_sleeper {
123 * @index: clock type index for per_cpu support when moving a 141 * @index: clock type index for per_cpu support when moving a
124 * timer to a base on another cpu. 142 * timer to a base on another cpu.
125 * @clockid: clock id for per_cpu support 143 * @clockid: clock id for per_cpu support
144 * @seq: seqcount around __run_hrtimer
145 * @running: pointer to the currently running hrtimer
126 * @active: red black tree root node for the active timers 146 * @active: red black tree root node for the active timers
127 * @get_time: function to retrieve the current time of the clock 147 * @get_time: function to retrieve the current time of the clock
128 * @offset: offset of this clock to the monotonic base 148 * @offset: offset of this clock to the monotonic base
129 */ 149 */
130struct hrtimer_clock_base { 150struct hrtimer_clock_base {
131 struct hrtimer_cpu_base *cpu_base; 151 struct hrtimer_cpu_base *cpu_base;
132 int index; 152 unsigned int index;
133 clockid_t clockid; 153 clockid_t clockid;
154 seqcount_t seq;
155 struct hrtimer *running;
134 struct timerqueue_head active; 156 struct timerqueue_head active;
135 ktime_t (*get_time)(void); 157 ktime_t (*get_time)(void);
136 ktime_t offset; 158 ktime_t offset;
137} __attribute__((__aligned__(HRTIMER_CLOCK_BASE_ALIGN))); 159} __hrtimer_clock_base_align;
138 160
139enum hrtimer_base_type { 161enum hrtimer_base_type {
140 HRTIMER_BASE_MONOTONIC, 162 HRTIMER_BASE_MONOTONIC,
141 HRTIMER_BASE_REALTIME, 163 HRTIMER_BASE_REALTIME,
142 HRTIMER_BASE_BOOTTIME, 164 HRTIMER_BASE_BOOTTIME,
143 HRTIMER_BASE_TAI, 165 HRTIMER_BASE_TAI,
166 HRTIMER_BASE_MONOTONIC_SOFT,
167 HRTIMER_BASE_REALTIME_SOFT,
168 HRTIMER_BASE_BOOTTIME_SOFT,
169 HRTIMER_BASE_TAI_SOFT,
144 HRTIMER_MAX_CLOCK_BASES, 170 HRTIMER_MAX_CLOCK_BASES,
145}; 171};
146 172
147/* 173/**
148 * struct hrtimer_cpu_base - the per cpu clock bases 174 * struct hrtimer_cpu_base - the per cpu clock bases
149 * @lock: lock protecting the base and associated clock bases 175 * @lock: lock protecting the base and associated clock bases
150 * and timers 176 * and timers
151 * @seq: seqcount around __run_hrtimer
152 * @running: pointer to the currently running hrtimer
153 * @cpu: cpu number 177 * @cpu: cpu number
154 * @active_bases: Bitfield to mark bases with active timers 178 * @active_bases: Bitfield to mark bases with active timers
155 * @clock_was_set_seq: Sequence counter of clock was set events 179 * @clock_was_set_seq: Sequence counter of clock was set events
156 * @migration_enabled: The migration of hrtimers to other cpus is enabled
157 * @nohz_active: The nohz functionality is enabled
158 * @expires_next: absolute time of the next event which was scheduled
159 * via clock_set_next_event()
160 * @next_timer: Pointer to the first expiring timer
161 * @in_hrtirq: hrtimer_interrupt() is currently executing
162 * @hres_active: State of high resolution mode 180 * @hres_active: State of high resolution mode
181 * @in_hrtirq: hrtimer_interrupt() is currently executing
163 * @hang_detected: The last hrtimer interrupt detected a hang 182 * @hang_detected: The last hrtimer interrupt detected a hang
183 * @softirq_activated: displays, if the softirq is raised - update of softirq
184 * related settings is not required then.
164 * @nr_events: Total number of hrtimer interrupt events 185 * @nr_events: Total number of hrtimer interrupt events
165 * @nr_retries: Total number of hrtimer interrupt retries 186 * @nr_retries: Total number of hrtimer interrupt retries
166 * @nr_hangs: Total number of hrtimer interrupt hangs 187 * @nr_hangs: Total number of hrtimer interrupt hangs
167 * @max_hang_time: Maximum time spent in hrtimer_interrupt 188 * @max_hang_time: Maximum time spent in hrtimer_interrupt
189 * @expires_next: absolute time of the next event, is required for remote
190 * hrtimer enqueue; it is the total first expiry time (hard
191 * and soft hrtimer are taken into account)
192 * @next_timer: Pointer to the first expiring timer
193 * @softirq_expires_next: Time to check, if soft queues needs also to be expired
194 * @softirq_next_timer: Pointer to the first expiring softirq based timer
168 * @clock_base: array of clock bases for this cpu 195 * @clock_base: array of clock bases for this cpu
169 * 196 *
170 * Note: next_timer is just an optimization for __remove_hrtimer(). 197 * Note: next_timer is just an optimization for __remove_hrtimer().
@@ -173,31 +200,28 @@ enum hrtimer_base_type {
173 */ 200 */
174struct hrtimer_cpu_base { 201struct hrtimer_cpu_base {
175 raw_spinlock_t lock; 202 raw_spinlock_t lock;
176 seqcount_t seq;
177 struct hrtimer *running;
178 unsigned int cpu; 203 unsigned int cpu;
179 unsigned int active_bases; 204 unsigned int active_bases;
180 unsigned int clock_was_set_seq; 205 unsigned int clock_was_set_seq;
181 bool migration_enabled; 206 unsigned int hres_active : 1,
182 bool nohz_active; 207 in_hrtirq : 1,
208 hang_detected : 1,
209 softirq_activated : 1;
183#ifdef CONFIG_HIGH_RES_TIMERS 210#ifdef CONFIG_HIGH_RES_TIMERS
184 unsigned int in_hrtirq : 1,
185 hres_active : 1,
186 hang_detected : 1;
187 ktime_t expires_next;
188 struct hrtimer *next_timer;
189 unsigned int nr_events; 211 unsigned int nr_events;
190 unsigned int nr_retries; 212 unsigned short nr_retries;
191 unsigned int nr_hangs; 213 unsigned short nr_hangs;
192 unsigned int max_hang_time; 214 unsigned int max_hang_time;
193#endif 215#endif
216 ktime_t expires_next;
217 struct hrtimer *next_timer;
218 ktime_t softirq_expires_next;
219 struct hrtimer *softirq_next_timer;
194 struct hrtimer_clock_base clock_base[HRTIMER_MAX_CLOCK_BASES]; 220 struct hrtimer_clock_base clock_base[HRTIMER_MAX_CLOCK_BASES];
195} ____cacheline_aligned; 221} ____cacheline_aligned;
196 222
197static inline void hrtimer_set_expires(struct hrtimer *timer, ktime_t time) 223static inline void hrtimer_set_expires(struct hrtimer *timer, ktime_t time)
198{ 224{
199 BUILD_BUG_ON(sizeof(struct hrtimer_clock_base) > HRTIMER_CLOCK_BASE_ALIGN);
200
201 timer->node.expires = time; 225 timer->node.expires = time;
202 timer->_softexpires = time; 226 timer->_softexpires = time;
203} 227}
@@ -266,16 +290,17 @@ static inline ktime_t hrtimer_cb_get_time(struct hrtimer *timer)
266 return timer->base->get_time(); 290 return timer->base->get_time();
267} 291}
268 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
269#ifdef CONFIG_HIGH_RES_TIMERS 299#ifdef CONFIG_HIGH_RES_TIMERS
270struct clock_event_device; 300struct clock_event_device;
271 301
272extern void hrtimer_interrupt(struct clock_event_device *dev); 302extern void hrtimer_interrupt(struct clock_event_device *dev);
273 303
274static inline int hrtimer_is_hres_active(struct hrtimer *timer)
275{
276 return timer->base->cpu_base->hres_active;
277}
278
279/* 304/*
280 * The resolution of the clocks. The resolution value is returned in 305 * The resolution of the clocks. The resolution value is returned in
281 * the clock_getres() system call to give application programmers an 306 * the clock_getres() system call to give application programmers an
@@ -298,11 +323,6 @@ extern unsigned int hrtimer_resolution;
298 323
299#define hrtimer_resolution (unsigned int)LOW_RES_NSEC 324#define hrtimer_resolution (unsigned int)LOW_RES_NSEC
300 325
301static inline int hrtimer_is_hres_active(struct hrtimer *timer)
302{
303 return 0;
304}
305
306static inline void clock_was_set_delayed(void) { } 326static inline void clock_was_set_delayed(void) { }
307 327
308#endif 328#endif
@@ -365,11 +385,12 @@ extern void hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim,
365 u64 range_ns, const enum hrtimer_mode mode); 385 u64 range_ns, const enum hrtimer_mode mode);
366 386
367/** 387/**
368 * hrtimer_start - (re)start an hrtimer on the current CPU 388 * hrtimer_start - (re)start an hrtimer
369 * @timer: the timer to be added 389 * @timer: the timer to be added
370 * @tim: expiry time 390 * @tim: expiry time
371 * @mode: expiry mode: absolute (HRTIMER_MODE_ABS) or 391 * @mode: timer mode: absolute (HRTIMER_MODE_ABS) or
372 * relative (HRTIMER_MODE_REL) 392 * relative (HRTIMER_MODE_REL), and pinned (HRTIMER_MODE_PINNED);
393 * softirq based mode is considered for debug purpose only!
373 */ 394 */
374static inline void hrtimer_start(struct hrtimer *timer, ktime_t tim, 395static inline void hrtimer_start(struct hrtimer *timer, ktime_t tim,
375 const enum hrtimer_mode mode) 396 const enum hrtimer_mode mode)
@@ -422,7 +443,7 @@ static inline int hrtimer_is_queued(struct hrtimer *timer)
422 */ 443 */
423static inline int hrtimer_callback_running(struct hrtimer *timer) 444static inline int hrtimer_callback_running(struct hrtimer *timer)
424{ 445{
425 return timer->base->cpu_base->running == timer; 446 return timer->base->running == timer;
426} 447}
427 448
428/* Forward a hrtimer so it expires after now: */ 449/* Forward a hrtimer so it expires after now: */
@@ -466,7 +487,7 @@ extern int schedule_hrtimeout_range(ktime_t *expires, u64 delta,
466extern int schedule_hrtimeout_range_clock(ktime_t *expires, 487extern int schedule_hrtimeout_range_clock(ktime_t *expires,
467 u64 delta, 488 u64 delta,
468 const enum hrtimer_mode mode, 489 const enum hrtimer_mode mode,
469 int clock); 490 clockid_t clock_id);
470extern int schedule_hrtimeout(ktime_t *expires, const enum hrtimer_mode mode); 491extern int schedule_hrtimeout(ktime_t *expires, const enum hrtimer_mode mode);
471 492
472/* Soft interrupt function to run the hrtimer queues: */ 493/* Soft interrupt function to run the hrtimer queues: */