AMD General

Regards,
      Prike

> -----Original Message-----
> From: [email protected] <[email protected]>
> Sent: Thursday, September 24, 2026 7:47 AM
> To: [email protected]
> Cc: Prosyak, Vitaly <[email protected]>; Koenig, Christian
> <[email protected]>; Deucher, Alexander
> <[email protected]>; Liang, Prike <[email protected]>
> Subject: [PATCH] drm/amdgpu: reserve fence slot before userq eviction rearm
>
> From: Vitaly Prosyak <[email protected]>
>
> During amd_deadlock userq reset testing, the restore worker reached
> amdgpu_evf_mgr_rearm() with a locked reservation object whose fence list had
> been rebuilt after validation. When all previous fences had completed, the 
> rebuilt list
> contained no active fences and dma_resv_reset_max_fences() left num_fences and
> max_fences at zero. dma_resv_add_fence() then triggered:
>
>   BUG_ON(fobj->num_fences >= fobj->max_fences)
>
> while adding the replacement BOOKKEEP eviction fence.
>
> The v1 proposal attempted to call dma_resv_reserve_fences() from inside
> amdgpu_evf_mgr_rearm(), immediately before dma_resv_add_fence(). This is not
> valid. dma_resv_reserve_fences() may allocate memory and replace the 
> reservation-
> fence list. If the replacement eviction fence has already been created by 
> rearm, that
> allocation can invalidate the newly created fence state again. This is the 
> ordering
> problem identified by Christian during review.
>
> v2 reserves the slot in the restore caller, before rearm creates the 
> replacement
> fence. After validation and GART work have completed, the caller still owns 
> every
> reservation through the DRM execution context. It refreshes one slot for 
> every locked
> object, allowing all possible reservation-list allocations to finish before
> amdgpu_evf_mgr_rearm() creates and attaches the new BOOKKEEP fence.
>
> The reservation remains caller-side. The eviction-fence helper does not 
> reserve
> memory and only consumes capacity prepared by its caller. The initial 
> caller-side
> preparation is still required for WPTR BOs and VM BOs, because it covers 
> validation
> and migration fences; the final refresh is required because later validation 
> can
> rebuild a reservation list and discard unused capacity.
>
> This v2 supersedes the v1 helper-side approach and the intermediate 
> caller-side
> allocation commits that did not refresh capacity after validation.
>
> Fixes: 91a358fe99d86 (drm/amdgpu: dont pin wptr bo instead use eviction fence)
>
> Reported-by: IGT amd_deadlock test
> Cc: Christian König <[email protected]>
> Cc: Alex Deucher <[email protected]>
> Cc: Prike Liang <[email protected]>
> Assisted-by: Claude:claude-sonnet-5
> Signed-off-by: Vitaly Prosyak <[email protected]>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c | 8 ++++++++
>  1 file changed, 8 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
> index 75d5ceaa53c6..a1b6ce8b348e 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
> @@ -1034,6 +1034,7 @@ amdgpu_userq_vm_validate_and_restore_queue(struct
> amdgpu_userq_mgr *uq_mgr)
>       struct amdgpu_bo_va *bo_va;
>       struct amdgpu_usermode_queue *queue;
>       struct amdgpu_bo *bo;
> +     struct drm_gem_object *obj;
>       struct drm_exec exec;
>       struct xarray xa;
>       int ret;
> @@ -1210,6 +1211,13 @@ amdgpu_userq_vm_validate_and_restore_queue(struct
> amdgpu_userq_mgr *uq_mgr)
>               queue->wptr_obj.gpu_addr = amdgpu_bo_gpu_offset(bo);
>       }



Regarding the eviction fence slot reservation: this looks good here, but we 
also need to revalidate the prelocked BOs if they backed off during the prelock 
sequence. I have a patch ready that prepares the BOs before rearming the 
eviction fence.

Thanks,
    Prike

> +     /* Re-reserve the rearm slot after validation may have rebuilt the 
> lists. */
> +     drm_exec_for_each_locked_object(&exec, tmp_key, obj) {
> +             ret = dma_resv_reserve_fences(obj->resv, 1);
> +             if (ret)
> +                     goto unlock_all;
> +     }
> +
>       ret = amdgpu_evf_mgr_rearm(&fpriv->evf_mgr, &exec);
>       if (ret) {
>               drm_file_err(uq_mgr->file, "Failed to replace eviction 
> fence\n");
> --
> 2.43.0

Reply via email to