public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2] Rust support for drm_gpuvm_exec
@ 2026-05-05 13:29 Alice Ryhl
  2026-05-05 13:29 ` [PATCH 1/2] rust: dma_buf: add stub dma_fence abstraction Alice Ryhl
  2026-05-05 13:29 ` [PATCH 2/2] drm/gpuvm: rust: add drm_gpuvm_exec support Alice Ryhl
  0 siblings, 2 replies; 3+ messages in thread
From: Alice Ryhl @ 2026-05-05 13:29 UTC (permalink / raw)
  To: Danilo Krummrich, Matthew Brost, Thomas Hellström,
	Daniel Almeida, Boris Brezillon, Gary Guo, Onur Özkan,
	Philipp Stanner
  Cc: Sumit Semwal, Christian König, Miguel Ojeda, Boqun Feng,
	Björn Roy Baron, Benno Lossin, Andreas Hindborg,
	Trevor Gross, linux-kernel, rust-for-linux, dri-devel, Alice Ryhl

Now that the core GPUVM support for Rust has been merged, I'm sending
this follow-up series that adds a super simple way of locking the dma
reservations and registering fences.

This logic was included in v1 of the original Rust GPUVM series, but was
dropped in v2 for inclusion in a follow-up. This series is that
follow-up.

Signed-off-by: Alice Ryhl <aliceryhl@google.com>
---
Alice Ryhl (1):
      drm/gpuvm: rust: add drm_gpuvm_exec support

Philipp Stanner (1):
      rust: dma_buf: add stub dma_fence abstraction

 rust/bindings/bindings_helper.h  |  2 ++
 rust/helpers/drm_gpuvm.c         |  6 ++++
 rust/kernel/dma_buf/dma_fence.rs | 32 ++++++++++++++++++
 rust/kernel/dma_buf/mod.rs       | 24 ++++++++++++++
 rust/kernel/drm/gpuvm/mod.rs     | 71 ++++++++++++++++++++++++++++++++++++++++
 rust/kernel/lib.rs               |  1 +
 6 files changed, 136 insertions(+)
---
base-commit: 37f748ed0c19e007e7c5677f5d605d6b93841792
change-id: 20260416-gpuvm-drm-exec-96a6151b0d53

Best regards,
-- 
Alice Ryhl <aliceryhl@google.com>


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH 1/2] rust: dma_buf: add stub dma_fence abstraction
  2026-05-05 13:29 [PATCH 0/2] Rust support for drm_gpuvm_exec Alice Ryhl
@ 2026-05-05 13:29 ` Alice Ryhl
  2026-05-05 13:29 ` [PATCH 2/2] drm/gpuvm: rust: add drm_gpuvm_exec support Alice Ryhl
  1 sibling, 0 replies; 3+ messages in thread
From: Alice Ryhl @ 2026-05-05 13:29 UTC (permalink / raw)
  To: Danilo Krummrich, Matthew Brost, Thomas Hellström,
	Daniel Almeida, Boris Brezillon, Gary Guo, Onur Özkan,
	Philipp Stanner
  Cc: Sumit Semwal, Christian König, Miguel Ojeda, Boqun Feng,
	Björn Roy Baron, Benno Lossin, Andreas Hindborg,
	Trevor Gross, linux-kernel, rust-for-linux, dri-devel, Alice Ryhl

From: Philipp Stanner <pstanner@redhat.com>

This adds a trivial DMA Fence type for use in other abstractions that
need to take a DMA fence as a parameter. For now, the type is a stub,
but may be used with fences defined by C.

Signed-off-by: Philipp Stanner <pstanner@redhat.com>
Signed-off-by: Alice Ryhl <aliceryhl@google.com>
---
This stub is included only for completeness. Most likely we will land
this on top of the Philipp's patch that actually adds Fence for real,
and this stub commit will not be necessary.

