From: Nick Piggin I think this might be causing problems. Maybe its there for a reason, but if so then I think some more work needs to be done. An idle CPU will be unable to pull tasks from a runqueue if they have all been run very recently. This patch changes that. Maybe it overbalances on other loads. It would be good to try those benchmarks on it... kernel/sched.c | 18 ++++++++++-------- 1 files changed, 10 insertions(+), 8 deletions(-) diff -puN kernel/sched.c~sched-cpu-migration-fix kernel/sched.c --- 25/kernel/sched.c~sched-cpu-migration-fix 2003-08-26 01:42:36.000000000 -0700 +++ 25-akpm/kernel/sched.c 2003-08-26 01:42:36.000000000 -0700 @@ -1125,7 +1125,7 @@ can_migrate_task(task_t *tsk, runqueue_t { unsigned long delta = sched_clock() - tsk->timestamp; - if (idle && (delta <= JIFFIES_TO_NS(cache_decay_ticks))) + if (!idle && (delta <= JIFFIES_TO_NS(cache_decay_ticks))) return 0; if (task_running(rq, tsk)) return 0; @@ -1276,15 +1276,17 @@ static void rebalance_tick(runqueue_t *t load_balance(this_rq, idle, cpu_to_node_mask(this_cpu)); spin_unlock(&this_rq->lock); } - } + + } else { #ifdef CONFIG_NUMA - if (!(j % BUSY_NODE_REBALANCE_TICK)) - balance_node(this_rq, idle, this_cpu); + if (!(j % BUSY_NODE_REBALANCE_TICK)) + balance_node(this_rq, idle, this_cpu); #endif - if (!(j % BUSY_REBALANCE_TICK)) { - spin_lock(&this_rq->lock); - load_balance(this_rq, 0, cpu_to_node_mask(this_cpu)); - spin_unlock(&this_rq->lock); + if (!(j % BUSY_REBALANCE_TICK)) { + spin_lock(&this_rq->lock); + load_balance(this_rq, idle, cpu_to_node_mask(this_cpu)); + spin_unlock(&this_rq->lock); + } } } #else _