diff options
-rw-r--r-- | include/linux/hrtimer.h | 3 | ||||
-rw-r--r-- | kernel/hrtimer.c | 7 | ||||
-rw-r--r-- | kernel/itimer.c | 3 | ||||
-rw-r--r-- | kernel/posix-timers.c | 14 |
4 files changed, 17 insertions, 10 deletions
diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index 64e2754ca734..84fc186324e6 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h | |||
@@ -130,7 +130,8 @@ static inline int hrtimer_active(const struct hrtimer *timer) | |||
130 | } | 130 | } |
131 | 131 | ||
132 | /* Forward a hrtimer so it expires after now: */ | 132 | /* Forward a hrtimer so it expires after now: */ |
133 | extern unsigned long hrtimer_forward(struct hrtimer *timer, ktime_t interval); | 133 | extern unsigned long |
134 | hrtimer_forward(struct hrtimer *timer, ktime_t now, ktime_t interval); | ||
134 | 135 | ||
135 | /* Precise sleep: */ | 136 | /* Precise sleep: */ |
136 | extern long hrtimer_nanosleep(struct timespec *rqtp, | 137 | extern long hrtimer_nanosleep(struct timespec *rqtp, |
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index b728cc53452b..e989c9981a96 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c | |||
@@ -301,18 +301,17 @@ void unlock_hrtimer_base(const struct hrtimer *timer, unsigned long *flags) | |||
301 | * hrtimer_forward - forward the timer expiry | 301 | * hrtimer_forward - forward the timer expiry |
302 | * | 302 | * |
303 | * @timer: hrtimer to forward | 303 | * @timer: hrtimer to forward |
304 | * @now: forward past this time | ||
304 | * @interval: the interval to forward | 305 | * @interval: the interval to forward |
305 | * | 306 | * |
306 | * Forward the timer expiry so it will expire in the future. | 307 | * Forward the timer expiry so it will expire in the future. |
307 | * Returns the number of overruns. | 308 | * Returns the number of overruns. |
308 | */ | 309 | */ |
309 | unsigned long | 310 | unsigned long |
310 | hrtimer_forward(struct hrtimer *timer, ktime_t interval) | 311 | hrtimer_forward(struct hrtimer *timer, ktime_t now, ktime_t interval) |
311 | { | 312 | { |
312 | unsigned long orun = 1; | 313 | unsigned long orun = 1; |
313 | ktime_t delta, now; | 314 | ktime_t delta; |
314 | |||
315 | now = timer->base->get_time(); | ||
316 | 315 | ||
317 | delta = ktime_sub(now, timer->expires); | 316 | delta = ktime_sub(now, timer->expires); |
318 | 317 | ||
diff --git a/kernel/itimer.c b/kernel/itimer.c index 680e6b70c872..af2ec6b4392c 100644 --- a/kernel/itimer.c +++ b/kernel/itimer.c | |||
@@ -136,7 +136,8 @@ int it_real_fn(void *data) | |||
136 | 136 | ||
137 | if (tsk->signal->it_real_incr.tv64 != 0) { | 137 | if (tsk->signal->it_real_incr.tv64 != 0) { |
138 | hrtimer_forward(&tsk->signal->real_timer, | 138 | hrtimer_forward(&tsk->signal->real_timer, |
139 | tsk->signal->it_real_incr); | 139 | tsk->signal->real_timer.base->softirq_time, |
140 | tsk->signal->it_real_incr); | ||
140 | 141 | ||
141 | return HRTIMER_RESTART; | 142 | return HRTIMER_RESTART; |
142 | } | 143 | } |
diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c index 9944379360b5..255657accf02 100644 --- a/kernel/posix-timers.c +++ b/kernel/posix-timers.c | |||
@@ -251,15 +251,18 @@ __initcall(init_posix_timers); | |||
251 | 251 | ||
252 | static void schedule_next_timer(struct k_itimer *timr) | 252 | static void schedule_next_timer(struct k_itimer *timr) |
253 | { | 253 | { |
254 | struct hrtimer *timer = &timr->it.real.timer; | ||
255 | |||
254 | if (timr->it.real.interval.tv64 == 0) | 256 | if (timr->it.real.interval.tv64 == 0) |
255 | return; | 257 | return; |
256 | 258 | ||
257 | timr->it_overrun += hrtimer_forward(&timr->it.real.timer, | 259 | timr->it_overrun += hrtimer_forward(timer, timer->base->get_time(), |
258 | timr->it.real.interval); | 260 | timr->it.real.interval); |
261 | |||
259 | timr->it_overrun_last = timr->it_overrun; | 262 | timr->it_overrun_last = timr->it_overrun; |
260 | timr->it_overrun = -1; | 263 | timr->it_overrun = -1; |
261 | ++timr->it_requeue_pending; | 264 | ++timr->it_requeue_pending; |
262 | hrtimer_restart(&timr->it.real.timer); | 265 | hrtimer_restart(timer); |
263 | } | 266 | } |
264 | 267 | ||
265 | /* | 268 | /* |
@@ -334,6 +337,7 @@ EXPORT_SYMBOL_GPL(posix_timer_event); | |||
334 | static int posix_timer_fn(void *data) | 337 | static int posix_timer_fn(void *data) |
335 | { | 338 | { |
336 | struct k_itimer *timr = data; | 339 | struct k_itimer *timr = data; |
340 | struct hrtimer *timer = &timr->it.real.timer; | ||
337 | unsigned long flags; | 341 | unsigned long flags; |
338 | int si_private = 0; | 342 | int si_private = 0; |
339 | int ret = HRTIMER_NORESTART; | 343 | int ret = HRTIMER_NORESTART; |
@@ -351,7 +355,8 @@ static int posix_timer_fn(void *data) | |||
351 | */ | 355 | */ |
352 | if (timr->it.real.interval.tv64 != 0) { | 356 | if (timr->it.real.interval.tv64 != 0) { |
353 | timr->it_overrun += | 357 | timr->it_overrun += |
354 | hrtimer_forward(&timr->it.real.timer, | 358 | hrtimer_forward(timer, |
359 | timer->base->softirq_time, | ||
355 | timr->it.real.interval); | 360 | timr->it.real.interval); |
356 | ret = HRTIMER_RESTART; | 361 | ret = HRTIMER_RESTART; |
357 | ++timr->it_requeue_pending; | 362 | ++timr->it_requeue_pending; |
@@ -623,7 +628,8 @@ common_timer_get(struct k_itimer *timr, struct itimerspec *cur_setting) | |||
623 | if (timr->it_requeue_pending & REQUEUE_PENDING || | 628 | if (timr->it_requeue_pending & REQUEUE_PENDING || |
624 | (timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE) { | 629 | (timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE) { |
625 | timr->it_overrun += | 630 | timr->it_overrun += |
626 | hrtimer_forward(timer, timr->it.real.interval); | 631 | hrtimer_forward(timer, timer->base->get_time(), |
632 | timr->it.real.interval); | ||
627 | remaining = hrtimer_get_remaining(timer); | 633 | remaining = hrtimer_get_remaining(timer); |
628 | } | 634 | } |
629 | calci: | 635 | calci: |