From: Ingo Molnar Change the order of tasks to be moved. This and the following patch will need more testing on big systems where it could hurt, but for now I guess it can go in. Breaking these out just makes them easier for people to test. --- 25-akpm/kernel/sched.c | 42 ++++++++++++++++++++++++++---------------- 1 files changed, 26 insertions(+), 16 deletions(-) diff -puN kernel/sched.c~sched-move-cold-task kernel/sched.c --- 25/kernel/sched.c~sched-move-cold-task 2004-04-05 18:45:30.816526744 -0700 +++ 25-akpm/kernel/sched.c 2004-04-05 18:45:30.824525528 -0700 @@ -331,6 +331,21 @@ static void enqueue_task(struct task_str p->array = array; } +#ifdef CONFIG_SMP +/* + * Used by the migration code - we pull tasks from the head of the + * remote queue so we want these tasks to show up at the head of the + * local queue: + */ +static inline void enqueue_task_head(struct task_struct *p, prio_array_t *array) +{ + list_add(&p->run_list, array->queue + p->prio); + __set_bit(p->prio, array->bitmap); + array->nr_active++; + p->array = array; +} +#endif + /* * effective_prio - return the priority that is based on the static * priority but is modified by bonuses/penalties. @@ -1262,7 +1277,7 @@ void pull_task(runqueue_t *src_rq, prio_ src_rq->nr_running--; set_task_cpu(p, this_cpu); this_rq->nr_running++; - enqueue_task(p, this_array); + enqueue_task_head(p, this_array); p->timestamp = sched_clock() - (src_rq->timestamp_last_tick - p->timestamp); /* @@ -1320,18 +1335,13 @@ static int move_tasks(runqueue_t *this_r if (max_nr_move <= 0 || busiest->nr_running <= 1) goto out; - /* - * We first consider expired tasks. Those will likely not be - * executed in the near future, and they are most likely to - * be cache-cold, thus switching CPUs has the least effect - * on them. - */ - if (busiest->expired->nr_active) { - array = busiest->expired; - dst_array = this_rq->expired; - } else { + /* We first consider active tasks. */ + if (busiest->active->nr_active) { array = busiest->active; dst_array = this_rq->active; + } else { + array = busiest->expired; + dst_array = this_rq->expired; } new_array: @@ -1343,20 +1353,20 @@ skip_bitmap: else idx = find_next_bit(array->bitmap, MAX_PRIO, idx); if (idx >= MAX_PRIO) { - if (array == busiest->expired && busiest->active->nr_active) { - array = busiest->active; - dst_array = this_rq->active; + if (array == busiest->active && busiest->expired->nr_active) { + array = busiest->expired; + dst_array = this_rq->expired; goto new_array; } goto out; } head = array->queue + idx; - curr = head->prev; + curr = head->next; skip_queue: tmp = list_entry(curr, task_t, run_list); - curr = curr->prev; + curr = curr->next; if (!can_migrate_task(tmp, busiest, this_cpu, sd, idle)) { if (curr != head) _