[Skiboot] [PATCH RFC 2/2] OCC: Reuse fsp_msg to queue lid loads

Vasant Hegde hegdevasant at linux.vnet.ibm.com
Thu Mar 12 22:26:13 AEDT 2015


Make code simpler by queuing the fsp_msg itself for lid load requests.

Signed-off-by: Vasant Hegde <hegdevasant at linux.vnet.ibm.com>
Signed-off-by: Ananth N Mavinakayanahalli <ananth at in.ibm.com>

---
Ananth, Ben,
  With this patch we still have OCC specific queue.. I think its better to
  generalize (Move queuing logic to FSP) this code so that if required we
  can use same queue for rest of the clients as well. What you say?

-Vasant
 hw/occ.c |  123 ++++++++++++++++++++++++++------------------------------------
 1 file changed, 52 insertions(+), 71 deletions(-)

diff --git a/hw/occ.c b/hw/occ.c
index 34d6de5..2b3becd 100644
--- a/hw/occ.c
+++ b/hw/occ.c
@@ -68,6 +68,8 @@ DEFINE_LOG_ENTRY(OPAL_RC_OCC_TIMEOUT, OPAL_PLATFORM_ERR_EVT, OPAL_OCC,
 		 OPAL_CEC_HARDWARE, OPAL_UNRECOVERABLE_ERR_GENERAL,
 		 OPAL_NA, NULL);
 
+static LIST_HEAD(occ_load_req_list);
+
 /* Check each chip's HOMER/Sapphire area for PState valid bit */
 static bool wait_for_all_occ_init(void)
 {
@@ -347,36 +349,34 @@ void occ_pstates_init(void)
 	}
 }
 
-struct occ_load_req {
-	u8 scope;
-	u32 dbob_id;
-	u32 seq_id;
-	struct list_node link;
-};
-static LIST_HEAD(occ_load_req_list);
-
-static void occ_queue_load(u8 scope, u32 dbob_id, u32 seq_id)
+static void occ_do_load(u8 scope, u32 dbob_id __unused, u32 seq_id)
 {
-	struct occ_load_req *occ_req;
+	struct fsp_msg *rsp, *stat;
+	int rc = -ENOMEM;
+	int status_word = 0;
+	struct proc_chip *chip = next_chip(NULL);
+	u8 err = 0;
 
-	occ_req = zalloc(sizeof(struct occ_load_req));
-	if (!occ_req) {
-		prerror("OCC: Could not allocate occ_load_req\n");
-		return;
+	/* Check arguments */
+	if (scope != 0x01 && scope != 0x02) {
+		prerror("OCC: Load message with invalid scope 0x%x\n",
+				scope);
+		err = 0x22;
 	}
 
-	occ_req->scope = scope;
-	occ_req->dbob_id = dbob_id;
-	occ_req->seq_id = seq_id;
-	list_add_tail(&occ_load_req_list, &occ_req->link);
-}
+	/* First queue up an OK response to the load message itself */
+	rsp = fsp_mkmsg(FSP_RSP_LOAD_OCC | err, 0);
+	if (rsp)
+		rc = fsp_queue_msg(rsp, fsp_freemsg);
+	if (rc) {
+		log_simple_error(&e_info(OPAL_RC_OCC_LOAD),
+			"OCC: Error %d queueing FSP OCC LOAD reply\n", rc);
+		fsp_freemsg(rsp);
+		return;
+	}
 
-static void __occ_do_load(u8 scope, u32 dbob_id __unused, u32 seq_id)
-{
-	struct fsp_msg *stat;
-	int rc = -ENOMEM;
-	int status_word = 0;
-	struct proc_chip *chip = next_chip(NULL);
+	if (err)
+		return;
 
 	/* Call HBRT... */
 	rc = host_services_occ_load();
@@ -399,7 +399,7 @@ static void __occ_do_load(u8 scope, u32 dbob_id __unused, u32 seq_id)
 			break;
 		}
 		log_simple_error(&e_info(OPAL_RC_OCC_LOAD),
-			"OCC: Error %d in load/start OCC\n", rc);
+			"OCC: Error %d in load/start OCC\n", err);
 	}
 
 	/* Send a single response for all chips */
