diff options
author | Shashank Sharma <shashank.sharma@amd.com> | 2024-11-20 18:04:33 +0100 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2025-04-08 16:48:18 -0400 |
commit | b8e6d3f68c3bd1ac54492e210ece87475e7f862b (patch) | |
tree | 735e89e388d5bf812e2acb829f73756270620ed9 /drivers/gpu/drm/amd/amdgpu/amdgpu_eviction_fence.c | |
parent | 44cfdf368fb72c03e4137709803d58288a22cb06 (diff) |
drm/amdgpu: handle eviction fence race
The eviction process can get into a race condition between the eviction
fence suspend work (which replaces the old fence with new) and kms_close
(which destroys the fence and doesn't expect a new one).
This patch:
- adds a flag to indicate that fd is closing, so fence replacement is
not required (evf_mgr->fd_closing)
- adds a flush_work() during the ev_fence_destroy routine
V2: Addressed review comments from Christian:
- Do not use mutex to sync
- Use flush_work and wait for suspend_work to be done
V3: Fixed state machine for queue->active, which adds into race between
suspend/resume and queue ops
Cc: Alex Deucher <alexander.deucher@amd.com>
Cc: Christian König <christian.koenig@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Shashank Sharma <shashank.sharma@amd.com>
Signed-off-by: Arvind Yadav <arvind.yadav@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_eviction_fence.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_eviction_fence.c | 7 |
1 files changed, 7 insertions, 0 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_eviction_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_eviction_fence.c index 189afb872775..c22767a75348 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_eviction_fence.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_eviction_fence.c @@ -117,6 +117,10 @@ amdgpu_eviction_fence_suspend_worker(struct work_struct *work) /* Signal old eviction fence */ amdgpu_eviction_fence_signal(evf_mgr); + /* Do not replace eviction fence is fd is getting closed */ + if (evf_mgr->fd_closing) + return; + /* Prepare the objects to replace eviction fence */ drm_exec_init(&exec, DRM_EXEC_IGNORE_DUPLICATES, 0); drm_exec_until_all_locked(&exec) { @@ -199,6 +203,9 @@ void amdgpu_eviction_fence_destroy(struct amdgpu_eviction_fence_mgr *evf_mgr) { struct amdgpu_eviction_fence *ev_fence; + /* Wait for any pending work to execute */ + flush_delayed_work(&evf_mgr->suspend_work); + spin_lock(&evf_mgr->ev_fence_lock); ev_fence = evf_mgr->ev_fence; spin_unlock(&evf_mgr->ev_fence_lock); |