Re: [PATCH] drm/amd/display: fix dc_lock leak on GPU reset error paths
Mario Limonciello <[email protected]>
| Newsgroups | org.freedesktop.lists.amd-gfx,org.freedesktop.lists.dri-devel,org.kernel.vger.linux-kernel,org.kernel.vger.stable |
|---|---|
| Message-ID | <[email protected]> |
On 8/19/26 00:47, Linkai Gong wrote:
> On GPU reset, dm_suspend() takes dc_lock and leaves it for dm_resume()
> to drop. If amdgpu_dm_commit_zero_streams() or dm_dmub_hw_init() fails,
> the function returns with the lock still held. The matching resume path
> is then skipped, so every later dc_lock take hangs.
>
> Release the cached DC state and unlock before returning the error.
>
> Fixes: 3cf7a0bc87f0 ("drm/amd/display: Catch failures for amdgpu_dm_commit_zero_streams()")
> Fixes: 2b6943df5413 ("drm/amd/display: Pass up errors for reset GPU that fails to init HW")
> Cc: [email protected]
> Signed-off-by: Linkai Gong <[email protected]>
Great finding and fix. I'll get this added to amd-staging-drm-next.
Reviewed-by: Mario Limonciello <[email protected]>
> ---
> drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 6 ++++++
> 1 file changed, 6 insertions(+)
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> index 941c1a312824..214aca906fe1 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -3511,6 +3511,9 @@ static int dm_suspend(struct amdgpu_ip_block *ip_block)
> res = amdgpu_dm_commit_zero_streams(dm->dc);
> if (res != DC_OK) {
> drm_err(adev_to_drm(adev), "Failed to commit zero streams: %d\n", res);
> + dc_state_release(dm->cached_dc_state);
> + dm->cached_dc_state = NULL;
> + mutex_unlock(&dm->dc_lock);
> return -EINVAL;
> }
>
> @@ -3824,6 +3827,9 @@ static int dm_resume(struct amdgpu_ip_block *ip_block)
> r = dm_dmub_hw_init(adev);
> if (r) {
> drm_err(adev_to_drm(adev), "DMUB interface failed to initialize: status=%d\n", r);
> + dc_state_release(dm->cached_dc_state);
> + dm->cached_dc_state = NULL;
> + mutex_unlock(&dm->dc_lock);
> return r;
> }
>