summaryrefslogtreecommitdiffstats
path: root/arch/openrisc/kernel/smp.c
diff options
context:
space:
mode:
authorStafford Horne <shorne@gmail.com>2017-06-24 07:09:59 +0900
committerStafford Horne <shorne@gmail.com>2017-11-03 14:01:14 +0900
commitc056718464512da06d7f65a27d5e4f1707b24c80 (patch)
tree3b3b3076d876428ae8b81826f7171f22e84009a5 /arch/openrisc/kernel/smp.c
parentb441aab7aa0e15955c432736b08a218a6a4c77f0 (diff)
openrisc: sleep instead of spin on secondary wait
Currently we do a spin on secondary cpus when waiting to boot. This theoretically causes issues with power consumption and does cause issues with qemu cycle burning (it starves cpu 0 from actually being able to boot.) This change puts each secondary cpu to sleep if they have a power management unit, then signals them to wake via IPI when its time to boot. If the cpus have no power management unit they will loop as before. Note: The wakeup IPI requires a special interrupt handler as on secondary cpu's the interrupt infrastructure is not yet established. This interrupt handler is set and reset by updating SPR_EVBAR. Signed-off-by: Stafford Horne <shorne@gmail.com>
Diffstat (limited to 'arch/openrisc/kernel/smp.c')
-rw-r--r--arch/openrisc/kernel/smp.c5
1 files changed, 5 insertions, 0 deletions
diff --git a/arch/openrisc/kernel/smp.c b/arch/openrisc/kernel/smp.c
index 154c94a0cfbc..685b4934fa39 100644
--- a/arch/openrisc/kernel/smp.c
+++ b/arch/openrisc/kernel/smp.c
@@ -26,6 +26,7 @@ unsigned long secondary_release = -1;
struct thread_info *secondary_thread_info;
enum ipi_msg_type {
+ IPI_WAKEUP,
IPI_RESCHEDULE,
IPI_CALL_FUNC,
IPI_CALL_FUNC_SINGLE,
@@ -42,6 +43,7 @@ static void boot_secondary(unsigned int cpu, struct task_struct *idle)
spin_lock(&boot_lock);
secondary_release = cpu;
+ smp_cross_call(cpumask_of(cpu), IPI_WAKEUP);
/*
* now the secondary core is starting up let it run its
@@ -140,6 +142,9 @@ void handle_IPI(unsigned int ipi_msg)
unsigned int cpu = smp_processor_id();
switch (ipi_msg) {
+ case IPI_WAKEUP:
+ break;
+
case IPI_RESCHEDULE:
scheduler_ipi();
break;