On Sat Jun 20, 2026 at 7:48 PM BST, Danilo Krummrich wrote:
> Add a RegistrationData associated type to drm::Driver. This is a ForLt
> type whose lifetime is tied to the parent bus device binding scope.
> Registration<'a, T> takes ownership of the data via Pin<KBox<_>>,
> storing it with its real lifetime. The pointer is written to drm::Device
> before drm_dev_register() to ensure it is already in place when ioctls
> arrive.
>
> Device<T, Registered>::registration_data_with() provides access with the
> lifetime shortened from 'static via a pointer cast. Since
> Registration::drop() calls drm_dev_unplug(), which performs an SRCU
> barrier waiting for all drm_dev_enter() critical sections to complete,
> the data is guaranteed to remain valid for the duration of any
> RegistrationGuard.
>
> Signed-off-by: Danilo Krummrich <[email protected]>
> ---
> drivers/gpu/drm/nova/driver.rs | 20 +++++--
> drivers/gpu/drm/tyr/driver.rs | 18 ++++--
> rust/kernel/drm/device.rs | 49 +++++++++++++++
> rust/kernel/drm/driver.rs | 106 +++++++++++++++++++++------------
> 4 files changed, 143 insertions(+), 50 deletions(-)
>
> diff --git a/rust/kernel/drm/driver.rs b/rust/kernel/drm/driver.rs
> index ceb2829985c7..e42b48e5cad2 100644
> --- a/rust/kernel/drm/driver.rs
> +++ b/rust/kernel/drm/driver.rs
> @@ -7,11 +7,11 @@
> use crate::{
> bindings,
> device,
> - devres,
> drm,
> error::to_result,
> prelude::*,
> - sync::aref::ARef, //
> + sync::aref::ARef,
> + types::ForLt, //
> };
> use core::{
> mem,
> @@ -110,6 +110,16 @@ pub trait Driver {
> /// Context data associated with the DRM driver
> type Data: Sync + Send;
>
> + /// Data owned by the [`Registration`] and accessible within a
> + /// [`RegistrationGuard`](drm::RegistrationGuard) critical section via
> + ///
> [`Device::registration_data_with()`](drm::Device::registration_data_with).
> + ///
> + /// This is a [`ForLt`](trait@ForLt) type whose lifetime is tied to the
> parent bus
> + /// device binding scope. References handed out by
> + ///
> [`Device::registration_data_with()`](drm::Device::registration_data_with) are
> tied to
> + /// the closure scope.
> + type RegistrationData: ForLt;
This could just be a GAT instead of using `ForLt`. It'd also have the benefit of
being able to have `Sync + Send` directly here instead of sprinkle the bound
everywhere.
Best,
Gary
> +
> /// The type used to manage memory for this driver.
> type Object: AllocImpl;
>
> @@ -139,65 +149,82 @@ pub trait Driver {
> /// The registration type of a `drm::Device`.
> ///
> /// Once the `Registration` structure is dropped, the device is unregistered.
> -pub struct Registration<T: Driver>(ARef<drm::Device<T>>);
> -
> -impl<T: Driver> Registration<T> {
> - fn new(drm: drm::UnregisteredDevice<T>, flags: usize) -> Result<Self> {
> - // SAFETY: `drm.as_raw()` is valid by the invariants of
> `drm::Device`.
> - to_result(unsafe { bindings::drm_dev_register(drm.as_raw(), flags)
> })?;
> -
> - // SAFETY: We just called `drm_dev_register` above
> - let new = NonNull::from(unsafe { drm.assume_ctx() });
> -
> - // Leak the ARef from UnregisteredDevice in preparation for
> transferring its ownership.
> - mem::forget(drm);
> -
> - // SAFETY: `drm`'s `Drop` constructor was never called, ensuring
> that there remains at least
> - // one reference to the device - which we take ownership over here.
> - let new = unsafe { ARef::from_raw(new) };
> -
> - Ok(Self(new))
> - }
> +pub struct Registration<'a, T: Driver> {
> + drm: ARef<drm::Device<T>>,
> + _reg_data: Pin<KBox<<T::RegistrationData as ForLt>::Of<'a>>>,
> +}