From: Alice Ryhl <aliceryhl@google.com>
To: Danilo Krummrich <dakr@kernel.org>
Cc: gregkh@linuxfoundation.org, rafael@kernel.org,
bhelgaas@google.com, kwilczynski@kernel.org,
david.m.ertman@intel.com, ira.weiny@intel.com, leon@kernel.org,
acourbot@nvidia.com, ojeda@kernel.org, alex.gaynor@gmail.com,
boqun.feng@gmail.com, gary@garyguo.net,
bjorn3_gh@protonmail.com, lossin@kernel.org,
a.hindborg@kernel.org, tmgross@umich.edu, pcolberg@redhat.com,
rust-for-linux@vger.kernel.org, linux-pci@vger.kernel.org,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH 0/8] Device::drvdata() and driver/driver interaction (auxiliary)
Date: Wed, 29 Oct 2025 13:03:19 +0000 [thread overview]
Message-ID: <aQIQl8lMhztucZhK@google.com> (raw)
In-Reply-To: <20251020223516.241050-1-dakr@kernel.org>
On Tue, Oct 21, 2025 at 12:34:22AM +0200, Danilo Krummrich wrote:
> tl;dr:
>
> Implement a safe Device<Bound>::drvdata() accessor (used for driver to
> driver interactions) based on the auxiliary bus.
>
> This provides a way to derive a driver's device private data when
> serving as a parent in a driver hierarchy, such as a driver utilizing
> the auxiliary bus.
>
> Please have a look at patch 8 ("samples: rust: auxiliary: illustrate
> driver interaction") to see how it turns out.
>
> --
>
> Full cover letter:
>
> In C dev_get_drvdata() has specific requirements under which it is valid
> to access the returned pointer. That is, drivers have to ensure that
>
> (1) for the duration the returned pointer is accessed the driver is
> bound and remains to be bound to the corresponding device,
>
> (2) the returned void * is treated according to the driver's private
> data type, i.e. according to what has been passed to
> dev_set_drvdata().
>
> In Rust, (1) can be ensured by simply requiring the Bound device
> context, i.e. provide the drvdata() method for Device<Bound> only.
>
> For (2) we would usually make the device type generic over the driver
> type, e.g. Device<T: Driver>, where <T as Driver>::Data is the type of
> the driver's private data.
>
> However, a device does not have a driver type known at compile time and
> may be bound to multiple drivers throughout its lifetime.
>
> Hence, in order to be able to provide a safe accessor for the driver's
> device private data, we have to do the type check on runtime.
>
> This is achieved by letting a driver assert the expected type, which is
> then compared to a type hash stored in struct device_private when
> dev_set_drvdata() is called [2].
>
> Example:
>
> // `dev` is a `&Device<Bound>`.
> let data = dev.drvdata::<SampleDriver>()?;
>
> There are two aspects to note:
>
> (1) Technically, the same check could be achieved by comparing the
> struct device_driver pointer of struct device with the struct
> device_driver pointer of the driver struct (e.g. struct
> pci_driver).
>
> However, this would - in addition the pointer comparison - require
> to tie back the private driver data type to the struct
> device_driver pointer of the driver struct to prove correctness.
>
> Besides that, accessing the driver struct (stored in the module
> structure) isn't trivial and would result into horrible code and
> API ergonomics.
>
> (2) Having a direct accessor to the driver's private data is not
> commonly required (at least in Rust): Bus callback methods already
> provide access to the driver's device private data through a &self
> argument, while other driver entry points such as IRQs,
> workqueues, timers, IOCTLs, etc. have their own private data with
> separate ownership and lifetime.
>
> In other words, a driver's device private data is only relevant
> for driver model contexts (such a file private is only relevant
> for file contexts).
>
> Having that said, the motivation for accessing the driver's device
> private data with Device<Bound>::drvdata() are interactions between
> drivers. For instance, when an auxiliary driver calls back into its
> parent, the parent has to be capable to derive its private data from the
> corresponding device (i.e. the parent of the auxiliary device).
>
> Therefore this patch series also contains the corresponding patches for
> the auxiliary bus abstraction, i.e. guarantee that the auxiliary
> device's parent is guaranteed to be bound when the auxiliary device
> itself is guaranteed to be bound, plus the corresponding
> Device<Bound>::parent() method.
>
> Finally, illustrate how things turn out by updating the auxiliary sample
> driver.
>
> Similarly, the same thing can be done for PCI virtual function drivers
> calling back into the corresponding physical function driver or MFD.
>
> The former (PCI PF/VF interaction) will be addressed by a separate patch
> series. Both, auxiliary and PCI PF/VF is required by the Nova project.
>
> A branch containing the series can be found in [1].
>
> [1] https://git.kernel.org/pub/scm/linux/kernel/git/dakr/linux.git/log/?h=drvdata
> [2] Type hash (TypeId) stored in struct device_private:
>
> The Rust type stored in struct device_private could be replaced
> by a dedicated (and transparent) private pointer (e.g.
> struct device_private::rust).
>
> While I'm not overly concerned about the extra allocation (not a
> hot path at all), I still wanted to try to store it directly in
> struct device_private, see how it turns out and gather opinions.
>
> Additionally, I don't expect any additional Rust specific
> private data to be required. But even if, changing things up to
> use a separate transparent allocation in the future is trivial.
>
> Danilo Krummrich (8):
> rust: device: narrow the generic of drvdata_obtain()
> rust: device: introduce Device::drvdata()
> rust: auxiliary: consider auxiliary devices always have a parent
> rust: auxiliary: unregister on parent device unbind
> rust: auxiliary: move parent() to impl Device
> rust: auxiliary: implement parent() for Device<Bound>
> samples: rust: auxiliary: misc cleanup of ParentDriver::connect()
> samples: rust: auxiliary: illustrate driver interaction
>
> drivers/base/base.h | 16 ++++
> drivers/gpu/drm/nova/file.rs | 2 +-
> drivers/gpu/nova-core/driver.rs | 8 +-
> rust/bindings/bindings_helper.h | 6 ++
> rust/kernel/auxiliary.rs | 108 ++++++++++++++++----------
> rust/kernel/device.rs | 83 ++++++++++++++++++--
> rust/kernel/pci.rs | 2 +-
> rust/kernel/platform.rs | 2 +-
> rust/kernel/usb.rs | 4 +-
> samples/rust/rust_driver_auxiliary.rs | 44 +++++++----
> 10 files changed, 207 insertions(+), 68 deletions(-)
It looks like there are some patches that add code that doesn't pass
rustfmt, which are then fixed in follow-up commits. You might want to do
a pass of rustfmt after each commit.
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
next prev parent reply other threads:[~2025-10-29 13:03 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-10-20 22:34 [PATCH 0/8] Device::drvdata() and driver/driver interaction (auxiliary) Danilo Krummrich
2025-10-20 22:34 ` [PATCH 1/8] rust: device: narrow the generic of drvdata_obtain() Danilo Krummrich
2025-11-03 6:43 ` Build error on -next in rust/kernel/usb.rs:92:34 (was: Re: [PATCH 1/8] rust: device: narrow the generic of drvdata_obtain()) Thorsten Leemhuis
2025-11-03 10:49 ` Build error on -next in rust/kernel/usb.rs:92:34 Danilo Krummrich
2025-10-20 22:34 ` [PATCH 2/8] rust: device: introduce Device::drvdata() Danilo Krummrich
2025-10-29 12:59 ` Alice Ryhl
2025-10-29 15:30 ` Danilo Krummrich
2025-10-29 17:02 ` Danilo Krummrich
2025-10-29 17:20 ` Alice Ryhl
2025-10-20 22:34 ` [PATCH 3/8] rust: auxiliary: consider auxiliary devices always have a parent Danilo Krummrich
2025-10-20 22:34 ` [PATCH 4/8] rust: auxiliary: unregister on parent device unbind Danilo Krummrich
2025-10-20 22:34 ` [PATCH 5/8] rust: auxiliary: move parent() to impl Device Danilo Krummrich
2025-10-20 22:34 ` [PATCH 6/8] rust: auxiliary: implement parent() for Device<Bound> Danilo Krummrich
2025-10-20 22:34 ` [PATCH 7/8] samples: rust: auxiliary: misc cleanup of ParentDriver::connect() Danilo Krummrich
2025-10-20 22:34 ` [PATCH 8/8] samples: rust: auxiliary: illustrate driver interaction Danilo Krummrich
2025-10-21 7:08 ` [PATCH 0/8] Device::drvdata() and driver/driver interaction (auxiliary) Greg KH
2025-10-29 13:03 ` Alice Ryhl [this message]
2025-10-29 15:33 ` Danilo Krummrich
2025-10-29 15:43 ` Danilo Krummrich
2025-10-29 18:10 ` 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=aQIQl8lMhztucZhK@google.com \
--to=aliceryhl@google.com \
--cc=a.hindborg@kernel.org \
--cc=acourbot@nvidia.com \
--cc=alex.gaynor@gmail.com \
--cc=bhelgaas@google.com \
--cc=bjorn3_gh@protonmail.com \
--cc=boqun.feng@gmail.com \
--cc=dakr@kernel.org \
--cc=david.m.ertman@intel.com \
--cc=gary@garyguo.net \
--cc=gregkh@linuxfoundation.org \
--cc=ira.weiny@intel.com \
--cc=kwilczynski@kernel.org \
--cc=leon@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=lossin@kernel.org \
--cc=ojeda@kernel.org \
--cc=pcolberg@redhat.com \
--cc=rafael@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.