summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorStewart Smith <stewart@linux.vnet.ibm.com>2015-10-14 17:50:41 +1100
committerStewart Smith <stewart@linux.vnet.ibm.com>2015-10-14 17:50:41 +1100
commita0e385b0ebbfa2c0a0d0b967cfa02500b839507c (patch)
tree3a3f3d888fef1b969c78e7dfc56476d91c7baede /core
parentf44fae728db9adb6b6c1ff5d16f464bc166c19b8 (diff)
parenta47b98e6709f8cb33ea7fd95bd2971c8373c1383 (diff)
downloadtalos-skiboot-a0e385b0ebbfa2c0a0d0b967cfa02500b839507c.tar.gz
talos-skiboot-a0e385b0ebbfa2c0a0d0b967cfa02500b839507c.zip
Merge fix for soft lockup on TB errors from branch 'stable'
Diffstat (limited to 'core')
-rw-r--r--core/hmi.c24
1 files changed, 23 insertions, 1 deletions
diff --git a/core/hmi.c b/core/hmi.c
index ee556fca..1bae71a5 100644
--- a/core/hmi.c
+++ b/core/hmi.c
@@ -164,6 +164,9 @@
*/
#define NX_HMI_ACTIVE PPC_BIT(54)
+/* Number of iterations for the various timeouts */
+#define TIMEOUT_LOOPS 20000000
+
static const struct core_xstop_bit_info {
uint8_t bit; /* CORE FIR bit number */
enum OpalHMI_CoreXstopReason reason;
@@ -448,8 +451,27 @@ static int decode_malfunction(struct OpalHMIEvent *hmi_evt)
static void wait_for_subcore_threads(void)
{
- while (!(*(this_cpu()->core_hmi_state_ptr) & HMI_STATE_CLEANUP_DONE))
+ uint64_t timeout = 0;
+
+ while (!(*(this_cpu()->core_hmi_state_ptr) & HMI_STATE_CLEANUP_DONE)) {
+ /*
+ * We use a fixed number of TIMEOUT_LOOPS rather
+ * than using the timebase to do a pseudo-wall time
+ * timeout due to the fact that timebase may not actually
+ * work at this point in time.
+ */
+ if (++timeout >= (TIMEOUT_LOOPS*3)) {
+ /*
+ * Break out the loop here and fall through
+ * recovery code. If recovery fails, kernel will get
+ * informed about the failure. This way we can avoid
+ * looping here if other threads are stuck.
+ */
+ prlog(PR_DEBUG, "HMI: TB pre-recovery timeout\n");
+ break;
+ }
cpu_relax();
+ }
}
/*
OpenPOWER on IntegriCloud