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 + 'static {
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 + 'static> {
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    pub fn new<'a>(fence: &'a Fence, callback: T) -> impl PinInit<Self, CallbackError<T>> + 'a
330    where
331        T: 'a,
332    {
333        try_pin_init!(Self {
334            // We need to fully initialize the fence because after
335            // `dma_fence_add_callback()` ran, the callback might immediately
336            // get invoked.
337            callback: ManuallyDrop::new(callback),
338            fence: ARef::from(fence),
339            callback_foreign <- Opaque::try_ffi_init(|ptr| {
340                // SAFETY: `fence.inner.get()` is a valid, initialized `struct
341                // dma_fence`. `ptr` points to the `struct dma_fence_cb` field
342                // within the pinned allocation, so it remains valid until
343                // `dma_fence_remove_callback()` in `PinnedDrop` or until the
344                // callback fires.
345                let ret = unsafe {
346                    to_result(bindings::dma_fence_add_callback(
347                        fence.inner.get(),
348                        ptr,
349                        Some(Self::dma_fence_callback),
350                    ))
351                };
352                match ret {
353                    Ok(()) => Ok(()),
354                    Err(e) => {
355                        // SAFETY: We could not register the callback. Thus,
356                        // C will not use it. So we can just take it back
357                        // and pass it to the user again.
358                        let cb_back = unsafe { ManuallyDrop::take(callback) };
359                        if e == ENOENT {
360                            Err(CallbackError::AlreadySignaled(cb_back))
361                        } else {
362                            Err(CallbackError::Other(e))
363                        }
364                    },
365                }
366            }),
367        }? CallbackError<T>)
368    }
369
370    /// Raw dma fence callback that is called by the C code.
371    ///
372    /// # Safety
373    ///
374    /// This is only called by the dma_fence subsystem with valid pointers.
375    unsafe extern "C" fn dma_fence_callback(
376        _fence: *mut bindings::dma_fence,
377        callback_foreign: *mut bindings::dma_fence_cb,
378    ) {
379        let ptr = Opaque::cast_from(callback_foreign).cast_mut();
380
381        // SAFETY: All callbacks we can receive here have been created in such a way that they are
382        // embedded into a `FenceCallbackRegistration`.
383        let reg: *mut Self = unsafe { container_of!(ptr, Self, callback_foreign) };
384
385        // SAFETY: `reg` is a valid `Self` pointer.
386        //
387        // The backend ensures synchronisation so whoever holds the registration object cannot drop
388        // it while this code is running. See `FenceCallbackRegistration::drop`.
389        unsafe { (*reg).callback.on_signal() };
390    }
391
392    /// Returns a reference to the fence this callback is registered on.
393    #[inline]
394    pub fn fence(&self) -> &Fence {
395        &self.fence
396    }
397}
398
399#[pinned_drop]
400impl<T: FenceCallback> PinnedDrop for FenceCallbackRegistration<T> {
401    fn drop(self: Pin<&mut Self>) {
402        // Always call `dma_fence_remove_callback()`, even if the callback
403        // already ran. This is necessary for synchronization:
404        // `dma_fence_remove_callback()` acquires `fence->lock`, which ensures
405        // that any in-flight `dma_fence_signal()` (which calls our callback
406        // while holding the same lock) has completed before we free the struct.
407        //
408        // Without this, Drop can race with a concurrent signal:
409        //   CPU0 (signal, lock held): take() -> on_signal(fence_ref) (in progress)
410        //   CPU1 (drop): skips lock -> frees struct
411        //   CPU0: accesses fence_ref -> use-after-free
412        //
413        // When the callback has already fired, the signal path detached the
414        // list node via `INIT_LIST_HEAD()`, so dma_fence_remove_callback just
415        // sees an empty node and returns false — the lock acquisition is the
416        // only thing that matters.
417        //
418        // SAFETY: The fence pointer is valid and the cb was initialized by
419        // `dma_fence_add_callback()` during construction.
420        unsafe {
421            bindings::dma_fence_remove_callback(self.fence.as_raw(), self.callback_foreign.get())
422        };
423
424        // SAFETY: This is literally the drop implementation, so no one has
425        // dropped this so far; so we can do it now.
426        unsafe { ManuallyDrop::<T>::drop(self.project().callback) };
427    }
428}
429
430// SAFETY: FenceCallbackRegistration can be sent between threads.
431unsafe impl<T: FenceCallback> Send for FenceCallbackRegistration<T> {}
432
433// SAFETY: &FenceCallbackRegistration can be shared between threads if &T can.
434unsafe impl<T: FenceCallback> Sync for FenceCallbackRegistration<T> where T: Sync {}
435
436/// The receiving counterpart of a [`DriverFence`].
437///
438/// The Rust DMA fence implementation has a dualistic design: [`DriverFence`]s
439/// are the producer-side, intended to be always owned by only one party. That
440/// party has the monopoly on signaling the fence.
441///
442/// A [`Fence`] is the counterpart for consumers. Thus, [`Fence`]s are always
443/// refcounted and can shared with an arbitrary number of parties, including
444/// userspace. A [`Fence`] can only be used for actions such as checking the
445/// fence's status or for registering callbacks on it.
446///
447/// Once the associated [`DriverFence`] signals, all
448/// [`FenceCallbackRegistration`]s registered on the [`Fence`] will be executed.
449///
450/// A [`Fence`] can arbitrarily outlive its [`DriverFence`] and the
451/// [`FenceContext`]. Signaling a [`DriverFence`] decouples it from its
452/// [`Fence`]s.
453#[repr(transparent)]
454pub struct Fence {
455    /// The actual dma_fence passed to C.
456    inner: Opaque<bindings::dma_fence>,
457}
458
459/// Guard helper for locking within this module.
460///
461/// Its only purpose for now is to avoid a number of unsafe lock-unlock cycles.
462/// It is never used outside of this module.
463// TODO: This should be made more canonical, probably by basing it on a
464// SpinLockIrqGuard once available.
465struct FenceGuard<'a> {
466    inner: &'a Fence,
467    flags: usize,
468}
469
470impl<'a> Deref for FenceGuard<'a> {
471    type Target = &'a Fence;
472
473    fn deref(&self) -> &Self::Target {
474        &self.inner
475    }
476}
477
478impl Drop for FenceGuard<'_> {
479    fn drop(&mut self) {
480        // SAFETY: `fence` is valid because `self` is valid. `flag_ptr` is
481        // merely a pointer to an integer, which lives as long as this function.
482        // When a `FenceGuard` exists, the lock has been taken by definition.
483        unsafe { bindings::dma_fence_unlock_irqrestore(self.as_raw(), &raw mut self.flags) };
484    }
485}
486
487// SAFETY: Fences are literally designed to be shared between threads.
488unsafe impl Send for Fence {}
489// SAFETY: Fences are literally designed to be shared between threads.
490unsafe impl Sync for Fence {}
491
492impl Fence {
493    /// Check whether the fence was signaled at the moment of the function call.
494    ///
495    /// Note that this can return `true` for a [`Fence`] whose [`DriverFence`]
496    /// has not yet been dropped. The reason is that the fence ops callbacks can
497    /// cause the fence to get signaled by the C backend.
498    #[inline]
499    pub fn is_signaled(&self) -> bool {
500        // We should not use `dma_fence_is_signaled_locked()` here, because
501        // according to the C backend's recommendations, that function is
502        // problematic and we should avoid calling that function with a lock
503        // held.
504
505        // SAFETY: Inner `fence` is valid because `self` is valid.
506        let ret = unsafe { bindings::dma_fence_is_signaled(self.as_raw()) };
507
508        // To be as robust as possible for the future we guarantee that an API
509        // caller can 100% rely on the signaling being completed (i.e., all
510        // fence callbacks ran), so we have to take the lock.
511        //
512        // The reason is that the C dma_fence backend currently does not
513        // carefully synchronize the `dma_fence_is_signaled()` function with the
514        // proper spinlock. This can lead to the function returning `true` while
515        // fence callbacks are still being executed. This can be mitigated by
516        // guarding the entire function with the spinlock.
517        //
518        // The fundamental reason is that the C backend currently does guard
519        // setting of the fence's signaled-bit with the fence's spinlock, but
520        // reading is done locklessly.
521        //
522        // See commit c8a5d5ea3ba6a.
523        let _ = self.lock();
524
525        ret
526    }
527
528    /// Lock the fence. A helper only to be used internally in this module.
529    fn lock(&self) -> FenceGuard<'_> {
530        let mut guard = FenceGuard {
531            inner: self,
532            flags: 0,
533        };
534
535        // SAFETY: `fence` is valid because `self` is valid. `flag_ptr` is
536        // merely a pointer to an integer, whose lifetime is tied to the guard
537        // object.
538        unsafe { bindings::dma_fence_lock_irqsave(self.as_raw(), &raw mut guard.flags) };
539
540        guard
541    }
542
543    /// Get the fence's sequence number.
544    #[inline]
545    pub fn seqno(&self) -> u64 {
546        // SAFETY: Valid because `self` is valid.
547        unsafe { (*self.as_raw()).seqno }
548    }
549
550    fn as_raw(&self) -> *mut bindings::dma_fence {
551        self.inner.get()
552    }
553
554    /// Create a [`Fence`] from a raw C [`bindings::dma_fence`].
555    ///
556    /// # Safety
557    ///
558    /// `ptr` must point to an initialized fence that is embedded into a [`Fence`].
559    #[inline]
560    pub unsafe fn from_raw<'a>(ptr: *mut bindings::dma_fence) -> &'a Self {
561        // SAFETY: Safe as per the function's overall safety requirements.
562        unsafe { &*ptr.cast() }
563    }
564}
565
566// SAFETY: These implement the C backends refcounting methods which are proven
567// to work correctly.
568unsafe impl AlwaysRefCounted for Fence {
569    fn inc_ref(&self) {
570        // SAFETY: `self.as_raw()` is a pointer to a valid `struct dma_fence`.
571        unsafe { bindings::dma_fence_get(self.as_raw()) }
572    }
573
574    unsafe fn dec_ref(ptr: NonNull<Self>) {
575        // SAFETY: `ptr` is never a NULL pointer; and when `dec_ref()` is called
576        // the fence is by definition still valid.
577        let fence = unsafe { (*ptr.as_ptr()).inner.get() };
578
579        // SAFETY: `fence` was created validly above. When `dec_ref()` is called,
580        // there is by definition still a reference alive that can be put.
581        unsafe { bindings::dma_fence_put(fence) }
582    }
583}
584
585// Necessary to guarantee that `inner` always comes first and can be freed by C.
586// Also useful for using casts instead of container_of().
587#[repr(C)]
588#[pin_data]
589struct DriverFenceData<'a, T: Send + Sync + FenceContextOps> {
590    #[pin]
591    /// The inner fence.
592    // Must always be the first member so that unsafe casting works; but also
593    // necessary so that the C backend can free the allocation (coming from our
594    // Rust code) with kfree_rcu().
595    inner: Fence,
596    /// Callback head for dropping this in a deferred manner through RCU.
597    rcu_head: bindings::callback_head,
598    /// Reference to access the FenceContext.
599    fctx: &'a FenceContext<T>,
600    /// The API user's data. It is essential that the data only performs
601    /// operations legal in atomic context in its [`Drop`] implementation.
602    #[pin]
603    data: T::FenceDataType,
604}
605
606/// A synchronization primitive mainly for GPU drivers.
607///
608/// The Rust DMA fence implementation has a dualistic design: [`DriverFence`]s
609/// are the producer-side, intended to be always owned by only one party. That
610/// party has the monopoly on signaling the fence.
611///
612/// A [`Fence`] is the counterpart for consumers. Thus, [`Fence`]s are always
613/// refcounted and can be shared with an arbitrary number of parties, including
614/// userspace. A [`Fence`] can only be used for actions such as checking the
615/// fence's status or for registering callbacks on it.
616///
617/// Once the associated [`DriverFence`] signals, all
618/// [`FenceCallbackRegistration`]s registered on a [`Fence`] will be executed.
619///
620/// A [`Fence`] can arbitrarily outlive its [`DriverFence`] and the
621/// [`FenceContext`]. Signaling a [`DriverFence`] decouples it from its
622/// [`Fence`]s.
623///
624/// It is crucial that a [`DriverFence`] always correctly represents the state
625/// of the associated job on the hardware. Especially, it is strictly necessary
626/// that the owner ensures that all [`DriverFence`]s eventually get signaled.
627/// As a last resort, a [`DriverFence`] will signal itself if it drops
628/// unsignaled and print a warning.
629///
630/// This design intends to implement the [`bindings::dma_fence_ops`] in such a
631/// way that the driver-data necessary to implement the callback's functionality
632/// resides in the [`FenceContext`]. Thus, a [`DriverFence`] contains a
633/// reference to the context, which can be accessed in the callbacks. The
634/// implementation, therefore, ensures that a [`DriverFence`] cannot outlive its
635/// [`FenceContext`]. Unfortunately, this can be circumvented under certain
636/// circumstances in Rust (e.g., usage of [`core::mem::forget`]).
637///
638/// In the unlikely case of such violations, a panic is thrown.
639///
640/// # Examples
641///
642/// ```
643/// use kernel::{
644///     dma_buf::{
645///         DriverFence,
646///         FenceContext,
647///         FenceContextOps,
648///         FenceCallback,
649///         FenceCallbackRegistration,
650///     },
651///     str::CString,
652///     sync::aref::ARef, //
653/// };
654/// use core::fmt::Display;
655///
656/// struct CallbackData { }
657///
658/// impl FenceCallback for CallbackData {
659///     fn on_signal(&mut self) {
660///         pr_info!("DmaFence callback executed.\n");
661///     }
662/// }
663///
664/// #[pin_data]
665/// struct FenceContextData {}
666///
667/// impl FenceContextData {
668///     fn new() -> impl PinInit<Self> {
669///         pin_init!(Self {})
670///     }
671/// }
672///
673/// impl FenceContextOps for FenceContextData {
674///     type FenceDataType = FenceData;
675/// }
676///
677/// let fctx_data = FenceContextData::new();
678///
679///
680/// let mut fctx = KBox::pin_init(
681///     FenceContext::new(0, c"dummy_driver", c"dummy_timeline", fctx_data),
682///     GFP_KERNEL
683/// )?;
684///
685/// struct FenceData {
686///     data: CString,
687/// }
688///
689/// let fence_data = FenceData { data: c"dummy_data".try_into()? };
690///
691/// let fence_alloc = fctx.new_fence_allocation(fence_data)?;
692/// let mut fence = fence_alloc.new_fence();
693///
694/// let cb_data = CallbackData { };
695/// let waiting_fence = ARef::from(fence.as_fence());
696/// let cb_reg = FenceCallbackRegistration::new(&waiting_fence, cb_data);
697/// let cb_reg = KBox::pin_init(cb_reg, GFP_KERNEL)?;
698///
699/// // TODO signalling guards
700/// assert_eq!(waiting_fence.is_signaled(), false);
701/// fence.signal(Ok(()));
702/// assert_eq!(waiting_fence.is_signaled(), true);
703///
704/// Ok::<(), Error>(())
705/// ```
706pub struct DriverFence<'a, T: Send + Sync + FenceContextOps> {
707    /// The actual content of the fence. Lives in a [`NonNull`] so that its
708    /// memory can be managed independently. Valid until both the [`DriverFence`]
709    /// and all associated [`Fence`]s have disappeared.
710    data: NonNull<DriverFenceData<'a, T>>,
711}
712
713/// A pre-prepared DMA fence, carrying the user's data and the memory it and the
714/// fence reside in. Only useful for creating a [`DriverFence`]. Splitting
715/// allocation and full initialization is necessary because fences cannot be
716/// allocated dynamically in some circumstances (deadlock).
717pub struct DriverFenceAllocation<'a, T: Send + Sync + FenceContextOps> {
718    /// The memory for the actual content of the fence.
719    /// Handed over to a [`DriverFence`], or deallocated once the
720    /// [`DriverFenceAllocation`] drops.
721    data: KBox<DriverFenceData<'a, T>>,
722    /// Reference for the ops for the associated [`FenceContext`]
723    ops: &'static bindings::dma_fence_ops,
724}
725
726impl<'a, T: Send + Sync + FenceContextOps> DriverFenceAllocation<'a, T> {
727    /// Create a new [`DriverFence`], the signalable counterpart of a [`Fence`].
728    ///
729    /// This increments the sequence number in the associated [`FenceContext`].
730    pub fn new_fence(self) -> DriverFence<'a, T> {
731        // We feed the C dma_fence backend a NULL for the spinlock so that it
732        // uses per-fence locks automatically.
733        let null_ptr: *mut bindings::spinlock = ptr::null_mut();
734        let seqno = self.data.fctx.next_seqno();
735        let fence_ptr = self.as_raw();
736        // SAFETY: `fence_ptr` has been created directly above. It will live
737        // at least as long as `Self`. The same applies to `&Self::OPS`.
738        unsafe {
739            bindings::dma_fence_init(fence_ptr, self.ops, null_ptr, self.data.fctx.nr, seqno)
740        };
741
742        self.data.fctx.nr_of_unsignaled_fences.fetch_add(1, Relaxed);
743
744        // A `DriverFenceAllocation`'s purpose is to carry allocated memory, so
745        // that `DriverFence`s can always be created without allocating. In this
746        // method, ownership over that memory is transferred to the new
747        // `DriverFence` and managed through refcounting. The C dma_fence
748        // backend will ultimately free the memory once the refcount reaches 0.
749        let ptr = KBox::into_raw(self.data);
750        // SAFETY: `ptr` was just created validly directly above.
751        let ptr = unsafe { NonNull::new_unchecked(ptr) };
752
753        DriverFence { data: ptr }
754    }
755
756    fn as_raw(&self) -> *mut bindings::dma_fence {
757        self.data.inner.inner.get()
758    }
759}
760
761impl<'a, T: Send + Sync + FenceContextOps> DriverFence<'a, T> {
762    fn as_raw(&self) -> *mut bindings::dma_fence {
763        // SAFETY: Valid because `self` is valid.
764        let fence_data = unsafe { &*self.data.as_ptr() };
765
766        fence_data.inner.inner.get()
767    }
768
769    /// Create a [`DriverFence`] from a raw pointer to a [`bindings::dma_fence`].
770    ///
771    /// # Safety
772    ///
773    /// `ptr` must be a valid pointer to a `dma_fence` that was obtained through
774    /// a [`DriverFence`] with matching generic data for both fence and associated
775    /// [`FenceContext`].
776    unsafe fn from_raw(ptr: *mut bindings::dma_fence) -> Self {
777        let opaque_fence = Opaque::cast_from(ptr);
778
779        // SAFETY: Safe due to the function's overall safety requirements.
780        let fence_ptr = unsafe { container_of!(opaque_fence, Fence, inner) };
781
782        // DriverFenceData is `repr(C)` and a Fence is its first member.
783        let fence_data_ptr = fence_ptr as *mut DriverFenceData<'a, T>;
784
785        // SAFETY: `fence_data_ptr` was created validly above.
786        let data = unsafe { NonNull::new_unchecked(fence_data_ptr) };
787
788        Self { data }
789    }
790
791    /// Return the underlying [`Fence`].
792    #[inline]
793    pub fn as_fence(&self) -> &Fence {
794        // SAFETY: `self` is by definition still valid, and it cannot drop until
795        // this new reference is gone.
796        unsafe { Fence::from_raw(self.as_raw()) }
797    }
798
799    /// Signal the fence. This will invoke all registered callbacks.
800    pub fn signal(self, res: Result) {
801        let fence = self.as_fence().lock();
802
803        // SAFETY: `fence` is valid because `self` is valid. The lock must be
804        // held, which we acquired directly above.
805        if !unsafe { bindings::dma_fence_test_signaled_flag(fence.as_raw()) } {
806            if let Err(err) = res {
807                // SAFETY: `fence` is valid because `self` is valid. The fence
808                // must not have been signaled yet, which we check directly above.
809                unsafe { bindings::dma_fence_set_error(fence.as_raw(), err.to_errno()) };
810            }
811            // SAFETY: `fence` is valid because `self` is valid. The lock must
812            // be held, which we acquired above.
813            unsafe { bindings::dma_fence_signal_locked(fence.as_raw()) };
814        }
815
816        // SAFETY: `self.data` is valid because `self` is valid.
817        let fctx = unsafe { self.data.as_ref().fctx };
818        let _ = fctx.nr_of_unsignaled_fences.fetch_sub(1, Relaxed);
819    }
820}
821
822// SAFETY: Fences are literally designed to be shared between threads.
823unsafe impl<'a, T: Send + Sync + FenceContextOps> Send for DriverFence<'a, T> {}
824// SAFETY: Fences are literally designed to be shared between threads.
825unsafe impl<'a, T: Send + Sync + FenceContextOps> Sync for DriverFence<'a, T> {}
826
827impl<'a, T: Send + Sync + FenceContextOps> Deref for DriverFence<'a, T> {
828    type Target = T::FenceDataType;
829
830    fn deref(&self) -> &Self::Target {
831        // SAFETY: Thanks to refcounting, `data` is always valid as long as `self` is.
832        let data = unsafe { &*self.data.as_ptr() };
833
834        &data.data
835    }
836}
837
838/// A borrow wrapper for [`DriverFence`]. Implements [`Deref`].
839pub struct DriverFenceBorrow<'a, T: Send + Sync + FenceContextOps> {
840    driver_fence: ManuallyDrop<DriverFence<'a, T>>,
841    _lifetime: PhantomData<&'a T>,
842}
843
844impl<'a, T: Send + Sync + FenceContextOps> Deref for DriverFenceBorrow<'a, T> {
845    type Target = DriverFence<'a, T>;
846
847    fn deref(&self) -> &Self::Target {
848        self.driver_fence.deref()
849    }
850}
851
852// SAFETY: The Rust dma_fence abstractions are already designed around the inner
853// C `dma_fence`, which can serve safely as the identification point when being
854// owned by C. Moreover, safety is ensured by not dropping `DriverFence` and by
855// only allowing operations without side effects on the Borrowed type.
856unsafe impl<T: Send + Sync + FenceContextOps> ForeignOwnable for DriverFence<'_, T> {
857    type Borrowed<'a>
858        = DriverFenceBorrow<'a, T>
859    where
860        Self: 'a;
861    type BorrowedMut<'a>
862        = DriverFenceBorrow<'a, T>
863    where
864        Self: 'a;
865
866    const FOREIGN_ALIGN: usize = core::mem::align_of::<bindings::dma_fence>();
867
868    fn into_foreign(self) -> *mut c_void {
869        let fence = self;
870
871        let ptr = fence.as_raw();
872
873        // DriverFence must not drop.
874        let _ = ManuallyDrop::new(fence);
875
876        ptr.cast()
877    }
878
879    unsafe fn from_foreign(ptr: *mut c_void) -> Self {
880        // SAFETY: Safe because the trait implementation only invokes this with
881        // a valid `ptr`, associated to a `DriverFence` with matching generic data.
882        unsafe { Self::from_raw(ptr.cast()) }
883    }
884
885    unsafe fn borrow<'a>(ptr: *mut c_void) -> Self::Borrowed<'a>
886    where
887        Self: 'a,
888    {
889        // SAFETY: The trait implementation ensures that `ptr` always resides
890        // within a [`Fence`] within a [`DriverFenceData`].
891        let driver_fence = unsafe { Self::from_raw(ptr.cast()) };
892
893        let driver_fence = ManuallyDrop::new(driver_fence);
894
895        DriverFenceBorrow {
896            driver_fence,
897            _lifetime: PhantomData,
898        }
899    }
900
901    unsafe fn borrow_mut<'a>(ptr: *mut c_void) -> Self::BorrowedMut<'a>
902    // FIXME: The bound below and the one above in `borrow` should actually be
903    // unnecessary since the compiler should be able to completely derive all
904    // necessary information automatically. There is currently a compiler bug
905    // preventing that, though:
906    //
907    // https://github.com/rust-lang/rust/issues/155430.
908    //
909    // (Help to) fix the compiler bug and remove the bounds afterwards.
910    where
911        Self: 'a,
912    {
913        // SAFETY: The trait implementation ensures that `ptr` always resides
914        // within a [`Fence`] within a [`DriverFenceData`].
915        let driver_fence = unsafe { Self::from_raw(ptr.cast()) };
916
917        let driver_fence = ManuallyDrop::new(driver_fence);
918
919        DriverFenceBorrow {
920            driver_fence,
921            _lifetime: PhantomData,
922        }
923    }
924}
925
926impl<'a, T: Send + Sync + FenceContextOps> Drop for DriverFence<'a, T> {
927    fn drop(&mut self) {
928        let guard = self.as_fence().lock();
929
930        // Use dma_fence_test_signaled_flag() instead of
931        // dma_fence_is_signaled_locked() because the C backend wants to get rid
932        // of the latter.
933
934        // SAFETY: `guard` is valid until the `call_rcu()` below.
935        let signaled: bool = unsafe { bindings::dma_fence_test_signaled_flag(guard.as_raw()) };
936        if !signaled {
937            pr_err!("DriverFence drops unsignaled. Danger of memory corruption!\n");
938            // SAFETY: `guard` is valid until the `call_rcu()` below. The fence
939            // must not have been signaled yet, which we check directly above.
940            unsafe { bindings::dma_fence_set_error(guard.as_raw(), ECANCELED.to_errno()) };
941            // SAFETY: `guard` is valid until the `call_rcu()` below. The lock
942            // must be held, which we acquired above.
943            unsafe { bindings::dma_fence_signal_locked(guard.as_raw()) };
944
945            // SAFETY: `self.data` is valid because `self` is valid.
946            let fctx = unsafe { self.data.as_ref().fctx };
947            let _ = fctx.nr_of_unsignaled_fences.fetch_sub(1, Relaxed);
948        }
949        drop(guard);
950
951        // `DriverFenceData` could be accessed through some dma_fence
952        // callbacks right now. Access is being revoked in principle above by
953        // signaling the fence, but since the C backend does not guarantee
954        // perfect full synchronization, we have to wait for one grace period to
955        // ensure that all accessors of `DriverFenceData` (through the
956        // dma_fence_ops accessible through a `Fence`) are gone.
957
958        if !core::mem::needs_drop::<T::FenceDataType>() {
959            // SAFETY: Once a `DriverFence` is initialized, the inner `fence` is
960            // valid and initialized. It is valid until the refcount drops to 0,
961            // which can earliest happen once we drop the `DriverFence`'s
962            // reference here.
963            unsafe { bindings::dma_fence_put(self.as_raw()) };
964            return;
965        }
966
967        // SAFETY: Valid because `self` is valid.
968        let rcu_head_ptr = unsafe { &raw mut (*self.data.as_ptr()).rcu_head };
969
970        // SAFETY: `call_rcu()` is always safe to be called. `rcu_head_ptr` was
971        // created validly above. The module must perform a `synchronize_rcu()`
972        // or `rcu_barrier()` call to guard against module unload.
973        unsafe { bindings::call_rcu(rcu_head_ptr, Some(drop_driver_fence_data::<T>)) };
974    }
975}
976
977// TODO:
978// The entire call_rcu() mechanism in the drop above and the code below would be
979// unnecessary if C's dma_fence_signal() could be reworked in a way that after it
980// ran, the caller knows that no fence_ops callbacks can be running anymore.
981// In other words, if the dma_fence backend would use its spinlock for full
982// synchronization.
983//
984// Then we could move the drop_in_place() and dma_fence_put() upwards into the
985// drop() implementation and call it a day.
986
987/// Finally really drop this `DriverFence<T>`
988///
989/// # Safety
990///
991/// `head` references the `rcu_head` field of an `DriverFenceData<T>`. All
992/// accessors to that `DriverFenceData<T>` must be gone by now. This must be
993/// ensured by signalling the associated `DriverFence<T>` and then waiting
994/// for a grace period until calling this function here.
995unsafe extern "C" fn drop_driver_fence_data<T: Send + Sync + FenceContextOps>(
996    head: *mut bindings::callback_head,
997) {
998    // SAFETY: Caller provides a pointer to the `rcu_head` field of a `DriverFenceData<C>`.
999    let fence_data = unsafe { container_of!(head, DriverFenceData<'_, T>, rcu_head) };
1000
1001    // SAFETY: `fence_data` was created validly above. All the fence's data will
1002    // only drop below, but the raw pointer to the raw C `dma_fence` remains
1003    // valid because the reference count is only decremented at the end of the
1004    // function.
1005    let fence = unsafe { (*fence_data).inner.inner.get() };
1006
1007    // SAFETY: `fence_data` was created validly above. The user has already
1008    // dropped the only conventional accessor to the user data, the `DriverFence`,
1009    // one grace period ago. All accessors are gone now.
1010    unsafe { drop_in_place(&raw mut (*fence_data).data) };
1011
1012    // The inner `Fence` explicitly does not get dropped because there may be
1013    // many more users / consumers, each holding their own reference.
1014
1015    // SAFETY: Once a `DriverFence` is initialized, the inner `fence` is valid
1016    // and initialized. It is valid until the refcount drops to 0, which can
1017    // earliest happen once we drop the `DriverFence`'s reference here.
1018    unsafe { bindings::dma_fence_put(fence) };
1019
1020    // The actual memory the data associated with a `DriverFence` lives in
1021    // gets freed by the C dma_fence backend once the fence's refcount reaches 0.
1022}