Index: MM-2.6.17-rc1-mm2/kernel/sched.c =================================================================== --- MM-2.6.17-rc1-mm2.orig/kernel/sched.c 2006-04-13 10:53:32.000000000 +1000 +++ MM-2.6.17-rc1-mm2/kernel/sched.c 2006-04-13 11:08:45.000000000 +1000 @@ -2043,7 +2043,7 @@ static int move_tasks(runqueue_t *this_r { prio_array_t *array, *dst_array; struct list_head *head, *curr; - int idx, pulled = 0, pinned = 0; + int idx, pulled = 0, pinned = 0, this_min_prio; long rem_load_move; task_t *tmp; @@ -2052,6 +2052,7 @@ static int move_tasks(runqueue_t *this_r rem_load_move = max_load_move; pinned = 1; + this_min_prio = this_rq->curr->prio; /* * We first consider expired tasks. Those will likely not be @@ -2091,7 +2092,12 @@ skip_queue: curr = curr->prev; - if (tmp->load_weight > rem_load_move || + /* + * To help distribute high priority tasks accross CPUs we don't + * skip a task if it will be the highest priority task (i.e. smallest + * prio value) on its new queue regardless of its load weight + */ + if ((idx >= this_min_prio && tmp->load_weight > rem_load_move) || !can_migrate_task(tmp, busiest, this_cpu, sd, idle, &pinned)) { if (curr != head) goto skip_queue; @@ -2113,6 +2119,8 @@ skip_queue: * and the prescribed amount of weighted load. */ if (pulled < max_nr_move && rem_load_move > 0) { + if (idx < this_min_prio) + this_min_prio = idx; if (curr != head) goto skip_queue; idx++;