Taken from:
https://gitlab.freedesktop.org/pstanner/linux-drm-work/-/merge_requests/1
---
 rust/kernel/dma_buf/dma_fence.rs | 32 ++++++++++++++++++++++++++++++++
 rust/kernel/dma_buf/mod.rs       |  7 +++++++
 rust/kernel/lib.rs               |  1 +
 3 files changed, 40 insertions(+)

diff --git a/rust/kernel/dma_buf/dma_fence.rs b/rust/kernel/dma_buf/dma_fence.rs
new file mode 100644
index 000000000000..135df74013db
--- /dev/null
+++ b/rust/kernel/dma_buf/dma_fence.rs
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (C) 2025, 2026 Red Hat Inc.:
+//   - Philipp Stanner <pstanner@redhat.com>
+
+//! DMA Fence support.
+//!
+//! Reference: <https://docs.kernel.org/driver-api/dma-buf.html#c.dma_fence>
+//!
+//! C header: [`include/linux/dma-fence.h`](srctree/include/linux/dma-fence.h)
+
+use crate::{
+    bindings,
+    prelude::*,
+    types::Opaque, //
+};
+
+/// A dma fence.
+#[pin_data]
+#[repr(transparent)]
+pub struct Fence {
+    #[pin]
+    inner: Opaque<bindings::dma_fence>,
+}
+
+impl Fence {
+    /// Access the raw dma fence.
+    #[inline]
+    pub fn as_raw(&self) -> *mut bindings::dma_fence {
+        self.inner.get()
+    }
+}
diff --git a/rust/kernel/dma_buf/mod.rs b/rust/kernel/dma_buf/mod.rs
new file mode 100644
index 000000000000..b66e747c35ad
--- /dev/null
+++ b/rust/kernel/dma_buf/mod.rs
@@ -0,0 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
+
+//! DMA-buf subsystem abstractions.
+
+pub mod dma_fence;
+
+pub use self::dma_fence::Fence;
diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs
index b72b2fbe046d..a05ccaa7598c 100644
--- a/rust/kernel/lib.rs
+++ b/rust/kernel/lib.rs
@@ -63,6 +63,7 @@
 pub mod device_id;
 pub mod devres;
 pub mod dma;
+pub mod dma_buf;
 pub mod driver;
 #[cfg(CONFIG_DRM = "y")]
 pub mod drm;

-- 
2.54.0.545.g6539524ca2-goog


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH 2/2] drm/gpuvm: rust: add drm_gpuvm_exec support
  2026-05-05 13:29 [PATCH 0/2] Rust support for drm_gpuvm_exec Alice Ryhl
  2026-05-05 13:29 ` [PATCH 1/2] rust: dma_buf: add stub dma_fence abstraction Alice Ryhl
@ 2026-05-05 13:29 ` Alice Ryhl
  1 sibling, 0 replies; 3+ messages in thread
From: Alice Ryhl @ 2026-05-05 13:29 UTC (permalink / raw)
  To: Danilo Krummrich, Matthew Brost, Thomas Hellström,
	Daniel Almeida, Boris Brezillon, Gary Guo, Onur Özkan,
	Philipp Stanner
  Cc: Sumit Semwal, Christian König, Miguel Ojeda, Boqun Feng,
	Björn Roy Baron, Benno Lossin, Andreas Hindborg,
	Trevor Gross, linux-kernel, rust-for-linux, dri-devel, Alice Ryhl

This adds support for simple usage of drm_gpuvm_exec() for locking all
of the dma reservations and adding fences to them. For more complex
usage that does not involve locking all reservations, it is expected
that the ww-mutex abstractions will be used instead.

Signed-off-by: Alice Ryhl <aliceryhl@google.com>
---
 rust/bindings/bindings_helper.h |  2 ++
 rust/helpers/drm_gpuvm.c        |  6 ++++
 rust/kernel/dma_buf/mod.rs      | 17 ++++++++++
 rust/kernel/drm/gpuvm/mod.rs    | 71 +++++++++++++++++++++++++++++++++++++++++
 4 files changed, 96 insertions(+)

