From: Danilo Krummrich Date: Mon, 25 May 2026 20:20:59 +0000 (+0200) Subject: rust: pci: make Driver trait lifetime-parameterized X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=16c2b8fdab7c0808ff36430b2f49569029a8f484;p=thirdparty%2Fkernel%2Flinux.git rust: pci: make Driver trait lifetime-parameterized Add a 'bound lifetime to the associated Data, changing type Data to type Data<'bound>. This allows the driver's bus device private data to capture the device / driver bound lifetime; device resources can be stored directly by reference rather than requiring Devres. The probe() and unbind() callbacks thus gain a 'bound lifetime parameter on the methods themselves; avoiding a global lifetime on the trait impl. Existing drivers set type Data<'bound> = Self, preserving the current behavior. Reviewed-by: Alexandre Courbot Reviewed-by: Greg Kroah-Hartman Reviewed-by: Gary Guo Link: https://patch.msgid.link/20260525202921.124698-13-dakr@kernel.org Signed-off-by: Danilo Krummrich --- diff --git a/drivers/gpu/nova-core/driver.rs b/drivers/gpu/nova-core/driver.rs index 13c5ff15e87fa..6ad1a856694ce 100644 --- a/drivers/gpu/nova-core/driver.rs +++ b/drivers/gpu/nova-core/driver.rs @@ -74,10 +74,13 @@ kernel::pci_device_table!( impl pci::Driver for NovaCore { type IdInfo = (); - type Data = Self; + type Data<'bound> = Self; const ID_TABLE: pci::IdTable = &PCI_TABLE; - fn probe(pdev: &pci::Device>, _info: &Self::IdInfo) -> impl PinInit { + fn probe<'bound>( + pdev: &'bound pci::Device>, + _info: &'bound Self::IdInfo, + ) -> impl PinInit + 'bound { pin_init::pin_init_scope(move || { dev_dbg!(pdev, "Probe Nova Core GPU driver.\n"); @@ -109,7 +112,7 @@ impl pci::Driver for NovaCore { }) } - fn unbind(pdev: &pci::Device>, this: Pin<&Self>) { + fn unbind<'bound>(pdev: &'bound pci::Device>, this: Pin<&Self>) { this.gpu.unbind(pdev.as_ref()); } } diff --git a/rust/kernel/pci.rs b/rust/kernel/pci.rs index 314ad9fefdb0b..5071cae6543fd 100644 --- a/rust/kernel/pci.rs +++ b/rust/kernel/pci.rs @@ -64,7 +64,7 @@ pub struct Adapter(T); // - `DEVICE_DRIVER_OFFSET` is the correct byte offset to the embedded `struct device_driver`. unsafe impl driver::DriverLayout for Adapter { type DriverType = bindings::pci_driver; - type DriverData<'bound> = T::Data; + type DriverData<'bound> = T::Data<'bound>; const DEVICE_DRIVER_OFFSET: usize = core::mem::offset_of!(Self::DriverType, driver); } @@ -129,8 +129,8 @@ impl Adapter { // SAFETY: `remove_callback` is only ever called after a successful call to // `probe_callback`, hence it's guaranteed that `Device::set_drvdata()` has been called - // and stored a `Pin>`. - let data = unsafe { pdev.as_ref().drvdata_borrow::() }; + // and stored a `Pin>>`. + let data = unsafe { pdev.as_ref().drvdata_borrow::>() }; T::unbind(pdev, data); } @@ -279,13 +279,13 @@ macro_rules! pci_device_table { /// /// impl pci::Driver for MyDriver { /// type IdInfo = (); -/// type Data = Self; +/// type Data<'bound> = Self; /// const ID_TABLE: pci::IdTable = &PCI_TABLE; /// -/// fn probe( -/// _pdev: &pci::Device>, -/// _id_info: &Self::IdInfo, -/// ) -> impl PinInit { +/// fn probe<'bound>( +/// _pdev: &'bound pci::Device>, +/// _id_info: &'bound Self::IdInfo, +/// ) -> impl PinInit, Error> + 'bound { /// Err(ENODEV) /// } /// } @@ -302,7 +302,7 @@ pub trait Driver { type IdInfo: 'static; /// The type of the driver's bus device private data. - type Data: Send; + type Data<'bound>: Send + 'bound; /// The table of device ids supported by the driver. const ID_TABLE: IdTable; @@ -311,10 +311,10 @@ pub trait Driver { /// /// Called when a new pci device is added or discovered. Implementers should /// attempt to initialize the device here. - fn probe( - dev: &Device>, - id_info: &Self::IdInfo, - ) -> impl PinInit; + fn probe<'bound>( + dev: &'bound Device>, + id_info: &'bound Self::IdInfo, + ) -> impl PinInit, Error> + 'bound; /// PCI driver unbind. /// @@ -326,7 +326,7 @@ pub trait Driver { /// operations to gracefully tear down the device. /// /// Otherwise, release operations for driver resources should be performed in `Drop`. - fn unbind(dev: &Device>, this: Pin<&Self::Data>) { + fn unbind<'bound>(dev: &'bound Device>, this: Pin<&Self::Data<'bound>>) { let _ = (dev, this); } } diff --git a/samples/rust/rust_dma.rs b/samples/rust/rust_dma.rs index 9a243e7c72989..c4d2d36602aff 100644 --- a/samples/rust/rust_dma.rs +++ b/samples/rust/rust_dma.rs @@ -58,10 +58,13 @@ kernel::pci_device_table!( impl pci::Driver for DmaSampleDriver { type IdInfo = (); - type Data = Self; + type Data<'bound> = Self; const ID_TABLE: pci::IdTable = &PCI_TABLE; - fn probe(pdev: &pci::Device>, _info: &Self::IdInfo) -> impl PinInit { + fn probe<'bound>( + pdev: &'bound pci::Device>, + _info: &'bound Self::IdInfo, + ) -> impl PinInit + 'bound { pin_init::pin_init_scope(move || { dev_info!(pdev, "Probe DMA test driver.\n"); diff --git a/samples/rust/rust_driver_auxiliary.rs b/samples/rust/rust_driver_auxiliary.rs index f0d419823f9a3..0e979f45cd680 100644 --- a/samples/rust/rust_driver_auxiliary.rs +++ b/samples/rust/rust_driver_auxiliary.rs @@ -69,11 +69,14 @@ kernel::pci_device_table!( impl pci::Driver for ParentDriver { type IdInfo = (); - type Data = Self; + type Data<'bound> = Self; const ID_TABLE: pci::IdTable = &PCI_TABLE; - fn probe(pdev: &pci::Device>, _info: &Self::IdInfo) -> impl PinInit { + fn probe<'bound>( + pdev: &'bound pci::Device>, + _info: &'bound Self::IdInfo, + ) -> impl PinInit + 'bound { Ok(Self { _reg0: auxiliary::Registration::new( pdev.as_ref(), diff --git a/samples/rust/rust_driver_pci.rs b/samples/rust/rust_driver_pci.rs index 3106f766fd932..6791d98e1c79f 100644 --- a/samples/rust/rust_driver_pci.rs +++ b/samples/rust/rust_driver_pci.rs @@ -140,11 +140,14 @@ impl SampleDriver { impl pci::Driver for SampleDriver { type IdInfo = TestIndex; - type Data = Self; + type Data<'bound> = Self; const ID_TABLE: pci::IdTable = &PCI_TABLE; - fn probe(pdev: &pci::Device>, info: &Self::IdInfo) -> impl PinInit { + fn probe<'bound>( + pdev: &'bound pci::Device>, + info: &'bound Self::IdInfo, + ) -> impl PinInit + 'bound { pin_init::pin_init_scope(move || { let vendor = pdev.vendor_id(); dev_dbg!(