[Skiboot] [PATCH 2/2] slw: Better instrumentation of SLW timer errors

Benjamin Herrenschmidt benh at kernel.crashing.org
Thu Sep 8 16:05:53 AEST 2016


Print the number of iterations trying to obtain an "even" value off
the SLW. Don't account the time spent trying to get identical
generations in the delay to get even values. Finally, add a max
retry of 100 for generation changes happening in the loop and
display the interation counts in all cases.

Signed-off-by: Benjamin Herrenschmidt <benh at kernel.crashing.org>
---
 hw/slw.c | 26 +++++++++++++++++++++-----
 1 file changed, 21 insertions(+), 5 deletions(-)

diff --git a/hw/slw.c b/hw/slw.c
index 74b9cd5..e4a30d1 100644
--- a/hw/slw.c
+++ b/hw/slw.c
@@ -1216,7 +1216,7 @@ static void slw_dump_timer_ffdc(void)
  */
 void slw_update_timer_expiry(uint64_t new_target)
 {
-	uint64_t count, gen, gen2, req, now = mftb();
+	uint64_t count, gen, gen2, req, iter1, iter2, now = mftb();
 	int64_t rc;
 
 	if (!slw_has_timer || new_target == slw_timer_target)
@@ -1238,9 +1238,9 @@ void slw_update_timer_expiry(uint64_t new_target)
 
 	prlog(PR_TRACE, "SLW: TMR expiry: 0x%llx, req: %016llx\n", count, req);
 
-	do {
+	for(iter2 = 0;; iter2++) {
 		/* Grab generation and spin if odd */
-		for (;;) {
+		for (iter1 = 0;; iter1++) {
 			rc = xscom_read(slw_timer_chip, 0xE0006, &gen);
 			if (rc) {
 				prerror("SLW: Error %lld reading tmr gen "
@@ -1250,7 +1250,8 @@ void slw_update_timer_expiry(uint64_t new_target)
 			if (!(gen & 1))
 				break;
 			if (tb_compare(now + msecs_to_tb(1), mftb()) == TB_ABEFOREB) {
-				prerror("SLW: Stuck with odd generation !\n");
+				prerror("SLW: Stuck with odd generation"
+					" for %lld iterations !\n", iter1);
 				slw_has_timer = false;
 				slw_dump_timer_ffdc();
 				return;
@@ -1270,7 +1271,22 @@ void slw_update_timer_expiry(uint64_t new_target)
 				" count\n", rc);
 			return;
 		}
-	} while(gen != gen2);
+
+		/* Generation didn't change, bail out */
+		if (gen == gen2)
+			break;
+
+		if (iter2 > 100) {
+			prerror("SLW: %lld changes of generation in a loop, giving up !\n",
+				iter2);
+			slw_has_timer = false;
+			slw_dump_timer_ffdc();
+			return;
+		}
+
+		/* Timestamp */
+		now = mftb();
+	}
 
 	/* Check if the timer is working. If at least 1ms has elapsed
 	 * since the last call to this function, check that the gen
-- 
2.7.4



More information about the Skiboot mailing list