Linux Media Controller development
 help / color / mirror / Atom feed
From: Alice Ryhl <aliceryhl@google.com>
To: phasta@kernel.org
Cc: "Miguel Ojeda" <ojeda@kernel.org>,
	"Boqun Feng" <boqun@kernel.org>, "Gary Guo" <gary@garyguo.net>,
	"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
	"Benno Lossin" <lossin@kernel.org>,
	"Andreas Hindborg" <a.hindborg@kernel.org>,
	"Trevor Gross" <tmgross@umich.edu>,
	"Danilo Krummrich" <dakr@kernel.org>,
	"Sumit Semwal" <sumit.semwal@linaro.org>,
	"Christian König" <christian.koenig@amd.com>,
	"Paul E. McKenney" <paulmck@kernel.org>,
	"Frederic Weisbecker" <frederic@kernel.org>,
	"Neeraj Upadhyay" <neeraj.upadhyay@kernel.org>,
	"Joel Fernandes" <joelagnelf@nvidia.com>,
	"Josh Triplett" <josh@joshtriplett.org>,
	"Uladzislau Rezki" <urezki@gmail.com>,
	"Steven Rostedt" <rostedt@goodmis.org>,
	"Mathieu Desnoyers" <mathieu.desnoyers@efficios.com>,
	"Lai Jiangshan" <jiangshanlai@gmail.com>,
	Zqiang <qiang.zhang@linux.dev>,
	"Daniel Almeida" <daniel.almeida@collabora.com>,
	"Greg Kroah-Hartman" <gregkh@linuxfoundation.org>,
	"Igor Korotin" <igor.korotin@linux.dev>,
	"Lorenzo Stoakes" <ljs@kernel.org>,
	"Alexandre Courbot" <acourbot@nvidia.com>,
	"FUJITA Tomonori" <fujita.tomonori@gmail.com>,
	"Krishna Ketan Rai" <prafulrai522@gmail.com>,
	"Shankari Anand" <shankari.ak0208@gmail.com>,
	manos@pitsidianak.is,
	"Boris Brezillon" <boris.brezillon@collabora.com>,
	linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org,
	linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org,
	linaro-mm-sig@lists.linaro.org, rcu@vger.kernel.org
Subject: Re: [PATCH 3/4] rust: Add dma_fence abstractions
Date: Mon, 1 Jun 2026 12:39:01 +0000	[thread overview]
Message-ID: <ah19ZVkr7b3m7V_u@google.com> (raw)
In-Reply-To: <0ea6b6fdd1e3f1e07445f17c0bf672524938dc85.camel@mailbox.org>

On Mon, Jun 01, 2026 at 02:26:17PM +0200, Philipp Stanner wrote:
> On Mon, 2026-06-01 at 10:36 +0000, Alice Ryhl wrote:
> > On Sat, May 30, 2026 at 04:35:11PM +0200, Philipp Stanner wrote:
> > > +        unsafe {
> > > +            bindings::dma_fence_remove_callback(self.fence.as_raw(), self.cb.get());
> > > +        }
> > 
> > Formatting nit: Usually the ; goes outside the unsafe block.
> 
> I could have sworn that it was rustfmt who did that? Maybe because the
> ; was inside to begin with.

Indeed, rustfmt will not change whether the ; is inside or outside the
unsafe block.

> > > +/// A trait to enforce that all data in a [`DriverFence`] either does not need
> > > +/// drop, or lives in a [`RcuBox`].
> > > +pub trait DriverFenceAllowedData: private::Sealed {}
> > > +
> > > +mod private {
> > > +    pub trait Sealed {}
> > > +}
> > > +
> > > +impl<F: Copy> DriverFenceAllowedData for F {}
> > > +impl<F: Send> DriverFenceAllowedData for RcuBox<F> {}
> > > +
> > > +impl<F: Copy> private::Sealed for F {}
> > > +impl<F: Send> private::Sealed for RcuBox<F> {}
> > 
> > Why sealed? Just make the trait unsafe and require the things you
> > require from the user.
> 
> This is far better. We definitely only allow the user to pass A or B,
> and only then it compiles.

What if I have another type that I want to use here? For example, maybe
I have a struct containing a copy field and an RcuBox. Or maybe I have
an ARef<_> of some C type that uses rcu for cleanup. Then I must edit
this file to add support for it?

