[Skiboot] [PATCH 3/4] Convert important polling loops to spin at lowest SMT priority

Nicholas Piggin npiggin at gmail.com
Mon May 22 15:53:02 AEST 2017


The pattern of calling cpu_relax() inside a polling loop does
not suit the powerpc SMT priority instructions. Prefrred is to
set a low priority then spin until break condition is reached,
then restore priority.

Signed-off-by: Nicholas Piggin <npiggin at gmail.com>
---
 core/hmi.c    |  4 +++-
 core/lock.c   |  5 ++++-
 core/timer.c  |  5 ++++-
 hw/lpc-uart.c | 10 +++++++---
 4 files changed, 18 insertions(+), 6 deletions(-)

diff --git a/core/hmi.c b/core/hmi.c
index e55a85b2..06d83476 100644
--- a/core/hmi.c
+++ b/core/hmi.c
@@ -599,6 +599,7 @@ static void wait_for_subcore_threads(void)
 {
 	uint64_t timeout = 0;
 
+	smt_lowest();
 	while (!(*(this_cpu()->core_hmi_state_ptr) & HMI_STATE_CLEANUP_DONE)) {
 		/*
 		 * We use a fixed number of TIMEOUT_LOOPS rather
@@ -616,8 +617,9 @@ static void wait_for_subcore_threads(void)
 			prlog(PR_DEBUG, "HMI: TB pre-recovery timeout\n");
 			break;
 		}
-		cpu_relax();
+		barrier();
 	}
+	smt_medium();
 }
 
 /*
diff --git a/core/lock.c b/core/lock.c
index e82048bf..0868f2ba 100644
--- a/core/lock.c
+++ b/core/lock.c
@@ -93,7 +93,10 @@ void lock(struct lock *l)
 	for (;;) {
 		if (try_lock(l))
 			break;
-		cpu_relax();
+		smt_lowest();
+		while (l->lock_val)
+			barrier();
+		smt_medium();
 	}
 }
 
diff --git a/core/timer.c b/core/timer.c
index 75489963..4b5925fe 100644
--- a/core/timer.c
+++ b/core/timer.c
@@ -45,7 +45,10 @@ static void __sync_timer(struct timer *t)
 
 	while (t->running) {
 		unlock(&timer_lock);
-		cpu_relax();
+		smt_lowest();
+		while (t->running)
+			barrier();
+		smt_medium();
 		/* Should we call the pollers here ? */
 		lock(&timer_lock);
 	}
diff --git a/hw/lpc-uart.c b/hw/lpc-uart.c
index 6e349ef9..912bffa5 100644
--- a/hw/lpc-uart.c
+++ b/hw/lpc-uart.c
@@ -115,10 +115,14 @@ static void uart_check_tx_room(void)
 
 static void uart_wait_tx_room(void)
 {
-	while(!tx_room) {
+	while (!tx_room) {
 		uart_check_tx_room();
-		if (!tx_room)
-			cpu_relax();
+		if (!tx_room) {
+			smt_lowest();
+			while (!tx_room)
+				barrier();
+			smt_medium();
+		}
 	}
 }
 
-- 
2.11.0



More information about the Skiboot mailing list