diff options
author | Stewart Smith <stewart@linux.vnet.ibm.com> | 2015-10-14 17:50:41 +1100 |
---|---|---|
committer | Stewart Smith <stewart@linux.vnet.ibm.com> | 2015-10-14 17:50:41 +1100 |
commit | a0e385b0ebbfa2c0a0d0b967cfa02500b839507c (patch) | |
tree | 3a3f3d888fef1b969c78e7dfc56476d91c7baede /core | |
parent | f44fae728db9adb6b6c1ff5d16f464bc166c19b8 (diff) | |
parent | a47b98e6709f8cb33ea7fd95bd2971c8373c1383 (diff) | |
download | talos-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.c | 24 |
1 files changed, 23 insertions, 1 deletions
@@ -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(); + } } /* |