[PATCH 098/109] drm/amd/ras: move BERT boot errors to BERT sw init

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

Keep BERT boot-error handling owned by the BERT module instead of letting
the MCE notifier lifecycle drive BERT processing and cleanup.

Group the cached boot-error state into a single structure so the related
poll result, raw record data, per-socket write tracking, and lock are
managed together.

Expose only the standard BERT sw_init/sw_fini entry points. The RAS manager
calls them around the existing MCE sw lifecycle, while the MCE code no
longer includes BERT headers or calls BERT helpers directly.

This lets BERT process cached boot records earlier in the RAS manager
sw_init path and release its cached state independently during sw_fini.

Signed-off-by: Xiang Liu <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
---
 .../gpu/drm/amd/ras/ras_mgr/amdgpu_ras_bert.c | 95 ++++++++++++-------
 .../gpu/drm/amd/ras/ras_mgr/amdgpu_ras_bert.h |  6 +-
 .../gpu/drm/amd/ras/ras_mgr/amdgpu_ras_mce.c  |  7 --
 .../gpu/drm/amd/ras/ras_mgr/amdgpu_ras_mgr.c  |  5 +
 4 files changed, 68 insertions(+), 45 deletions(-)

diff --git a/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_ras_bert.c b/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_ras_bert.c
index 29111b10b00a3..04490f5173c41 100644
--- a/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_ras_bert.c
+++ b/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_ras_bert.c
@@ -31,15 +31,23 @@
 
 #include "amdgpu_ras_mgr.h"
 
