All of lore.kernel.org
 help / color / mirror / Atom feed
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 3/7] rust: v4l2: add support for video device nodes
Date: Mon, 18 Aug 2025 11:26:32 +0200	[thread overview]
Message-ID: <DC5G2LJGBN3D.8JSJY9U25IAW@kernel.org> (raw)
In-Reply-To: <20250818-v4l2-v1-3-6887e772aac2@collabora.com>

On Mon Aug 18, 2025 at 7:49 AM CEST, Daniel Almeida wrote:
> Video device nodes back the actual /dev/videoX files. They expose a rich
> ioctl interface for which we will soon add support for and allow for
> modelling complex hardware through a topology of nodes, each modelling a
> particular hardware function or component.
>
> V4l2 drivers rely on video device nodes pretty extensively, so add a
> minimal Rust abstraction for them. The abstraction currently does the
> bare-minimum to let users register a V4L2 device node. It also
> introduces the video::Driver trait that will be implemented by Rust v4l2
> drivers. This trait will then be refined in future patches.
>
> Signed-off-by: Daniel Almeida <daniel.almeida@collabora.com>
> ---
>  rust/helpers/v4l2-device.c       |  16 +++
>  rust/kernel/media/v4l2/device.rs |   1 -
>  rust/kernel/media/v4l2/mod.rs    |   3 +
>  rust/kernel/media/v4l2/video.rs  | 251 +++++++++++++++++++++++++++++++++++++++
>  4 files changed, 270 insertions(+), 1 deletion(-)
>
> diff --git a/rust/helpers/v4l2-device.c b/rust/helpers/v4l2-device.c
> index d19b46e8283ce762b4259e3df5ecf8bb18e863e9..0ead52b9a1ccc0fbc4d7df63578b334b17c05b70 100644
> --- a/rust/helpers/v4l2-device.c
> +++ b/rust/helpers/v4l2-device.c
> @@ -6,3 +6,19 @@ void rust_helper_v4l2_device_get(struct v4l2_device *v4l2_dev)
>  {
>      v4l2_device_get(v4l2_dev);
>  }
> +
> +void rust_helper_video_get(struct video_device *vdev)
> +{
> +    get_device(&vdev->dev);

Rust helpers shouldn't encode semantics. I think you want to use video_get()
instead.

> +}
> +
> +void rust_helper_video_put(struct video_device *vdev)
> +{
> +    put_device(&vdev->dev);

video_put()

> +/// Represents the registration of a V4L2 device node.
> +pub struct Registration<T: Driver>(ARef<Device<T>>);
> +
> +impl<T: Driver> Registration<T> {
> +    /// Returns a new `Registration` for the given device, which guarantees that
> +    /// the underlying device node is properly initialized and registered, which
> +    /// means that it can be safely used.
> +    pub fn new(
> +        dev: &v4l2::device::Device<T>,
> +        data: impl PinInit<<T as Driver>::Data, Error>,
> +        flags: alloc::Flags,
> +    ) -> Result<Self> {

Same comment regarding Device having its own constructor as for
v4l::device::Registration. I don't see a reason why Registration::new() should
serve as constructor for Device.

Additionally, I think we should use devres::register() for the Registration, such
that you can provide &Device<Bound> cookies in the video callbacks / ioctls.

As far as I can see, video devices are synchronized when unregistered [1]
-- let's take advantage of that.

We do the same thing in the PWM abstractions [2], which is a great optimization.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/media/v4l2-core/v4l2-dev.c?h=v6.16#n1105
[2] https://lore.kernel.org/linux-pwm/20250806-rust-next-pwm-working-fan-for-sending-v13-3-690b669295b6@samsung.com/

> +        let video_dev = try_pin_init!(Device {
> +            inner <- Opaque::try_ffi_init(move |slot: *mut bindings::video_device| {
> +                let opts: DeviceOptions<'_, T> = DeviceOptions {
> +                    dev,
> +                    _phantom: PhantomData
> +                };
> +
> +                // SAFETY: `DeviceOptions::into_raw` produces a valid
> +                // `bindings::video_device` that is ready for registration.
> +                unsafe { slot.write(opts.into_raw()) };
> +
> +
> +                // SAFETY: It is OK to call this function on a zeroed
> +                // `video_device` and a valid `v4l2::Device` reference.
> +                to_result(unsafe { bindings::video_register_device(slot, T::NODE_TYPE as c_uint, -1) })
> +            }),
> +            data <- data,
> +        });
> +
> +        let video_dev = KBox::pin_init(video_dev, flags)?;
> +
> +        // SAFETY: We will be passing the ownership 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(video_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 video device.
> +    pub fn device(&self) -> &video::Device<T> {
> +        &self.0
> +    }
> +}
> +
> +impl<T: Driver> Drop for Registration<T> {
> +    fn drop(&mut self) {
> +        // SAFETY: `self.0` is a valid `video_device` that was registered in
> +        // [`Registration::new`].
> +        unsafe { bindings::video_unregister_device(self.0.as_raw()) };
> +    }
> +}
>
> -- 
> 2.50.1


  reply	other threads:[~2025-08-18  9:26 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
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 [this message]
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=DC5G2LJGBN3D.8JSJY9U25IAW@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.