From: "Danilo Krummrich" <dakr@kernel.org>
To: "Daniel Almeida" <daniel.almeida@collabora.com>
Cc: "Miguel Ojeda" <ojeda@kernel.org>,
"Alex Gaynor" <alex.gaynor@gmail.com>,
"Boqun Feng" <boqun.feng@gmail.com>,
"Gary Guo" <gary@garyguo.net>,
"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
"Benno Lossin" <lossin@kernel.org>,
"Andreas Hindborg" <a.hindborg@kernel.org>,
"Alice Ryhl" <aliceryhl@google.com>,
"Trevor Gross" <tmgross@umich.edu>,
"Alexandre Courbot" <acourbot@nvidia.com>,
linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org,
kernel@collabora.com, linux-media@vger.kernel.org
Subject: Re: [PATCH 2/7] rust: v4l2: add support for v4l2_device
Date: Mon, 18 Aug 2025 11:14:02 +0200 [thread overview]
Message-ID: <DC5FT0XAFW59.VN0EKI1LYNKW@kernel.org> (raw)
In-Reply-To: <20250818-v4l2-v1-2-6887e772aac2@collabora.com>
On Mon Aug 18, 2025 at 7:49 AM CEST, Daniel Almeida wrote:
> +/// A logical V4L2 device handle.
> +///
> +/// # Invariants
> +///
> +/// - `inner` points to a valid `v4l2_device` that has been registered.
> +#[pin_data]
> +#[repr(C)]
> +pub struct Device<T: Driver> {
> + #[pin]
> + inner: Opaque<bindings::v4l2_device>,
> + #[pin]
> + data: T::Data,
> +}
> +
> +impl<T: Driver> Device<T> {
> + /// Converts a raw pointer to a `Device<T>` reference.
> + ///
> + /// # Safety
> + ///
> + /// - `ptr` must be a valid pointer to a `struct v4l2_device` that must
> + /// remain valid for the lifetime 'a.
"valid pointer to a `struct v4l2_device`" is not sufficient for casting it to
Device<T>.
> + #[expect(dead_code)]
> + pub(super) unsafe fn from_raw<'a>(ptr: *mut bindings::v4l2_device) -> &'a Device<T> {
> + // SAFETY: `ptr` is a valid pointer to a `struct v4l2_device` as per the
> + // safety requirements of this function.
> + unsafe { &*(ptr.cast::<Device<T>>()) }
> + }
<snip>
> +/// Represents the registration of a [`Device`].
> +///
> +/// # Invariants
> +///
> +/// - The underlying device was registered via [`bindings::v4l2_device_register`].
> +pub struct Registration<T: Driver>(ARef<Device<T>>);
> +
> +impl<T: Driver> Registration<T> {
> + /// Creates and registers a [`Device`] given a [`kernel::device::Device`] reference and
> + /// the associated data.
> + pub fn new(
> + dev: &device::Device,
> + data: impl PinInit<T::Data, Error>,
> + flags: alloc::Flags,
> + ) -> Result<Self> {
Why does Registration::new() create the Device<T> instance?
I think Device<T> should have its own constructor. It is confusing that the
Device<T> is silently created by the Registration and to get a reference one has
to call `reg.device().into()` afterwards.
> + let v4l2_dev = try_pin_init!(Device {
> + inner <- Opaque::try_ffi_init(move |slot: *mut bindings::v4l2_device| {
> + let v4l2_dev = bindings::v4l2_device {
> + release: Some(Device::<T>::release_callback),
> + // SAFETY: All zeros is valid for this C type.
> + ..unsafe { MaybeUninit::zeroed().assume_init() }
> + };
> +
> + // SAFETY: The initializer can write to the slot.
> + unsafe { slot.write(v4l2_dev) };
> +
> + // SAFETY: It is OK to call this function on a zeroed
> + // v4l2_device and a valid `device::Device` reference.
> + to_result(unsafe { bindings::v4l2_device_register(dev.as_raw(), slot) })
> + }),
> + data <- data,
> + });
> +
> + let v4l2_dev = KBox::pin_init(v4l2_dev, flags)?;
> +
> + // SAFETY: We will be passing the ownership of the increment to ARef<T>,
> + // which treats the underlying memory as pinned throughout its lifetime.
> + //
> + // This is true because:
> + //
> + // - ARef<T> does not expose a &mut T, so there is no way to move the T
> + // (e.g.: via a `core::mem::swap` or similar).
> + // - ARef<T>'s member functions do not move the T either.
> + let ptr = KBox::into_raw(unsafe { Pin::into_inner_unchecked(v4l2_dev) });
> +
> + // SAFETY:
> + //
> + // - the refcount is one, and we are transfering the ownership of that
> + // increment to the ARef.
> + // - `ptr` is non-null as it came from `KBox::into_raw`, so it is safe
> + // to call `NonNulll::new_unchecked`.
> + Ok(Self(unsafe { ARef::from_raw(NonNull::new_unchecked(ptr)) }))
> + }
> +
> + /// Returns a reference to the underlying [`Device`].
> + pub fn device(&self) -> &Device<T> {
> + &self.0
> + }
> +}
> +
> +impl<T: Driver> Drop for Registration<T> {
> + fn drop(&mut self) {
> + // SAFETY: Safe as per the invariants of [`Registration`].
> + unsafe { bindings::v4l2_device_unregister(self.0.as_raw()) }
> + }
> +}
next prev parent reply other threads:[~2025-08-18 9:14 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-08-18 5:49 [PATCH 0/7] rust: add initial v4l2 support Daniel Almeida
2025-08-18 5:49 ` [PATCH 1/7] rust: media: add the media module Daniel Almeida
2025-08-18 8:56 ` Miguel Ojeda
2025-08-18 10:28 ` Janne Grunau
2025-08-18 5:49 ` [PATCH 2/7] rust: v4l2: add support for v4l2_device Daniel Almeida
2025-08-18 9:14 ` Danilo Krummrich [this message]
2025-08-18 5:49 ` [PATCH 3/7] rust: v4l2: add support for video device nodes Daniel Almeida
2025-08-18 9:26 ` Danilo Krummrich
2025-08-18 5:49 ` [PATCH 4/7] rust: v4l2: add support for v4l2 file handles Daniel Almeida
2025-08-18 5:49 ` [PATCH 5/7] rust: v4l2: add device capabilities Daniel Almeida
2025-08-20 4:14 ` Elle Rhumsaa
2025-08-18 5:49 ` [PATCH 6/7] rust: v4l2: add basic ioctl support Daniel Almeida
2025-08-20 4:22 ` Elle Rhumsaa
2025-08-18 5:49 ` [PATCH 7/7] rust: samples: add the v4l2 sample driver Daniel Almeida
2025-08-20 4:24 ` Elle Rhumsaa
2025-08-20 12:39 ` Danilo Krummrich
2025-08-18 8:45 ` [PATCH 0/7] rust: add initial v4l2 support Miguel Ojeda
2025-12-16 17:03 ` Frederic Laing
2025-12-17 14:35 ` Daniel Almeida
2025-12-18 10:12 ` Hans Verkuil
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=DC5FT0XAFW59.VN0EKI1LYNKW@kernel.org \
--to=dakr@kernel.org \
--cc=a.hindborg@kernel.org \
--cc=acourbot@nvidia.com \
--cc=alex.gaynor@gmail.com \
--cc=aliceryhl@google.com \
--cc=bjorn3_gh@protonmail.com \
--cc=boqun.feng@gmail.com \
--cc=daniel.almeida@collabora.com \
--cc=gary@garyguo.net \
--cc=kernel@collabora.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-media@vger.kernel.org \
--cc=lossin@kernel.org \
--cc=ojeda@kernel.org \
--cc=rust-for-linux@vger.kernel.org \
--cc=tmgross@umich.edu \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.