Skip to content

Commit 276e8be

Browse files
committed
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>
1 parent c5da9e9 commit 276e8be

File tree

2 files changed

+43
-0
lines changed

2 files changed

+43
-0
lines changed

drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,14 @@ static u64 amdgpu_userq_fence_read(struct amdgpu_userq_fence_driver *fence_drv)
6767
return le64_to_cpu(*fence_drv->cpu_addr);
6868
}
6969

70+
static void
71+
amdgpu_userq_fence_write(struct amdgpu_userq_fence_driver *fence_drv,
72+
u64 seq)
73+
{
74+
if (fence_drv->cpu_addr)
75+
*fence_drv->cpu_addr = cpu_to_le64(seq);
76+
}
77+
7078
int amdgpu_userq_fence_driver_alloc(struct amdgpu_device *adev,
7179
struct amdgpu_usermode_queue *userq)
7280
{
@@ -408,6 +416,40 @@ static void amdgpu_userq_fence_cleanup(struct dma_fence *fence)
408416
dma_fence_put(fence);
409417
}
410418

419+
static void
420+
amdgpu_userq_fence_driver_set_error(struct amdgpu_userq_fence *fence,
421+
int error)
422+
{
423+
struct amdgpu_userq_fence_driver *fence_drv = fence->fence_drv;
424+
unsigned long flags;
425+
struct dma_fence *f;
426+
427+
spin_lock_irqsave(&fence_drv->fence_list_lock, flags);
428+
429+
f = rcu_dereference_protected(&fence->base,
430+
lockdep_is_held(&fence_drv->fence_list_lock));
431+
if (f && !dma_fence_is_signaled_locked(f))
432+
dma_fence_set_error(f, error);
433+
spin_unlock_irqrestore(&fence_drv->fence_list_lock, flags);
434+
}
435+
436+
void
437+
amdgpu_userq_fence_driver_force_completion(struct amdgpu_usermode_queue *userq)
438+
{
439+
struct dma_fence *f = userq->last_fence;
440+
441+
if (f) {
442+
struct amdgpu_userq_fence *fence = to_amdgpu_userq_fence(f);
443+
struct amdgpu_userq_fence_driver *fence_drv = fence->fence_drv;
444+
u64 wptr = fence->base.seqno;
445+
446+
amdgpu_userq_fence_driver_set_error(fence, -ECANCELED);
447+
amdgpu_userq_fence_write(fence_drv, wptr);
448+
amdgpu_userq_fence_driver_process(fence_drv);
449+
450+
}
451+
}
452+
411453
int amdgpu_userq_signal_ioctl(struct drm_device *dev, void *data,
412454
struct drm_file *filp)
413455
{

drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ int amdgpu_userq_fence_driver_alloc(struct amdgpu_device *adev,
6767
struct amdgpu_usermode_queue *userq);
6868
void amdgpu_userq_fence_driver_free(struct amdgpu_usermode_queue *userq);
6969
void amdgpu_userq_fence_driver_process(struct amdgpu_userq_fence_driver *fence_drv);
70+
void amdgpu_userq_fence_driver_force_completion(struct amdgpu_usermode_queue *userq);
7071
void amdgpu_userq_fence_driver_destroy(struct kref *ref);
7172
int amdgpu_userq_signal_ioctl(struct drm_device *dev, void *data,
7273
struct drm_file *filp);

0 commit comments

Comments
 (0)