> The unsafe implementation could be messed up.
> 
> I thought that's what Sealed is for. Or isn't it?

Sealed is for making 100% sure that downstream crates/drivers cannot
provide their own implementations. But I don't see why you need that.
All you require is that the value remains valid for one grace period
after cleanup begins. As long as the type satisfies that, you are happy.
An unsafe trait can require that sort of requirement from the user.

I think what you want is expressed well by `RcuFreeSafe` from this
thread:
https://rust-for-linux.zulipchat.com/#narrow/channel/291566-Library/topic/Consolidate.20.60PollCondVarBox.60.20into.20.60Rcu.2ABox.60/near/598726724

> > > +/// A synchronization primitive mainly for GPU drivers.
> > > +///
> > > +/// Fences 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::dma_buf::{DriverFence, FenceCtx, FenceCb, FenceCbRegistration};
> > > +/// use kernel::str::CString;
> > > +/// use kernel::sync::{
> > > +///     aref::ARef,
> > > +///     rcu::RcuBox, //
> > > +/// };
> > > +/// use core::ops::Deref;
> > > +/// use core::fmt::Display;
> > 
> > Use fmt traits from kernel instead. (Actually, I don't think you use
> > Display at all here?)
> 
> I tried, see a few lines below:
> 
> > 
> > > +/// struct CallbackData { }
> > > +///
> > > +/// impl FenceCb for CallbackData {
> > > +///     fn called(&mut self) {
> > > +///         pr_info!("DmaFence callback executed.\n");
> > > +///     }
> > > +/// }
> > > +///
> > > +/// let driver_name = CString::try_from_fmt(fmt!("dummy_driver"))?;
> > > +/// let timeline_name = CString::try_from_fmt(fmt!("dummy_timeline"))?;
> > > +///
> > > +/// let fctx = FenceCtx::new(driver_name, timeline_name, ())?;
> > > +///
> > > +/// let fence_data = CString::try_from_fmt(fmt!("dummy_data"))?;
> > > +/// // DriverFence::data must either not need drop, or live in an RcuBox.
> > > +/// let fence_data = RcuBox::new(fence_data, GFP_KERNEL)?;
> > > +///
> > > +/// let fence_alloc = fctx.as_arc_borrow().new_fence_allocation(fence_data)?;
> > > +/// let mut fence = fctx.new_fence(fence_alloc);
> > > +///
> > > +/// let cb_data = CallbackData { };
> > > +/// let waiting_fence = ARef::from(fence.as_fence());
> > > +/// let cb_reg = FenceCbRegistration::new(&waiting_fence, cb_data);
> > > +/// let cb_reg = KBox::pin_init(cb_reg, GFP_KERNEL)?;
> > > +///
> > > +/// // DriverFence implements Deref.
> > > +/// // FIXME: unit test claims that CString does not implement Display. Why?
> > > +/// // pr_info!("Fence's inner data is: {}", fence.deref().deref());
> 
> Lazily, I was hoping that someone here will tell me how that is
> supposed to be done correctly 8-)

This specific code could be written cleaner as &**fence, but it looks
like CString should implement fmt::Display like CStr does.

