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>>>,
> +}

Reply via email to