Thread (7 messages) 7 messages, 1 author, 2026-01-01

[PATCH RFC 6/6] rust: WIP: Replace ModuleMetadata with THIS_MODULE

STALE276d

From: Kari Argillander <hidden>
Date: 2026-01-01 05:21:57
Also in: lkml, rust-for-linux
Subsystem: auxiliary bus driver, core driver for nvidia gpus [rust], driver core, kobjects, debugfs and sysfs, drm drivers, drm drivers and common infrastructure [rust], firmware loader (request_firmware), i2c subsystem [rust], module support, pci subsystem [rust], rust, the rest, usb subsystem · Maintainers: Greg Kroah-Hartman, "Rafael J. Wysocki", Danilo Krummrich, Alexandre Courbot, David Airlie, Simona Vetter, Alice Ryhl, Luis Chamberlain, Igor Korotin, Petr Pavlu, Daniel Gomez, Sami Tolvanen, Miguel Ojeda, Linus Torvalds

ModuleMetadata seems redudant after we have prober THIS_MODULE.
---
 drivers/gpu/nova-core/nova_core.rs    |  2 +-
 rust/kernel/auxiliary.rs              | 10 +++++++---
 rust/kernel/driver.rs                 | 10 ++++------
 rust/kernel/firmware.rs               |  2 +-
 rust/kernel/i2c.rs                    |  4 ++--
 rust/kernel/lib.rs                    |  8 ++------
 rust/kernel/pci.rs                    |  6 +++---
 rust/kernel/platform.rs               |  4 ++--
 rust/kernel/usb.rs                    |  6 +++---
 rust/macros/module.rs                 | 13 +++++++------
 samples/rust/rust_driver_auxiliary.rs |  6 +++---
 11 files changed, 35 insertions(+), 36 deletions(-)
diff --git a/drivers/gpu/nova-core/nova_core.rs b/drivers/gpu/nova-core/nova_core.rs
index b98a1c03f13d..fbfbcc9446c0 100644
--- a/drivers/gpu/nova-core/nova_core.rs
+++ b/drivers/gpu/nova-core/nova_core.rs
@@ -19,7 +19,7 @@
 mod util;
 mod vbios;
 