> > > +// SAFETY: The Rust dma_fence abstractions are already designed around the inner
> > > +// C `dma_fence`, which can serve safely as the identification point when being
> > > +// owned by C. Moreover, safety is ensured by not dropping `DriverFence` and by
> > > +// only allowing operations without side effects on the Borrowed type.
> > > +unsafe impl<F: Send + Sync + 'static, C: Send + Sync + 'static> ForeignOwnable
> > > +    for DriverFence<F, C>
> > > +{
> > > +    // `DriverFence` is merely a wrapper around a raw pointer. Thus, we can just
> > > +    // use it directly.
> > > +    type Borrowed<'a> = DriverFenceBorrow<F, C>;
> > > +    type BorrowedMut<'a> = DriverFenceBorrow<F, C>;
> > > +
> > > +    const FOREIGN_ALIGN: usize = core::mem::align_of::<bindings::dma_fence>();
> > > +
> > > +    fn into_foreign(self) -> *mut c_void {
> > > +        let fence = self;
> > > +
> > > +        let ptr = fence.as_raw();
> > > +
> > > +        // DriverFence must not drop.
> > > +        core::mem::forget(fence);
> > 
> > Nit: Modern Rust uses ManuallyDrop instead of forget().
> 
> You mean still take `self` here, then stuff it into ManuallyDrop and
> let it go out of scope, aye?

I mean this:

let fence = ManuallyDrop::new(self);
let ptr = fence.as_raw();

This avoids moving `fence` after calling `as_raw()`.

Alice

  reply	other threads:[~2026-06-01 12:39 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-30 14:35 [PATCH 0/4] rust / dma_buf: Add abstractions for dma_fence Philipp Stanner
2026-05-30 14:35 ` [PATCH 1/4] rust: types: implement ForeignOwnable for ARef<T> Philipp Stanner
2026-05-30 14:45   ` sashiko-bot
2026-06-01  9:46   ` Alice Ryhl
2026-05-30 14:35 ` [PATCH 2/4] rust: rcu: add RcuBox type Philipp Stanner
2026-05-30 14:54   ` sashiko-bot
2026-05-30 15:08   ` Boqun Feng
2026-05-30 15:27     ` Danilo Krummrich
2026-06-01  7:56     ` Philipp Stanner
2026-06-01 13:41       ` Boqun Feng
2026-05-30 14:35 ` [PATCH 3/4] rust: Add dma_fence abstractions Philipp Stanner
2026-05-30 15:06   ` sashiko-bot
2026-06-01 10:20     ` Alice Ryhl
2026-06-01 12:34       ` Philipp Stanner
2026-06-01 12:55         ` Alice Ryhl
2026-06-01 13:14           ` Philipp Stanner
2026-06-01 13:30             ` Philipp Stanner
2026-06-01 13:54               ` Alice Ryhl
2026-06-01 13:44             ` Alice Ryhl
2026-05-30 15:16   ` Danilo Krummrich
2026-06-01  8:46     ` Philipp Stanner
2026-06-01 10:13       ` Danilo Krummrich
2026-06-01 10:36   ` Alice Ryhl
2026-06-01 10:59     ` Boris Brezillon
2026-06-01 11:17       ` Philipp Stanner
2026-06-01 12:35         ` Boris Brezillon
2026-06-01 12:26     ` Philipp Stanner
2026-06-01 12:39       ` Alice Ryhl [this message]
2026-06-01 12:47         ` Philipp Stanner
2026-06-01 13:22           ` Alice Ryhl
2026-06-01 13:23             ` Philipp Stanner
2026-06-01 13:27               ` Alice Ryhl
2026-06-01 12:37     ` Boris Brezillon
2026-05-30 14:35 ` [PATCH 4/4] MAINTAINERS: Add entry for Rust dma-buf Philipp Stanner
2026-05-30 15:20   ` Danilo Krummrich

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ah19ZVkr7b3m7V_u@google.com \
    --to=aliceryhl@google.com \
    --cc=a.hindborg@kernel.org \
    --cc=acourbot@nvidia.com \
    --cc=bjorn3_gh@protonmail.com \
    --cc=boqun@kernel.org \
    --cc=boris.brezillon@collabora.com \
    --cc=christian.koenig@amd.com \
    --cc=dakr@kernel.org \
    --cc=daniel.almeida@collabora.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=frederic@kernel.org \
    --cc=fujita.tomonori@gmail.com \
    --cc=gary@garyguo.net \
    --cc=gregkh@linuxfoundation.org \
    --cc=igor.korotin@linux.dev \
    --cc=jiangshanlai@gmail.com \
    --cc=joelagnelf@nvidia.com \
    --cc=josh@joshtriplett.org \
    --cc=linaro-mm-sig@lists.linaro.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-media@vger.kernel.org \
    --cc=ljs@kernel.org \
    --cc=lossin@kernel.org \
    --cc=manos@pitsidianak.is \
    --cc=mathieu.desnoyers@efficios.com \
    --cc=neeraj.upadhyay@kernel.org \
    --cc=ojeda@kernel.org \
    --cc=paulmck@kernel.org \
    --cc=phasta@kernel.org \
    --cc=prafulrai522@gmail.com \
    --cc=qiang.zhang@linux.dev \
    --cc=rcu@vger.kernel.org \
    --cc=rostedt@goodmis.org \
    --cc=rust-for-linux@vger.kernel.org \
    --cc=shankari.ak0208@gmail.com \
    --cc=sumit.semwal@linaro.org \
    --cc=tmgross@umich.edu \
    --cc=urezki@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox