When a GPU dma-fence signals, drivers often need to access userspace memory from a kthread context — either to write a fence completion value to a userspace VA (XE) or to signal a per-queue eventfd (AMDGPU). Both require borrowing the process MM via kthread_use_mm(), and both use the same kref-managed dma-fence-callback-to-workqueue pattern.
Extracting this pattern into a shared DRM helper allows both XE and AMDGPU to use it instead of maintaining independent open-coded implementations. This series does that: Patch 1 introduces drm_user_fence — an embeddable base structure with driver-supplied worker/destroy callbacks. The common code handles: - process MM grab at init (mmgrab) - dma-fence callback registration - workqueue dispatch on fence signal - mmget_not_zero/kthread_use_mm/mmput in the worker - kref lifetime management - cancellation via drm_user_fence_cancel_sync() for safe driver teardown Patch 2 converts XE to use the new helper. struct xe_user_fence embeds struct drm_user_fence as its base. XE-specific fields (xe_device pointer for ufence_wq wake-up, userspace VA, expected value, signalled flag) remain in the wrapper. No behavioral change is intended. A follow-on patch (not in this series) will wire AMDGPU's render-node EOP eventfd signaling path to the same helper. v3: - Store fence reference inside drm_user_fence during add_callback so drm_user_fence_cancel() can be called safely without the caller holding a separate fence reference, fixing a potential UAF when a foreign dma-fence signals after driver teardown. (Sashiko review) - Fix contradictory kernel-doc for drm_user_fence_cancel() which incorrectly instructed callers to put references that the function already puts internally. (Sashiko review) - Add drm_user_fence_cancel_sync() to guarantee the worker has fully completed before returning. Wire into xe_sync_entry_cleanup() and xe_vma_destroy_late() for safe XE teardown. (Sashiko review) - Add xe_sync_ufence_cancel_sync() wrapper in xe_sync.c so xe_vm.c does not need to include drm_user_fence.h or access struct xe_user_fence internals directly. - Add smp_wmb() in xe_ufence_worker() between WRITE_ONCE(signalled) and copy_to_user() to prevent store reordering on weakly-ordered architectures such as ARM64. (Sashiko review) - Replace XE_WARN_ON() on copy_to_user() failure with drm_dbg() to prevent unprivileged userspace from triggering a kernel warning by unmapping the user fence memory before it signals. (Sashiko review) v2: - Move INIT_WORK() to drm_user_fence_init() fixing lockdep class divergence caused by two different INIT_WORK() call sites. (Sashiko review) - drm_user_fence_add_callback() now consumes the fence reference in all paths: transferred to the callback on success, put immediately on the already-signaled and error paths. (Sashiko review) - Add drm_user_fence_cancel() to allow drivers to safely detach a pending callback before context teardown. (Sashiko review) - Fix premature dma_fence_put() after drm_user_fence_add_callback() in xe_sync_entry_signal(). (Sashiko review) - Fix missing newline at end of new files. Suggested-by: Christian König <[email protected]> Cc: Alex Deucher <[email protected]> Cc: Matthew Brost <[email protected]> Cc: Mika Kuoppala <[email protected]> Cc: Thomas Hellström <[email protected]> Cc: Rodrigo Vivi <[email protected]> Cc: Maarten Lankhorst <[email protected]> Cc: Maxime Ripard <[email protected]> Cc: Thomas Zimmermann <[email protected]> Cc: David Airlie <[email protected]> Cc: Simona Vetter <[email protected]> Cc: Sumit Semwal <[email protected]> Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Srinivasan Shanmugam (2): drm: Add common drm_user_fence helper drm/xe: Convert xe_user_fence to drm_user_fence drivers/gpu/drm/Makefile | 1 + drivers/gpu/drm/drm_user_fence.c | 210 +++++++++++++++++++++++++++++ drivers/gpu/drm/xe/xe_sync.c | 140 +++++++++---------- drivers/gpu/drm/xe/xe_sync.h | 1 + drivers/gpu/drm/xe/xe_sync_types.h | 3 +- drivers/gpu/drm/xe/xe_vm.c | 1 + include/drm/drm_user_fence.h | 76 +++++++++++ 7 files changed, 360 insertions(+), 72 deletions(-) create mode 100644 drivers/gpu/drm/drm_user_fence.c create mode 100644 include/drm/drm_user_fence.h -- 2.34.1
