[PATCH] fix next_timer_interrupt() for hrtimer

Also from Thomas Gleixner <tglx@linutronix.de>

Function next_timer_interrupt() got broken with a recent patch
6ba1b91213 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>
This commit is contained in:
Tony Lindgren 2006-03-06 15:42:45 -08:00 committed by Linus Torvalds
parent f7c09bd972
commit 69239749e1
4 changed files with 61 additions and 4 deletions

View file

@ -505,6 +505,41 @@ ktime_t hrtimer_get_remaining(const struct hrtimer *timer)
return rem;
}
#ifdef CONFIG_NO_IDLE_HZ
/**
* hrtimer_get_next_event - get the time until next expiry event
*
* Returns the delta to the next expiry event or KTIME_MAX if no timer
* is pending.
*/
ktime_t hrtimer_get_next_event(void)
{
struct hrtimer_base *base = __get_cpu_var(hrtimer_bases);
ktime_t delta, mindelta = { .tv64 = KTIME_MAX };
unsigned long flags;
int i;
for (i = 0; i < MAX_HRTIMER_BASES; i++, base++) {
struct hrtimer *timer;
spin_lock_irqsave(&base->lock, flags);
if (!base->first) {
spin_unlock_irqrestore(&base->lock, flags);
continue;
}
timer = rb_entry(base->first, struct hrtimer, node);
delta.tv64 = timer->expires.tv64;
spin_unlock_irqrestore(&base->lock, flags);
delta = ktime_sub(delta, base->get_time());
if (delta.tv64 < mindelta.tv64)
mindelta.tv64 = delta.tv64;
}
if (mindelta.tv64 < 0)
mindelta.tv64 = 0;
return mindelta;
}
#endif
/**
* hrtimer_init - initialize a timer to the given clock
*