From: Vitaly Prosyak <[email protected]>

This series fixes two bugs exposed by running the amd_basic IGT test with
AMDGPU_ENABLE_USERQTEST=1 on a GFX12 GPU with CONFIG_LOCKDEP=y enabled.

Bug 1: kernel BUG at drivers/dma-buf/dma-resv.c:319
-----------------------------------------------------
amdgpu_evf_mgr_attach_fence() calls ttm_bo_validate() then
dma_resv_add_fence() without reserving a fence slot first.
ttm_bo_validate() consumes the pre-allocated slots for its own fences,
leaving none for the eviction fence:

  kernel BUG at drivers/dma-buf/dma-resv.c:319!
  BUG_ON(fobj->num_fences >= fobj->max_fences)
  RIP: dma_resv_add_fence+0x294/0x2b0
  Workqueue: events amdgpu_userq_restore_worker

Patch 1 adds the missing dma_resv_reserve_fences(resv, 1) call.

Bug 2: four lockdep violations during GPU reset (CONFIG_LOCKDEP=y)
-------------------------------------------------------------------
With lockdep enabled a MES timeout during cs-compute-fwm-UMQ triggers
a GPU reset, exposing four lock ordering violations. All involve
reset_domain->sem being held while other locks that must come before it
in the established ordering are acquired.

The violations (each addressed by one patch):

1. halt_activities() -> drm_client_dev_suspend() takes clientlist_mutex
   while reset_domain->sem is already held. Fixed in patch 3 by moving
   the reset lock acquisition to after halt_activities().

2. psp_resume() takes firmware.mutex while reset_domain->sem is held.
   Fixed in patch 4 by skipping firmware.mutex in reset context, since
   down_write(reset_domain->sem) already provides exclusive protection.

3. amdgpu_device_reinit_after_reset() calls drm_client_dev_resume()
   which takes clientlist_mutex while reset_domain->sem is held. Fixed
   in patch 5 by moving the call to after recovery_put_reset_lock().

4. amdgpu_userq_destroy() calls cancel_delayed_work_sync() inside
   userq_mutex; the work itself takes userq_mutex. Fixed in patch 2 by
   moving the cancel before mutex_lock().

After all 5 patches the amd_basic UMQ subtests pass with no lockdep
warnings on a CONFIG_LOCKDEP=y / CONFIG_PROVE_LOCKING=y kernel.

Tested-on: GFX12 (Radeon RX 9070 XT / device 0x7550)
           IGT amd_basic with AMDGPU_ENABLE_USERQTEST=1
           Kernel: 7.1.0+, CONFIG_LOCKDEP=y, CONFIG_PROVE_LOCKING=y

Vitaly Prosyak (5):
  drm/amdgpu: reserve dma_resv slot before adding eviction fence
  drm/amdgpu: cancel hang_detect_work before taking userq_mutex
  drm/amdgpu: take reset lock after halt_activities
  drm/amdgpu/psp: skip firmware.mutex in psp_resume during GPU reset
  drm/amdgpu: move drm_client_dev_resume outside reset_domain->sem

 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c         |  9 ++++---
 drivers/gpu/drm/amd/amdgpu/amdgpu_eviction_fence.c |  2 ++
 drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c            | 10 ++++----
 drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c          |  4 +++-
 4 files changed, 17 insertions(+), 8 deletions(-)

Vitaly Prosyak (5):
  drm/amdgpu: reserve dma_resv slot before adding eviction fence
  drm/amdgpu: cancel hang_detect_work before taking userq_mutex
  drm/amdgpu: take reset lock after halt_activities
  drm/amdgpu/psp: skip firmware.mutex in psp_resume during GPU reset
  drm/amdgpu: move drm_client_dev_resume outside reset_domain->sem

 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c    | 21 ++++++++++++++-----
 .../drm/amd/amdgpu/amdgpu_eviction_fence.c    |  2 ++
 drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c       | 13 +++++++++---
 drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c     |  5 ++++-
 4 files changed, 32 insertions(+), 9 deletions(-)

-- 
2.54.0

Reply via email to