diff options
author | Joel Stanley <joel@jms.id.au> | 2014-08-13 18:09:44 +1000 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2014-08-13 18:23:07 +1000 |
commit | bb8be0ec098a57796776b8a1d1fb49a220a539d8 (patch) | |
tree | 2fcfa1d238cfb11e2ec19db252938934c81bcf62 /core/cpu.c | |
parent | 52a920308d1850a85023e3b61678cf68c73593cc (diff) | |
download | skiboot-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.c | 16 |
1 files changed, 14 insertions, 2 deletions
@@ -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(); |