lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-Id: <DG721WEFTFZY.2CSCXBQ8H0Y1A@garyguo.net>
Date: Thu, 05 Feb 2026 13:16:35 +0000
From: "Gary Guo" <gary@...yguo.net>
To: "Boris Brezillon" <boris.brezillon@...labora.com>, "Philipp Stanner"
 <phasta@...nel.org>
Cc: "David Airlie" <airlied@...il.com>, "Simona Vetter" <simona@...ll.ch>,
 "Danilo Krummrich" <dakr@...nel.org>, "Alice Ryhl" <aliceryhl@...gle.com>,
 "Gary Guo" <gary@...yguo.net>, "Benno Lossin" <lossin@...nel.org>,
 Christian König <christian.koenig@....com>, "Daniel
 Almeida" <daniel.almeida@...labora.com>, "Joel Fernandes"
 <joelagnelf@...dia.com>, <linux-kernel@...r.kernel.org>,
 <dri-devel@...ts.freedesktop.org>, <rust-for-linux@...r.kernel.org>
Subject: Re: [RFC PATCH 2/4] rust: sync: Add dma_fence abstractions

On Thu Feb 5, 2026 at 10:16 AM GMT, Boris Brezillon wrote:
> On Tue,  3 Feb 2026 09:14:01 +0100
> Philipp Stanner <phasta@...nel.org> wrote:
>
>> +/// A synchronization primitive mainly for GPU drivers.
>> +///
>> +/// DmaFences are always reference counted. The typical use case is that one side registers
>> +/// callbacks on the fence which will perform a certain action (such as queueing work) once the
>> +/// other side signals the fence.
>> +///
>> +/// # Examples
>> +///
>> +/// ```
>> +/// use kernel::sync::{Arc, ArcBorrow, DmaFence, DmaFenceCtx, DmaFenceCb, DmaFenceCbFunc};
>> +/// use core::sync::atomic::{self, AtomicBool};
>> +///
>> +/// static mut CHECKER: AtomicBool = AtomicBool::new(false);
>> +///
>> +/// struct CallbackData {
>> +///     i: u32,
>> +/// }
>> +///
>> +/// impl CallbackData {
>> +///     fn new() -> Self {
>> +///         Self { i: 9 }
>> +///     }
>> +/// }
>> +///
>> +/// impl DmaFenceCbFunc for CallbackData {
>> +///     fn callback(cb: Pin<KBox<DmaFenceCb<Self>>>) where Self: Sized {
>> +///         assert_eq!(cb.data.i, 9);
>> +///         // SAFETY: Just to have an easy way for testing. This cannot race with the checker
>> +///         // because the fence signalling callbacks are executed synchronously.
>> +///         unsafe { CHECKER.store(true, atomic::Ordering::Relaxed); }
>> +///     }
>> +/// }
>> +///
>> +/// struct DriverData {
>> +///     i: u32,
>> +/// }
>> +///
>> +/// impl DriverData {
>> +///     fn new() -> Self {
>> +///         Self { i: 5 }
>> +///     }
>> +/// }
>> +///
>> +/// let data = DriverData::new();
>> +/// let fctx = DmaFenceCtx::new()?;
>> +///
>> +/// let mut fence = fctx.as_arc_borrow().new_fence(data)?;
>> +///
>> +/// let cb_data = CallbackData::new();
>> +/// fence.register_callback(cb_data);
>> +/// // fence.begin_signalling();
>> +/// fence.signal()?;
>> +/// // Now check wehether the callback was actually executed.
>> +/// // SAFETY: `fence.signal()` above works sequentially. We just check here whether the signalling
>> +/// // actually did set the boolean correctly.
>> +/// unsafe { assert_eq!(CHECKER.load(atomic::Ordering::Relaxed), true); }
>> +///
>> +/// Ok::<(), Error>(())
>> +/// ```
>> +#[pin_data]
>> +pub struct DmaFence<T> {
>> +    /// The actual dma_fence passed to C.
>> +    #[pin]
>> +    inner: Opaque<bindings::dma_fence>,
>> +    /// User data.
>> +    #[pin]
>> +    data: T,
>
> A DmaFence is a cross-device synchronization mechanism that can (and
> will) cross the driver boundary (one driver can wait on a fence emitted
> by a different driver). As such, I don't think embedding a generic T in
> the DmaFence and considering it's the object being passed around is
> going to work, because, how can one driver know the T chosen by the
> driver that created the fence? If you want to have some fence emitter
> data attached to the DmaFence allocation, you'll need two kind of
> objects:
>
> - one that's type agnostic and on which you can do the callback
>   registration/unregistration, signalling checks, and generally all
>   type-agnostic operations. That's basically just a wrapper around a
>   bindings::dma_fence implementing AlwaysRefCounted.
> - one that has the extra data and fctx, with a way to transmute from a
>   generic fence to a implementer specific one in case the driver wants
>   to do something special when waiting on its own fences (check done
>   with the fence ops in C, I don't know how that translates in rust)

If `data` is moved to the end of struct and `DmaFence<T>` changed to
`DmaFence<T: ?Sized>`, you would also gain the ability to coerce `DmaFence<T>`
to `DmaFence<dyn Trait>`, e.g. `DmaFence<dyn Any>`.

Best,
Gary

>
>> +    /// Marks whether the fence is currently in the signalling critical section.
>> +    signalling: bool,
>> +    /// A boolean needed for the C backend's lockdep guard.
>> +    signalling_cookie: bool,
>> +    /// A reference to the associated [`DmaFenceCtx`] so that it cannot be dropped while there are
>> +    /// still fences around.
>> +    fctx: Arc<DmaFenceCtx>,
>> +}


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