On Sun, Jun 28, 2026 at 04:53:20PM +0200, Danilo Krummrich wrote:
> DRM ioctls run in process context without any guarantee that the parent
> bus device is still bound. This series solves the problem by introducing
> RegistrationGuard -- a guard representing a drm_dev_enter/exit SRCU
> critical section that proves the parent bus device is bound for the
> lifetime of the guard.
> 
> As initial plumbing for this, the DRM DeviceContext typestates are
> reworked: Uninit is renamed to Normal, defaults are adjusted,
> AlwaysRefCounted is restricted to Normal, and a Deref chain from
> Device<T, Registered> to Device<T, Normal> is established. This gives
> Device<T, Registered> the semantic that the device is currently
> registered and the parent bus device is bound, which makes the
> RegistrationGuard and ioctl dispatch much cleaner. An Ioctl context
> restricts registration_guard() to ioctl dispatch, where the DRM core
> guarantees prior registration.
> 
> On top of that, add RegistrationData as a GAT (Generic Associated Type)
> on drm::Driver, allowing drivers to store data whose lifetime is tied to
> the parent bus device binding scope. The data is allocated in
> Registration::new(), lifetime-erased to 'static for storage, and made
> accessible through Device<T, Registered>::registration_data_with(). The
> closure's HRTB ties the lifetime to the closure scope; internally the
> 'static pointer is cast back to the closure-scoped lifetime. The
> reference is valid for the duration of the drm_dev_enter/exit critical
> section held by RegistrationGuard.
> 
> Also update the ioctl dispatch macro to wrap every handler in a
> RegistrationGuard, returning ENODEV if the device has been unplugged,
> and pass the registration data to handlers.
> 
> A branch with all patches can be found in [1].
> 
> [1] 
> https://git.kernel.org/pub/scm/linux/kernel/git/dakr/linux.git/log/?h=drm-lifetime

Thanks Danilo, I tested this whole series with Tyr today and it is
working for me without any issues. It's included in latest branch
https://gitlab.freedesktop.org/panfrost/linux/-/commits/tyr-for-upstream

Tested-by: Deborah Brouwer <[email protected]>

> 
> Changes in v5:
> - Replace __call_ioctl() helper with a simple for<'a> fn(...) coercion
> - Rebase onto latest drm-rust-next, which requires a faux::Device type with
>   AsBusDevice impl and motivates the removal of the DeviceContext generic from
>   shmem::Object entirely
> - Replace ForLt with a GAT type RegistrationData<'a>
> - Fix drm_dev_register() error path race on the C side
> - Add a few missing #[inline] annotations
> 
> Changes in v4:
> - Fix pre-existing unbounded lifetimes in ioctl handler arguments.
> - Fix registration_guard() being callable on unregistered devices by
>   introducing an Ioctl device context typestate; registration_guard() is
>   now only available on Device<T, Ioctl>, which is exclusively
>   constructed in ioctl dispatch context where the DRM core guarantees
>   prior registration.
> - Fix type inference allowing handlers to obtain Device<Registered>
>   before RegistrationGuard is acquired.
> - Make RegistrationGuard !Send via NotThreadSafe to prevent potential
>   lockdep splats from cross-thread SRCU unlock.
> - Store &Device<T, Registered> directly in RegistrationGuard instead of
>   calling assume_ctx() in Deref.
> 
> Changes in v3:
> - Rename UnbindGuard to RegistrationGuard
> - RegistrationGuard no longer dereferences to &Device<Bound>; it
>   dereferences to &drm::Device<T, Registered> instead
> - Drop Registration::new() and rename Registration::new_with_lt() to
>   Registration::new()
> - Rework DeviceContext typestates: rename Uninit to Normal, restrict
>   AlwaysRefCounted to Normal, establish Deref chain from Registered
>   to Normal
> - Add AsRef<ParentDevice<Bound>> on Device<T, Registered> for parent
>   device access
> - Move registration_data_with() from RegistrationGuard to
>   drm::Device<T, Registered>
> - Ioctl handlers no longer receive &Device<Bound>, only registration
>   data and drm::Device<T, Registered>
> - Use Device<Registered>::as_ref() to access parent device in nova-drm
> 
> Changes in v2:
> - Replace unsafe direct registration data access in ioctl dispatch with
>   safe UnbindGuard::registration_data_with() closure
> - Eliminate unbind_guard() free function; use type-inference anchor to
>   enable direct dev.unbind_guard() method call in the ioctl macro
> - UnbindGuard::registration_data_with() provides both parent device and
>   registration data to the closure
> - Add nova-drm conversion patch demonstrating lifetime-aware registration
>   data with &'bound auxiliary::Device<Bound>
> - Various safety comment and documentation improvements
> 
> Danilo Krummrich (19):
>   rust: drm: ioctl: fix unbounded lifetimes in ioctl handler arguments
>   rust: drm: rename Uninit DeviceContext to Normal
>   rust: faux: add Device type with AsBusDevice support
>   rust: drm: Add Driver::ParentDevice associated type
>   rust: drm: change default DeviceContext to Normal
>   rust: drm: restrict AlwaysRefCounted to Normal Device context
>   rust: drm: restrict AlwaysRefCounted to Normal GEM Object context
>   rust: drm/gem: remove DeviceContext from shmem::Object
>   rust: drm: split Deref for Device context typestates
>   rust: drm: pin ioctl Device reference to Normal context
>   rust: drm: add Ioctl device context typestate
>   rust: drm: Add RegistrationGuard for drm_dev_enter/exit critical
>     sections
>   rust: drm: Wrap ioctl dispatch in RegistrationGuard
>   rust: drm: return ParentDevice from Device AsRef
>   rust: drm: add AsRef<ParentDevice<Bound>> for Device<Registered>
>   drm: fix race between partial drm_dev_register() failure and ioctl
>   rust: drm: Add RegistrationData to drm::Driver
>   rust: drm: Pass registration data to ioctl handlers
>   drm: nova: Use drm::Device<Registered> to access the parent bus device
> 
>  drivers/gpu/drm/drm_drv.c        |  34 +++-
>  drivers/gpu/drm/nova/driver.rs   |  38 ++--
>  drivers/gpu/drm/nova/file.rs     |  22 ++-
>  drivers/gpu/drm/nova/gem.rs      |  18 +-
>  drivers/gpu/drm/tyr/driver.rs    |  25 ++-
>  drivers/gpu/drm/tyr/file.rs      |   8 +-
>  drivers/gpu/drm/tyr/gem.rs       |  11 +-
>  rust/kernel/drm/device.rs        | 293 +++++++++++++++++++++++--------
>  rust/kernel/drm/driver.rs        | 111 +++++++-----
>  rust/kernel/drm/gem/mod.rs       |  98 +++++------
>  rust/kernel/drm/gem/shmem.rs     | 257 +++++++++++++--------------
>  rust/kernel/drm/ioctl.rs         |  56 +++++-
>  rust/kernel/drm/mod.rs           |   4 +-
>  rust/kernel/faux.rs              |  69 ++++++--
>  samples/rust/rust_driver_faux.rs |   3 +-
>  15 files changed, 660 insertions(+), 387 deletions(-)
> 
> 
> base-commit: fa8cc4e3067f958ea2057f37a8a6f9c6b10a9c03
> -- 
> 2.54.0
> 

Reply via email to