summaryrefslogtreecommitdiff
path: root/kernel/time/tick-broadcast.c
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2008-09-03 21:37:14 +0000
committerThomas Gleixner <tglx@linutronix.de>2008-09-05 11:11:53 +0200
commit1fb9b7d29d8e85ba3196eaa7ab871bf76fc98d36 (patch)
tree1fbefa54e16e76f76616202d8abf9607725afeff /kernel/time/tick-broadcast.c
parent9c17bcda991000351cb2373f78be7e4b1c44caa3 (diff)
downloadlwn-1fb9b7d29d8e85ba3196eaa7ab871bf76fc98d36.tar.gz
lwn-1fb9b7d29d8e85ba3196eaa7ab871bf76fc98d36.zip
clockevents: prevent endless loop lockup
The C1E/HPET bug reports on AMDX2/RS690 systems where tracked down to a too small value of the HPET minumum delta for programming an event. The clockevents code needs to enforce an interrupt event on the clock event device in some cases. The enforcement code was stupid and naive, as it just added the minimum delta to the current time and tried to reprogram the device. When the minimum delta is too small, then this loops forever. Add a sanity check. Allow reprogramming to fail 3 times, then print a warning and double the minimum delta value to make sure, that this does not happen again. Use the same function for both tick-oneshot and tick-broadcast code. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel/time/tick-broadcast.c')
-rw-r--r--kernel/time/tick-broadcast.c12
1 files changed, 2 insertions, 10 deletions
diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c
index 5744f40b2697..2bc1f046151c 100644
--- a/kernel/time/tick-broadcast.c
+++ b/kernel/time/tick-broadcast.c
@@ -372,16 +372,8 @@ cpumask_t *tick_get_broadcast_oneshot_mask(void)
static int tick_broadcast_set_event(ktime_t expires, int force)
{
struct clock_event_device *bc = tick_broadcast_device.evtdev;
- ktime_t now = ktime_get();
- int res;
-
- for(;;) {
- res = clockevents_program_event(bc, expires, now);
- if (!res || !force)
- return res;
- now = ktime_get();
- expires = ktime_add(now, ktime_set(0, bc->min_delta_ns));
- }
+
+ return tick_dev_program_event(bc, expires, force);
}
int tick_resume_broadcast_oneshot(struct clock_event_device *bc)