Index: linux-2.6.9-rc3/kernel/sched.c
===================================================================
--- linux-2.6.9-rc3.orig/kernel/sched.c	2004-10-05 21:48:26.000000000 +1000
+++ linux-2.6.9-rc3/kernel/sched.c	2004-10-05 22:08:56.030578806 +1000
@@ -71,6 +71,7 @@
  * Some helpers for converting nanosecond timing to jiffy resolution
  */
 #define NS_TO_JIFFIES(TIME)	((TIME) / (1000000000 / HZ))
+#define NSJIFFY			(1000000000 / HZ)	/* One jiffy in ns */
 
 int sched_compute = 0;
 /* 
@@ -582,6 +583,20 @@ static inline void sched_info_switch(tas
 #define sched_info_switch(t, next)	do { } while (0)
 #endif /* CONFIG_SCHEDSTATS */
 
+/*
+ * Get unsigned long long difference without overflowing unsigned long.
+ */
+static unsigned long uldiff(unsigned long long v1, unsigned long long v2)
+{
+	unsigned long long vdiff;
+	if (unlikely(v1 < v2))
+		return 0;
+	vdiff = v1 - v2;
+	if (vdiff > 1 << 31)
+		vdiff = 1 << 31;
+	return (unsigned long)vdiff;
+}
+
 static inline int task_queued(task_t *task)
 {
 	return !list_empty(&task->run_list);
@@ -715,7 +730,7 @@ static int effective_prio(task_t *p)
  */
 static void recalc_task_prio(task_t *p, unsigned long long now)
 {
-	unsigned long sleep_time = now - p->timestamp;
+	unsigned long sleep_time = uldiff(now, p->timestamp);
 	unsigned int rr = RR_INTERVAL();
 	unsigned int best_burst = burst(p);
 	unsigned int minrun = rr * (p->burst + 1) / (best_burst + 1) ? : 1;
@@ -2155,6 +2170,7 @@ void scheduler_tick(int user_ticks, int 
 	struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat;
 	runqueue_t *rq = this_rq();
 	task_t *p = current;
+	unsigned long debit;
 
 	rq->timestamp_last_tick = sched_clock();
 
@@ -2176,7 +2192,7 @@ void scheduler_tick(int user_ticks, int 
 		else
 			cpustat->idle += sys_ticks;
 		if (wake_priority_sleeper(rq))
-			goto out_unlock;
+			goto out;
 		rebalance_tick(cpu, rq, IDLE);
 		return;
 	}
@@ -2196,6 +2212,11 @@ void scheduler_tick(int user_ticks, int 
 	 */
 	if (unlikely(p->policy == SCHED_FIFO))
 		goto out;
+	debit = uldiff(rq->timestamp_last_tick, p->timestamp);
+	if (debit < NSJIFFY) {
+		p->totalrun += debit;
+		goto out;
+	}
 
 	spin_lock(&rq->lock);
 	/*
@@ -2282,7 +2303,6 @@ static int dependent_sleeper(int this_cp
 {
 	struct sched_domain *sd = this_rq->sd;
 	cpumask_t sibling_map;
-	prio_array_t *array;
 	int ret = 0, i;
 	task_t *p;
 
@@ -2408,7 +2428,7 @@ need_resched:
 	schedstat_inc(rq, sched_cnt);
 	now = sched_clock();
 
-	prev->runtime = now - prev->timestamp;
+	prev->runtime = uldiff(now, prev->timestamp);
 	spin_lock_irq(&rq->lock);
 
 	/*
