summaryrefslogtreecommitdiffstats
path: root/core/direct-controls.c
diff options
context:
space:
mode:
authorNicholas Piggin <npiggin@gmail.com>2017-12-05 09:53:08 +1000
committerStewart Smith <stewart@linux.vnet.ibm.com>2017-12-04 21:25:50 -0600
commit631ed5f2e06a0c55268b61cfaf89c833cef14ae1 (patch)
tree874716357736a5fe9d0a901fd5d4f25ce412b55d /core/direct-controls.c
parent9587573f4be085f949e1eed36f62fef98a77a394 (diff)
downloadblackbird-skiboot-631ed5f2e06a0c55268b61cfaf89c833cef14ae1.tar.gz
blackbird-skiboot-631ed5f2e06a0c55268b61cfaf89c833cef14ae1.zip
dctl: p9 increase thread quiesce timeout
We require all instructions to be completed before a thread is considered stopped, by the dctl interface. Long running instructions like cache misses and CI loads may take a significant amount of time to complete, and timeouts have been observed in stress testing. Increase the timeout significantly, to cover this. The workbook just says to poll, but we like to have timeouts to avoid getting stuck in firmware. Signed-off-by: Nicholas Piggin <npiggin@gmail.com> Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'core/direct-controls.c')
-rw-r--r--core/direct-controls.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/core/direct-controls.c b/core/direct-controls.c
index ba3e4d1d..411a1b28 100644
--- a/core/direct-controls.c
+++ b/core/direct-controls.c
@@ -263,7 +263,9 @@ static int p8_sreset_thread(struct cpu_thread *cpu)
#define P9_RAS_STATUS 0x10a02
#define P9_THREAD_QUIESCED(t) PPC_BITMASK(0 + 8*(t), 3 + 8*(t))
-#define P9_QUIESCE_RETRIES 100
+/* Long running instructions may take time to complete. Timeout 100ms */
+#define P9_QUIESCE_POLL_INTERVAL 100
+#define P9_QUIESCE_TIMEOUT 100000
#define P9_EC_DIRECT_CONTROLS 0x10a9c
#define P9_THREAD_STOP(t) PPC_BIT(7 + 8*(t))
@@ -306,7 +308,7 @@ static int p9_core_set_special_wakeup(struct cpu_thread *cpu)
return OPAL_HARDWARE;
}
- for (i = 0; i < P9_SPWKUP_TIMEOUT/P9_SPWKUP_POLL_INTERVAL; i++) {
+ for (i = 0; i < P9_SPWKUP_TIMEOUT / P9_SPWKUP_POLL_INTERVAL; i++) {
if (xscom_read(chip_id, sshhyp_addr, &val)) {
prlog(PR_ERR, "Could not set special wakeup on %u:%u:"
" Unable to read PPM_SSHHYP.\n",
@@ -357,7 +359,7 @@ static int p9_core_clear_special_wakeup(struct cpu_thread *cpu)
}
time_wait_us(1);
- for (i = 0; i < P9_SPWKUP_TIMEOUT/P9_SPWKUP_POLL_INTERVAL; i++) {
+ for (i = 0; i < P9_SPWKUP_TIMEOUT / P9_SPWKUP_POLL_INTERVAL; i++) {
if (xscom_read(chip_id, sshhyp_addr, &val)) {
prlog(PR_ERR, "Could not clear special wakeup on %u:%u:"
" Unable to read PPM_SSHHYP.\n",
@@ -392,6 +394,12 @@ static int p9_thread_quiesced(struct cpu_thread *cpu)
return OPAL_HARDWARE;
}
+ /*
+ * This returns true when the thread is quiesced and all
+ * instructions completed. For sreset this may not be necessary,
+ * but we may want to use instruction ramming or stepping
+ * direct controls where it is important.
+ */
if ((ras_status & P9_THREAD_QUIESCED(thread_id))
== P9_THREAD_QUIESCED(thread_id))
return 1;
@@ -425,12 +433,14 @@ static int p9_stop_thread(struct cpu_thread *cpu)
return OPAL_HARDWARE;
}
- for (i = 0; i < P9_QUIESCE_RETRIES; i++) {
+ for (i = 0; i < P9_QUIESCE_TIMEOUT / P9_QUIESCE_POLL_INTERVAL; i++) {
int rc = p9_thread_quiesced(cpu);
if (rc < 0)
break;
if (rc)
return 0;
+
+ time_wait_us(P9_QUIESCE_POLL_INTERVAL);
}
prlog(PR_ERR, "Could not stop thread %u:%u:%u:"
OpenPOWER on IntegriCloud