Hi Felix, The worker is only canceled when the last compute VM is destroyed in amdgpu_amdkfd_gpuvm_destroy_cb() — i.e., late in process exit. On surprise removal that window is unbounded: in my repro the SIGBUS exit path deadlocked in SVM migration (patch 3/3 in the v3 resend), so process termination never reached the destroy callback. The worker kept rescheduling at 1ms delay, ~11k cycles, taking process_info->lock and notifier_lock each round until the system soft-locked up.
There's also a self-reschedule race with cancel_delayed_work_sync(): if the handler is running when the cancel executes, it re-arms itself at the bottom of the function after cancel returns — then process_info is freed right after cancel_delayed_work_sync() in destroy_cb, leaving a pending delayed work on freed memory. The retry loop needs a stop condition; returning -ENODEV on a gone device is it, and it also avoids retrying validation that can never succeed again. Transient errors still reschedule as before. Olivier
