aboutsummaryrefslogtreecommitdiff
path: root/include/cpu.h
diff options
context:
space:
mode:
authorMahesh Salgaonkar <mahesh@linux.vnet.ibm.com>2015-10-07 00:18:06 +0530
committerStewart Smith <stewart@linux.vnet.ibm.com>2015-10-14 17:42:05 +1100
commita47b98e6709f8cb33ea7fd95bd2971c8373c1383 (patch)
treedefa8cfd713c22993a7fe670b2d3473d668cd267 /include/cpu.h
parentb5d8248fb88fd6060f43483ba41cf5a1e66ea8a8 (diff)
downloadskiboot-a47b98e6709f8cb33ea7fd95bd2971c8373c1383.zip
skiboot-a47b98e6709f8cb33ea7fd95bd2971c8373c1383.tar.gz
skiboot-a47b98e6709f8cb33ea7fd95bd2971c8373c1383.tar.bz2
opal/hmi: Fix the soft lockup issue on HMI for certain TB errors.
A while loop from wait_for_subcore_threads() function loops until one thread from each subcore completes the pre-cleanup task and sets a cleanup done bit. while (!(*(this_cpu()->core_hmi_state_ptr) & HMI_STATE_CLEANUP_DONE)) cpu_relax(); Without a memory barrier we see that the compiler optimizes the above while loop not to re-fetch the data from memory pointed by this_cpu()->core_hmi_state_ptr. This makes CPU to spin infinitely even though the other CPUs have modified the data causing soft lockup in kernel. There are two ways to fix this, 1) introduce volatile specifier to force re-read the fresh value from the memory. 2) Add barrier() call to cpu_relax(). Second approach will avoid similar bugs in future. This patch uses the second approach to fix this issue. This patch also introduces a timeout for the while loop to handle a worst situation where all other threads are badly stuck without setting a cleanup done bit. Under such situation timeout will help to avoid soft lockups and report failure to kernel. Signed-off-by: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com> [stewart@linux.vnet.ibm.com: add explanation as to why we don't use timebase for timeout] Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'include/cpu.h')
-rw-r--r--include/cpu.h1
1 files changed, 1 insertions, 0 deletions
diff --git a/include/cpu.h b/include/cpu.h
index 03a51f9..982b48a 100644
--- a/include/cpu.h
+++ b/include/cpu.h
@@ -113,6 +113,7 @@ static inline void __nomcount cpu_relax(void)
"nop; nop; nop; nop;\n"
"nop; nop; nop; nop;\n");
smt_medium();
+ barrier();
}
/* Initialize CPUs */