[PATCH] fix unsafe operation in high resolution timer

From: Hillf Danton
Date: Thu Dec 23 2010 - 08:30:02 EST


After calling the callback function of hrtimer, the timer could become
unreliable in corner cases where the timer will no longer be queued
and the mm segment, in which the timer is embedded, could be reclaimed
in the callback.

The unreliability is fixed by checking the result of callback before
operating the timer again.

Signed-off-by: Hillf Danton <dhillf@xxxxxxxxx>
---

--- a/kernel/hrtimer.c 2010-11-01 19:54:12.000000000 +0800
+++ b/kernel/hrtimer.c 2010-12-23 21:17:02.000000000 +0800
@@ -1225,6 +1225,7 @@ static void __run_hrtimer(struct hrtimer
raw_spin_unlock(&cpu_base->lock);
trace_hrtimer_expire_entry(timer, now);
restart = fn(timer);
+ if (restart != HRTIMER_NORESTART)
trace_hrtimer_expire_exit(timer);
raw_spin_lock(&cpu_base->lock);

@@ -1236,11 +1237,8 @@ static void __run_hrtimer(struct hrtimer
if (restart != HRTIMER_NORESTART) {
BUG_ON(timer->state != HRTIMER_STATE_CALLBACK);
enqueue_hrtimer(timer, base);
+ timer->state &= ~HRTIMER_STATE_CALLBACK;
}
-
- WARN_ON_ONCE(!(timer->state & HRTIMER_STATE_CALLBACK));
-
- timer->state &= ~HRTIMER_STATE_CALLBACK;
}

#ifdef CONFIG_HIGH_RES_TIMERS
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/