
From: Ingo Molnar <mingo@elte.hu>

In add_timer_internal() we simply leave the timer pending forever if the
expiry is in more than 0xffffffff jiffies.  This means more than 48 days on
eg.  ia64 - which is not an unrealistic timeout.  IIRC crond is happy to
use extremely large timeouts.

Fix that by making add_timer() use a maximum length timeout if the timeout
is greater than 0xffffffff.  The short timeout should be handled fine by
major users such as eg.  schedule_timeout().



 kernel/timer.c |   16 ++++++++++------
 1 files changed, 10 insertions(+), 6 deletions(-)

diff -puN kernel/timer.c~add_timer-fix kernel/timer.c
--- 25/kernel/timer.c~add_timer-fix	2003-07-05 12:23:59.000000000 -0700
+++ 25-akpm/kernel/timer.c	2003-07-05 12:23:59.000000000 -0700
@@ -126,13 +126,17 @@ static void internal_add_timer(tvec_base
 		 * or you set a timer to go off in the past
 		 */
 		vec = base->tv1.vec + (base->timer_jiffies & TVR_MASK);
-	} else if (idx <= 0xffffffffUL) {
-		int i = (expires >> (TVR_BITS + 3 * TVN_BITS)) & TVN_MASK;
-		vec = base->tv5.vec + i;
 	} else {
-		/* Can only get here on architectures with 64-bit jiffies */
-		INIT_LIST_HEAD(&timer->entry);
-		return;
+		int i;
+		/* If the timeout is larger than 0xffffffff on 64-bit
+		 * architectures then we use the maximum timeout:
+		 */
+		if (idx > 0xffffffffUL) {
+			idx = 0xffffffffUL;
+			expires = idx + base->timer_jiffies;
+		}
+		i = (expires >> (TVR_BITS + 3 * TVN_BITS)) & TVN_MASK;
+		vec = base->tv5.vec + i;
 	}
 	/*
 	 * Timers are FIFO:

_
