Messages in this thread |  | | Date | Thu, 7 May 2026 14:14:36 +0200 | | From | Dirk Behme <> | | Subject | Re: [PATCH v2 00/25] rust: device: Higher-Ranked Lifetime Types for device drivers |
| |
On 06.05.2026 23:50, Danilo Krummrich wrote: > Currently, Rust device drivers access device resources such as PCI BAR mappings > and I/O memory regions through Devres<T>. > > Devres::access() provides zero-overhead access by taking a &Device<Bound> > reference as proof that the device is still bound. Since a &Device<Bound> is > available in almost all contexts by design, Devres is mostly a type-system level > proof that the resource is valid, but it can also be used from scopes without > this guarantee through its try_access() accessor. > > This works well in general, but has a few limitations: > > - Every access to a device resource goes through Devres::access(), which > despite zero cost, adds boilerplate to every access site. > > - Destructors do not receive a &Device<Bound>, so they must use try_access(), > which can fail. In practice the access succeeds if teardown ordering is > correct, but the type system can't express this, forcing drivers to handle a > failure path that should never be taken. > > - Sharing a resource across components (e.g. passing a BAR to a sub-component) > requires Arc<Devres<T>>. > > - Device references must be stored as ARef<Device> rather than plain &Device > borrows. > > These limitations stem from the driver's bus device private data being 'static > -- the driver struct cannot borrow from the device reference it receives in > probe(), even though it structurally cannot outlive the device binding. > > This series introduces Higher-Ranked Lifetime Types (HRT) for Rust device > drivers. An HRT is a type that is generic over a lifetime -- it does not have a > fixed lifetime, but can be instantiated with any lifetime chosen by the caller. > > Rust does not directly support types that are generic over a lifetime as type > parameters; the ForLt trait (contributed by Gary Guo) encodes this internally. > > The module_*_driver! macros handle the wrapping, so driver authors just write > struct MyDriver<'a> and impl Driver<'a>. > > With HRT, driver structs carry a lifetime parameter tied to the device binding > scope -- the interval of a bus device being bound to a driver. Device resources > like pci::Bar<'a> and IoMem<'a> are handed out with this lifetime, so the > compiler enforces at build time that they do not escape the binding scope. > > Before: > > struct MyDriver { > pdev: ARef<pci::Device>, > bar: Devres<pci::Bar<BAR_SIZE>>, > } > > let io = self.bar.access(dev)?; > io.read32(OFFSET); > > After: > > struct MyDriver<'a> { > pdev: &'a pci::Device, > bar: pci::Bar<'a, BAR_SIZE>, > } > > self.bar.read32(OFFSET); > > Lifetime-parameterized device resources can be put into a Devres at any point > via Bar::into_devres() / IoMem::into_devres(), providing the exact same > semantics as before. This is useful for resources shared across subsystem > boundaries where revocation is needed. > > This also synergizes with the upcoming self-referential initialization support > in pin-init, which allows one field of the driver struct to borrow another > during initialization without unsafe code. > > The same pattern is applied to auxiliary device registration data as a first > example beyond bus device private data. Registration<F: ForLt> can hold > lifetime-parameterized data tied to the parent driver's binding scope. Since the > auxiliary bus guarantees that the parent remains bound while the auxiliary > device is registered, the registration data can safely borrow the parent's > device resources. > > More generally, binding resource lifetimes to a registration scope applies to > every registration that is scoped to a driver binding -- auxiliary devices, > class devices, IRQ handlers, workqueues. > > A follow-up series extends this to class device registrations, starting with > DRM, so that class device callbacks (IOCTLs, etc.) can safely access device > resources through the separate registration data bound to the registration's > lifetime without Devres indirection. > > The series contains a few driver patches for reference, indicated by the REF > suffix. > > Thanks to Gary for coming up with the ForLt implementation; thanks to Alice for > the early discussions around lifetime-parameterized private data that helped > shape the direction of this work. > > This series depends on [1]. > > [1] https://lore.kernel.org/driver-core/20260505152400.3905096-1-dakr@kernel.org/
I have applied this series together with [1] on top of 7.1.0-rc1. I made some adaptions to local changes (e.g. my ARM64 TMU interrupt test) and boot tested it. Several parts this patch series touches (e.g. PCI, auxiliary, gpu) I might not use or even don't have it enabled. So I don't know if this is worth mentioning
Tested-by: Dirk Behme <dirk.behme@de.bosch.com>
Please feel free to ignore this, then.
Thanks
Dirk
> Changes in v2: > - Add 'a bound to ForLt::Of<'a> and WithLt::Of, making the lifetime bound > inherent to the trait; remove all F::Of<'static>: 'static where clauses > - Drop "rust: devres: add ForLt support to Devres"; Devres itself stays > unchanged -- ForLt-aware access is introduced later through DevresLt in a > separate series > - Use 'bound instead of 'a; add patches to consistently use 'bound for > pre-existing 'a > > Danilo Krummrich (24): > rust: driver core: drop drvdata before devres release > rust: device: generalize drvdata methods over ForLt > rust: driver: make Adapter trait lifetime-parameterized > rust: pci: implement Sync for Device<Bound> > rust: platform: implement Sync for Device<Bound> > rust: auxiliary: implement Sync for Device<Bound> > rust: usb: implement Sync for Device<Bound> > rust: device: implement Sync for Device<Bound> > rust: pci: make Driver trait lifetime-parameterized > rust: platform: make Driver trait lifetime-parameterized > rust: auxiliary: make Driver trait lifetime-parameterized > rust: auxiliary: generalize Registration over ForLt > samples: rust: rust_driver_auxiliary: showcase lifetime-bound > registration data > rust: usb: make Driver trait lifetime-parameterized > rust: i2c: make Driver trait lifetime-parameterized > rust: pci: make Bar lifetime-parameterized > rust: io: make IoMem and ExclusiveIoMem lifetime-parameterized > samples: rust: rust_driver_pci: use HRT lifetime for Bar > rust: driver-core: rename 'a lifetime to 'bound > gpu: nova-core: rename 'a lifetime to 'bound > gpu: nova-core: use HRT lifetime for Bar > gpu: nova-core: unregister sysmem flush page from Drop > gpu: nova-core: replace ARef<Device> with &'bound Device in > SysmemFlush > gpu: drm: tyr: use HRT lifetime for IoMem > > Gary Guo (1): > rust: types: add `ForLt` trait for higher-ranked lifetime support > > drivers/base/dd.c | 2 +- > drivers/cpufreq/rcpufreq_dt.rs | 10 +- > drivers/gpu/drm/nova/driver.rs | 9 +- > drivers/gpu/drm/tyr/driver.rs | 24 ++- > drivers/gpu/drm/tyr/gpu.rs | 62 +++--- > drivers/gpu/drm/tyr/regs.rs | 21 +- > drivers/gpu/nova-core/driver.rs | 48 ++--- > drivers/gpu/nova-core/fb.rs | 31 ++- > drivers/gpu/nova-core/firmware/gsp.rs | 8 +- > drivers/gpu/nova-core/gpu.rs | 38 ++-- > drivers/gpu/nova-core/gsp/commands.rs | 10 +- > drivers/gpu/nova-core/gsp/fw/commands.rs | 4 +- > drivers/gpu/nova-core/nova_core.rs | 4 +- > drivers/pwm/pwm_th1520.rs | 14 +- > include/linux/device/driver.h | 4 +- > rust/Makefile | 1 + > rust/kernel/auxiliary.rs | 132 +++++++++---- > rust/kernel/cpufreq.rs | 8 +- > rust/kernel/device.rs | 79 +++++--- > rust/kernel/devres.rs | 16 +- > rust/kernel/driver.rs | 44 +++-- > rust/kernel/i2c.rs | 130 +++++++----- > rust/kernel/io/mem.rs | 131 ++++++------ > rust/kernel/pci.rs | 89 ++++++--- > rust/kernel/pci/io.rs | 68 ++++--- > rust/kernel/pci/irq.rs | 38 ++-- > rust/kernel/platform.rs | 120 +++++++---- > rust/kernel/types.rs | 4 + > rust/kernel/types/for_lt.rs | 117 +++++++++++ > rust/kernel/usb.rs | 94 +++++---- > rust/macros/for_lt.rs | 242 +++++++++++++++++++++++ > rust/macros/lib.rs | 12 ++ > samples/rust/rust_debugfs.rs | 10 +- > samples/rust/rust_dma.rs | 9 +- > samples/rust/rust_driver_auxiliary.rs | 53 +++-- > samples/rust/rust_driver_i2c.rs | 18 +- > samples/rust/rust_driver_pci.rs | 93 ++++----- > samples/rust/rust_driver_platform.rs | 12 +- > samples/rust/rust_driver_usb.rs | 14 +- > samples/rust/rust_i2c_client.rs | 12 +- > samples/rust/rust_soc.rs | 12 +- > 41 files changed, 1220 insertions(+), 627 deletions(-) > create mode 100644 rust/kernel/types/for_lt.rs > create mode 100644 rust/macros/for_lt.rs >
|  |