drm/amdgpu/userq: add force completion helpers

Add support for forcing completion of userq fences.
This is needed for userq resets and asic resets so that we
can set the error on the fence and force completion.

Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
Alex Deucher 2025-04-18 11:35:49 -04:00
parent c5da9e9c02
commit 276e8beb2a
2 changed files with 43 additions and 0 deletions

View file

@ -67,6 +67,14 @@ static u64 amdgpu_userq_fence_read(struct amdgpu_userq_fence_driver *fence_drv)
return le64_to_cpu(*fence_drv->cpu_addr);
}
static void
amdgpu_userq_fence_write(struct amdgpu_userq_fence_driver *fence_drv,
u64 seq)
{
if (fence_drv->cpu_addr)
*fence_drv->cpu_addr = cpu_to_le64(seq);
}
int amdgpu_userq_fence_driver_alloc(struct amdgpu_device *adev,
struct amdgpu_usermode_queue *userq)
{
@ -408,6 +416,40 @@ static void amdgpu_userq_fence_cleanup(struct dma_fence *fence)
dma_fence_put(fence);
}
static void
amdgpu_userq_fence_driver_set_error(struct amdgpu_userq_fence *fence,
int error)
{
struct amdgpu_userq_fence_driver *fence_drv = fence->fence_drv;
unsigned long flags;
struct dma_fence *f;
spin_lock_irqsave(&fence_drv->fence_list_lock, flags);
f = rcu_dereference_protected(&fence->base,
lockdep_is_held(&fence_drv->fence_list_lock));
if (f && !dma_fence_is_signaled_locked(f))
dma_fence_set_error(f, error);
spin_unlock_irqrestore(&fence_drv->fence_list_lock, flags);
}
void
amdgpu_userq_fence_driver_force_completion(struct amdgpu_usermode_queue *userq)
{
struct dma_fence *f = userq->last_fence;
if (f) {
struct amdgpu_userq_fence *fence = to_amdgpu_userq_fence(f);
struct amdgpu_userq_fence_driver *fence_drv = fence->fence_drv;
u64 wptr = fence->base.seqno;
amdgpu_userq_fence_driver_set_error(fence, -ECANCELED);
amdgpu_userq_fence_write(fence_drv, wptr);
amdgpu_userq_fence_driver_process(fence_drv);
}
}
int amdgpu_userq_signal_ioctl(struct drm_device *dev, void *data,
struct drm_file *filp)
{

View file

@ -67,6 +67,7 @@ int amdgpu_userq_fence_driver_alloc(struct amdgpu_device *adev,
struct amdgpu_usermode_queue *userq);
void amdgpu_userq_fence_driver_free(struct amdgpu_usermode_queue *userq);
void amdgpu_userq_fence_driver_process(struct amdgpu_userq_fence_driver *fence_drv);
void amdgpu_userq_fence_driver_force_completion(struct amdgpu_usermode_queue *userq);
void amdgpu_userq_fence_driver_destroy(struct kref *ref);
int amdgpu_userq_signal_ioctl(struct drm_device *dev, void *data,
struct drm_file *filp);