-static DEFINE_MUTEX(boot_err_lock);
-static bool boot_err_polled, boot_err_written[MAX_GPU_INSTANCE];
-static int boot_err_poll_result;
-static u8 *boot_err_raw_data;
-static u32 boot_err_raw_data_len;
-
-int amdgpu_ras_bert_process_boot_errors(struct amdgpu_device *adev)
+struct amdgpu_ras_bert_boot_err_state {
+	struct mutex lock; /* protects cached boot error state */
+	bool polled;
+	bool written[MAX_GPU_INSTANCE];
+	int poll_result;
+	u8 *raw_data;
+	u32 raw_data_len;
+};
+
+static struct amdgpu_ras_bert_boot_err_state boot_err_state = {
+	.lock = __MUTEX_INITIALIZER(boot_err_state.lock),
+};
+
+static int amdgpu_ras_bert_process_boot_errors(struct amdgpu_device *adev)
 {
 	struct amdgpu_ras_mgr *ras_mgr = amdgpu_ras_mgr_get_context(adev);
+	struct amdgpu_ras_bert_boot_err_state *state = &boot_err_state;
 	struct acpi_bert_region *boot_error_region;
 	struct acpi_table_header *table;
 	struct acpi_table_bert *bert_tab;
@@ -51,11 +59,11 @@ int amdgpu_ras_bert_process_boot_errors(struct amdgpu_device *adev)
 	if (!ras_mgr || !ras_mgr->ras_core)
 		return -EPERM;
 
-	mutex_lock(&boot_err_lock);
+	mutex_lock(&state->lock);
 
-	if (!boot_err_polled) {
-		boot_err_polled = true;
-		boot_err_poll_result = 0;
+	if (!state->polled) {
+		state->polled = true;
+		state->poll_result = 0;
 		ret = 0;
 
 		if (acpi_disabled)
@@ -67,7 +75,7 @@ int amdgpu_ras_bert_process_boot_errors(struct amdgpu_device *adev)
 
 		if (ACPI_FAILURE(status)) {
 			RAS_DEV_ERR(adev, "get table failed, %s.\n", acpi_format_exception(status));
-			boot_err_poll_result = -EINVAL;
+			state->poll_result = -EINVAL;
 			goto out_unlock;
 		}
 		bert_tab = (struct acpi_table_bert *)table;
@@ -75,36 +83,36 @@ int amdgpu_ras_bert_process_boot_errors(struct amdgpu_device *adev)
 		if (bert_tab->header.length < sizeof(struct acpi_table_bert) ||
 		    bert_tab->region_length < sizeof(struct acpi_bert_region)) {
 			RAS_DEV_ERR(adev, "table invalid.\n");
-			boot_err_poll_result = -EINVAL;
+			state->poll_result = -EINVAL;
 			goto out_put_bert_tab;
 		}
 
 		region_len = bert_tab->region_length;
 		boot_error_region = acpi_os_map_memory(bert_tab->address, region_len);
 		if (boot_error_region) {
-			boot_err_raw_data = kmemdup(boot_error_region, region_len, GFP_KERNEL);
+			state->raw_data = kmemdup(boot_error_region, region_len, GFP_KERNEL);
 			acpi_os_unmap_memory(boot_error_region, region_len);
-			if (!boot_err_raw_data) {
+			if (!state->raw_data) {
 				RAS_DEV_ERR(adev, "failed to cache BERT raw data.\n");
-				boot_err_poll_result = -ENOMEM;
+				state->poll_result = -ENOMEM;
 			} else {
-				boot_err_raw_data_len = region_len;
+				state->raw_data_len = region_len;
 			}
 		} else {
 			RAS_DEV_ERR(adev, "failed to map BERT region.\n");
-			boot_err_poll_result = -ENOMEM;
+			state->poll_result = -ENOMEM;
 		}
 
 out_put_bert_tab:
 		acpi_put_table(table);
 	}
 
-	if (boot_err_poll_result) {
-		ret = boot_err_poll_result;
+	if (state->poll_result) {
+		ret = state->poll_result;
 		goto out_unlock;
 	}
 
-	if (!boot_err_raw_data || !boot_err_raw_data_len ||
+	if (!state->raw_data || !state->raw_data_len ||
 	    !(adev && (adev->gmc.xgmi.connected_to_cpu || adev->gmc.is_app_apu))) {
 		ret = 0;
 		goto out_unlock;
@@ -122,31 +130,50 @@ int amdgpu_ras_bert_process_boot_errors(struct amdgpu_device *adev)
 		goto out_unlock;
 	}
 
-	if (boot_err_written[socket_id]) {
+	if (state->written[socket_id]) {
 		ret = 0;
 		goto out_unlock;
 	}
 
 	ret = ras_bert_process_records(ras_mgr->ras_core,
-				       boot_err_raw_data, boot_err_raw_data_len);
+				       state->raw_data, state->raw_data_len);
 	if (!ret)
-		boot_err_written[socket_id] = true;
+		state->written[socket_id] = true;
 
 out_unlock:
-	mutex_unlock(&boot_err_lock);
+	mutex_unlock(&state->lock);
 
 	return ret;
 }
 
-void amdgpu_ras_bert_reset_boot_errors(void)
+static void amdgpu_ras_bert_reset_boot_errors(void)
 {
-	mutex_lock(&boot_err_lock);
-	memset(boot_err_written, 0, sizeof(boot_err_written));
-	kfree(boot_err_raw_data);
-	boot_err_raw_data = NULL;
-	boot_err_raw_data_len = 0;
-	boot_err_poll_result = 0;
-	boot_err_polled = false;
-	mutex_unlock(&boot_err_lock);
+	struct amdgpu_ras_bert_boot_err_state *state = &boot_err_state;
+
+	mutex_lock(&state->lock);
+	memset(state->written, 0, sizeof(state->written));
+	kfree(state->raw_data);
+	state->raw_data = NULL;
+	state->raw_data_len = 0;
+	state->poll_result = 0;
+	state->polled = false;
+	mutex_unlock(&state->lock);
 }
 #endif
+
+int amdgpu_ras_bert_sw_init(struct amdgpu_device *adev)
+{
+#if defined(CONFIG_X86_MCE_AMD) && defined(CONFIG_ACPI_APEI)
+	return amdgpu_ras_bert_process_boot_errors(adev);
+#else
+	return 0;
+#endif
+}
+
+int amdgpu_ras_bert_sw_fini(struct amdgpu_device *adev)
+{
+#if defined(CONFIG_X86_MCE_AMD) && defined(CONFIG_ACPI_APEI)
+	amdgpu_ras_bert_reset_boot_errors();
+#endif
+	return 0;
+}
diff --git a/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_ras_bert.h b/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_ras_bert.h
index 27e2378ea5f3a..e56aa143ad952 100644
--- a/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_ras_bert.h
+++ b/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_ras_bert.h
@@ -24,9 +24,7 @@
 #ifndef __AMDGPU_RAS_BERT_H__
 #define __AMDGPU_RAS_BERT_H__
 
-#if defined(CONFIG_X86_MCE_AMD) && defined(CONFIG_ACPI_APEI)
-int amdgpu_ras_bert_process_boot_errors(struct amdgpu_device *adev);
-void amdgpu_ras_bert_reset_boot_errors(void);
-#endif
+int amdgpu_ras_bert_sw_init(struct amdgpu_device *adev);
+int amdgpu_ras_bert_sw_fini(struct amdgpu_device *adev);
 
 #endif
diff --git a/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_ras_mce.c b/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_ras_mce.c
index 97ef50149fdf9..bc7a44618ac6c 100644
--- a/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_ras_mce.c
+++ b/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_ras_mce.c
@@ -23,7 +23,6 @@
  */
 
 #include "amdgpu.h"
-#include "amdgpu_ras_bert.h"
 #include "amdgpu_ras_mgr.h"
 #include "amdgpu_ras_mce.h"
 #include <asm/mce.h>
@@ -123,9 +122,6 @@ static int amdgpu_ras_unregister_mce_notifier(struct amdgpu_device *adev)
 	if (atomic_read(&mce_mgr->ref_count) <= 0) {
 		atomic_set(&mce_mgr->dev_count, 0);
 		mce_unregister_decode_chain(&mce_mgr->nb);
-#ifdef CONFIG_ACPI_APEI
-		amdgpu_ras_bert_reset_boot_errors();
-#endif
 	}
 
 	return 0;
@@ -243,9 +239,6 @@ static int amdgpu_ras_mce_notifier(struct amdgpu_device *adev,
 
 int amdgpu_ras_mce_hw_init(struct amdgpu_device *adev)
 {
-#if defined(CONFIG_X86_MCE_AMD) && defined(CONFIG_ACPI_APEI)
-	amdgpu_ras_bert_process_boot_errors(adev);
-#endif
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_ras_mgr.c b/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_ras_mgr.c
index bda1f76d2dbf9..64622b593ab94 100644
--- a/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_ras_mgr.c
+++ b/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_ras_mgr.c
@@ -33,6 +33,7 @@
 #include "amdgpu_ras_mp1_v13_0.h"
 #include "amdgpu_ras_mp1.h"
 #include "amdgpu_ras_nbio_v7_9.h"
+#include "amdgpu_ras_bert.h"
 #include "amdgpu_ras_mce.h"
 
 #define MAX_AID_NUM_PER_SOCKET_GFX9     4
@@ -356,6 +357,7 @@ int amdgpu_ras_mgr_sw_init(struct amdgpu_device *adev, struct ras_module_param *
 		goto err2;
 	}
 	amdgpu_ras_mgr_init_event_mgr(ras_mgr->ras_core);
+	amdgpu_ras_bert_sw_init(adev);
 	amdgpu_ras_mce_sw_init(adev);
 
 	if (amdgpu_sriov_vf(adev)) {
@@ -370,6 +372,8 @@ int amdgpu_ras_mgr_sw_init(struct amdgpu_device *adev, struct ras_module_param *
 	return 0;
 
 err3:
+	amdgpu_ras_mce_sw_fini(adev);
+	amdgpu_ras_bert_sw_fini(adev);
 	if (ras_mgr->ras_core)
 		ras_core_sw_fini(ras_mgr->ras_core);
 err2:
@@ -398,6 +402,7 @@ int amdgpu_ras_mgr_sw_fini(struct amdgpu_device *adev)
 		amdgpu_virt_ras_sw_fini(adev);
 
 	amdgpu_ras_mce_sw_fini(adev);
+	amdgpu_ras_bert_sw_fini(adev);
 	amdgpu_ras_process_fini(adev);
 	ras_core_sw_fini(ras_mgr->ras_core);
 	ras_core_destroy(ras_mgr->ras_core);
-- 
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.