diff --git a/rust/bindings/bindings_helper.h b/rust/bindings/bindings_helper.h
index 1124785e210b..3978682a6f2e 100644
--- a/rust/bindings/bindings_helper.h
+++ b/rust/bindings/bindings_helper.h
@@ -151,6 +151,8 @@ const vm_flags_t RUST_CONST_HELPER_VM_MIXEDMAP = VM_MIXEDMAP;
 const vm_flags_t RUST_CONST_HELPER_VM_HUGEPAGE = VM_HUGEPAGE;
 const vm_flags_t RUST_CONST_HELPER_VM_NOHUGEPAGE = VM_NOHUGEPAGE;
 
+const u32 RUST_CONST_HELPER_DRM_EXEC_INTERRUPTIBLE_WAIT = DRM_EXEC_INTERRUPTIBLE_WAIT;
+
 #if IS_ENABLED(CONFIG_GPU_BUDDY)
 const unsigned long RUST_CONST_HELPER_GPU_BUDDY_RANGE_ALLOCATION = GPU_BUDDY_RANGE_ALLOCATION;
 const unsigned long RUST_CONST_HELPER_GPU_BUDDY_TOPDOWN_ALLOCATION = GPU_BUDDY_TOPDOWN_ALLOCATION;
diff --git a/rust/helpers/drm_gpuvm.c b/rust/helpers/drm_gpuvm.c
index 4130b6325213..30fb1777fbf2 100644
--- a/rust/helpers/drm_gpuvm.c
+++ b/rust/helpers/drm_gpuvm.c
@@ -23,4 +23,10 @@ bool rust_helper_drm_gpuvm_is_extobj(struct drm_gpuvm *gpuvm,
 	return drm_gpuvm_is_extobj(gpuvm, obj);
 }
 
+__rust_helper
+void rust_helper_drm_gpuvm_exec_unlock(struct drm_gpuvm_exec *vm_exec)
+{
+	drm_gpuvm_exec_unlock(vm_exec);
+}
+
 #endif // CONFIG_RUST_DRM_GPUVM
diff --git a/rust/kernel/dma_buf/mod.rs b/rust/kernel/dma_buf/mod.rs
index b66e747c35ad..234936ba8265 100644
--- a/rust/kernel/dma_buf/mod.rs
+++ b/rust/kernel/dma_buf/mod.rs
@@ -5,3 +5,20 @@
 pub mod dma_fence;
 
 pub use self::dma_fence::Fence;
+
+/// How the fences from a `dma_resv` obj are used.
+///
+/// Please see [the C-side documentation][dma_resv_usage] for more details.
+///
+/// [dma_resv_usage]: https://docs.kernel.org/driver-api/dma-buf.html#c.dma_resv_usage
+#[repr(u32)]
+pub enum DmaResvUsage {
+    /// For in kernel memory management only (e.g. copying, clearing memory).
+    Kernel = bindings::dma_resv_usage_DMA_RESV_USAGE_KERNEL,
+    /// Implicit write synchronization for userspace submissions.
+    Write = bindings::dma_resv_usage_DMA_RESV_USAGE_WRITE,
+    /// Implicit read synchronization for userspace submissions.
+    Read = bindings::dma_resv_usage_DMA_RESV_USAGE_READ,
+    /// No implicit sync (e.g. preemption fences, page table updates, TLB flushes).
+    Bookkeep = bindings::dma_resv_usage_DMA_RESV_USAGE_BOOKKEEP,
+}
diff --git a/rust/kernel/drm/gpuvm/mod.rs b/rust/kernel/drm/gpuvm/mod.rs
index ae58f6f667c1..a52fb25f22ff 100644
--- a/rust/kernel/drm/gpuvm/mod.rs
+++ b/rust/kernel/drm/gpuvm/mod.rs
@@ -16,6 +16,7 @@
         Flags as AllocFlags, //
     },
     bindings,
+    dma_buf::{DmaResvUsage, Fence},
     drm,
     drm::gem::IntoGEMObject,
     error::to_result,
