This patch introduces two new helper functions to manage user queue preemption and restoration:
1. amdgpu_userqueue_preempt_helper() - Handles preempting a user queue by calling the appropriate IP-specific preempt function and updating the queue state. If preemption fails, it marks the queue as hung and triggers queue detection/reset. 2. amdgpu_userqueue_restore_helper() - Handles restoring a preempted user queue by calling the IP-specific restore function. On failure, it marks the queue as hung and triggers a GPU reset. The helpers properly manage queue state transitions between MAPPED, PREEMPTED, and HUNG states, and handle error cases by initiating appropriate recovery actions. These functions will be used by subsequent patches to implement user queue preemption support in the driver. Signed-off-by: Alex Deucher <[email protected]> Signed-off-by: Jesse Zhang <[email protected]> --- drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c | 48 +++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c index aac0de86f3e8..1496544cd1c2 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c @@ -44,6 +44,54 @@ u32 amdgpu_userq_get_supported_ip_mask(struct amdgpu_device *adev) return userq_ip_mask; } +static int +amdgpu_userqueue_preempt_helper(struct amdgpu_userq_mgr *uq_mgr, + struct amdgpu_usermode_queue *queue) +{ + struct amdgpu_device *adev = uq_mgr->adev; + const struct amdgpu_userq_funcs *userq_funcs = + adev->userq_funcs[queue->queue_type]; + int r = 0; + + if (queue->state == AMDGPU_USERQ_STATE_MAPPED) { + r = userq_funcs->preempt(uq_mgr, queue); + if (r) { + amdgpu_userq_detect_and_reset_queues(uq_mgr); + queue->state = AMDGPU_USERQ_STATE_HUNG; + } else { + queue->state = AMDGPU_USERQ_STATE_PREEMPTED; + } + } + + return r; +} + +static int +amdgpu_userqueue_restore_helper(struct amdgpu_userq_mgr *uq_mgr, + struct amdgpu_usermode_queue *queue) +{ + struct amdgpu_device *adev = uq_mgr->adev; + const struct amdgpu_userq_funcs *userq_funcs = + adev->userq_funcs[queue->queue_type]; + bool gpu_reset = false; + int r = 0; + + if (queue->state == AMDGPU_USERQ_STATE_PREEMPTED) { + r = userq_funcs->restore(uq_mgr, queue); + if (r) { + queue->state = AMDGPU_USERQ_STATE_HUNG; + gpu_reset = true; + } else { + queue->state = AMDGPU_USERQ_STATE_MAPPED; + } + } + + if (gpu_reset) + amdgpu_userq_gpu_reset(adev); + + return r; +} + static int amdgpu_userq_unmap_helper(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermode_queue *queue) -- 2.49.0