-pub(crate) const MODULE_NAME: &kernel::str::CStr = <LocalModule as kernel::ModuleMetadata>::NAME;
+pub(crate) const MODULE_NAME: &kernel::str::CStr = THIS_MODULE::name();
 
 kernel::module_pci_driver! {
     type: driver::NovaCore,
diff --git a/rust/kernel/auxiliary.rs b/rust/kernel/auxiliary.rs
index 323074322505..bd064b677c05 100644
--- a/rust/kernel/auxiliary.rs
+++ b/rust/kernel/auxiliary.rs
@@ -27,10 +27,10 @@
 unsafe impl<T: Driver + 'static> driver::RegistrationOps for Adapter<T> {
     type RegType = bindings::auxiliary_driver;
 
-    unsafe fn register<M: ThisModule>(adrv: &Opaque<Self::RegType>, name: &'static CStr) -> Result {
+    unsafe fn register<M: ThisModule>(adrv: &Opaque<Self::RegType>) -> Result {
         // SAFETY: It's safe to set the fields of `struct auxiliary_driver` on initialization.
         unsafe {
-            (*adrv.get()).name = name.as_char_ptr();
+            (*adrv.get()).name = M::NAME.as_char_ptr();
             (*adrv.get()).probe = Some(Self::probe_callback);
             (*adrv.get()).remove = Some(Self::remove_callback);
             (*adrv.get()).id_table = T::ID_TABLE.as_ptr();
@@ -38,7 +38,11 @@ unsafe fn register<M: ThisModule>(adrv: &Opaque<Self::RegType>, name: &'static C
 
         // SAFETY: `adrv` is guaranteed to be a valid `RegType`.
         to_result(unsafe {
-            bindings::__auxiliary_driver_register(adrv.get(), M::OWNER.as_ptr(), name.as_char_ptr())
+            bindings::__auxiliary_driver_register(
+                adrv.get(),
+                M::OWNER.as_ptr(),
+                M::NAME.as_char_ptr(),
+            )
         })
     }
 
diff --git a/rust/kernel/driver.rs b/rust/kernel/driver.rs
index 7c4ad24bb48a..5bb029075a57 100644
--- a/rust/kernel/driver.rs
+++ b/rust/kernel/driver.rs
@@ -118,7 +118,7 @@ pub unsafe trait RegistrationOps {
     ///
     /// On success, `reg` must remain pinned and valid until the matching call to
     /// [`RegistrationOps::unregister`].
-    unsafe fn register<M: ThisModule>(reg: &Opaque<Self::RegType>, name: &'static CStr) -> Result;
+    unsafe fn register<M: ThisModule>(reg: &Opaque<Self::RegType>) -> Result;
 
     /// Unregisters a driver previously registered with [`RegistrationOps::register`].
     ///
@@ -151,7 +151,7 @@ unsafe impl<T: RegistrationOps> Send for Registration<T> {}
 
 impl<T: RegistrationOps> Registration<T> {
     /// Creates a new instance of the registration object.
-    pub fn new<M: ThisModule>(name: &'static CStr) -> impl PinInit<Self, Error> {
+    pub fn new<M: ThisModule>() -> impl PinInit<Self, Error> {
         try_pin_init!(Self {
             reg <- Opaque::try_ffi_init(|ptr: *mut T::RegType| {
                 // SAFETY: `try_ffi_init` guarantees that `ptr` is valid for write.
@@ -162,7 +162,7 @@ pub fn new<M: ThisModule>(name: &'static CStr) -> impl PinInit<Self, Error> {
                 let drv = unsafe { &*(ptr as *const Opaque<T::RegType>) };
 
                 // SAFETY: `drv` is guaranteed to be pinned until `T::unregister`.
-                unsafe { T::register::<M>(drv, name) }
+                unsafe { T::register::<M>(drv) }
             }),
         })
     }
@@ -195,9 +195,7 @@ struct DriverModule {
         impl $crate::InPlaceModule for DriverModule {
             fn init<M: ::kernel::ThisModule>() -> impl ::pin_init::PinInit<Self, $crate::error::Error> {
                 $crate::try_pin_init!(Self {
-                    _driver <- $crate::driver::Registration::new::<M>(
-                        <Self as $crate::ModuleMetadata>::NAME,
-                    ),
+                    _driver <- $crate::driver::Registration::new::<M>(),
                 })
             }
         }
diff --git a/rust/kernel/firmware.rs b/rust/kernel/firmware.rs
index 71168d8004e2..254b5c6b64af 100644
--- a/rust/kernel/firmware.rs
+++ b/rust/kernel/firmware.rs
@@ -206,7 +206,7 @@ macro_rules! module_firmware {
             const __MODULE_FIRMWARE_PREFIX: &'static $crate::str::CStr = if cfg!(MODULE) {
                 c""
             } else {
-                <LocalModule as $crate::ModuleMetadata>::NAME
+                THIS_MODULE::name()
             };
 
             #[link_section = ".modinfo"]
diff --git a/rust/kernel/i2c.rs b/rust/kernel/i2c.rs
index bc154506b16f..31db4d45bab1 100644
--- a/rust/kernel/i2c.rs
+++ b/rust/kernel/i2c.rs
@@ -97,7 +97,7 @@ macro_rules! i2c_device_table {
 unsafe impl<T: Driver + 'static> driver::RegistrationOps for Adapter<T> {
     type RegType = bindings::i2c_driver;
 
-    unsafe fn register<M: ThisModule>(idrv: &Opaque<Self::RegType>, name: &'static CStr) -> Result {
+    unsafe fn register<M: ThisModule>(idrv: &Opaque<Self::RegType>) -> Result {
         build_assert!(
             T::ACPI_ID_TABLE.is_some() || T::OF_ID_TABLE.is_some() || T::I2C_ID_TABLE.is_some(),
             "At least one of ACPI/OF/Legacy tables must be present when registering an i2c driver"
@@ -120,7 +120,7 @@ unsafe fn register<M: ThisModule>(idrv: &Opaque<Self::RegType>, name: &'static C
 
         // SAFETY: It's safe to set the fields of `struct i2c_client` on initialization.
         unsafe {
-            (*idrv.get()).driver.name = name.as_char_ptr();
+            (*idrv.get()).driver.name = M::NAME.as_char_ptr();
             (*idrv.get()).probe = Some(Self::probe_callback);
             (*idrv.get()).remove = Some(Self::remove_callback);
             (*idrv.get()).shutdown = Some(Self::shutdown_callback);
diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs
index 6d4563662a02..3bae80a949d2 100644
--- a/rust/kernel/lib.rs
+++ b/rust/kernel/lib.rs
@@ -199,12 +199,6 @@ fn init<M: ThisModule>() -> impl pin_init::PinInit<Self, error::Error> {
     }
 }
 
-/// Metadata attached to a [`Module`] or [`InPlaceModule`].
-pub trait ModuleMetadata {
-    /// The name of the module as specified in the `module!` macro.
-    const NAME: &'static crate::str::CStr;
-}
-
 pub mod this_module {
     //! TODO
     //!
@@ -224,6 +218,8 @@ pub mod this_module {
     pub trait ThisModule {
         /// TODO Doc
         const OWNER: ModuleWrapper;
+        /// TODO Doc
+        const NAME: &'static kernel::str::CStr;
     }
 
     /// See [`this_module`]
diff --git a/rust/kernel/pci.rs b/rust/kernel/pci.rs
index 792560ca8020..b043d7a388d0 100644
--- a/rust/kernel/pci.rs
+++ b/rust/kernel/pci.rs
@@ -54,10 +54,10 @@
 unsafe impl<T: Driver + 'static> driver::RegistrationOps for Adapter<T> {
     type RegType = bindings::pci_driver;
 
-    unsafe fn register<M: ThisModule>(pdrv: &Opaque<Self::RegType>, name: &'static CStr) -> Result {
+    unsafe fn register<M: ThisModule>(pdrv: &Opaque<Self::RegType>) -> Result {
         // SAFETY: It's safe to set the fields of `struct pci_driver` on initialization.
         unsafe {
-            (*pdrv.get()).name = name.as_char_ptr();
+            (*pdrv.get()).name = M::NAME.as_char_ptr();
             (*pdrv.get()).probe = Some(Self::probe_callback);
             (*pdrv.get()).remove = Some(Self::remove_callback);
             (*pdrv.get()).id_table = T::ID_TABLE.as_ptr();
@@ -65,7 +65,7 @@ unsafe fn register<M: ThisModule>(pdrv: &Opaque<Self::RegType>, name: &'static C
 
         // SAFETY: `pdrv` is guaranteed to be a valid `RegType`.
         to_result(unsafe {
-            bindings::__pci_register_driver(pdrv.get(), M::OWNER.as_ptr(), name.as_char_ptr())
+            bindings::__pci_register_driver(pdrv.get(), M::OWNER.as_ptr(), M::NAME.as_char_ptr())
         })
     }
 
diff --git a/rust/kernel/platform.rs b/rust/kernel/platform.rs
index 67d46231600e..27f196a140e5 100644
--- a/rust/kernel/platform.rs
+++ b/rust/kernel/platform.rs
@@ -30,7 +30,7 @@
 unsafe impl<T: Driver + 'static> driver::RegistrationOps for Adapter<T> {
     type RegType = bindings::platform_driver;
 
-    unsafe fn register<M: ThisModule>(pdrv: &Opaque<Self::RegType>, name: &'static CStr) -> Result {
+    unsafe fn register<M: ThisModule>(pdrv: &Opaque<Self::RegType>) -> Result {
         let of_table = match T::OF_ID_TABLE {
             Some(table) => table.as_ptr(),
             None => core::ptr::null(),
@@ -43,7 +43,7 @@ unsafe fn register<M: ThisModule>(pdrv: &Opaque<Self::RegType>, name: &'static C
 
         // SAFETY: It's safe to set the fields of `struct platform_driver` on initialization.
         unsafe {
-            (*pdrv.get()).driver.name = name.as_char_ptr();
+            (*pdrv.get()).driver.name = M::NAME.as_char_ptr();
             (*pdrv.get()).probe = Some(Self::probe_callback);
             (*pdrv.get()).remove = Some(Self::remove_callback);
             (*pdrv.get()).driver.of_match_table = of_table;
diff --git a/rust/kernel/usb.rs b/rust/kernel/usb.rs
index c6ee98d12875..43259307986f 100644
--- a/rust/kernel/usb.rs
+++ b/rust/kernel/usb.rs
@@ -31,10 +31,10 @@
 unsafe impl<T: Driver + 'static> driver::RegistrationOps for Adapter<T> {
     type RegType = bindings::usb_driver;
 
-    unsafe fn register<M: ThisModule>(udrv: &Opaque<Self::RegType>, name: &'static CStr) -> Result {
+    unsafe fn register<M: ThisModule>(udrv: &Opaque<Self::RegType>) -> Result {
         // SAFETY: It's safe to set the fields of `struct usb_driver` on initialization.
         unsafe {
-            (*udrv.get()).name = name.as_char_ptr();
+            (*udrv.get()).name = M::NAME.as_char_ptr();
             (*udrv.get()).probe = Some(Self::probe_callback);
             (*udrv.get()).disconnect = Some(Self::disconnect_callback);
             (*udrv.get()).id_table = T::ID_TABLE.as_ptr();
@@ -42,7 +42,7 @@ unsafe fn register<M: ThisModule>(udrv: &Opaque<Self::RegType>, name: &'static C
 
         // SAFETY: `udrv` is guaranteed to be a valid `RegType`.
         to_result(unsafe {
-            bindings::usb_register_driver(udrv.get(), M::OWNER.as_ptr(), name.as_char_ptr())
+            bindings::usb_register_driver(udrv.get(), M::OWNER.as_ptr(), M::NAME.as_char_ptr())
         })
     }
 
diff --git a/rust/macros/module.rs b/rust/macros/module.rs
index 6b8753d122cc..6a1ce6435e8f 100644
--- a/rust/macros/module.rs
+++ b/rust/macros/module.rs
@@ -375,6 +375,13 @@ pub(crate) fn module(ts: TokenStream) -> TokenStream {
             #[allow(non_camel_case_types)]
             pub struct THIS_MODULE;
 
+            impl THIS_MODULE {{
+                /// Returns the name of this module.
+                pub const fn name() -> &'static ::kernel::str::CStr {{
+                    c\"{name}\"
+                }}
+            }}
+
             impl ::kernel::prelude::ThisModule for THIS_MODULE {{
                 #[cfg(not(MODULE))] 
                 const OWNER: ::kernel::this_module::ModuleWrapper = unsafe {{
@@ -392,13 +399,7 @@ impl ::kernel::prelude::ThisModule for THIS_MODULE {{
                     
                     ::kernel::this_module::ModuleWrapper::from_ptr(__this_module.get())
                 }};
-            }}
-
-            /// The `LocalModule` type is the type of the module created by `module!`,
-            /// `module_pci_driver!`, `module_platform_driver!`, etc.
-            type LocalModule = {type_};
 
-            impl ::kernel::ModuleMetadata for {type_} {{
                 const NAME: &'static ::kernel::str::CStr = c\"{name}\";
             }}
 
diff --git a/samples/rust/rust_driver_auxiliary.rs b/samples/rust/rust_driver_auxiliary.rs
index e996dca19454..2f77b0873e81 100644
--- a/samples/rust/rust_driver_auxiliary.rs
+++ b/samples/rust/rust_driver_auxiliary.rs
@@ -18,7 +18,7 @@
 use core::any::TypeId;
 use pin_init::PinInit;
 
-const MODULE_NAME: &CStr = <LocalModule as kernel::ModuleMetadata>::NAME;
+const MODULE_NAME: &CStr = THIS_MODULE::name();
 const AUXILIARY_NAME: &CStr = c_str!("auxiliary");
 
 struct AuxiliaryDriver;
@@ -113,8 +113,8 @@ struct SampleModule {
 impl InPlaceModule for SampleModule {
     fn init<M: ThisModule>() -> impl PinInit<Self, Error> {
         try_pin_init!(Self {
-            _pci_driver <- driver::Registration::new::<M>(MODULE_NAME),
-            _aux_driver <- driver::Registration::new::<M>(MODULE_NAME),
+            _pci_driver <- driver::Registration::new::<M>(),
+            _aux_driver <- driver::Registration::new::<M>(),
         })
     }
 }
-- 
2.43.0
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help