@@ -216,6 +217,30 @@ pub fn obtain(
         Ok(GpuVmBoAlloc::new(self, obj, data)?.obtain())
     }
 
+    /// Prepare this GPUVM.
+    ///
+    /// The parameter indicates how many fences to preallocate space for.
+    #[inline]
+    pub fn prepare(&self, num_fences: u32) -> impl PinInit<GpuVmExec<'_, T>, Error> {
+        try_pin_init!(GpuVmExec {
+            exec <- Opaque::try_ffi_init(|exec: *mut bindings::drm_gpuvm_exec| {
+                // SAFETY: exec is valid but unused memory, so we can write.
+                unsafe {
+                    ptr::write_bytes(exec, 0u8, 1usize);
+                    ptr::write(&raw mut (*exec).vm, self.as_raw());
+                    ptr::write(&raw mut (*exec).flags, bindings::DRM_EXEC_INTERRUPTIBLE_WAIT);
+                    ptr::write(&raw mut (*exec).num_fences, num_fences);
+                }
+
+                // SAFETY: If successful, this `struct drm_gpuvm_exec` remains valid until this is
+                // unlocked because it's pinned and unlocks it in drop. The contained pointer to
+                // `self` remains valid because `GpuVmExec` borrows from `self`.
+                to_result(unsafe { bindings::drm_gpuvm_exec_lock(exec) })
+            }),
+            _gpuvm: PhantomData,
+        })
+    }
+
     /// Clean up buffer objects that are no longer used.
     #[inline]
     pub fn deferred_cleanup(&self) {
@@ -326,3 +351,49 @@ fn deref(&self) -> &GpuVm<T> {
         &self.0
     }
 }
+
+/// The exec token for preparing the objects.
+///
+/// # Invariants
+///
+/// Owns a GPUVM exec context.
+#[pin_data(PinnedDrop)]
+pub struct GpuVmExec<'vm, T: DriverGpuVm> {
+    #[pin]
+    exec: Opaque<bindings::drm_gpuvm_exec>,
+    _gpuvm: PhantomData<&'vm mut GpuVm<T>>,
+}
+
+impl<'vm, T: DriverGpuVm> GpuVmExec<'vm, T> {
+    /// Add a fence.
+    ///
+    /// The caller must ensure that the preallocated space for fences is sufficient.
+    #[inline]
+    pub fn resv_add_fence(
+        &self,
+        fence: &Fence,
+        private_usage: DmaResvUsage,
+        extobj_usage: DmaResvUsage,
+    ) {
+        // SAFETY: This method takes a refcount on the fence, so it's only required to be valid for
+        // the duration of this method. If there is not enough space for the pre-allocated fence,
+        // then this leads to a BUG_ON() but does not trigger UB.
+        unsafe {
+            bindings::drm_gpuvm_resv_add_fence(
+                (*self.exec.get()).vm,
+                &raw mut (*self.exec.get()).exec,
+                fence.as_raw(),
+                private_usage as u32,
+                extobj_usage as u32,
+            )
+        }
+    }
+}
+
+#[pinned_drop]
+impl<'vm, T: DriverGpuVm> PinnedDrop for GpuVmExec<'vm, T> {
+    fn drop(self: Pin<&mut Self>) {
+        // SAFETY: We hold the lock, so it's safe to unlock.
+        unsafe { bindings::drm_gpuvm_exec_unlock(self.exec.get()) };
+    }
+}

-- 
2.54.0.545.g6539524ca2-goog


^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-05-05 13:29 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-05 13:29 [PATCH 0/2] Rust support for drm_gpuvm_exec Alice Ryhl
2026-05-05 13:29 ` [PATCH 1/2] rust: dma_buf: add stub dma_fence abstraction Alice Ryhl
2026-05-05 13:29 ` [PATCH 2/2] drm/gpuvm: rust: add drm_gpuvm_exec support Alice Ryhl

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox