---
 kernel/sched.c |   19 ++++++++++++-------
 1 files changed, 12 insertions(+), 7 deletions(-)

Index: linux-2.6.17-rc4-mm1/kernel/sched.c
===================================================================
--- linux-2.6.17-rc4-mm1.orig/kernel/sched.c	2006-05-19 11:12:07.000000000 +1000
+++ linux-2.6.17-rc4-mm1/kernel/sched.c	2006-05-19 22:03:22.000000000 +1000
@@ -3189,6 +3189,12 @@ static inline int interactive_sleep(enum
 		sleep_type == SLEEP_INTERRUPTED);
 }
 
+static inline void idle_next(struct runqueue *rq, struct task_struct **next)
+{
+	schedstat_inc(rq, sched_goidle);
+	*next = rq->idle;
+}
+
 /*
  * schedule() is the main scheduler function.
  */
@@ -3270,7 +3276,6 @@ need_resched_nonpreemptible:
 go_idle:
 		idle_balance(cpu, rq);
 		if (!rq->nr_running) {
-			next = rq->idle;
 			rq->expired_timestamp = 0;
 			wake_sleeping_dependent(cpu, rq);
 			/*
@@ -3278,12 +3283,14 @@ go_idle:
 			 * the runqueue, so break out if we got new
 			 * tasks meanwhile:
 			 */
-			if (!rq->nr_running)
+			if (!rq->nr_running) {
+				idle_next(rq, &next);
 				goto switch_tasks;
+			}
 		}
 	} else {
 		if (dependent_sleeper(cpu, rq)) {
-			next = rq->idle;
+			idle_next(rq, &next);
 			goto switch_tasks;
 		}
 		/*
@@ -3311,6 +3318,8 @@ go_idle:
 	idx = sched_find_first_bit(array->bitmap);
 	queue = array->queue + idx;
 	next = list_entry(queue->next, task_t, run_list);
+	prefetch(next);
+	prefetch_stack(next);
 
 	if (!rt_task(next) && interactive_sleep(next->sleep_type)) {
 		unsigned long long delta = now - next->timestamp;
@@ -3331,10 +3340,6 @@ go_idle:
 	}
 	next->sleep_type = SLEEP_NORMAL;
 switch_tasks:
-	if (next == rq->idle)
-		schedstat_inc(rq, sched_goidle);
-	prefetch(next);
-	prefetch_stack(next);
 	clear_tsk_need_resched(prev);
 	rcu_qsctr_inc(task_cpu(prev));
 
