aboutsummaryrefslogtreecommitdiff
path: root/core/cpu.c
diff options
context:
space:
mode:
authorJoel Stanley <joel@jms.id.au>2014-08-13 18:09:44 +1000
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2014-08-13 18:23:07 +1000
commitbb8be0ec098a57796776b8a1d1fb49a220a539d8 (patch)
tree2fcfa1d238cfb11e2ec19db252938934c81bcf62 /core/cpu.c
parent52a920308d1850a85023e3b61678cf68c73593cc (diff)
downloadskiboot-bb8be0ec098a57796776b8a1d1fb49a220a539d8.zip
skiboot-bb8be0ec098a57796776b8a1d1fb49a220a539d8.tar.gz
skiboot-bb8be0ec098a57796776b8a1d1fb49a220a539d8.tar.bz2
Add cpu_relax to stop cores spinning hard
Ensure a thread is not stopping its siblings from making forward progress when we are busy-waiting on older DD1.x CPU revisions where SMT priorities are somewhat broken. Signed-off-by: Joel Stanley <joel@jms.id.au> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'core/cpu.c')
-rw-r--r--core/cpu.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/core/cpu.c b/core/cpu.c
index 8376559..7ce7c60 100644
--- a/core/cpu.c
+++ b/core/cpu.c
@@ -62,6 +62,19 @@ void __attrconst *cpu_stack_bottom(unsigned int pir)
return (void *)&cpu_stacks[pir] + sizeof(struct cpu_thread);
}
+void cpu_relax(void)
+{
+ /* Relax a bit to give sibling threads some breathing space */
+ smt_low();
+ smt_very_low();
+ asm volatile("nop; nop; nop\n");
+ asm volatile("nop; nop; nop\n");
+ asm volatile("nop; nop; nop\n");
+ asm volatile("nop; nop; nop\n");
+ asm volatile("nop; nop; nop\n");
+ smt_medium();
+}
+
void __attrconst *cpu_stack_top(unsigned int pir)
{
/* This is the top of the MC stack which is above the normal
@@ -121,8 +134,7 @@ void cpu_wait_job(struct cpu_job *job, bool free_it)
/* Handle pollers if master CPU */
if (this_cpu() == boot_cpu)
opal_run_pollers();
- else
- smt_low();
+ cpu_relax();
lwsync();
}
lwsync();