From: Vitaly Prosyak <[email protected]>

A user queue restore can rearm an eviction fence after the BO reservation has 
been unlocked.
Since dma_resv_unlock() discards unused pre-reserved capacity, a BO with no 
remaining fences
can reach rearm with max_fences equal to zero. Reserve one fence slot 
immediately before
attaching the replacement BOOKKEEP eviction fence. The BO is already held by 
the drm_exec
context at this point, so the reservation remains valid for 
dma_resv_add_fence(). Keep the
reservation in the rearm path rather than hiding it in 
amdgpu_evf_mgr_attach_fence(), so
the caller-side accounting remains explicit.
This fixes the dma-resv BUG_ON at dma-resv.c:319 and the resulting crash in
amdgpu_userq_restore_worker. The earlier root-PD and WPTR-caller reservations 
are reverted
by the preceding commits because they do not cover this reservation lifetime. 
Validated with
repeated amd_deadlock runs, including the userqueue restore reproducer.

Cc: Christian König <[email protected]>
Cc: Alex Deucher <[email protected]>
Cc: Prike Liang <[email protected]>
Signed-off-by: Vitaly Prosyak <[email protected]>
Change-Id: Id156389c1b2193fc3e1354acd5194f756faf39c9
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_eviction_fence.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_eviction_fence.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_eviction_fence.c
index a0802012de49..6c1f994ea78b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_eviction_fence.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_eviction_fence.c
@@ -125,6 +125,7 @@ int amdgpu_evf_mgr_rearm(struct amdgpu_eviction_fence_mgr 
*evf_mgr,
        struct amdgpu_eviction_fence *ev_fence;
        struct drm_gem_object *obj;
        unsigned long index;
+       int ret;
 
        /* Create and initialize a new eviction fence */
        ev_fence = kzalloc_obj(*ev_fence);
@@ -146,6 +147,13 @@ int amdgpu_evf_mgr_rearm(struct amdgpu_eviction_fence_mgr 
*evf_mgr,
        drm_exec_for_each_locked_object(exec, index, obj) {
                struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj);
 
+               ret = dma_resv_reserve_fences(bo->tbo.base.resv, 1);
+               if (ret) {
+                    pr_err("userq evf rearm attach failed index=%lu bo=%p 
ret=%d\n",
+                           index, bo, ret);
+                    return ret;
+                }
+
                amdgpu_evf_mgr_attach_fence(evf_mgr, bo);
        }
        return 0;
-- 
2.55.0

Reply via email to