From: Vitaly Prosyak <[email protected]>

Problem:

    kernel BUG/CRASH at drivers/dma-buf/dma-resv.c:319!
    BUG_ON(fobj->num_fences >= fobj->max_fences)
    Workqueue: events amdgpu_userq_restore_worker

During userqueue restore, amdgpu_evf_mgr_rearm() attaches a replacement
BOOKKEEP eviction fence after the BO reservation may already have been
unlocked. dma_resv_unlock() discards unused pre-reserved capacity, so a BO
with no remaining fences can reach rearm with max_fences equal to zero.
The subsequent dma_resv_add_fence() then triggers BUG 319.

Reserve one slot in the caller-side rearm transaction immediately before
attaching the replacement fence. The BO is already locked by the drm_exec
context, so the reservation remains valid for dma_resv_add_fence(). Keep the
reservation out of amdgpu_evf_mgr_attach_fence() so caller-side accounting
remains explicit.

The earlier allocation patches do not address this reservation-lifetime root
cause and are no longer required:

Fixes:
- 00af92666f29 drm/amdgpu: reserve root PD fence slots for userq eviction-fence 
rearm
- 118037152820 drm/amdgpu: reserve eviction-fence slot at WPTR caller

Those commits should therefore be reverted.

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]>
---
 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 4c5e38dea4c2..636d9fc819c9 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_eviction_fence.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_eviction_fence.c
@@ -122,6 +122,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);
@@ -142,6 +143,13 @@ int amdgpu_evf_mgr_rearm(struct amdgpu_eviction_fence_mgr 
*evf_mgr,
        /* And add it to all existing BOs */
        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);
        }
-- 
2.43.0

Reply via email to