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}