Skip to main content

kernel/dma_buf/
dma_fence.rs

1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (C) 2025-2026 Red Hat Inc.
4 * Author: Philipp Stanner <pstanner@redhat.com>
5 */
6
7//! DMA Fence support.
8//!
9//! Reference: <https://docs.kernel.org/driver-api/dma-buf.html#c.dma_fence>
10//!
11//! header: [`include/linux/dma-fence.h`](srctree/include/linux/dma-fence.h)
12
13use crate::{
14    alloc::AllocError,
15    bindings,
16    container_of,
17    error::to_result,
18    prelude::*,
19    types::ForeignOwnable,
20    types::Opaque, //
21};
22
23use core::{
24    marker::PhantomData,
25    mem::ManuallyDrop,
26    ops::Deref,
27    ptr,
28    ptr::{
29        drop_in_place,
30        NonNull, //
31    }, //
32};
33
34use kernel::{
35    str::CString,
36    sync::{
37        aref::{
38            ARef,
39            AlwaysRefCounted, //
40        },
41        atomic::{
42            Atomic,
43            Relaxed, //
44        },
45        rcu::rcu_barrier, //
46    }, //
47};
48
49/// VTable for dma_fence backend_ops callbacks.
50//
51// Mandatory dma_fence backend_ops are implemented implicitly through
52// [`FenceContext`]. Additional ones shall get implemented on this trait.
53pub trait FenceContextOps {
54    /// The generic payload data for [`DriverFence`]s created on this fctx.
55    type FenceDataType: Send + Sync;
56}
57
58/// A dma-fence context. A fence context takes care of associating related fences
59/// with each other, providing each with raising sequence numbers and a common
60/// identifier.
61#[pin_data(PinnedDrop)]
62pub struct FenceContext<T: FenceContextOps + Send + Sync> {
63    /// The fence context number.
64    nr: u64,
65    /// The sequence number for the next fence created.
66    seqno: Atomic<u64>,
67    // The name parameters can be accessed by the dma_fence backend_ops. UAF
68    // errors are prevented by the `call_rcu()` in `drop_driver_fence_data()`.
69    /// The name of the driver this FenceContext's fences belong to.
70    driver_name: CString,
71    /// The name of the timeline this FenceContext's fences belong to.
72    timeline_name: CString,
73    /// The number of all unsignaled fences on this context.
74    // Used to prevent bugs due to forgotten fences.
75    //
76    // The lifetime on `DriverFence`s should typically prevent this from
77    // happening.
78    //
79    // However, we cannot fully guarantee in Rust that `DriverFence`s will not
80    // be forgotten, e.g., through `core::mem::forget()`. This could circumvent
81    // the lifetime which intends to enforce that all fences disappear before
82    // their context.
83    nr_of_unsignaled_fences: Atomic<usize>,
84    /// The user's data.
85    #[pin]
86    data: T,
87}
88
89impl<'a, T: Send + Sync + FenceContextOps> FenceContext<T> {
90    // This can later be extended as a vtable in case other parties need support
91    // for the more "exotic" callbacks.
92    const OPS: bindings::dma_fence_ops = bindings::dma_fence_ops {
93        get_driver_name: Some(Self::get_driver_name),
94        get_timeline_name: Some(Self::get_timeline_name),
95        enable_signaling: None,
96        signaled: None,
97        // Deprecated.
98        wait: None,
99        // Must never be implemented for these abstractions.
100        release: None,
101        set_deadline: None,
102    };
103
104    /// Create a new `FenceContext`.
105    pub fn new<E>(
106        initial_seqno: u64,
107        driver_name: &CStr,
108        timeline_name: &CStr,
109        data: impl PinInit<T, E>,
110    ) -> impl PinInit<Self, Error>
111    where
112        Error: From<E>,
113    {
114        let driver_name = CString::try_from(driver_name);
115        let timeline_name = CString::try_from(timeline_name);
116        try_pin_init!(Self {
117            // SAFETY: `dma_fence_context_alloc()` merely works on a global
118            // atomic. Parameter `1` is the number of contexts we want to
119            // allocate.
120            nr: unsafe { bindings::dma_fence_context_alloc(1) },
121            seqno: Atomic::new(initial_seqno),
122            driver_name: driver_name?,
123            timeline_name: timeline_name?,
124            nr_of_unsignaled_fences: Atomic::new(0),
125            data <- data,
126        })
127    }
128
129    fn next_seqno(&self) -> u64 {
130        self.seqno.fetch_add(1, Relaxed)
131    }
132
133    /// Allocate the memory for a [`DriverFence`] and already store `data` inside.
134    ///
135    /// This is needed because many times, creation of a [`DriverFence`] must not
136    /// fail, and allocating might deadlock in some situations.
137    ///
138    /// The `data` you pass here must not perform any operations that are illegal
139    /// in atomic context in its [`Drop`] implementation.
140    pub fn new_fence_allocation(
141        &self,
142        data: T::FenceDataType,
143    ) -> Result<DriverFenceAllocation<'_, T>> {
144        let fence_data = DriverFenceData {
145            rcu_head: Default::default(),
146            // `inner` remains uninitialized until a `DriverFence` takes over.
147            inner: Fence {
148                inner: Opaque::uninit(),
149            },
150            fctx: self,
151            data,
152        };
153
154        // In order to support the C dma_fence callbacks, it is necessary for
155        // a `Fence` and a `DriverFence` to live in the same allocation,
156        // because the C backend passes a dma_fence, from which the driver most
157        // likely wants to be able to access its `data` in `DriverFence`.
158        //
159        // Hence, we need the manage the memory manually. It will be freed by the
160        // C backend automatically once the refcount within `Fence` drops to 0.
161        let data = KBox::new(fence_data, GFP_KERNEL | __GFP_ZERO)?;
162
163        Ok(DriverFenceAllocation {
164            data,
165            ops: &Self::OPS,
166        })
167    }
168
169    extern "C" fn get_driver_name(ptr: *mut bindings::dma_fence) -> *const c_char {
170        // SAFETY: The C backend only invokes this callback with `ptr` pointing
171        // to a valid, unsignaled `bindings::dma_fence`. All fences created in
172        // this module always reside within `Fence` which always resides in a
173        // `DriverFenceData`, thus satisfying the function's safety
174        // requirements.
175        let fctx = unsafe { Self::from_raw_fence(ptr) };
176
177        fctx.driver_name.as_char_ptr()
178    }
179
180    extern "C" fn get_timeline_name(ptr: *mut bindings::dma_fence) -> *const c_char {
181        // SAFETY: The C backend only invokes this callback with `ptr` pointing
182        // to a valid, unsignaled `bindings::dma_fence`. All fences created in
183        // this module always reside within `Fence` which always resides in a
184        // `DriverFenceData`, thus satisfying the function's safety
185        // requirements.
186        let fctx = unsafe { Self::from_raw_fence(ptr) };
187
188        fctx.timeline_name.as_char_ptr()
189    }
190
191    /// Create a [`FenceContext`] from an associated [`bindings::dma_fence`].
192    ///
193    /// # Safety
194    ///
195    /// `ptr` must be a valid pointer to a [`bindings::dma_fence`] which resides
196    /// within a [`Fence`], which in turn resides in a [`DriverFenceData`].
197    unsafe fn from_raw_fence(ptr: *mut bindings::dma_fence) -> &'a Self {
198        let opaque_fence = Opaque::cast_from(ptr);
199
200        // SAFETY: Safe due to the function's overall safety requirements.
201        let fence_ptr = unsafe { container_of!(opaque_fence, Fence, inner) };
202
203        // CAST: `DriverFenceData` is `repr(C)` and a `Fence` is its first member.
204        let fence_data_ptr: *const DriverFenceData<'a, T> = fence_ptr.cast();
205
206        // SAFETY: Safe because of the comments directly above.
207        let fence_data = unsafe { &*fence_data_ptr };
208
209        fence_data.fctx
210    }
211}
212
213#[pinned_drop]
214impl<T: FenceContextOps + Send + Sync> PinnedDrop for FenceContext<T> {
215    fn drop(self: Pin<&mut Self>) {
216        // Fence ops callbacks can be called on unsignaled fences. Since these
217        // callbacks can access the fence context and its data, it needs to be
218        // guaranteed that a context only drops after all associated
219        // `DriverFence`s have been dropped. This is unlikely to occur, but
220        // would result in silent UAF. Throw a panic to prevent that.
221        //
222        // TODO:
223        // It would be better if the fence context signals all forgotten fences
224        // itself. To do so, it would keep a list of unsignaled fences. That
225        // list's members would have to be pre-allocated (see
226        // `FenceCallback::new_fence_allocation()`).
227        if self.nr_of_unsignaled_fences.load(Relaxed) != 0 {
228            panic!("Forgotten fences in FenceContext.");
229        }
230
231        // Ensure that the driver cannot unload while there are still dma_fence
232        // callbacks running. At the same time, the RCU barrier addresses the
233        // problem inherited by the C backend, in which backend ops callbacks
234        // might be accessing the fence while it is being signaled (or shortly
235        // after). This could cause UAF access on the fence context's
236        // `fctx.driver_name` and `fctx.timeline_name`.
237        //
238        // Wait for the RCU callbacks in `DriverFence::drop`.
239        rcu_barrier();
240    }
241}
242
243/// Error type for fence callback registration.
244///
245/// Generic over `T` so that `AlreadySignaled` can return the callback to the
246/// caller, allowing it to reclaim any resources owned by the callback (e.g.,
247/// a fence handle that needs to be signaled).
248#[derive(Debug)]
249pub enum CallbackError<T> {
250    /// The fence was already signaled. The callback is returned so the caller
251    /// can extract owned resources without losing them.
252    AlreadySignaled(T),
253    /// Some other error occurred during registration.
254    Other(Error),
255}
256
257impl<T> From<CallbackError<T>> for Error {
258    #[inline]
259    fn from(err: CallbackError<T>) -> Self {
260        match err {
261            CallbackError::AlreadySignaled(_) => ENOENT,
262            CallbackError::Other(e) => e,
263        }
264    }
265}
266
267impl<T> From<AllocError> for CallbackError<T> {
268    #[inline]
269    fn from(e: AllocError) -> Self {
270        CallbackError::Other(Error::from(e))
271    }
272}
273
274/// Trait for callbacks that can be registered on fences.
275///
276/// When the fence signals, the callback will be invoked.
277///
278/// # Example
279///
280/// ```rust
281/// use kernel::dma_buf::FenceCallback;
282///
283/// struct MyCallback {
284///     // Your callback state here
285/// }
286///
287/// impl FenceCallback for MyCallback {
288///     fn on_signal(&mut self) {
289///         pr_info!("Fence signaled!\n");
290///         // Handle fence completion
291///     }
292/// }
293/// ```
294pub trait FenceCallback: Send {
295    /// Called when the fence is signaled.
296    ///
297    /// This is called from the fence signaling path, which may be in interrupt
298    /// context or with locks held, which is why `self` is only borrowed, so that
299    /// it cannot drop. Implementations must not sleep or perform
300    /// long-running operations.
301    ///
302    /// An implementation likely wants to inform itself (e.g., through a work item)
303    /// within this callback that the associated [`FenceCallbackRegistration`]
304    /// can now be dropped.
305    fn on_signal(&mut self);
306}
307
308/// A callback registration on a fence.
309///
310/// When this object is dropped, the callback is automatically removed if it
311/// hasn't been called yet.
312#[pin_data(PinnedDrop)]
313pub struct FenceCallbackRegistration<T: FenceCallback> {
314    #[pin]
315    callback_foreign: Opaque<bindings::dma_fence_cb>,
316    callback: ManuallyDrop<T>,
317    fence: ARef<Fence>,
318}
319
320impl<T: FenceCallback> FenceCallbackRegistration<T> {
321    /// Create a [`PinInit`] closure for registering a callback on a fence.
322    ///
323    /// The actual attempt at registering the callback will take place once you
324    /// call an allocator's `pin_init()` function.
325    ///
326    /// On success the callback is pinned in place and will fire when the fence
327    /// signals. On `AlreadySignaled` the callback is returned to the caller so
328    /// that owned resources can be reclaimed.
329    ///
330    /// # Safety
331    ///
332    /// The callback registration must not be forgotten.
333    pub unsafe fn new<'a>(
334        fence: &'a Fence,
335        callback: T,
336    ) -> impl PinInit<Self, CallbackError<T>> + 'a
337    where
338        T: 'a,
339    {
340        try_pin_init!(Self {
341            // We need to fully initialize the fence because after
342            // `dma_fence_add_callback()` ran, the callback might immediately
343            // get invoked.
344            callback: ManuallyDrop::new(callback),
345            fence: ARef::from(fence),
346            callback_foreign <- Opaque::try_ffi_init(|ptr| {
347                // SAFETY: `fence.inner.get()` is a valid, initialized `struct
348                // dma_fence`. `ptr` points to the `struct dma_fence_cb` field
349                // within the pinned allocation, so it remains valid until
350                // `dma_fence_remove_callback()` in `PinnedDrop` or until the
351                // callback fires.
352                let ret = unsafe {
353                    to_result(bindings::dma_fence_add_callback(
354                        fence.inner.get(),
355                        ptr,
356                        Some(Self::dma_fence_callback),
357                    ))
358                };
359                match ret {
360                    Ok(()) => Ok(()),
361                    Err(e) => {
362                        // SAFETY: We could not register the callback. Thus,
363                        // C will not use it. So we can just take it back
364                        // and pass it to the user again.
365                        let cb_back = unsafe { ManuallyDrop::take(callback) };
366                        if e == ENOENT {
367                            Err(CallbackError::AlreadySignaled(cb_back))
368                        } else {
369                            Err(CallbackError::Other(e))
370                        }
371                    },
372                }
373            }),
374        }? CallbackError<T>)
375    }
376
377    /// Raw dma fence callback that is called by the C code.
378    ///
379    /// # Safety
380    ///
381    /// This is only called by the dma_fence subsystem with valid pointers.
382    unsafe extern "C" fn dma_fence_callback(
383        _fence: *mut bindings::dma_fence,
384        callback_foreign: *mut bindings::dma_fence_cb,
385    ) {
386        let ptr = Opaque::cast_from(callback_foreign).cast_mut();
387
388        // SAFETY: All callbacks we can receive here have been created in such a way that they are
389        // embedded into a `FenceCallbackRegistration`.
390        let reg: *mut Self = unsafe { container_of!(ptr, Self, callback_foreign) };
391
392        // SAFETY: `reg` is a valid `Self` pointer.
393        //
394        // The backend ensures synchronisation so whoever holds the registration object cannot drop
395        // it while this code is running. See `FenceCallbackRegistration::drop`.
396        unsafe { (*reg).callback.on_signal() };
397    }
398
399    /// Returns a reference to the fence this callback is registered on.
400    #[inline]
401    pub fn fence(&self) -> &Fence {
402        &self.fence
403    }
404}
405
406#[pinned_drop]
407impl<T: FenceCallback> PinnedDrop for FenceCallbackRegistration<T> {
408    fn drop(self: Pin<&mut Self>) {
409        // Always call `dma_fence_remove_callback()`, even if the callback
410        // already ran. This is necessary for synchronization:
411        // `dma_fence_remove_callback()` acquires `fence->lock`, which ensures
412        // that any in-flight `dma_fence_signal()` (which calls our callback
413        // while holding the same lock) has completed before we free the struct.
414        //
415        // Without this, Drop can race with a concurrent signal:
416        //   CPU0 (signal, lock held): take() -> on_signal(fence_ref) (in progress)
417        //   CPU1 (drop): skips lock -> frees struct
418        //   CPU0: accesses fence_ref -> use-after-free
419        //
420        // When the callback has already fired, the signal path detached the
421        // list node via `INIT_LIST_HEAD()`, so dma_fence_remove_callback just
422        // sees an empty node and returns false — the lock acquisition is the
423        // only thing that matters.
424        //
425        // SAFETY: The fence pointer is valid and the cb was initialized by
426        // `dma_fence_add_callback()` during construction.
427        unsafe {
428            bindings::dma_fence_remove_callback(self.fence.as_raw(), self.callback_foreign.get())
429        };
430
431        // SAFETY: This is literally the drop implementation, so no one has
432        // dropped this so far; so we can do it now.
433        unsafe { ManuallyDrop::<T>::drop(self.project().callback) };
434    }
435}
436
437// SAFETY: FenceCallbackRegistration can be sent between threads.
438unsafe impl<T: FenceCallback> Send for FenceCallbackRegistration<T> {}
439
440// SAFETY: &FenceCallbackRegistration can be shared between threads if &T can.
441unsafe impl<T: FenceCallback> Sync for FenceCallbackRegistration<T> where T: Sync {}
442
443/// The receiving counterpart of a [`DriverFence`].
444///
445/// The Rust DMA fence implementation has a dualistic design: [`DriverFence`]s
446/// are the producer-side, intended to be always owned by only one party. That
447/// party has the monopoly on signaling the fence.
448///
449/// A [`Fence`] is the counterpart for consumers. Thus, [`Fence`]s are always
450/// refcounted and can shared with an arbitrary number of parties, including
451/// userspace. A [`Fence`] can only be used for actions such as checking the
452/// fence's status or for registering callbacks on it.
453///
454/// Once the associated [`DriverFence`] signals, all
455/// [`FenceCallbackRegistration`]s registered on the [`Fence`] will be executed.
456///
457/// A [`Fence`] can arbitrarily outlive its [`DriverFence`] and the
458/// [`FenceContext`]. Signaling a [`DriverFence`] decouples it from its
459/// [`Fence`]s.
460#[repr(transparent)]
461pub struct Fence {
462    /// The actual dma_fence passed to C.
463    inner: Opaque<bindings::dma_fence>,
464}
465
466/// Guard helper for locking within this module.
467///
468/// Its only purpose for now is to avoid a number of unsafe lock-unlock cycles.
469/// It is never used outside of this module.
470// TODO: This should be made more canonical, probably by basing it on a
471// SpinLockIrqGuard once available.
472struct FenceGuard<'a> {
473    inner: &'a Fence,
474    flags: usize,
475}
476
477impl<'a> Deref for FenceGuard<'a> {
478    type Target = &'a Fence;
479
480    fn deref(&self) -> &Self::Target {
481        &self.inner
482    }
483}
484
485impl Drop for FenceGuard<'_> {
486    fn drop(&mut self) {
487        // SAFETY: `fence` is valid because `self` is valid. `flag_ptr` is
488        // merely a pointer to an integer, which lives as long as this function.
489        // When a `FenceGuard` exists, the lock has been taken by definition.
490        unsafe { bindings::dma_fence_unlock_irqrestore(self.as_raw(), &raw mut self.flags) };
491    }
492}
493
494// SAFETY: Fences are literally designed to be shared between threads.
495unsafe impl Send for Fence {}
496// SAFETY: Fences are literally designed to be shared between threads.
497unsafe impl Sync for Fence {}
498
499impl Fence {
500    /// Check whether the fence was signaled at the moment of the function call.
501    ///
502    /// Note that this can return `true` for a [`Fence`] whose [`DriverFence`]
503    /// has not yet been dropped. The reason is that the fence ops callbacks can
504    /// cause the fence to get signaled by the C backend.
505    #[inline]
506    pub fn is_signaled(&self) -> bool {
507        // We should not use `dma_fence_is_signaled_locked()` here, because
508        // according to the C backend's recommendations, that function is
509        // problematic and we should avoid calling that function with a lock
510        // held.
511
512        // SAFETY: Inner `fence` is valid because `self` is valid.
513        let ret = unsafe { bindings::dma_fence_is_signaled(self.as_raw()) };
514
515        // To be as robust as possible for the future we guarantee that an API
516        // caller can 100% rely on the signaling being completed (i.e., all
517        // fence callbacks ran), so we have to take the lock.
518        //
519        // The reason is that the C dma_fence backend currently does not
520        // carefully synchronize the `dma_fence_is_signaled()` function with the
521        // proper spinlock. This can lead to the function returning `true` while
522        // fence callbacks are still being executed. This can be mitigated by
523        // guarding the entire function with the spinlock.
524        //
525        // The fundamental reason is that the C backend currently does guard
526        // setting of the fence's signaled-bit with the fence's spinlock, but
527        // reading is done locklessly.
528        //
529        // See commit c8a5d5ea3ba6a.
530        let _ = self.lock();
531
532        ret
533    }
534
535    /// Lock the fence. A helper only to be used internally in this module.
536    fn lock(&self) -> FenceGuard<'_> {
537        let mut guard = FenceGuard {
538            inner: self,
539            flags: 0,
540        };
541
542        // SAFETY: `fence` is valid because `self` is valid. `flag_ptr` is
543        // merely a pointer to an integer, whose lifetime is tied to the guard
544        // object.
545        unsafe { bindings::dma_fence_lock_irqsave(self.as_raw(), &raw mut guard.flags) };
546
547        guard
548    }
549
550    /// Get the fence's sequence number.
551    #[inline]
552    pub fn seqno(&self) -> u64 {
553        // SAFETY: Valid because `self` is valid.
554        unsafe { (*self.as_raw()).seqno }
555    }
556
557    fn as_raw(&self) -> *mut bindings::dma_fence {
558        self.inner.get()
559    }
560
561    /// Create a [`Fence`] from a raw C [`bindings::dma_fence`].
562    ///
563    /// # Safety
564    ///
565    /// `ptr` must point to an initialized fence that is embedded into a [`Fence`].
566    #[inline]
567    pub unsafe fn from_raw<'a>(ptr: *mut bindings::dma_fence) -> &'a Self {
568        // SAFETY: Safe as per the function's overall safety requirements.
569        unsafe { &*ptr.cast() }
570    }
571}
572
573// SAFETY: These implement the C backends refcounting methods which are proven
574// to work correctly.
575unsafe impl AlwaysRefCounted for Fence {
576    fn inc_ref(&self) {
577        // SAFETY: `self.as_raw()` is a pointer to a valid `struct dma_fence`.
578        unsafe { bindings::dma_fence_get(self.as_raw()) }
579    }
580
581    unsafe fn dec_ref(ptr: NonNull<Self>) {
582        // SAFETY: `ptr` is never a NULL pointer; and when `dec_ref()` is called
583        // the fence is by definition still valid.
584        let fence = unsafe { (*ptr.as_ptr()).inner.get() };
585
586        // SAFETY: `fence` was created validly above. When `dec_ref()` is called,
587        // there is by definition still a reference alive that can be put.
588        unsafe { bindings::dma_fence_put(fence) }
589    }
590}
591
592// Necessary to guarantee that `inner` always comes first and can be freed by C.
593// Also useful for using casts instead of container_of().
594#[repr(C)]
595#[pin_data]
596struct DriverFenceData<'a, T: Send + Sync + FenceContextOps> {
597    #[pin]
598    /// The inner fence.
599    // Must always be the first member so that unsafe casting works; but also
600    // necessary so that the C backend can free the allocation (coming from our
601    // Rust code) with kfree_rcu().
602    inner: Fence,
603    /// Callback head for dropping this in a deferred manner through RCU.
604    rcu_head: bindings::callback_head,
605    /// Reference to access the FenceContext.
606    fctx: &'a FenceContext<T>,
607    /// The API user's data. It is essential that the data only performs
608    /// operations legal in atomic context in its [`Drop`] implementation.
609    #[pin]
610    data: T::FenceDataType,
611}
612
613/// A synchronization primitive mainly for GPU drivers.
614///
615/// The Rust DMA fence implementation has a dualistic design: [`DriverFence`]s
616/// are the producer-side, intended to be always owned by only one party. That
617/// party has the monopoly on signaling the fence.
618///
619/// A [`Fence`] is the counterpart for consumers. Thus, [`Fence`]s are always
620/// refcounted and can be shared with an arbitrary number of parties, including
621/// userspace. A [`Fence`] can only be used for actions such as checking the
622/// fence's status or for registering callbacks on it.
623///
624/// Once the associated [`DriverFence`] signals, all
625/// [`FenceCallbackRegistration`]s registered on a [`Fence`] will be executed.
626///
627/// A [`Fence`] can arbitrarily outlive its [`DriverFence`] and the
628/// [`FenceContext`]. Signaling a [`DriverFence`] decouples it from its
629/// [`Fence`]s.
630///
631/// It is crucial that a [`DriverFence`] always correctly represents the state
632/// of the associated job on the hardware. Especially, it is strictly necessary
633/// that the owner ensures that all [`DriverFence`]s eventually get signaled.
634/// As a last resort, a [`DriverFence`] will signal itself if it drops
635/// unsignaled and print a warning.
636///
637/// This design intends to implement the [`bindings::dma_fence_ops`] in such a
638/// way that the driver-data necessary to implement the callback's functionality
639/// resides in the [`FenceContext`]. Thus, a [`DriverFence`] contains a
640/// reference to the context, which can be accessed in the callbacks. The
641/// implementation, therefore, ensures that a [`DriverFence`] cannot outlive its
642/// [`FenceContext`]. Unfortunately, this can be circumvented under certain
643/// circumstances in Rust (e.g., usage of [`core::mem::forget`]).
644///
645/// In the unlikely case of such violations, a panic is thrown.
646///
647/// # Examples
648///
649/// ```
650/// use kernel::{
651///     dma_buf::{
652///         DriverFence,
653///         FenceContext,
654///         FenceContextOps,
655///         FenceCallback,
656///         FenceCallbackRegistration,
657///     },
658///     str::CString,
659///     sync::aref::ARef, //
660/// };
661/// use core::fmt::Display;
662///
663/// struct CallbackData { }
664///
665/// impl FenceCallback for CallbackData {
666///     fn on_signal(&mut self) {
667///         pr_info!("DmaFence callback executed.\n");
668///     }
669/// }
670///
671/// #[pin_data]
672/// struct FenceContextData {}
673///
674/// impl FenceContextData {
675///     fn new() -> impl PinInit<Self> {
676///         pin_init!(Self {})
677///     }
678/// }
679///
680/// impl FenceContextOps for FenceContextData {
681///     type FenceDataType = FenceData;
682/// }
683///
684/// let fctx_data = FenceContextData::new();
685///
686///
687/// let mut fctx = KBox::pin_init(
688///     FenceContext::new(0, c"dummy_driver", c"dummy_timeline", fctx_data),
689///     GFP_KERNEL
690/// )?;
691///
692/// struct FenceData {
693///     data: CString,
694/// }
695///
696/// let fence_data = FenceData { data: c"dummy_data".try_into()? };
697///
698/// let fence_alloc = fctx.new_fence_allocation(fence_data)?;
699/// let mut fence = fence_alloc.new_fence();
700///
701/// let cb_data = CallbackData { };
702/// let waiting_fence = ARef::from(fence.as_fence());
703/// // SAFETY: `cb_data` is not forgotten.
704/// let cb_reg = unsafe { FenceCallbackRegistration::new(&waiting_fence, cb_data) };
705/// let cb_reg = KBox::pin_init(cb_reg, GFP_KERNEL)?;
706///
707/// // TODO signalling guards
708/// assert_eq!(waiting_fence.is_signaled(), false);
709/// fence.signal(Ok(()));
710/// assert_eq!(waiting_fence.is_signaled(), true);
711///
712/// Ok::<(), Error>(())
713/// ```
714pub struct DriverFence<'a, T: Send + Sync + FenceContextOps> {
715    /// The actual content of the fence. Lives in a [`NonNull`] so that its
716    /// memory can be managed independently. Valid until both the [`DriverFence`]
717    /// and all associated [`Fence`]s have disappeared.
718    data: NonNull<DriverFenceData<'a, T>>,
719}
720
721/// A pre-prepared DMA fence, carrying the user's data and the memory it and the
722/// fence reside in. Only useful for creating a [`DriverFence`]. Splitting
723/// allocation and full initialization is necessary because fences cannot be
724/// allocated dynamically in some circumstances (deadlock).
725pub struct DriverFenceAllocation<'a, T: Send + Sync + FenceContextOps> {
726    /// The memory for the actual content of the fence.
727    /// Handed over to a [`DriverFence`], or deallocated once the
728    /// [`DriverFenceAllocation`] drops.
729    data: KBox<DriverFenceData<'a, T>>,
730    /// Reference for the ops for the associated [`FenceContext`]
731    ops: &'static bindings::dma_fence_ops,
732}
733
734impl<'a, T: Send + Sync + FenceContextOps> DriverFenceAllocation<'a, T> {
735    /// Create a new [`DriverFence`], the signalable counterpart of a [`Fence`].
736    ///
737    /// This increments the sequence number in the associated [`FenceContext`].
738    pub fn new_fence(self) -> DriverFence<'a, T> {
739        // We feed the C dma_fence backend a NULL for the spinlock so that it
740        // uses per-fence locks automatically.
741        let null_ptr: *mut bindings::spinlock = ptr::null_mut();
742        let seqno = self.data.fctx.next_seqno();
743        let fence_ptr = self.as_raw();
744        // SAFETY: `fence_ptr` has been created directly above. It will live
745        // at least as long as `Self`. The same applies to `&Self::OPS`.
746        unsafe {
747            bindings::dma_fence_init(fence_ptr, self.ops, null_ptr, self.data.fctx.nr, seqno)
748        };
749
750        self.data.fctx.nr_of_unsignaled_fences.fetch_add(1, Relaxed);
751
752        // A `DriverFenceAllocation`'s purpose is to carry allocated memory, so
753        // that `DriverFence`s can always be created without allocating. In this
754        // method, ownership over that memory is transferred to the new
755        // `DriverFence` and managed through refcounting. The C dma_fence
756        // backend will ultimately free the memory once the refcount reaches 0.
757        let ptr = KBox::into_raw(self.data);
758        // SAFETY: `ptr` was just created validly directly above.
759        let ptr = unsafe { NonNull::new_unchecked(ptr) };
760
761        DriverFence { data: ptr }
762    }
763
764    fn as_raw(&self) -> *mut bindings::dma_fence {
765        self.data.inner.inner.get()
766    }
767}
768
769impl<'a, T: Send + Sync + FenceContextOps> DriverFence<'a, T> {
770    fn as_raw(&self) -> *mut bindings::dma_fence {
771        // SAFETY: Valid because `self` is valid.
772        let fence_data = unsafe { &*self.data.as_ptr() };
773
774        fence_data.inner.inner.get()
775    }
776
777    /// Create a [`DriverFence`] from a raw pointer to a [`bindings::dma_fence`].
778    ///
779    /// # Safety
780    ///
781    /// `ptr` must be a valid pointer to a `dma_fence` that was obtained through
782    /// a [`DriverFence`] with matching generic data for both fence and associated
783    /// [`FenceContext`].
784    unsafe fn from_raw(ptr: *mut bindings::dma_fence) -> Self {
785        let opaque_fence = Opaque::cast_from(ptr);
786
787        // SAFETY: Safe due to the function's overall safety requirements.
788        let fence_ptr = unsafe { container_of!(opaque_fence, Fence, inner) };
789
790        // DriverFenceData is `repr(C)` and a Fence is its first member.
791        let fence_data_ptr = fence_ptr as *mut DriverFenceData<'a, T>;
792
793        // SAFETY: `fence_data_ptr` was created validly above.
794        let data = unsafe { NonNull::new_unchecked(fence_data_ptr) };
795
796        Self { data }
797    }
798
799    /// Return the underlying [`Fence`].
800    #[inline]
801    pub fn as_fence(&self) -> &Fence {
802        // SAFETY: `self` is by definition still valid, and it cannot drop until
803        // this new reference is gone.
804        unsafe { Fence::from_raw(self.as_raw()) }
805    }
806
807    /// Signal the fence. This will invoke all registered callbacks.
808    pub fn signal(self, res: Result) {
809        let fence = self.as_fence().lock();
810
811        // SAFETY: `fence` is valid because `self` is valid. The lock must be
812        // held, which we acquired directly above.
813        if !unsafe { bindings::dma_fence_test_signaled_flag(fence.as_raw()) } {
814            if let Err(err) = res {
815                // SAFETY: `fence` is valid because `self` is valid. The fence
816                // must not have been signaled yet, which we check directly above.
817                unsafe { bindings::dma_fence_set_error(fence.as_raw(), err.to_errno()) };
818            }
819            // SAFETY: `fence` is valid because `self` is valid. The lock must
820            // be held, which we acquired above.
821            unsafe { bindings::dma_fence_signal_locked(fence.as_raw()) };
822        }
823
824        // SAFETY: `self.data` is valid because `self` is valid.
825        let fctx = unsafe { self.data.as_ref().fctx };
826        let _ = fctx.nr_of_unsignaled_fences.fetch_sub(1, Relaxed);
827    }
828}
829
830// SAFETY: Fences are literally designed to be shared between threads.
831unsafe impl<'a, T: Send + Sync + FenceContextOps> Send for DriverFence<'a, T> {}
832// SAFETY: Fences are literally designed to be shared between threads.
833unsafe impl<'a, T: Send + Sync + FenceContextOps> Sync for DriverFence<'a, T> {}
834
835impl<'a, T: Send + Sync + FenceContextOps> Deref for DriverFence<'a, T> {
836    type Target = T::FenceDataType;
837
838    fn deref(&self) -> &Self::Target {
839        // SAFETY: Thanks to refcounting, `data` is always valid as long as `self` is.
840        let data = unsafe { &*self.data.as_ptr() };
841
842        &data.data
843    }
844}
845
846/// A borrow wrapper for [`DriverFence`]. Implements [`Deref`].
847pub struct DriverFenceBorrow<'a, T: Send + Sync + FenceContextOps> {
848    driver_fence: ManuallyDrop<DriverFence<'a, T>>,
849    _lifetime: PhantomData<&'a T>,
850}
851
852impl<'a, T: Send + Sync + FenceContextOps> Deref for DriverFenceBorrow<'a, T> {
853    type Target = DriverFence<'a, T>;
854
855    fn deref(&self) -> &Self::Target {
856        self.driver_fence.deref()
857    }
858}
859
860// SAFETY: The Rust dma_fence abstractions are already designed around the inner
861// C `dma_fence`, which can serve safely as the identification point when being
862// owned by C. Moreover, safety is ensured by not dropping `DriverFence` and by
863// only allowing operations without side effects on the Borrowed type.
864unsafe impl<T: Send + Sync + FenceContextOps> ForeignOwnable for DriverFence<'_, T> {
865    type Borrowed<'a>
866        = DriverFenceBorrow<'a, T>
867    where
868        Self: 'a;
869    type BorrowedMut<'a>
870        = DriverFenceBorrow<'a, T>
871    where
872        Self: 'a;
873
874    const FOREIGN_ALIGN: usize = core::mem::align_of::<bindings::dma_fence>();
875
876    fn into_foreign(self) -> *mut c_void {
877        let fence = self;
878
879        let ptr = fence.as_raw();
880
881        // DriverFence must not drop.
882        let _ = ManuallyDrop::new(fence);
883
884        ptr.cast()
885    }
886
887    unsafe fn from_foreign(ptr: *mut c_void) -> Self {
888        // SAFETY: Safe because the trait implementation only invokes this with
889        // a valid `ptr`, associated to a `DriverFence` with matching generic data.
890        unsafe { Self::from_raw(ptr.cast()) }
891    }
892
893    unsafe fn borrow<'a>(ptr: *mut c_void) -> Self::Borrowed<'a>
894    where
895        Self: 'a,
896    {
897        // SAFETY: The trait implementation ensures that `ptr` always resides
898        // within a [`Fence`] within a [`DriverFenceData`].
899        let driver_fence = unsafe { Self::from_raw(ptr.cast()) };
900
901        let driver_fence = ManuallyDrop::new(driver_fence);
902
903        DriverFenceBorrow {
904            driver_fence,
905            _lifetime: PhantomData,
906        }
907    }
908
909    unsafe fn borrow_mut<'a>(ptr: *mut c_void) -> Self::BorrowedMut<'a>
910    // FIXME: The bound below and the one above in `borrow` should actually be
911    // unnecessary since the compiler should be able to completely derive all
912    // necessary information automatically. There is currently a compiler bug
913    // preventing that, though:
914    //
915    // https://github.com/rust-lang/rust/issues/155430.
916    //
917    // (Help to) fix the compiler bug and remove the bounds afterwards.
918    where
919        Self: 'a,
920    {
921        // SAFETY: The trait implementation ensures that `ptr` always resides
922        // within a [`Fence`] within a [`DriverFenceData`].
923        let driver_fence = unsafe { Self::from_raw(ptr.cast()) };
924
925        let driver_fence = ManuallyDrop::new(driver_fence);
926
927        DriverFenceBorrow {
928            driver_fence,
929            _lifetime: PhantomData,
930        }
931    }
932}
933
934impl<'a, T: Send + Sync + FenceContextOps> Drop for DriverFence<'a, T> {
935    fn drop(&mut self) {
936        let guard = self.as_fence().lock();
937
938        // Use dma_fence_test_signaled_flag() instead of
939        // dma_fence_is_signaled_locked() because the C backend wants to get rid
940        // of the latter.
941
942        // SAFETY: `guard` is valid until the `call_rcu()` below.
943        let signaled: bool = unsafe { bindings::dma_fence_test_signaled_flag(guard.as_raw()) };
944        if !signaled {
945            pr_err!("DriverFence drops unsignaled. Danger of memory corruption!\n");
946            // SAFETY: `guard` is valid until the `call_rcu()` below. The fence
947            // must not have been signaled yet, which we check directly above.
948            unsafe { bindings::dma_fence_set_error(guard.as_raw(), ECANCELED.to_errno()) };
949            // SAFETY: `guard` is valid until the `call_rcu()` below. The lock
950            // must be held, which we acquired above.
951            unsafe { bindings::dma_fence_signal_locked(guard.as_raw()) };
952
953            // SAFETY: `self.data` is valid because `self` is valid.
954            let fctx = unsafe { self.data.as_ref().fctx };
955            let _ = fctx.nr_of_unsignaled_fences.fetch_sub(1, Relaxed);
956        }
957        drop(guard);
958
959        // `DriverFenceData` could be accessed through some dma_fence
960        // callbacks right now. Access is being revoked in principle above by
961        // signaling the fence, but since the C backend does not guarantee
962        // perfect full synchronization, we have to wait for one grace period to
963        // ensure that all accessors of `DriverFenceData` (through the
964        // dma_fence_ops accessible through a `Fence`) are gone.
965
966        if !core::mem::needs_drop::<T::FenceDataType>() {
967            // SAFETY: Once a `DriverFence` is initialized, the inner `fence` is
968            // valid and initialized. It is valid until the refcount drops to 0,
969            // which can earliest happen once we drop the `DriverFence`'s
970            // reference here.
971            unsafe { bindings::dma_fence_put(self.as_raw()) };
972            return;
973        }
974
975        // SAFETY: Valid because `self` is valid.
976        let rcu_head_ptr = unsafe { &raw mut (*self.data.as_ptr()).rcu_head };
977
978        // SAFETY: `call_rcu()` is always safe to be called. `rcu_head_ptr` was
979        // created validly above. The module must perform a `synchronize_rcu()`
980        // or `rcu_barrier()` call to guard against module unload.
981        unsafe { bindings::call_rcu(rcu_head_ptr, Some(drop_driver_fence_data::<T>)) };
982    }
983}
984
985// TODO:
986// The entire call_rcu() mechanism in the drop above and the code below would be
987// unnecessary if C's dma_fence_signal() could be reworked in a way that after it
988// ran, the caller knows that no fence_ops callbacks can be running anymore.
989// In other words, if the dma_fence backend would use its spinlock for full
990// synchronization.
991//
992// Then we could move the drop_in_place() and dma_fence_put() upwards into the
993// drop() implementation and call it a day.
994
995/// Finally really drop this `DriverFence<T>`
996///
997/// # Safety
998///
999/// `head` references the `rcu_head` field of an `DriverFenceData<T>`. All
1000/// accessors to that `DriverFenceData<T>` must be gone by now. This must be
1001/// ensured by signalling the associated `DriverFence<T>` and then waiting
1002/// for a grace period until calling this function here.
1003unsafe extern "C" fn drop_driver_fence_data<T: Send + Sync + FenceContextOps>(
1004    head: *mut bindings::callback_head,
1005) {
1006    // SAFETY: Caller provides a pointer to the `rcu_head` field of a `DriverFenceData<C>`.
1007    let fence_data = unsafe { container_of!(head, DriverFenceData<'_, T>, rcu_head) };
1008
1009    // SAFETY: `fence_data` was created validly above. All the fence's data will
1010    // only drop below, but the raw pointer to the raw C `dma_fence` remains
1011    // valid because the reference count is only decremented at the end of the
1012    // function.
1013    let fence = unsafe { (*fence_data).inner.inner.get() };
1014
1015    // SAFETY: `fence_data` was created validly above. The user has already
1016    // dropped the only conventional accessor to the user data, the `DriverFence`,
1017    // one grace period ago. All accessors are gone now.
1018    unsafe { drop_in_place(&raw mut (*fence_data).data) };
1019
1020    // The inner `Fence` explicitly does not get dropped because there may be
1021    // many more users / consumers, each holding their own reference.
1022
1023    // SAFETY: Once a `DriverFence` is initialized, the inner `fence` is valid
1024    // and initialized. It is valid until the refcount drops to 0, which can
1025    // earliest happen once we drop the `DriverFence`'s reference here.
1026    unsafe { bindings::dma_fence_put(fence) };
1027
1028    // The actual memory the data associated with a `DriverFence` lives in
1029    // gets freed by the C dma_fence backend once the fence's refcount reaches 0.
1030}