[Skiboot] [RFC PATCH] FSP: Solidify timeout poll code

Benjamin Herrenschmidt benh at au1.ibm.com
Tue Dec 9 07:37:11 AEDT 2014


Here's a reworked version that I've asked them to test. I'll commit
if it passes the tests to both update-2.1.1.1 and master.

Ben.

diff --git a/hw/fsp/fsp.c b/hw/fsp/fsp.c
index 8a73f2c..37bf07b 100644
--- a/hw/fsp/fsp.c
+++ b/hw/fsp/fsp.c
@@ -91,6 +91,7 @@ static void *fsp_inbound_buf = NULL;
 static u32 fsp_inbound_off;
 
 static struct lock fsp_lock = LOCK_UNLOCKED;
+static struct lock fsp_poll_lock = LOCK_UNLOCKED;
 
 static u64 fsp_cmdclass_resp_bitmask;
 static u64 timeout_timer;
@@ -1920,11 +1921,14 @@ static void fsp_timeout_poll(void *data __unused)
 	 * So every 30secs, check if there is any message
 	 * waiting for a response from the FSP
 	 */
-	if ((tb_compare(now, timeout_timer) == TB_AAFTERB) ||
-		(tb_compare(now, timeout_timer) == TB_AEQUALB))
-		timeout_timer = now + secs_to_tb(30);
-	else
+	if (tb_compare(now, timeout_timer) == TB_ABEFOREB)
+		return;
+	if (!try_lock(&fsp_poll_lock))
+		return;
+	if (tb_compare(now, timeout_timer) == TB_ABEFOREB) {
+		unlock(&fsp_poll_lock);
 		return;
+	}
 
 	while (cmdclass_resp_bitmask) {
 		u64 time_sent = 0;
@@ -1940,26 +1944,32 @@ static void fsp_timeout_poll(void *data __unused)
 
 		/* Now check if the response has timed out */
 		if (tb_compare(time_to_comp, timeout_val) == TB_AAFTERB) {
-			u64 resetbit = 0;
 			u32 w0, w1;
 			enum fsp_msg_state mstate;
 
 			/* Take the FSP lock now and re-check */
 			lock(&fsp_lock);
-			if (!(fsp_cmdclass_resp_bitmask & (1 << index)) ||
+			if (!(fsp_cmdclass_resp_bitmask & (1ull << index)) ||
 			    time_sent != cmdclass->timesent) {
 				unlock(&fsp_lock);
 				goto next_bit;
-			}
+			}			
 			req = list_top(&cmdclass->msgq,	struct fsp_msg, link);
+			if (!req) {
+				printf("FSP: Timeout state mismatch on class %d\n",
+				       index);
+				fsp_cmdclass_resp_bitmask &= ~(1ull << index);
+				cmdclass->timesent = 0;
+				unlock(&fsp_lock);
+				goto next_bit;
+			}
 			w0 = req->word0;
 			w1 = req->word1;
 			mstate = req->state;
 			printf("FSP: Response from FSP timed out, word0 = %x,"
 			       "word1 = %x state: %d\n", w0, w1, mstate);
 			fsp_reg_dump();
-			resetbit = ~fsp_get_class_bit(req->word0 & 0xff);
-			fsp_cmdclass_resp_bitmask &= resetbit;
+			fsp_cmdclass_resp_bitmask &= ~(1ull << index);
 			cmdclass->timesent = 0;
 			if (req->resp)
 				req->resp->state = fsp_msg_timeout;
@@ -1974,6 +1984,7 @@ static void fsp_timeout_poll(void *data __unused)
 		cmdclass_resp_bitmask = cmdclass_resp_bitmask >> 1;
 		index++;
 	}
+	unlock(&fsp_poll_lock);
 }
 
 void fsp_opl(void)




More information about the Skiboot mailing list