diff options
author | Shashank Sharma <shashank.sharma@amd.com> | 2024-11-20 18:59:49 +0100 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2025-04-08 16:48:18 -0400 |
commit | b0328087c179f47ea6558c3b91b4487c5e10deda (patch) | |
tree | 7b41fee39432946812413fccfd15364beac238e0 /drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c | |
parent | 30e4d781385dda92fdee574b0a95094dfa143b52 (diff) |
drm/amdgpu: suspend gfx userqueues
This patch adds suspend support for gfx userqueues. It typically does
the following:
- adds an enable_signaling function for the eviction fence, so that it
can trigger the userqueue suspend,
- adds a delayed work to handle suspending of the eviction_fence
- adds a suspend function to handle suspending of userqueues which
suspends all the queues under this userq manager and signals the
eviction fence,
- adds a function to replace the old eviction fence with a new one and
attach it to each of the objects,
- adds reference of userq manager in the eviction fence container so
that it can be used in the suspend function.
V2: Addressed Christian's review comments:
- schedule suspend work immediately
V4: Addressed Christian's review comments:
- wait for pending uq fences before starting suspend, added
queue->last_fence for the same
- accommodate ev_fence_mgr into existing code
- some bug fixes and NULL checks
V5: Addressed Christian's review comments (gitlab)
- Wait for eviction fence to get signaled in destroy,
don't signal it
- Wait for eviction fence to get signaled in replace fence,
don't signal it
V6: Addressed Christian's review comments
- Do not destroy the old eviction fence until we have it replaced
- Change the sequence of fence replacement sub-tasks
- reusing the ev_fence delayed work for userqueue suspend as well
(Shashank).
V7: Addressed Christian's review comments
- give evf_mgr as argument (instead of fpriv) to replace_fence()
- save ptr to evf_mgr in ev_fence (instead of uq_mgr)
- modify suspend_all_queues logic to reflect error properly
- remove the garbage drm_exec_lock section in wait_for_signal
- grab the userqueue mutex before starting the wait for fence
- remove the unrelated gobj check from signal_ioctl
V8: Added race condition fixes
Cc: Alex Deucher <alexander.deucher@amd.com>
Cc: Christian Koenig <christian.koenig@amd.com>
Acked-by: Christian Koenig <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_userq_fence.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c | 37 |
1 files changed, 26 insertions, 11 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c index 6157a540c929..877cb17a14e9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c @@ -466,6 +466,16 @@ int amdgpu_userq_signal_ioctl(struct drm_device *dev, void *data, } } + /* Save the fence to wait for during suspend */ + mutex_lock(&userq_mgr->userq_mutex); + + /* Retrieve the user queue */ + queue = idr_find(&userq_mgr->userq_idr, args->queue_id); + if (!queue) { + r = -ENOENT; + mutex_unlock(&userq_mgr->userq_mutex); + } + drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, (num_read_bo_handles + num_write_bo_handles)); @@ -473,30 +483,35 @@ int amdgpu_userq_signal_ioctl(struct drm_device *dev, void *data, drm_exec_until_all_locked(&exec) { r = drm_exec_prepare_array(&exec, gobj_read, num_read_bo_handles, 1); drm_exec_retry_on_contention(&exec); - if (r) + if (r) { + mutex_unlock(&userq_mgr->userq_mutex); goto exec_fini; + } r = drm_exec_prepare_array(&exec, gobj_write, num_write_bo_handles, 1); drm_exec_retry_on_contention(&exec); - if (r) + if (r) { + mutex_unlock(&userq_mgr->userq_mutex); goto exec_fini; - } - - /*Retrieve the user queue */ - queue = idr_find(&userq_mgr->userq_idr, args->queue_id); - if (!queue) { - r = -ENOENT; - goto exec_fini; + } } r = amdgpu_userq_fence_read_wptr(queue, &wptr); - if (r) + if (r) { + mutex_unlock(&userq_mgr->userq_mutex); goto exec_fini; + } /* Create a new fence */ r = amdgpu_userq_fence_create(queue, wptr, &fence); - if (r) + if (r) { + mutex_unlock(&userq_mgr->userq_mutex); goto exec_fini; + } + + dma_fence_put(queue->last_fence); + queue->last_fence = dma_fence_get(fence); + mutex_unlock(&userq_mgr->userq_mutex); for (i = 0; i < num_read_bo_handles; i++) { if (!gobj_read || !gobj_read[i]->resv) |