Index: linux-2.6.19-rc2-mm2/kernel/sched.c =================================================================== --- linux-2.6.19-rc2-mm2.orig/kernel/sched.c 2006-10-23 22:29:15.000000000 -0500 +++ linux-2.6.19-rc2-mm2/kernel/sched.c 2006-10-23 22:48:07.695098795 -0500 @@ -2817,6 +2817,8 @@ static void active_load_balance(struct r spin_unlock(&target_rq->lock); } +static DEFINE_PER_CPU(unsigned long, next_balance); + /* * rebalance_domains is called when needed from the migration thread. * @@ -2826,9 +2828,10 @@ static void active_load_balance(struct r * * Balancing parameters are set up in arch_init_sched_domains. */ -static unsigned long -rebalance_domains(int this_cpu, struct rq *this_rq) +static void rebalance_domains(unsigned long dummy) { + int this_cpu = smp_processor_id(); + struct rq *this_rq = cpu_rq(this_cpu); unsigned long interval; struct sched_domain *sd; /* Idle means on the idle queue without a runnable task */ @@ -2863,8 +2866,10 @@ rebalance_domains(int this_cpu, struct r } next_balance = min(next_balance, sd->next_balance); } - return next_balance; + __get_cpu_var(next_balance) = next_balance; } + +DECLARE_TASKLET(rebalance, &rebalance_domains, 0L); #else /* * on UP we do not need to balance between CPUs: @@ -3110,8 +3115,6 @@ out_unlock: spin_unlock(&rq->lock); } -static DEFINE_PER_CPU(unsigned long, next_balance); - /* * This function gets called by the timer code, with HZ frequency. * We call it with interrupts disabled. @@ -3143,7 +3146,7 @@ void scheduler_tick(void) } update_load(rq); if (jiffies >= __get_cpu_var(next_balance)) - __get_cpu_var(next_balance) = rebalance_domains(cpu, rq); + tasklet_schedule(&rebalance); } #ifdef CONFIG_SCHED_SMT