From e35c9cf5512814fb04f369f2eada64f0a7164609 Mon Sep 17 00:00:00 2001 From: Lizhi Hou Date: Tue, 16 Jun 2026 14:24:29 -0700 Subject: [PATCH] accel/amdxdna: Prevent PM resume deadlock in hwctx_sync_debug_bo() amdxdna_hwctx_sync_debug_bo() invokes the hardware hwctx_sync_debug_bo() callback while holding xdna->dev_lock. The callback may call amdxdna_cmd_submit(), which in turn calls amdxdna_pm_resume_get(). If the device is suspended, amdxdna_pm_resume_get() may synchronously execute amdxdna_pm_resume(), which also acquires xdna->dev_lock, resulting in a deadlock. Avoid the deadlock by calling amdxdna_pm_resume_get() before holding xdna->dev_lock in both amdxdna_hwctx_sync_debug_bo() and amdxdna_drm_config_hwctx_ioctl() Fixes: 7ea046838021 ("accel/amdxdna: Support firmware debug buffer") Reviewed-by: Max Zhen Signed-off-by: Lizhi Hou Link: https://patch.msgid.link/20260616212429.3620645-1-lizhi.hou@amd.com --- drivers/accel/amdxdna/aie2_ctx.c | 2 +- drivers/accel/amdxdna/amdxdna_ctx.c | 26 ++++++++++++++++++++++---- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/drivers/accel/amdxdna/aie2_ctx.c b/drivers/accel/amdxdna/aie2_ctx.c index 54486960cbf5e..4fa9abd90cd7d 100644 --- a/drivers/accel/amdxdna/aie2_ctx.c +++ b/drivers/accel/amdxdna/aie2_ctx.c @@ -875,7 +875,7 @@ static int aie2_hwctx_cu_config(struct amdxdna_hwctx *hwctx, void *buf, u32 size if (!hwctx->cus) return -ENOMEM; - ret = amdxdna_pm_resume_get_locked(xdna); + ret = amdxdna_pm_resume_get(xdna); if (ret) goto free_cus; diff --git a/drivers/accel/amdxdna/amdxdna_ctx.c b/drivers/accel/amdxdna/amdxdna_ctx.c index 855da8c79a1cd..67a2abcf173ee 100644 --- a/drivers/accel/amdxdna/amdxdna_ctx.c +++ b/drivers/accel/amdxdna/amdxdna_ctx.c @@ -382,16 +382,25 @@ int amdxdna_drm_config_hwctx_ioctl(struct drm_device *dev, void *data, struct dr return -EINVAL; } - guard(mutex)(&xdna->dev_lock); + ret = amdxdna_pm_resume_get(xdna); + if (ret) { + XDNA_ERR(xdna, "Resume failed, ret %d", ret); + goto free_buf; + } + + mutex_lock(&xdna->dev_lock); hwctx = xa_load(&client->hwctx_xa, args->handle); if (!hwctx) { XDNA_DBG(xdna, "PID %d failed to get hwctx %d", client->pid, args->handle); ret = -EINVAL; - goto free_buf; + goto unlock; } ret = xdna->dev_info->ops->hwctx_config(hwctx, args->param_type, val, buf, buf_size); +unlock: + mutex_unlock(&xdna->dev_lock); + amdxdna_pm_suspend_put(xdna); free_buf: kfree(buf); return ret; @@ -412,16 +421,25 @@ int amdxdna_hwctx_sync_debug_bo(struct amdxdna_client *client, u32 debug_bo_hdl) if (!gobj) return -EINVAL; + ret = amdxdna_pm_resume_get(xdna); + if (ret) { + XDNA_ERR(xdna, "Resume failed, ret %d", ret); + goto put_obj; + } + abo = to_xdna_obj(gobj); - guard(mutex)(&xdna->dev_lock); + mutex_lock(&xdna->dev_lock); hwctx = xa_load(&client->hwctx_xa, abo->assigned_hwctx); if (!hwctx) { ret = -EINVAL; - goto put_obj; + goto unlock; } ret = xdna->dev_info->ops->hwctx_sync_debug_bo(hwctx, debug_bo_hdl); +unlock: + mutex_unlock(&xdna->dev_lock); + amdxdna_pm_suspend_put(xdna); put_obj: drm_gem_object_put(gobj); return ret; -- 2.47.3