[PATCH 6/9] drm/amdgpu/userq: add force completion helpers

Khatri, Sunil sukhatri at amd.com
Mon Apr 28 09:20:36 UTC 2025


On 4/26/2025 12:08 AM, Alex Deucher wrote:
> 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.
>
> Signed-off-by: Alex Deucher <alexander.deucher at amd.com>
> ---
>   .../gpu/drm/amd/amdgpu/amdgpu_userq_fence.c   | 42 +++++++++++++++++++
>   .../gpu/drm/amd/amdgpu/amdgpu_userq_fence.h   |  1 +
>   2 files changed, 43 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c
> index 3288c2ff692e7..3494ac9e9e9db 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c
> @@ -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;

Do we want to declare there structures to beginning of the function ??

Regards
Sunil Khatri

> +		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)
>   {
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.h
> index 97a125ab8a786..d76add2afc774 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.h
> @@ -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);


More information about the amd-gfx mailing list