From: Zwane Mwaikambo Andi noted that during normal runtime cpu_idle_map is bounced around a lot, and occassionally at a higher frequency than the timer interrupt wakeup which we normally exit pm_idle from. So switch to a percpu variable. I didn't move things to the slow path because it would involve adding scheduler code to wakeup the idle thread on the cpus we're waiting for. Signed-off-by: Zwane Mwaikambo Signed-off-by: Andrew Morton --- 25-akpm/arch/i386/kernel/process.c | 27 ++++++++++++++++++++------- 1 files changed, 20 insertions(+), 7 deletions(-) diff -puN arch/i386/kernel/process.c~x86-reduce-cacheline-bouncing-in-cpu_idle_wait arch/i386/kernel/process.c --- 25/arch/i386/kernel/process.c~x86-reduce-cacheline-bouncing-in-cpu_idle_wait 2005-03-13 20:11:40.000000000 -0800 +++ 25-akpm/arch/i386/kernel/process.c 2005-03-13 20:11:40.000000000 -0800 @@ -73,7 +73,7 @@ unsigned long thread_saved_pc(struct tas * Powermanagement idle function, if any.. */ void (*pm_idle)(void); -static cpumask_t cpu_idle_map; +static DEFINE_PER_CPU(unsigned int, cpu_idle_state); void disable_hlt(void) { @@ -153,8 +153,9 @@ void cpu_idle (void) while (!need_resched()) { void (*idle)(void); - if (cpu_isset(cpu, cpu_idle_map)) - cpu_clear(cpu, cpu_idle_map); + if (__get_cpu_var(cpu_idle_state)) + __get_cpu_var(cpu_idle_state) = 0; + rmb(); idle = pm_idle; @@ -170,16 +171,28 @@ void cpu_idle (void) void cpu_idle_wait(void) { - int cpu; + unsigned int cpu, this_cpu = get_cpu(); cpumask_t map; - for_each_online_cpu(cpu) - cpu_set(cpu, cpu_idle_map); + set_cpus_allowed(current, cpumask_of_cpu(this_cpu)); + put_cpu(); + + cpus_clear(map); + for_each_online_cpu(cpu) { + per_cpu(cpu_idle_state, cpu) = 1; + cpu_set(cpu, map); + } + + __get_cpu_var(cpu_idle_state) = 0; wmb(); do { ssleep(1); - cpus_and(map, cpu_idle_map, cpu_online_map); + for_each_online_cpu(cpu) { + if (cpu_isset(cpu, map) && !per_cpu(cpu_idle_state, cpu)) + cpu_clear(cpu, map); + } + cpus_and(map, map, cpu_online_map); } while (!cpus_empty(map)); } EXPORT_SYMBOL_GPL(cpu_idle_wait); _