From 502ca3e72e19278d25a390e2f9e891d632a2a44b Mon Sep 17 00:00:00 2001 From: Dean Sanner Date: Fri, 8 Feb 2019 06:58:44 -0600 Subject: Find cpu struct directly in doorbell interrupt handler This fix accesses the cpu struct based on current thread PIR instead of relying on an indirect pointer in the current task struct. It is attempting to eliminate a weak consistency/timing issue on the thread wakeups on the secondary cores. Given the way hostboot wakes up from the doorbell, there is a good chunck of code executed prior to the doorbell interrupt handler --> this also adds a msgsync instruction in the sreset (0x100) interrupt handler. Change-Id: I23db1d786a8a8f0637a890e2ac5de6197ee9cabb Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/71582 Tested-by: Jenkins Server Reviewed-by: William G. Hoffa Tested-by: Jenkins OP Build CI Tested-by: FSP CI Jenkins Reviewed-by: Nicholas E. Bofferding Tested-by: Jenkins OP HW Reviewed-by: Daniel M. Crowell --- src/kernel/start.S | 6 +++++- src/kernel/syscall.C | 7 ++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/kernel/start.S b/src/kernel/start.S index 0eda5b003..5b99ef691 100644 --- a/src/kernel/start.S +++ b/src/kernel/start.S @@ -5,7 +5,7 @@ # # OpenPOWER HostBoot Project # -# Contributors Listed Below - COPYRIGHT 2010,2018 +# Contributors Listed Below - COPYRIGHT 2010,2019 # [+] International Business Machines Corp. # [+] Joel Stanley # @@ -765,6 +765,10 @@ intvect_system_reset: ;// Raise priority to high. or 2,2,2 + ;// Need to send a msgysnc to prevent weak consistency issues + ;// with doorbells (they execute this path prior to dbell intr) + .long 0x7C0006EC + ;// Free up two registers temporarily. mtsprg0 r1 mtsprg1 r2 diff --git a/src/kernel/syscall.C b/src/kernel/syscall.C index 1df43b78e..ff45f1ccf 100644 --- a/src/kernel/syscall.C +++ b/src/kernel/syscall.C @@ -65,19 +65,20 @@ void kernel_execute_hyp_doorbell() doorbell_clear(); //Execute all work items on doorbell_actions stack - KernelWorkItem *l_work = t->cpu->doorbell_actions.pop(); + cpu_t* l_cpu = CpuManager::getCurrentCPU(); + KernelWorkItem *l_work = l_cpu->doorbell_actions.pop(); while(l_work != nullptr) { //Execute Work Item and then delete it (*l_work)(); delete l_work; - l_work = t->cpu->doorbell_actions.pop(); + l_work = l_cpu->doorbell_actions.pop(); } //IPC messages come in only on the master, so //If this is a doorbell to the master -- check cpu_t* master = CpuManager::getMasterCPU(); - if(t->cpu == master) + if(l_cpu == master) { size_t pir = getPIR(); printk("IPC msg pir %lx incoming\n", pir); -- cgit v1.2.1