hrtimer: Fix migration expiry check
authorThomas Gleixner <tglx@linutronix.de>
Fri, 10 Jul 2009 12:57:05 +0000 (14:57 +0200)
committerThomas Gleixner <tglx@linutronix.de>
Fri, 10 Jul 2009 15:32:55 +0000 (17:32 +0200)
commit6ff7041dbfeb3bd7dfe9aa67275c21199ef760d6
treec8897de7ba6c09d51d83557d981ced3da48bba61
parent7e0c5086c172ecf8b0c2ad860b02a586967d17d0
hrtimer: Fix migration expiry check

The timer migration expiry check should prevent the migration of a
timer to another CPU when the timer expires before the next event is
scheduled on the other CPU. Migrating the timer might delay it because
we can not reprogram the clock event device on the other CPU. But the
code implementing that check has two flaws:

- for !HIGHRES the check compares the expiry value with the clock
  events device expiry value which is wrong for CLOCK_REALTIME based
  timers.

- the check is racy. It holds the hrtimer base lock of the target CPU,
  but the clock event device expiry value can be modified
  nevertheless, e.g. by an timer interrupt firing.

The !HIGHRES case is easy to fix as we can enqueue the timer on the
cpu which was selected by the load balancer. It runs the idle
balancing code once per jiffy anyway. So the maximum delay for the
timer is the same as when we keep the tick on the current cpu going.

In the HIGHRES case we can get the next expiry value from the hrtimer
cpu_base of the target CPU and serialize the update with the cpu_base
lock. This moves the lock section in hrtimer_interrupt() so we can set
next_event to KTIME_MAX while we are handling the expired timers and
set it to the next expiry value after we handled the timers under the
base lock. While the expired timers are processed timer migration is
blocked because the expiry time of the timer is always <= KTIME_MAX.

Also remove the now useless clockevents_get_next_event() function.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
include/linux/clockchips.h
kernel/hrtimer.c
kernel/time/clockevents.c