diff options
author | Tony Lindgren <tony@atomide.com> | 2006-03-06 18:42:45 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-03-06 21:40:44 -0500 |
commit | 69239749e1ac4f3496906aa4267cb9f61ce52c9c (patch) | |
tree | c64bc2c254b7fa81b50b11c851fe5c86ecdd83c1 /kernel/hrtimer.c | |
parent | f7c09bd972b7111b8c69bf57a189571edd4d4a7d (diff) |
[PATCH] fix next_timer_interrupt() for hrtimer
Also from Thomas Gleixner <tglx@linutronix.de>
Function next_timer_interrupt() got broken with a recent patch
6ba1b91213e81aa92b5cf7539f7d2a94ff54947c as sys_nanosleep() was moved to
hrtimer. This broke things as next_timer_interrupt() did not check hrtimer
tree for next event.
Function next_timer_interrupt() is needed with dyntick (CONFIG_NO_IDLE_HZ,
VST) implementations, as the system can be in idle when next hrtimer event
was supposed to happen. At least ARM and S390 currently use
next_timer_interrupt().
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: Russell King <rmk@arm.linux.org.uk>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'kernel/hrtimer.c')
-rw-r--r-- | kernel/hrtimer.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index 5ae51f1bc7c8..14bc9cfa6399 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c | |||
@@ -505,6 +505,41 @@ ktime_t hrtimer_get_remaining(const struct hrtimer *timer) | |||
505 | return rem; | 505 | return rem; |
506 | } | 506 | } |
507 | 507 | ||
508 | #ifdef CONFIG_NO_IDLE_HZ | ||
509 | /** | ||
510 | * hrtimer_get_next_event - get the time until next expiry event | ||
511 | * | ||
512 | * Returns the delta to the next expiry event or KTIME_MAX if no timer | ||
513 | * is pending. | ||
514 | */ | ||
515 | ktime_t hrtimer_get_next_event(void) | ||
516 | { | ||
517 | struct hrtimer_base *base = __get_cpu_var(hrtimer_bases); | ||
518 | ktime_t delta, mindelta = { .tv64 = KTIME_MAX }; | ||
519 | unsigned long flags; | ||
520 | int i; | ||
521 | |||
522 | for (i = 0; i < MAX_HRTIMER_BASES; i++, base++) { | ||
523 | struct hrtimer *timer; | ||
524 | |||
525 | spin_lock_irqsave(&base->lock, flags); | ||
526 | if (!base->first) { | ||
527 | spin_unlock_irqrestore(&base->lock, flags); | ||
528 | continue; | ||
529 | } | ||
530 | timer = rb_entry(base->first, struct hrtimer, node); | ||
531 | delta.tv64 = timer->expires.tv64; | ||
532 | spin_unlock_irqrestore(&base->lock, flags); | ||
533 | delta = ktime_sub(delta, base->get_time()); | ||
534 | if (delta.tv64 < mindelta.tv64) | ||
535 | mindelta.tv64 = delta.tv64; | ||
536 | } | ||
537 | if (mindelta.tv64 < 0) | ||
538 | mindelta.tv64 = 0; | ||
539 | return mindelta; | ||
540 | } | ||
541 | #endif | ||
542 | |||
508 | /** | 543 | /** |
509 | * hrtimer_init - initialize a timer to the given clock | 544 | * hrtimer_init - initialize a timer to the given clock |
510 | * | 545 | * |