@@ -415,55 +415,23 @@ static void __occ_do_load(u8 scope, u32 dbob_id __unused, u32 seq_id)
 
 void occ_poke_load_queue(void)
 {
-	struct occ_load_req *occ_req;
+	struct fsp_msg *msg;
+	u32 dbob_id, seq_id;
+	u8 scope;
 
 	if (list_empty(&occ_load_req_list))
 		return;
 
-	list_for_each(&occ_load_req_list, occ_req, link) {
-		__occ_do_load(occ_req->scope, occ_req->dbob_id,
-				occ_req->seq_id);
-		list_del(&occ_req->link);
-		free(occ_req);
-	}
-}
-
-static void occ_do_load(u8 scope, u32 dbob_id __unused, u32 seq_id)
-{
-	struct fsp_msg *rsp;
-	int rc = -ENOMEM;
-	u8 err = 0;
-
-	if (scope != 0x01 && scope != 0x02) {
-		prerror("OCC: Load message with invalid scope 0x%x\n",
-				scope);
-		err = 0x22;
-	}
-
-	/* First queue up an OK response to the load message itself */
-	rsp = fsp_mkmsg(FSP_RSP_LOAD_OCC | err, 0);
-	if (rsp)
-		rc = fsp_queue_msg(rsp, fsp_freemsg);
-	if (rc) {
-		log_simple_error(&e_info(OPAL_RC_OCC_LOAD),
-			"OCC: Error %d queueing FSP OCC LOAD reply\n", rc);
-		fsp_freemsg(rsp);
-		return;
-	}
-
-	if (err)
-		return;
+	list_for_each(&occ_load_req_list, msg, link) {
+		scope = msg->data.bytes[3];
+		dbob_id = msg->data.words[1];
+		seq_id = msg->data.words[2];
 
-	/*
-	 * Check if hostservices lid caching is complete. If not, queue
-	 * the load request.
-	 */
-	if (!hservices_lid_preload_complete()) {
-		occ_queue_load(scope, dbob_id, seq_id);
-		return;
+		occ_do_load(scope, dbob_id, seq_id);
+		list_del(&msg->link);
+		msg->refcount--;
+		fsp_freemsg(msg);
 	}
-
-	__occ_do_load(scope, dbob_id, seq_id);
 }
 
 static void occ_do_reset(u8 scope, u32 dbob_id, u32 seq_id)
@@ -591,9 +559,22 @@ static bool fsp_occ_msg(u32 cmd_sub_mod, struct fsp_msg *msg)
 		seq_id = msg->data.words[2];
 		prlog(PR_INFO, "OCC: Got OCC Load message, scope=0x%x"
 		      " dbob=0x%x seq=0x%x\n", scope, dbob_id, seq_id);
-		occ_do_load(scope, dbob_id, seq_id);
-		return true;
 
+		if (!hservices_lid_preload_complete()) {
+			/*
+			 * We have 16 minutes to respond to the OCC load.
+			 * So, no need to queue an OK response to the FSP
+			 * right away.
+			 */
+			prlog(PR_TRACE, "OCC: Queuing lid load for"
+			      " scope=0x%x dbob=0x%x seq=0x%x\n",
+			      scope, dbob_id, seq_id);
+			msg->refcount++;
+			list_add_tail(&occ_load_req_list, &msg->link);
+		} else {
+			occ_do_load(scope, dbob_id, seq_id);
+		}
+		return true;
 	case FSP_CMD_RESET_OCC:
 		/*
 		 * We shouldn't be getting this one, but if we do, we have



More information about the Skiboot mailing list