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(-)
