[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