On Wed Aug 12, 2026 at 9:22 AM CEST, Philipp Stanner wrote:
> Add abstractions for dma_fence in Rust.

I was about to pick this up, but ended up with too many things to tweak.

  * Fix checkpatch.pl warnings,
  * take &CStr instead of CString in FenceContext::new(),
  * change DriverFenceAllocation::ops to &'static from *const,
  * remove # Safety comment on AlwaysRefCounted::dec_ref() impl,
  * use Opaque::zeroed() instead of __GFP_ZERO,
  * use kernel vertical import style.

Here's the diff I suggest for a v11:

diff --git a/rust/helpers/dma_fence.c b/rust/helpers/dma_fence.c
index 0e08411098fa..549f6b6a7171 100644
--- a/rust/helpers/dma_fence.c
+++ b/rust/helpers/dma_fence.c
@@ -37,7 +37,8 @@ __rust_helper void rust_helper_dma_fence_lock_irqsave(struct 
dma_fence *f, unsig
        dma_fence_lock_irqsave(f, *flags);
 }

-__rust_helper void rust_helper_dma_fence_unlock_irqrestore(struct dma_fence 
*f, unsigned long *flags)
+__rust_helper void rust_helper_dma_fence_unlock_irqrestore(struct dma_fence *f,
+                                                          unsigned long *flags)
 {
        dma_fence_unlock_irqrestore(f, *flags);
 }
diff --git a/rust/kernel/dma_buf/dma_fence.rs b/rust/kernel/dma_buf/dma_fence.rs
index f22f4a07c152..d82b69f68e61 100644
--- a/rust/kernel/dma_buf/dma_fence.rs
+++ b/rust/kernel/dma_buf/dma_fence.rs
@@ -102,21 +102,23 @@ impl<'a, T: Send + Sync + FenceContextOps> 
FenceContext<T> {
     /// Create a new `FenceContext`.
     pub fn new<E>(
         initial_seqno: u64,
-        driver_name: CString,
-        timeline_name: CString,
+        driver_name: &CStr,
+        timeline_name: &CStr,
         data: impl PinInit<T, E>,
     ) -> impl PinInit<Self, Error>
     where
         Error: From<E>,
     {
+        let driver_name = CString::try_from(driver_name);
+        let timeline_name = CString::try_from(timeline_name);
         try_pin_init!(Self {
             // SAFETY: `dma_fence_context_alloc()` merely works on a global
             // atomic. Parameter `1` is the number of contexts we want to
             // allocate.
             nr: unsafe { bindings::dma_fence_context_alloc(1) },
             seqno: Atomic::new(initial_seqno),
-            driver_name,
-            timeline_name,
+            driver_name: driver_name?,
+            timeline_name: timeline_name?,
             nr_of_unsignaled_fences: Atomic::new(0),
             data <- data,
         })
@@ -141,7 +143,7 @@ pub fn new_fence_allocation(
             rcu_head: Default::default(),
             // `inner` remains uninitialized until a `DriverFence` takes over.
             inner: Fence {
-                inner: Opaque::uninit(),
+                inner: Opaque::zeroed(),
             },
             fctx: self,
             data,
@@ -154,7 +156,7 @@ pub fn new_fence_allocation(
         //
         // Hence, we need the manage the memory manually. It will be freed by 
the
         // C backend automatically once the refcount within `Fence` drops to 0.
-        let data = KBox::new(fence_data, GFP_KERNEL | __GFP_ZERO)?;
+        let data = KBox::new(fence_data, GFP_KERNEL)?;

         Ok(DriverFenceAllocation {
             data,
@@ -212,7 +214,7 @@ fn drop(self: Pin<&mut Self>) {
         // Fence ops callbacks can be called on unsignaled fences. Since these
         // callbacks can access the fence context and its data, it needs to be
         // guaranteed that a context only drops after all associated
-        // `DriverFence`s have been dropped. This is unlikely to ocurr, but 
would
+        // `DriverFence`s have been dropped. This is unlikely to occur, but 
would
         // result in silent UAF. Throw a panic to prevent that.
         //
         // TODO:
@@ -568,9 +570,6 @@ fn inc_ref(&self) {
         unsafe { bindings::dma_fence_get(self.as_raw()) }
     }

-    /// # Safety
-    ///
-    /// `ptr`must be a valid pointer to a [`DriverFence`].
     unsafe fn dec_ref(ptr: NonNull<Self>) {
         // SAFETY: `ptr` is never a NULL pointer; and when `dec_ref()` is 
called
         // the fence is by definition still valid.
@@ -640,15 +639,17 @@ struct DriverFenceData<'a, T: Send + Sync + 
FenceContextOps> {
 /// # Examples
 ///
 /// ```
-/// use kernel::dma_buf::{
-///     DriverFence,
-///     FenceContext,
-///     FenceContextOps,
-///     FenceCallback,
-///     FenceCallbackRegistration, //
+/// use kernel::{
+///     dma_buf::{
+///         DriverFence,
+///         FenceContext,
+///         FenceContextOps,
+///         FenceCallback,
+///         FenceCallbackRegistration,
+///     },
+///     str::CString,
+///     sync::aref::ARef,
 /// };
-/// use kernel::str::CString;
-/// use kernel::sync::aref::ARef;
 /// use core::fmt::Display;
 ///
 /// struct CallbackData { }
@@ -674,18 +675,16 @@ struct DriverFenceData<'a, T: Send + Sync + 
FenceContextOps> {
 ///
 /// let fctx_data = FenceContextData::new();
 ///
-/// let driver_name = CString::try_from_fmt(fmt!("dummy_driver"))?;
-/// let timeline_name = CString::try_from_fmt(fmt!("dummy_timeline"))?;
-///
 /// let mut fctx = KBox::pin_init(
-///     FenceContext::new(0, driver_name, timeline_name, fctx_data), 
GFP_KERNEL)?;
+///     FenceContext::new(0, c"dummy_driver", c"dummy_timeline", fctx_data),
+///     GFP_KERNEL,
+/// )?;
 ///
 /// struct FenceData {
 ///     data: CString,
 /// }
 ///
-/// let data = CString::try_from_fmt(fmt!("dummy_data"))?;
-/// let fence_data = FenceData { data };
+/// let fence_data = FenceData { data: c"dummy_data".try_into()? };
 ///
 /// let fence_alloc = fctx.new_fence_allocation(fence_data)?;
 /// let mut fence = fence_alloc.new_fence();
@@ -718,8 +717,8 @@ pub struct DriverFenceAllocation<'a, T: Send + Sync + 
FenceContextOps> {
     /// Handed over to a [`DriverFence`], or deallocated once the
     /// [`DriverFenceAllocation`] drops.
     data: KBox<DriverFenceData<'a, T>>,
-    /// Pointer for the ops for the associated [`FenceContext`]
-    ops: *const bindings::dma_fence_ops,
+    /// Reference for the ops for the associated [`FenceContext`]
+    ops: &'static bindings::dma_fence_ops,
 }

 impl<'a, T: Send + Sync + FenceContextOps> DriverFenceAllocation<'a, T> {

Reply via email to