[PATCH 080/109] drm/amd/ras: limit eeprom ras table validation to init and post-write

Alex Deucher <[email protected]>
Newsgroups org.freedesktop.lists.amd-gfx
Message-ID <[email protected]>
From: YiPeng Chai <[email protected]>

The eeprom ras table can be quite large, and each read requires multiple
smu i2c transactions (max 24 bytes per transfer). Limit the validation
to avoid excessive i2c traffic and CPU busy-wait overhead.

Signed-off-by: YiPeng Chai <[email protected]>
Reviewed-by: Tao Zhou <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
---
 drivers/gpu/drm/amd/ras/core/eeprom.c | 31 +++++++++++++++++++++++----
 drivers/gpu/drm/amd/ras/core/eeprom.h |  2 ++
 2 files changed, 29 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/ras/core/eeprom.c b/drivers/gpu/drm/amd/ras/core/eeprom.c
index 61cc0538f4622..e7aad113b98a5 100644
--- a/drivers/gpu/drm/amd/ras/core/eeprom.c
+++ b/drivers/gpu/drm/amd/ras/core/eeprom.c
@@ -153,6 +153,8 @@
 
 #define to_ras_core_context(x) (container_of(x, struct ras_core_context, eeprom_mgr))
 
+static int __check_ras_table(struct ras_core_context *ras_core,
+			struct ras_eeprom_control *control);
 
 static bool __get_eeprom_i2c_addr(struct ras_core_context *ras_core,
 				  struct ras_eeprom_control *control)
@@ -801,6 +803,9 @@ static int ras_eeprom_append(struct ras_core_context *ras_core,
 
 	mutex_unlock(&control->ras_tbl_mutex);
 
+	if (!res)
+		res = __check_ras_table(ras_core, control);
+
 	return res;
 }
 
@@ -1123,6 +1128,7 @@ static int ras_eeprom_hw_init(struct ras_core_context *ras_core,
 		struct ras_eeprom_param *param)
 {
 	struct ras_eeprom_control *control = ras_core->eeprom_mgr.ras_eeprom;
+	int ret;
 
 	if (!control)
 		return -EINVAL;
@@ -1133,7 +1139,15 @@ static int ras_eeprom_hw_init(struct ras_core_context *ras_core,
 	control->i2c_port = param->eeprom_i2c_port;
 	control->i2c_address = param->eeprom_i2c_addr;
 
-	return __ras_table_init(ras_core);
+	ret = __ras_table_init(ras_core);
+	if (ret)
+		return ret;
+
+	ret = __check_ras_table(ras_core, control);
+	if (ret)
+		RAS_DEV_WARN(ras_core->dev, "Invalid eeprom ras table! ret: %d\n", ret);
+
+	return 0;
 }
 
 static int ras_eeprom_hw_fini(struct ras_core_context *ras_core)
@@ -1167,10 +1181,19 @@ static int __check_ras_table(struct ras_core_context *ras_core,
 
 	mutex_lock(&control->ras_tbl_mutex);
 	res = __verify_ras_table_checksum(control);
+	/* Update RAS table status only after an actual table
+	 * validation has been performed.
+	 */
+	if (res >= 0)
+		control->ras_tbl_status_ok = res ? false : true;
 	mutex_unlock(&control->ras_tbl_mutex);
-	if (res)
+	if (res) {
 		RAS_DEV_ERR(ras_core->dev,
-			"RAS table checksum is incorrect! ret: %d\n", res);
+			"RAS table validation failed! ret: %d\n", res);
+
+		if (res > 0)
+			res = -EFAULT;
+	}
 
 	return res;
 }
@@ -1185,7 +1208,7 @@ static void __get_eeprom_status(struct ras_core_context *ras_core,
 		return;
 
 	hdr = &control->tbl_hdr;
-	if (!fast_mode && __check_ras_table(ras_core, control))
+	if (!control->ras_tbl_status_ok)
 		*status = RAS_EEPROM_FAULT;
 	else if (hdr->header == RAS_TABLE_HDR_VAL)
 		*status = RAS_EEPROM_OK;
diff --git a/drivers/gpu/drm/amd/ras/core/eeprom.h b/drivers/gpu/drm/amd/ras/core/eeprom.h
index bf721c2a11f1e..1482450c2781f 100644
--- a/drivers/gpu/drm/amd/ras/core/eeprom.h
+++ b/drivers/gpu/drm/amd/ras/core/eeprom.h
@@ -134,6 +134,8 @@ struct ras_eeprom_control {
 	/* Record channel info which occurred bad pages
 	 */
 	u32 bad_channel_bitmap;
+
+	bool ras_tbl_status_ok;
 };
 
 /*
-- 
2.55.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.