Timer robustness patch

Finn Arne Gangstad (finnag@fast.no)
Fri, 2 Jul 1999 22:45:39 +0200 (MEST)


This small patch should improve timer robustness a lot, especially if
someone changed timer->expires when they shouldn't. cascade_timers now
knows how to handle timers that are put right back into the list they were
already in. Previously this would lead to corrupted timer lists, and/or
timers trigging at very strange times.

As an added bonus, you can now make timers with more than 2^32 jiffies
timeout on 64 bit architectures (whee! :)

The patch is relative to 2.3.7, but should work on many older versions as
well.

- Finn Arne

diff -ur linux.orig/kernel/sched.c linux/kernel/sched.c
--- linux.orig/kernel/sched.c Wed May 12 23:41:36 1999
+++ linux/kernel/sched.c Fri Jul 2 22:34:10 1999
@@ -513,9 +513,7 @@

static inline void internal_add_timer(struct timer_list *timer)
{
- /*
- * must be cli-ed when calling this
- */
+ /* must have timerlist_lock spinlock when calling this */
unsigned long expires = timer->expires;
unsigned long idx = expires - timer_jiffies;

@@ -536,12 +534,9 @@
* or you set a timer to go off in the past
*/
insert_timer(timer, tv1.vec, tv1.index);
- } else if (idx <= 0xffffffffUL) {
+ } else {
int i = (expires >> (TVR_BITS + 3 * TVN_BITS)) & TVN_MASK;
insert_timer(timer, tv5.vec, i);
- } else {
- /* Can only get here on architectures with 64-bit jiffies */
- timer->next = timer->prev = timer;
}
}

@@ -1106,14 +1101,14 @@
timer = tv->vec[tv->index];
/*
* We are removing _all_ timers from the list, so we don't have to
- * detach them individually, just clear the list afterwards.
+ * detach them individually, just clear the list first.
*/
+ tv->vec[tv->index] = NULL;
while (timer) {
struct timer_list *tmp = timer;
timer = timer->next;
internal_add_timer(tmp);
}
- tv->vec[tv->index] = NULL;
tv->index = (tv->index + 1) & TVN_MASK;
}

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/