In amdgpu_ras_recovery_fini(), mutex_destroy(&con->page_rsv_lock) was called prior to cancel_work_sync(&con->recovery_work) and cancel_delayed_work_sync(&con->page_retirement_dwork).
If pending work ran during teardown, it could attempt to acquire page_rsv_lock after its destruction, leading to a locking violation and potential use-after-free. Fix this by moving cancel_work_sync(&con->recovery_work) and cancel_delayed_work_sync(&con->page_retirement_dwork) before mutex_destroy(&con->page_rsv_lock), ensuring both work items are synchronously canceled while the lock remains intact. Signed-off-by: Sreeraj S Kurup <[email protected]> --- drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c index 764cd4950408..1d6b4300d80a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c @@ -3994,15 +3994,14 @@ static int amdgpu_ras_recovery_fini(struct amdgpu_device *adev) if (con->page_retirement_thread) kthread_stop(con->page_retirement_thread); + cancel_work_sync(&con->recovery_work); + cancel_delayed_work_sync(&con->page_retirement_dwork); + atomic_set(&con->page_retirement_req_cnt, 0); atomic_set(&con->poison_creation_count, 0); mutex_destroy(&con->page_rsv_lock); - cancel_work_sync(&con->recovery_work); - - cancel_delayed_work_sync(&con->page_retirement_dwork); - amdgpu_ras_ecc_log_fini(&con->umc_ecc_log); mutex_lock(&con->recovery_lock); -- 2.54.0
