Index: linux-2.6.19-rc4-mm2/include/asm-ia64/topology.h =================================================================== --- linux-2.6.19-rc4-mm2.orig/include/asm-ia64/topology.h 2006-11-10 21:13:20.554975620 -0600 +++ linux-2.6.19-rc4-mm2/include/asm-ia64/topology.h 2006-11-10 22:46:45.395884734 -0600 @@ -101,6 +101,7 @@ void build_cpu_to_node_map(void); .flags = SD_LOAD_BALANCE \ | SD_BALANCE_EXEC \ | SD_BALANCE_FORK \ + | SD_SERIALIZE \ | SD_WAKE_BALANCE, \ .last_balance = jiffies, \ .balance_interval = 64, \ Index: linux-2.6.19-rc4-mm2/include/linux/sched.h =================================================================== --- linux-2.6.19-rc4-mm2.orig/include/linux/sched.h 2006-11-10 21:13:20.090092031 -0600 +++ linux-2.6.19-rc4-mm2/include/linux/sched.h 2006-11-10 22:46:45.495502632 -0600 @@ -647,6 +647,7 @@ enum idle_type #define SD_SHARE_CPUPOWER 128 /* Domain members share cpu power */ #define SD_POWERSAVINGS_BALANCE 256 /* Balance for power savings */ #define SD_SHARE_PKG_RESOURCES 512 /* Domain members share cpu pkg resources */ +#define SD_SERIALIZE 1024 /* Only a single load balancing instance */ #define BALANCE_FOR_MC_POWER \ (sched_smt_power_savings ? SD_POWERSAVINGS_BALANCE : 0) Index: linux-2.6.19-rc4-mm2/include/linux/topology.h =================================================================== --- linux-2.6.19-rc4-mm2.orig/include/linux/topology.h 2006-11-10 22:45:24.408486940 -0600 +++ linux-2.6.19-rc4-mm2/include/linux/topology.h 2006-11-10 22:46:45.531638536 -0600 @@ -194,7 +194,8 @@ .wake_idx = 0, /* unused */ \ .forkexec_idx = 0, /* unused */ \ .per_cpu_gain = 100, \ - .flags = SD_LOAD_BALANCE, \ + .flags = SD_LOAD_BALANCE \ + | SD_SERIALIZE, \ .last_balance = jiffies, \ .balance_interval = 64, \ .nr_balance_failed = 0, \ Index: linux-2.6.19-rc4-mm2/kernel/sched.c =================================================================== --- linux-2.6.19-rc4-mm2.orig/kernel/sched.c 2006-11-10 22:46:29.518549748 -0600 +++ linux-2.6.19-rc4-mm2/kernel/sched.c 2006-11-10 22:46:45.659579170 -0600 @@ -2871,6 +2871,7 @@ static void run_rebalance_domains(struct struct rq *this_rq = cpu_rq(this_cpu); unsigned long interval; struct sched_domain *sd; + static atomic_t nr_balancing = ATOMIC_INIT(0); /* * We are idle if there are no processes running. This * is valid even if we are the idle process (SMT). @@ -2893,6 +2894,11 @@ static void run_rebalance_domains(struct if (unlikely(!interval)) interval = 1; + if (sd->flags & SD_SERIALIZE) { + if (!atomic_add_unless(&nr_balancing, 1, 1)) + goto out; + } + if (time_after_eq(jiffies, sd->last_balance + interval)) { if (load_balance(this_cpu, this_rq, sd, idle)) { /* @@ -2904,6 +2910,10 @@ static void run_rebalance_domains(struct } sd->last_balance = jiffies; } + + if (sd->flags & SD_SERIALIZE) + atomic_dec(&nr_balancing); +out: /* * Calculate the next balancing point assuming that * the idle state does not change. If we are idle and then