[Skiboot] [PATCH] SBE-p8: Do all sbe timer update with xscom lock held

Stewart Smith stewart at linux.ibm.com
Mon Sep 17 09:33:53 AEST 2018


Without this, on some P8 platforms, we could (falsely) think the SBE timer
had stalled getting the dreaded "timer stuck" message.

The code was doing the mftb() to set the start of the timeout period while
*not* holding the lock, so the 1ms timeout started sometime when somebody
else had the xscom lock.

The simple solution is to just do the whole routine holding the xscom lock,
so do it that way.

Signed-off-by: Stewart Smith <stewart at linux.ibm.com>
---
 hw/sbe-p8.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/hw/sbe-p8.c b/hw/sbe-p8.c
index 58049c715f93..452af41090da 100644
--- a/hw/sbe-p8.c
+++ b/hw/sbe-p8.c
@@ -71,7 +71,7 @@ static void p8_sbe_dump_timer_ffdc(void)
  */
 void p8_sbe_update_timer_expiry(uint64_t new_target)
 {
-	uint64_t count, gen, gen2, req, now = mftb();
+	uint64_t count, gen, gen2, req, now;
 	int64_t rc;
 
 	if (!sbe_has_timer || new_target == sbe_timer_target)
@@ -79,6 +79,8 @@ void p8_sbe_update_timer_expiry(uint64_t new_target)
 
 	sbe_timer_target = new_target;
 
+	_xscom_lock();
+	now = mftb();
 	/* Calculate how many increments from now, rounded up */
 	if (now < new_target)
 		count = (new_target - now + sbe_timer_inc - 1) / sbe_timer_inc;
@@ -95,7 +97,6 @@ void p8_sbe_update_timer_expiry(uint64_t new_target)
 
 	do {
 		/* Grab generation and spin if odd */
-		_xscom_lock();
 		for (;;) {
 			rc = _xscom_read(sbe_timer_chip, 0xE0006, &gen, false);
 			if (rc) {
@@ -148,8 +149,8 @@ void p8_sbe_update_timer_expiry(uint64_t new_target)
 			_xscom_unlock();
 			return;
 		}
-		_xscom_unlock();
 	} while(gen != gen2);
+	_xscom_unlock();
 
 	/* Check if the timer is working. If at least 1ms has elapsed
 	 * since the last call to this function, check that the gen
-- 
2.17.1



More information about the Skiboot mailing list