[Skiboot] [PATCH 3/3] ... to prevent any potential poller recursions during lid load.

Ananth N Mavinakayanahalli ananth at in.ibm.com
Tue Feb 17 02:15:33 AEDT 2015


See bz121430 for one such case.

With this change:

...

[10810950484,5] CUPD: P side ML Keyword = FW830.00
[10832756491,6] HBRT: 1 lids to load
[10832762732,7] FSP: Fetch data id: 05 sid: 81e00430 to 0x306cf500(0x100000
bytes)
[10832766825,7] FSP:  0x00100000 bytes balign=306cf000 boff=500 bsize=101000
[10857829395,5] CUPD: Marker LID id : size : status = 0x80a08001 : 0x5d0 : 0x0
[10966464432,7] FSP:   -> rc=0x00 off: 00000000 twritten: 0007fb80
[10966468418,7] HBRT: LID 0x81e00430 successfully loaded, len=0x31b83db8

...

[19485180658,7] HBRT: stopOCCs() rc  = 0
[19582727570,6] OCC: Got OCC Load message, scope=0x2 dbob=0x0 seq=0x10
[19582732660,7] HBRT: OCC Load requested
[19582734678,7] HBRT: Calling loadOCC() homer 0000000401400000, occ_common_area
0000000400800000, chip 0000
[19582803643,6] HBRT: Lid load request for 0x81e00430
[19582806532,7] HBRT: Serviced from cache, len=0x7fb80
[19582996931,7] HBRT: -> rc = 0
[19582999113,7] HBRT: Calling loadOCC() homer 0000000401c00000, occ_common_area
0000000400800000, chip 0001
[19583097594,6] HBRT: Lid load request for 0x81e00430
[19583100343,7] HBRT: Serviced from cache, len=0x7fb80
[19583274638,7] HBRT: -> rc = 0
[19583277114,6] HBRT: OCC Start requested


Signed-off-by: Ananth N Mavinakayanahalli <ananth at in.ibm.com>
---
 core/hostservices.c    |  117 +++++++++++++++++++++++++++++++++++-------------
 core/init.c            |    3 +
 include/hostservices.h |    1 
 3 files changed, 89 insertions(+), 32 deletions(-)

diff --git a/core/hostservices.c b/core/hostservices.c
index 952f6b8..1bda67f 100644
--- a/core/hostservices.c
+++ b/core/hostservices.c
@@ -386,36 +386,26 @@ static int hservice_scom_write(uint64_t chip_id, uint64_t addr,
 	return xscom_write(chip_id, addr, val);
 }
 
