[PATCH 017/109] drm/amd/ras: Add fifo to cache ras data from mce notification
Alex Deucher <[email protected]>
| Newsgroups | org.freedesktop.lists.amd-gfx |
|---|---|
| Message-ID | <[email protected]> |
From: YiPeng Chai <[email protected]> Add fifo to cache ras data from mce notification. Signed-off-by: YiPeng Chai <[email protected]> Reviewed-by: Hawking Zhang <[email protected]> Signed-off-by: Alex Deucher <[email protected]> --- drivers/gpu/drm/amd/ras/core/Makefile | 3 +- drivers/gpu/drm/amd/ras/core/aca.h | 1 + drivers/gpu/drm/amd/ras/core/core.c | 5 + drivers/gpu/drm/amd/ras/core/log_ring.h | 1 + drivers/gpu/drm/amd/ras/core/ras.h | 2 + drivers/gpu/drm/amd/ras/core/ras_mce.c | 146 ++++++++++++++++++++++++ drivers/gpu/drm/amd/ras/core/ras_mce.h | 51 +++++++++ 7 files changed, 208 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/amd/ras/core/ras_mce.c create mode 100644 drivers/gpu/drm/amd/ras/core/ras_mce.h diff --git a/drivers/gpu/drm/amd/ras/core/Makefile b/drivers/gpu/drm/amd/ras/core/Makefile index 871c104db24e5..81f148c76d8d3 100644 --- a/drivers/gpu/drm/amd/ras/core/Makefile +++ b/drivers/gpu/drm/amd/ras/core/Makefile @@ -38,7 +38,8 @@ RAS_CORE_FILES = core.o \ ras_cper.o \ ras_psp.o \ ras_psp_v13_0.o \ - eeprom_fw.o + eeprom_fw.o \ + ras_mce.o RAS_CORE = $(addprefix $(AMD_GPU_RAS_PATH)/core/,$(RAS_CORE_FILES)) diff --git a/drivers/gpu/drm/amd/ras/core/aca.h b/drivers/gpu/drm/amd/ras/core/aca.h index 343525dab744e..f42f408f4acfe 100644 --- a/drivers/gpu/drm/amd/ras/core/aca.h +++ b/drivers/gpu/drm/amd/ras/core/aca.h @@ -54,6 +54,7 @@ struct aca_block; struct aca_bank_reg { uint64_t timestamp; + u32 bank_type; u32 ecc_type; u64 seq_no; u64 regs[ACA_REG_MAX_COUNT]; diff --git a/drivers/gpu/drm/amd/ras/core/core.c b/drivers/gpu/drm/amd/ras/core/core.c index ab5a287a83b51..2ddb011e8082b 100644 --- a/drivers/gpu/drm/amd/ras/core/core.c +++ b/drivers/gpu/drm/amd/ras/core/core.c @@ -375,6 +375,10 @@ int ras_core_sw_init(struct ras_core_context *ras_core) if (ret) return ret; + ret = ras_mce_sw_init(ras_core); + if (ret) + return ret; + return 0; } @@ -388,6 +392,7 @@ int ras_core_sw_fini(struct ras_core_context *ras_core) ras_cmd_fini(ras_core); ras_umc_sw_fini(ras_core); ras_aca_sw_fini(ras_core); + ras_mce_sw_fini(ras_core); return 0; } diff --git a/drivers/gpu/drm/amd/ras/core/log_ring.h b/drivers/gpu/drm/amd/ras/core/log_ring.h index 2eaeccfb8965f..bcefd228aad3c 100644 --- a/drivers/gpu/drm/amd/ras/core/log_ring.h +++ b/drivers/gpu/drm/amd/ras/core/log_ring.h @@ -40,6 +40,7 @@ enum ras_log_event { RAS_LOG_EVENT_RMA, RAS_LOG_EVENT_MCE, RAS_LOG_EVENT_BOOT, + RAS_LOG_EVENT_CPU_RAS, RAS_LOG_EVENT_COUNT_MAX, }; diff --git a/drivers/gpu/drm/amd/ras/core/ras.h b/drivers/gpu/drm/amd/ras/core/ras.h index af19a0983fcea..2fed47a476168 100644 --- a/drivers/gpu/drm/amd/ras/core/ras.h +++ b/drivers/gpu/drm/amd/ras/core/ras.h @@ -37,6 +37,7 @@ #include "ras_psp.h" #include "log_ring.h" #include "eeprom_fw.h" +#include "ras_mce.h" #define RAS_HW_ERR "[Hardware Error]: " @@ -348,6 +349,7 @@ struct ras_core_context { struct ras_mp1 ras_mp1; struct ras_process ras_proc; struct ras_log_ring ras_log_ring; + struct ras_mce ras_mce; const struct ras_sys_func *sys_fn; diff --git a/drivers/gpu/drm/amd/ras/core/ras_mce.c b/drivers/gpu/drm/amd/ras/core/ras_mce.c new file mode 100644 index 0000000000000..018429e397979 --- /dev/null +++ b/drivers/gpu/drm/amd/ras/core/ras_mce.c @@ -0,0 +1,146 @@ +// SPDX-License-Identifier: MIT +/* + * Copyright 2026 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "ras.h" +#include "ras_mce.h" +#define RAS_MCE_BANK_FIFO_SIZE (1024 * sizeof(struct aca_bank_reg)) +#define RAS_MCE_BANK_COUNT(x) ((x) / sizeof(struct aca_bank_reg)) + +struct mce_smca_bank_range { + u32 start; + u32 end; +}; + +static const struct mce_smca_bank_range mce_smca_bank_range_v5[] = { + [MCE_BANK_TYPE_GPU] = {32, 63}, + [MCE_BANK_TYPE_CPU] = {0, 31}, +}; + +bool ras_mce_check_bank(struct ras_core_context *ras_core, + enum mce_bank_type type, u32 bank) +{ + const struct mce_smca_bank_range *range; + u32 aca_ip_version = 0; + + if (!ras_core || type >= MCE_BANK_TYPE_MAX) + return false; + + if (ras_core_get_ip_version(ras_core, + RAS_UNIT_ID_ACA, &aca_ip_version)) + return false; + + switch (aca_ip_version) { + case IP_VERSION(5, 0, 0): + range = &mce_smca_bank_range_v5[type]; + break; + default: + return false; + } + + return ((bank >= range->start) && (bank <= range->end)) ? true : false; +} + +static int ras_mce_add_gpu_bank(struct ras_core_context *ras_core, + struct aca_bank_reg *aca_bank) +{ + struct ras_mce *mce = &ras_core->ras_mce; + int ret; + + ret = kfifo_in_spinlocked(&mce->mce_fifo, + aca_bank, sizeof(*aca_bank), &mce->mce_fifo_lock); + if (ret) + ras_process_add_interrupt_req(ras_core, NULL, true); + + return ret ? 0 : -ENOSPC; +} + +static int ras_mce_log_cpu_bank(struct ras_core_context *ras_core, + struct aca_bank_reg *aca_bank) +{ + + ras_log_ring_add_log_event(ras_core, + RAS_LOG_EVENT_CPU_RAS, aca_bank, sizeof(*aca_bank), NULL); + + return 0; +} + +int ras_mce_sw_init(struct ras_core_context *ras_core) +{ + struct ras_mce *mce = &ras_core->ras_mce; + + if (kfifo_alloc(&mce->mce_fifo, RAS_MCE_BANK_FIFO_SIZE, GFP_KERNEL)) + return -ENOMEM; + + spin_lock_init(&mce->mce_fifo_lock); + + return 0; +} + +int ras_mce_sw_fini(struct ras_core_context *ras_core) +{ + kfifo_free(&ras_core->ras_mce.mce_fifo); + + return 0; +} + +int ras_mce_get_bank_count(struct ras_core_context *ras_core, + enum ras_err_type type, u32 *count) +{ + u32 data_count; + + if (!ras_core || !count) + return -EINVAL; + + data_count = RAS_MCE_BANK_COUNT(kfifo_len(&ras_core->ras_mce.mce_fifo)); + + *count = (data_count <= MAX_RECORD_PER_BATCH) ? data_count : MAX_RECORD_PER_BATCH; + + return 0; +} + +int ras_mce_dump_bank(struct ras_core_context *ras_core, + u32 type, u32 idx, struct aca_bank_reg *reg_bank) +{ + struct ras_mce *mce = &ras_core->ras_mce; + int ret; + + if (!ras_core || !reg_bank) + return -EINVAL; + + ret = kfifo_out_spinlocked(&mce->mce_fifo, + reg_bank, sizeof(*reg_bank), &mce->mce_fifo_lock); + + return ret ? 0 : -ENOENT; +} + +int ras_mce_add_aca_bank(struct ras_core_context *ras_core, + struct aca_bank_reg *aca_bank) +{ + if (!ras_core || !aca_bank) + return -EINVAL; + + return (aca_bank->bank_type == MCE_BANK_TYPE_GPU) ? + ras_mce_add_gpu_bank(ras_core, aca_bank) : + ras_mce_log_cpu_bank(ras_core, aca_bank); +} diff --git a/drivers/gpu/drm/amd/ras/core/ras_mce.h b/drivers/gpu/drm/amd/ras/core/ras_mce.h new file mode 100644 index 0000000000000..3b1f690d2eb69 --- /dev/null +++ b/drivers/gpu/drm/amd/ras/core/ras_mce.h @@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright 2026 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + */ +#ifndef __RAS_MCE_H__ +#define __RAS_MCE_H__ + +enum mce_bank_type { + MCE_BANK_TYPE_GPU, + MCE_BANK_TYPE_CPU, + MCE_BANK_TYPE_MAX +}; + +struct ras_mce { + struct kfifo mce_fifo; + spinlock_t mce_fifo_lock; +}; + +int ras_mce_sw_init(struct ras_core_context *ras_core); +int ras_mce_sw_fini(struct ras_core_context *ras_core); + +int ras_mce_get_bank_count(struct ras_core_context *ras_core, + enum ras_err_type type, u32 *count); +int ras_mce_dump_bank(struct ras_core_context *ras_core, + u32 type, u32 idx, struct aca_bank_reg *aca_bank); + +bool ras_mce_check_bank(struct ras_core_context *ras_core, + enum mce_bank_type, u32 bank); +int ras_mce_add_aca_bank(struct ras_core_context *ras_core, + struct aca_bank_reg *aca_bank); + +#endif -- 2.55.0