Commit 8c27e07f authored by Fenghua Yu's avatar Fenghua Yu Committed by Linus Torvalds

[PATCH] add cpu_relax() in spin loops & clean up barrier()

The patch adds cpu_relax() in the body of some spin loops for 2.6.9.  The
patch also removes redundant barrier() code after cpu_relax() on ia32.

In the PAUSE instruction section, IA32 SDM claims "it is recommended that a
PASUE instruction be placed in all spin-wait loops".  And x86_64 SDM says
that PAUSE instruction is same as legacy mode in IA-32e mode operation.

This patch is against 2.6.9 (kernel.org).  It was tested on ia32 and
x86_64.
Acked-by: default avatarAndi Kleen <ak@muc.de>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent fc62f159
......@@ -149,10 +149,8 @@ static void ipi_handler(void *info)
local_irq_save(flags);
atomic_dec(&data->count);
while(!atomic_read(&data->gate)) {
while(!atomic_read(&data->gate))
cpu_relax();
barrier();
}
/* The master has cleared me to execute */
if (data->smp_reg != ~0U)
......@@ -162,10 +160,9 @@ static void ipi_handler(void *info)
mtrr_if->set_all();
atomic_dec(&data->count);
while(atomic_read(&data->gate)) {
while(atomic_read(&data->gate))
cpu_relax();
barrier();
}
atomic_dec(&data->count);
local_irq_restore(flags);
}
......@@ -230,10 +227,9 @@ static void set_mtrr(unsigned int reg, unsigned long base,
local_irq_save(flags);
while(atomic_read(&data.count)) {
while(atomic_read(&data.count))
cpu_relax();
barrier();
}
/* ok, reset count and toggle gate */
atomic_set(&data.count, num_booting_cpus() - 1);
atomic_set(&data.gate,1);
......@@ -250,10 +246,9 @@ static void set_mtrr(unsigned int reg, unsigned long base,
mtrr_if->set(reg,base,size,type);
/* wait for the others */
while(atomic_read(&data.count)) {
while(atomic_read(&data.count))
cpu_relax();
barrier();
}
atomic_set(&data.count, num_booting_cpus() - 1);
atomic_set(&data.gate,0);
......@@ -261,10 +256,9 @@ static void set_mtrr(unsigned int reg, unsigned long base,
* Wait here for everyone to have seen the gate change
* So we're the last ones to touch 'data'
*/
while(atomic_read(&data.count)) {
while(atomic_read(&data.count))
cpu_relax();
barrier();
}
local_irq_restore(flags);
}
......
......@@ -538,11 +538,11 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
/* Wait for response */
while (atomic_read(&data.started) != cpus)
barrier();
cpu_relax();
if (wait)
while (atomic_read(&data.finished) != cpus)
barrier();
cpu_relax();
spin_unlock(&call_lock);
return 0;
......
......@@ -310,10 +310,10 @@ static void __smp_call_function (void (*func) (void *info), void *info,
/* Wait for response */
while (atomic_read(&data.started) != cpus)
barrier();
cpu_relax();
while (atomic_read(&data.finished) != cpus)
barrier();
cpu_relax();
}
/*
......
......@@ -53,7 +53,8 @@ static __inline unsigned long apic_read(unsigned long reg)
static __inline__ void apic_wait_icr_idle(void)
{
do { } while ( apic_read( APIC_ICR ) & APIC_ICR_BUSY );
while ( apic_read( APIC_ICR ) & APIC_ICR_BUSY )
cpu_relax();
}
int get_physical_broadcast(void);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment