Index: linux-2.6.10-ckdev/kernel/sched.c
===================================================================
--- linux-2.6.10-ckdev.orig/kernel/sched.c	2005-01-13 10:40:42.000000000 +1100
+++ linux-2.6.10-ckdev/kernel/sched.c	2005-01-13 14:51:12.017227920 +1100
@@ -630,12 +630,30 @@
 		return prio;
 	prio += 1 + (used_slice - first_slice) / rr;
 	if (prio >= MAX_PRIO - 2) {
-		prio = MAX_PRIO - 2;
 		p->totalrun = 0;
+		prio = MAX_PRIO - 2;
 	}
 	return prio;
 }
 
+static void continue_slice(task_t *p, unsigned int rr)
+{
+	unsigned long total_run = NS_TO_JIFFIES(p->totalrun);
+	if (total_run >= p->slice && p->prio >= MAX_PRIO - 2) {
+		p->totalrun = 0;
+		dec_burst(p);
+	} else {
+		unsigned int remainder;
+		if (likely(total_run < p->slice))
+			p->slice -= total_run;
+		else
+			p->slice = 1;
+		remainder = p->slice % rr;
+		if (remainder)
+			p->time_slice = remainder;
+	}
+}
+
 /*
  * recalc_task_prio - this checks for tasks that run ultra short timeslices
  * or have just forked a thread/process and make them continue their old
@@ -645,38 +663,42 @@
 {
 	unsigned long sleep_time = ns_diff(now, p->timestamp);
 	unsigned int rr = rr_interval(p);
-	unsigned int best_burst = burst(p);
-	if (p->flags & PF_FORKED || sched_compute ||
-		(p->runtime > sleep_time && 
-		(NS_TO_JIFFIES(p->runtime + sleep_time) < rr))) {
-			unsigned long ns_totalrun = p->totalrun + p->runtime;
-			unsigned long total_run = NS_TO_JIFFIES(ns_totalrun);
+
+	if (NS_TO_JIFFIES(p->totalrun) >= (p->slice - rr) &&
+		p->prio >= MAX_PRIO - 2) {
 			p->flags &= ~PF_FORKED;
-			if (p->slice - total_run < 1) {
-				p->totalrun = 0;
-				dec_burst(p);
-			} else {
-				unsigned int intervals = total_run / rr;
-				unsigned int remainder;
-				p->totalrun = ns_totalrun;
-				p->slice -= intervals * rr;
-				if (p->slice <= rr) {
-					p->totalrun = 0;
-					dec_burst(p);
-				} else {
-					remainder = p->slice % rr;
-					if (remainder)
-						p->time_slice = remainder;
-				}
-			}
-	} else {
-		if (NS_TO_JIFFIES(p->totalrun) > (best_burst - p->burst) * rr)
-			dec_burst(p);
-		else if (!(p->flags & PF_UISLEEP || p->totalrun))
-			inc_burst(p);
-		p->runtime = 0;
-		p->totalrun = 0;
+			goto new_slice;
+	}
+	p->totalrun += p->runtime;
+
+	if (p->flags & PF_FORKED) {
+		continue_slice(p, rr);
+		p->flags &= ~PF_FORKED;
+		goto out;
+	}
+
+	if (sched_compute) {
+		continue_slice(p, rr);
+		goto out;
 	}
+
+	if (sleep_time >= p->totalrun)
+		goto reset_slice;
+	p->totalrun -= sleep_time;
+
+	if (NS_TO_JIFFIES(p->runtime + sleep_time) < rr) {
+		continue_slice(p, rr);
+		goto out;
+	}
+new_slice:
+	if (NS_TO_JIFFIES(p->totalrun) > p->burst * rr)
+		dec_burst(p);
+	else if (!(p->flags & PF_UISLEEP || p->totalrun))
+		inc_burst(p);
+reset_slice:
+	p->totalrun = 0;
+out:
+	return;
 }
 
 /*
@@ -2178,6 +2200,7 @@
 		dec_burst(p);
 		p->slice = slice(p);
 		time_slice_expired(p, rq);
+		p->totalrun = 0;
 		goto out_unlock;
 	}
 	/*

