[PATCH 057/109] drm/amdgpu/ras: prepare ras_psp for ras_mgr-owned TA reload
Alex Deucher <[email protected]>
| Newsgroups | org.freedesktop.lists.amd-gfx |
|---|---|
| Message-ID | <[email protected]> |
From: Xiang Liu <[email protected]> Stop deriving RAS TA session state from the legacy PSP status query and switch ras_psp over to locally tracked TA lifetime. Delegate TA init parameters and fini cleanup through ras_psp sys callbacks, update the load and unload flow to keep firmware metadata in rascore, and add a skip_lock load path that can be used after PSP reinitialization. This prepares ras_psp for a later ras_mgr resume hook that reloads the TA without relying on legacy PSP-managed session ownership. Signed-off-by: Jinzhou Su <[email protected]> Signed-off-by: Xiang Liu <[email protected]> Reviewed-by: Hawking Zhang <[email protected]> Signed-off-by: Alex Deucher <[email protected]> --- drivers/gpu/drm/amd/ras/core/ras.h | 1 + drivers/gpu/drm/amd/ras/core/ras_psp.c | 149 ++++++++++-------- drivers/gpu/drm/amd/ras/core/ras_psp.h | 15 +- .../gpu/drm/amd/ras/ras_mgr/amdgpu_ras_mgr.c | 3 - 4 files changed, 89 insertions(+), 79 deletions(-) diff --git a/drivers/gpu/drm/amd/ras/core/ras.h b/drivers/gpu/drm/amd/ras/core/ras.h index 4cee407c36595..3faf16c850da3 100644 --- a/drivers/gpu/drm/amd/ras/core/ras.h +++ b/drivers/gpu/drm/amd/ras/core/ras.h @@ -269,6 +269,7 @@ struct ras_psp_sys_func { struct ras_psp_sys_status *status); int (*get_ras_ta_init_param)(struct ras_core_context *ras_core, struct ras_ta_init_param *ras_ta_param); + void (*put_ras_ta_fini_param)(struct ras_core_context *ras_core); }; struct ras_sys_func { diff --git a/drivers/gpu/drm/amd/ras/core/ras_psp.c b/drivers/gpu/drm/amd/ras/core/ras_psp.c index 30d22c51758a3..b7af0f2dd6ac6 100644 --- a/drivers/gpu/drm/amd/ras/core/ras_psp.c +++ b/drivers/gpu/drm/amd/ras/core/ras_psp.c @@ -55,7 +55,6 @@ static const struct ras_psp_ip_func *ras_psp_get_ip_funcs( static int ras_psp_sync_system_ras_psp_status(struct ras_core_context *ras_core) { struct ras_psp *psp = &ras_core->ras_psp; - struct ras_ta_ctx *ta_ctx = &ras_core->ras_psp.ta_ctx; struct ras_psp_ctx *psp_ctx = &ras_core->ras_psp.psp_ctx; struct ras_psp_sys_status status = {0}; int ret; @@ -65,12 +64,6 @@ static int ras_psp_sync_system_ras_psp_status(struct ras_core_context *ras_core) if (ret) return ret; - if (status.initialized) { - ta_ctx->preload_ras_ta_enabled = true; - ta_ctx->ras_ta_initialized = status.initialized; - ta_ctx->session_id = status.session_id; - } - psp_ctx->external_mutex = status.psp_cmd_mutex; } @@ -81,22 +74,20 @@ static int ras_psp_get_ras_ta_init_param(struct ras_core_context *ras_core, struct ras_ta_init_param *ras_ta_param) { struct ras_psp *psp = &ras_core->ras_psp; - int ret; - if (!psp->sys_func || !psp->sys_func->get_ras_ta_init_param) { - RAS_DEV_ERR(ras_core->dev, "Not config get_ras_ta_init_param API!!\n"); - return -EINVAL; - } + if (psp->sys_func && psp->sys_func->get_ras_ta_init_param) + return psp->sys_func->get_ras_ta_init_param(ras_core, ras_ta_param); - ret = psp->sys_func->get_ras_ta_init_param(ras_core, ras_ta_param); - if (ret) - return ret; + RAS_DEV_ERR(ras_core->dev, "Not config get_ras_ta_init_param API!!\n"); + return -EACCES; +} - ras_ta_param->nps_mode = ras_core_get_curr_nps_mode(ras_core); - ras_ta_param->vram_type = ras_core_get_vram_type(ras_core); - ras_ta_param->poison_mode_en = ras_core_poison_supported(ras_core) ? 1 : 0; +static void ras_psp_put_ras_ta_fini_param(struct ras_core_context *ras_core) +{ + struct ras_psp *psp = &ras_core->ras_psp; - return 0; + if (psp->sys_func && psp->sys_func->put_ras_ta_fini_param) + psp->sys_func->put_ras_ta_fini_param(ras_core); } static struct gpu_mem_block *ras_psp_get_gpu_mem(struct ras_core_context *ras_core, @@ -384,7 +375,10 @@ static int send_ras_ta_runtime_cmd(struct ras_core_context *ras_core, return -EINVAL; } - ras_psp_sync_system_ras_psp_status(ras_core); + if (!ta_ctx->ras_ta_initialized) { + RAS_DEV_ERR(ras_core->dev, "RAS TA is not initialized, cmd_id: %u\n", cmd_id); + return -EACCES; + } cmd_mem = ras_psp_get_gpu_mem(ras_core, GPU_MEM_TYPE_RAS_TA_CMD); if (!cmd_mem) @@ -479,11 +473,11 @@ static int trigger_ras_ta_error(struct ras_core_context *ras_core, } static int send_load_ta_fw_cmd(struct ras_core_context *ras_core, - struct ras_ta_ctx *ta_ctx) + struct ras_ta_ctx *ta_ctx, bool skip_lock) { struct ras_ta_fw_bin *fw_bin = &ta_ctx->fw_bin; - struct gpu_mem_block *fw_mem; - struct gpu_mem_block *cmd_mem; + struct gpu_mem_block *fw_mem = NULL; + struct gpu_mem_block *cmd_mem = NULL; struct ras_ta_cmd *ta_cmd; struct ras_ta_init_flags *ta_init_flags; struct psp_gfx_cmd_load_ta psp_load_ta_cmd; @@ -491,6 +485,10 @@ static int send_load_ta_fw_cmd(struct ras_core_context *ras_core, struct ras_ta_image_header *fw_hdr = NULL; int ret; + ret = ras_psp_get_ras_ta_init_param(ras_core, &ta_ctx->init_param); + if (ret) + goto err; + fw_mem = ras_psp_get_gpu_mem(ras_core, GPU_MEM_TYPE_RAS_TA_FW); if (!fw_mem) return -ENOMEM; @@ -501,11 +499,12 @@ static int send_load_ta_fw_cmd(struct ras_core_context *ras_core, goto err; } - ret = ras_psp_get_ras_ta_init_param(ras_core, &ta_ctx->init_param); - if (ret) - goto err; - - if (!ras_core_down_trylock_gpu_reset_lock(ras_core)) { + /* + * When skip_lock is true (called from .resume), the PSP has already + * been re-initialized and it is safe to proceed without the read lock + * (GPU reset holds write lock; S3/S4 has no lock to acquire). + */ + if (!skip_lock && !ras_core_down_trylock_gpu_reset_lock(ras_core)) { ret = -EACCES; goto err; } @@ -552,7 +551,8 @@ static int send_load_ta_fw_cmd(struct ras_core_context *ras_core, "Failed to load RAS TA! ret:%d, status:%d\n", ret, resp.status); } - ras_core_up_gpu_reset_lock(ras_core); + if (!skip_lock) + ras_core_up_gpu_reset_lock(ras_core); err: ras_psp_put_gpu_mem(ras_core, fw_mem); @@ -560,24 +560,12 @@ static int send_load_ta_fw_cmd(struct ras_core_context *ras_core, return ret; } -static int load_ras_ta_firmware(struct ras_core_context *ras_core, - struct ras_psp_ta_load *ras_ta_load) +static int load_ras_ta_firmware(struct ras_core_context *ras_core, bool skip_lock) { struct ras_ta_ctx *ta_ctx = &ras_core->ras_psp.ta_ctx; - struct ras_ta_fw_bin *fw_bin = &ta_ctx->fw_bin; int ret; - fw_bin->bin_addr = ras_ta_load->bin_addr; - fw_bin->bin_size = ras_ta_load->bin_size; - fw_bin->fw_version = ras_ta_load->fw_version; - fw_bin->feature_version = ras_ta_load->feature_version; - - ret = send_load_ta_fw_cmd(ras_core, ta_ctx); - if (!ret) { - ras_ta_load->out_session_id = ta_ctx->session_id; - ras_ta_load->out_loaded_ta_version = ta_ctx->ta_version; - } - + ret = send_load_ta_fw_cmd(ras_core, ta_ctx, skip_lock); return ret; } @@ -602,12 +590,13 @@ static int unload_ras_ta_firmware(struct ras_core_context *ras_core, goto unlock; } - kfree(ta_ctx->fw_bin.bin_addr); - memset(&ta_ctx->fw_bin, 0, sizeof(ta_ctx->fw_bin)); + RAS_DEV_INFO(ras_core->dev, + "Successfully to unload RAS TA! ret:%d, status:%u\n", + ret, resp.status); + ta_ctx->ta_version = 0; ta_ctx->ras_ta_initialized = false; ta_ctx->session_id = 0; - unlock: ras_core_up_gpu_reset_lock(ras_core); @@ -615,26 +604,42 @@ static int unload_ras_ta_firmware(struct ras_core_context *ras_core, } int ras_psp_load_firmware(struct ras_core_context *ras_core, - struct ras_psp_ta_load *ras_ta_load) + bool skip_lock) { struct ras_ta_ctx *ta_ctx = &ras_core->ras_psp.ta_ctx; struct ras_psp_ta_unload ras_ta_unload = {0}; - int ret; - - if (ta_ctx->preload_ras_ta_enabled) - return 0; + int ret = 0; - if (!ras_ta_load) - return -EINVAL; + if (skip_lock) { + /* + * Called from .resume: PSP has been re-initialized after a GPU + * reset or S3/S4, so any previous TA session is gone. Clear + * stale state and proceed directly to a fresh load, bypassing + * both the unload step and the reset read-lock acquisition + * (which would deadlock inside a GPU reset). + */ + ta_ctx->preload_ras_ta_enabled = false; + ta_ctx->ras_ta_initialized = false; + ta_ctx->session_id = 0; + ta_ctx->ta_version = 0; + } else { + /* + * Normal path: only skip a reload when the current TA session is + * known to be alive. Firmware metadata may already be cached even + * when the TA is not loaded, so that must not suppress a reload. + */ + if (ta_ctx->preload_ras_ta_enabled && ta_ctx->ras_ta_initialized) + return 0; - if (ta_ctx->ras_ta_initialized) { - ras_ta_unload.ras_session_id = ta_ctx->session_id; - ret = unload_ras_ta_firmware(ras_core, &ras_ta_unload); - if (ret) - return ret; + if (ta_ctx->ras_ta_initialized) { + ras_ta_unload.ras_session_id = ta_ctx->session_id; + ret = unload_ras_ta_firmware(ras_core, &ras_ta_unload); + if (ret) + return ret; + } } - return load_ras_ta_firmware(ras_core, ras_ta_load); + return load_ras_ta_firmware(ras_core, skip_lock); } int ras_psp_unload_firmware(struct ras_core_context *ras_core, @@ -642,9 +647,6 @@ int ras_psp_unload_firmware(struct ras_core_context *ras_core, { struct ras_ta_ctx *ta_ctx = &ras_core->ras_psp.ta_ctx; - if (ta_ctx->preload_ras_ta_enabled) - return 0; - if ((!ras_ta_unload) || (ras_ta_unload->ras_session_id != ta_ctx->session_id)) return -EINVAL; @@ -719,7 +721,9 @@ int ras_psp_sw_fini(struct ras_core_context *ras_core) int ras_psp_hw_init(struct ras_core_context *ras_core) { + int ret = 0; struct ras_psp *psp = &ras_core->ras_psp; + struct ras_ta_ctx *ta_ctx = &ras_core->ras_psp.ta_ctx; psp->psp_ip_version = ras_core->config->psp_ip_version; @@ -741,11 +745,30 @@ int ras_psp_hw_init(struct ras_core_context *ras_core) */ ras_psp_sync_system_ras_psp_status(ras_core); - return 0; + if (!ta_ctx->preload_ras_ta_enabled && !ta_ctx->ras_ta_initialized) + ret = ras_psp_load_firmware(ras_core, false); + + return ret; } int ras_psp_hw_fini(struct ras_core_context *ras_core) { + struct ras_ta_ctx *ta_ctx = &ras_core->ras_psp.ta_ctx; + struct ras_psp_ta_unload ras_ta_unload = {0}; + + if (ta_ctx->ras_ta_initialized) { + ras_ta_unload.ras_session_id = ta_ctx->session_id; + ras_psp_unload_firmware(ras_core, &ras_ta_unload); + } + + ta_ctx->ta_version = 0; + ta_ctx->ras_ta_initialized = false; + ta_ctx->preload_ras_ta_enabled = false; + ta_ctx->session_id = 0; + + /* Free shared BO only on hw_fini, not on suspend */ + ras_psp_put_ras_ta_fini_param(ras_core); + return 0; } diff --git a/drivers/gpu/drm/amd/ras/core/ras_psp.h b/drivers/gpu/drm/amd/ras/core/ras_psp.h index f1d32f31a64ee..cb564b532ac9e 100644 --- a/drivers/gpu/drm/amd/ras/core/ras_psp.h +++ b/drivers/gpu/drm/amd/ras/core/ras_psp.h @@ -41,8 +41,6 @@ struct ras_ta_image_header { }; struct ras_psp_sys_status { - bool initialized; - uint32_t session_id; void *psp_cmd_mutex; }; @@ -146,15 +144,6 @@ struct ras_psp { const struct ras_psp_sys_func *sys_func; }; -struct ras_psp_ta_load { - uint32_t fw_version; - uint32_t feature_version; - uint32_t bin_size; - uint8_t *bin_addr; - uint64_t out_session_id; - uint32_t out_loaded_ta_version; -}; - struct ras_psp_ta_unload { uint64_t ras_session_id; }; @@ -163,8 +152,8 @@ int ras_psp_sw_init(struct ras_core_context *ras_core); int ras_psp_sw_fini(struct ras_core_context *ras_core); int ras_psp_hw_init(struct ras_core_context *ras_core); int ras_psp_hw_fini(struct ras_core_context *ras_core); -int ras_psp_load_firmware(struct ras_core_context *ras_core, - struct ras_psp_ta_load *ras_ta_load); + +int ras_psp_load_firmware(struct ras_core_context *ras_core, bool skip_lock); int ras_psp_unload_firmware(struct ras_core_context *ras_core, struct ras_psp_ta_unload *ras_ta_unload); int ras_psp_trigger_error(struct ras_core_context *ras_core, 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 525abb7e05474..29558888832c1 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 @@ -188,10 +188,7 @@ static int amdgpu_ras_mgr_get_ras_psp_system_status(struct ras_core_context *ras struct ras_psp_sys_status *status) { struct amdgpu_device *adev = (struct amdgpu_device *)ras_core->dev; - struct ta_context *context = &adev->psp.ras_context.context; - status->initialized = context->initialized; - status->session_id = context->session_id; status->psp_cmd_mutex = &adev->psp.mutex; return 0; -- 2.55.0