On 2026-10-07 13:24, Olivier Kaloudoff wrote:
Hi Felix,

Shouldn't cancel_delayed_work_sync wait for the worker function to
exit? I don't see how that can race with the re-scheduling in the
worker function itself.
You're right, my UAF framing was wrong on current kernels. I checked
the workqueue code: __cancel_work_sync() marks the work disabled in
its off-queue data while it flushes, and queue_delayed_work_on() drops
the requeue via clear_pending_if_disabled(). Self-reschedule from a
running handler, delayed or not, can't survive the cancel.

The argument that does stand: the cancel only runs at last-VM destroy
during process exit (gpuvm_destroy_cb, when n_vms hits 0). On surprise
removal that path itself can stall — the SIGBUS'd task deadlocks in
its own exit path (SVM migrate -> fence that never signals, patch
3/3), so process_info teardown never runs and nobody ever calls the
cancel.

On that path you changed the dma_fence_wait to dma_fence_wait_timeout. That should be sufficient to prevent the stall. I believe the extra checks for pci_dev_is_disconnected are unnecessary. IMO the cleanest solution is the one with the least special case handling deep in the KFD code. drm_dev_enter/exit is meant to abstract that away from most of the driver code. Therefore, just guarding the critical sections that need HW access between drm_dev_enter/exit, and not having any unbounded fence-wait inside those critical sections, should be sufficient.

Regards,
  Felix


  That whole window is where the ~11k-cycle spin at 1ms delay
happened, holding process_info->lock and notifier_lock each round
until soft-lockup.

So the -ENODEV check isn't about racing the cancel — it's the stop
condition for the window where the device's lifetime has ended but
process_info's hasn't. Transient errors still retry as before.

Olivier

Reply via email to