-static int hservice_lid_load(uint32_t lid, void **buf, size_t *len)
+struct hbrt_lid {
+	void *load_addr;
+	size_t len;
+	uint32_t id;
+	struct list_node link;
+};
+static LIST_HEAD(hbrt_lid_list);
+
+/* TODO: Few of the following routines can be generalized */
+static int __hservice_lid_load(uint32_t lid, void **buf, size_t *len)
 {
 	int rc;
-	static void *lid_cache;
-	static size_t lid_cache_len;
-	static uint32_t lid_cache_id;
-
-	prlog(PR_INFO, "HBRT: LID load request for 0x%08x\n", lid);
 
 	/* Adjust LID side first or we get a cache mismatch */
 	lid = fsp_adjust_lid_side(lid);
 
-	/* Check for cache */
-	if (lid_cache && lid_cache_id == lid) {
-		*buf = lid_cache;
-		*len = lid_cache_len;
-		prlog(PR_DEBUG, "HBRT: Serviced from cache, len=0x%lx\n",
-		      lid_cache_len);
-		return 0;
-	}
-
-	/* Cache mismatch, discard old one */
-	if (lid_cache) {
-		prlog(PR_DEBUG, "HBRT: Cache mismatch, discarding old"
-		      " 0x%08x\n", lid_cache_id);
-		free(lid_cache);
-		lid_cache = NULL;
-	}
-
-	/* Allocate a new buffer and load the LID into it */
+	/*
+	 * Allocate a new buffer and load the LID into it
+	 * XXX: We currently use the same size for each HBRT lid.
+	 */
 	*buf = malloc(HBRT_LOAD_LID_SIZE);
 	*len = HBRT_LOAD_LID_SIZE;
 	rc = fsp_fetch_data(0, FSP_DATASET_NONSP_LID, lid, 0, *buf, len);
@@ -424,17 +414,80 @@ static int hservice_lid_load(uint32_t lid, void **buf, size_t *len)
 		*len = 0;
 	*buf = realloc(*buf, *len);
 
-	/* We managed, let's cache it */
-	if (rc == 0 && *len) {
-		lid_cache = *buf;
-		lid_cache_len = *len;
-		lid_cache_id = lid;
+	prlog(PR_DEBUG, "HBRT: LID 0x%08x successfully loaded, len=0x%lx\n",
+			lid, (unsigned long)len);
 
-		prlog(PR_DEBUG, "HBRT: LID 0x%08x successfully loaded and"
-		      " cached, len=0x%lx\n", lid, lid_cache_len);
+	return rc;
+}
+
+static int __hservice_lid_preload(const uint32_t lid)
+{
+	struct hbrt_lid *hlid;
+	void *buf;
+	size_t len;
+	int rc;
+
+	hlid = zalloc(sizeof(struct hbrt_lid));
+	if (!hlid) {
+		prerror("HBRT: Could not allocate struct hbrt_lid\n");
+		return -ENOMEM;
 	}
 
-	return rc;
+	rc = __hservice_lid_load(lid, &buf, &len);
+	if (rc) {
+		free(hlid);
+		return rc;
+	}
+
+	hlid->load_addr = buf;
+	hlid->len = len;
+	hlid->id = lid;
+	list_add_tail(&hbrt_lid_list, &hlid->link);
+
+	return 0;
+}
+
+/* Find and preload all lids needed by hostservices */
+void hservices_lid_preload(void)
+{
+	const uint32_t *lid_list = NULL;
+	size_t num_lids;
+
+	if (!hservice_runtime)
+		return;
+
+	lid_list = (const uint32_t *)hservice_runtime->get_lid_list(&num_lids);
+	if (!lid_list) {
+		prerror("HBRT: get_lid_list() returned NULL\n");
+		return;
+	}
+
+	prlog(PR_INFO, "HBRT: %d lids to load\n", (int)num_lids);
+
+	/* Currently HBRT needs only one (OCC) lid */
+	while (num_lids--)
+		__hservice_lid_preload(lid_list[num_lids]);
+}
+
+static int hservice_lid_load(uint32_t lid, void **buf, size_t *len)
+{
+	struct hbrt_lid *hlid;
+
+	prlog(PR_INFO, "HBRT: Lid load request for 0x%08x\n", lid);
+
+	if (list_empty(&hbrt_lid_list))	/* Should not happen */
+		hservices_lid_preload();
+
+	list_for_each(&hbrt_lid_list, hlid, link) {
+		if (hlid->id == lid) {
+			*buf = hlid->load_addr;
+			*len = hlid->len;
+			prlog(PR_DEBUG, "HBRT: Serviced from cache,"
+					" len=0x%lx\n", hlid->len);
+			return 0;
+		}
+	}
+	return -ENOENT;
 }
 
 static int hservice_lid_unload(void *buf __unused)
diff --git a/core/init.c b/core/init.c
index 0b29e2b..018f10f 100644
--- a/core/init.c
+++ b/core/init.c
@@ -645,6 +645,9 @@ void __noreturn main_cpu_entry(const void *fdt, u32 master_cpu)
 	if (platform.init)
 		platform.init();
 
+	/* Preload hostservices lids */
+	hservices_lid_preload();
+
 	/* Setup dummy console nodes if it's enabled */
 	if (dummy_console_enabled())
 		dummy_console_add_nodes();
diff --git a/include/hostservices.h b/include/hostservices.h
index 7279c8e..c8958a3 100644
--- a/include/hostservices.h
+++ b/include/hostservices.h
@@ -18,6 +18,7 @@
 #define __HOSTSERVICES_H
 
 bool hservices_init(void);
+void hservices_lid_preload(void);
 
 int host_services_occ_load(void);
 int host_services_occ_start(void);



More information about the Skiboot mailing list