On PCIe surprise removal (Thunderbolt eGPU link drop) with KFD
processes attached, three stacked problems wedge the removal path:

1. amdgpu_device_fini_hw() frees kfd.dev via the early
   amdgpu_amdkfd_device_fini_sw() on the disconnected path before
   amdgpu_amdkfd_teardown_processes() in ip_fini_early ever runs -
   the unguarded kfd_processes_count dereference then NULL-faults
   (or UAFs) the pciehp removal thread.

2. The KFD userptr and SVM restore workers reschedule themselves
   unconditionally on validation failure. On a gone device validation
   can never succeed; each 1ms retry takes process_info->lock and
   notifier_lock, observed as ~11k cycles until soft-lockup while
   process teardown cannot proceed.

3. The dying process's own exit path faults on its SVM ranges
   (SIGBUS -> coredump -> do_swap_page -> svm_migrate_to_ram) and
   submits a copy job to an already-killed drm_sched entity, then
   waits uninterruptibly on a fence that can never signal - holding
   svms->lock the whole time, so kfd_processes_count never drains.

Patch 1 moves the process teardown ahead of the early fini_sw() so
the drain wait runs while kfd.dev is still valid, and keeps a NULL
guard for the second teardown invocation. The wait stays unbounded
by design - returning early would just defer a use-after-free.

Patch 2 stops both restore workers rescheduling on -ENODEV.

Patch 3 makes the SVM migration paths hold drm_dev_enter() across
submit+wait so unplug cannot tear the sched entity down underneath,
keeps pci_dev_is_disconnected() as the early-out for the
physically-gone window, and bounds the fence wait with
AMDGPU_FENCE_JIFFIES_TIMEOUT as a fallback.

All three verified together on MI50 32GB behind Thunderbolt 3 (Razer
Core X, ~2GB of SVM managed ranges + queues, pciehp Surprise+ slot
power-off): SIGBUS is delivered, coredump completes, the process
count drains in ~7s, removal completes, and the device re-enumerates
cleanly on slot re-power. ftrace confirms teardown now runs before
fini_sw.

Changes in v4 (per Felix Kuehling's review):
- 3/3: drm_dev_enter/exit around the migration instead of bare flag
  checks; AMDGPU_FENCE_JIFFIES_TIMEOUT instead of open-coded 10s
- svm_range_restore_work() -ENODEV hunk moved from 3/3 to 2/3
- 2/3: also assign ret on the evicted_bos-mismatch and
  confirm_valid_user_pages paths - posted v2 read ret uninitialized
  on those two paths
- 1/3: unchanged

Changes in v3:
- 1/3: drop the 30s bound (Christian); run teardown before the early
  fini_sw; NULL guard for the second invocation
- 2/3: resubmission of the posted v2 userptr worker patch
- 3/3: new, SVM migration fail-fast

Changes in v2 of the userptr patch:
- ret not pre-initialized; no pr_warn_once (Christian König)

Olivier Kaloudoff (3):
  drm/amdkfd: teardown processes before freeing kfd.dev on surprise removal
  drm/amdkfd: stop restore retries on device unplug
  drm/amdkfd: fail fast on unplugged device in SVM migration paths

 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c       |  5 +++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c | 16 ++++++++---
 drivers/gpu/drm/amd/amdkfd/kfd_device.c          |  9 ++++++-
 drivers/gpu/drm/amd/amdkfd/kfd_migrate.c         | 33 ++++++++++++++++++++++--
 drivers/gpu/drm/amd/amdkfd/kfd_svm.c             |  4 ++-
 5 files changed, 60 insertions(+), 8 deletions(-)

Reply via email to