[PATCH RFC 2/6] rust: WIP: Introduce ThisModule trait and THIS_MODULE impl
STALE273d
From: Kari Argillander <hidden>
Date: 2026-01-01 05:21:37
Also in:
lkml, rust-for-linux
Subsystem:
module support, rust, the rest · Maintainers:
Luis Chamberlain, Petr Pavlu, Daniel Gomez, Sami Tolvanen, Miguel Ojeda, Linus Torvalds
--- rust/kernel/lib.rs | 61 +++++++++++++++++++++++++++++++++++---------------- rust/macros/module.rs | 36 ++++++++++++++++++------------ 2 files changed, 64 insertions(+), 33 deletions(-)
diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs
index 69a798fbb563..224410745734 100644
--- a/rust/kernel/lib.rs
+++ b/rust/kernel/lib.rs@@ -205,31 +205,54 @@ pub trait ModuleMetadata { const NAME: &'static crate::str::CStr; } -/// Equivalent to `THIS_MODULE` in the C API. -/// -/// C header: [`include/linux/init.h`](srctree/include/linux/init.h) -pub struct ThisModule(*mut bindings::module); +pub mod this_module { + //! TODO + //! + //! # For driver cretors + //! + //! For each module we define own custom THIS_MODULE in + //! [`macros::module::module`]. Mechanism is equivalent to `THIS_MODULE` in + //! the [C API](srctree/include/linux/init.h). + //! + //! TODO + //! + //! # For abstraction creators + //! + //! TODO -// SAFETY: `THIS_MODULE` may be used from all threads within a module. -unsafe impl Sync for ThisModule {} + /// See [`this_module`] + pub trait ThisModule { + /// TODO Doc + const OWNER: ModuleWrapper; + } -impl ThisModule { - /// Creates a [`ThisModule`] given the `THIS_MODULE` pointer. - /// - /// # Safety - /// - /// The pointer must be equal to the right `THIS_MODULE`. - pub const unsafe fn from_ptr(ptr: *mut bindings::module) -> ThisModule { - ThisModule(ptr) + /// See [`this_module`] + pub struct ModuleWrapper { + ptr: *mut bindings::module, } - /// Access the raw pointer for this module. - /// - /// It is up to the user to use it correctly. - pub const fn as_ptr(&self) -> *mut bindings::module { - self.0 + impl ModuleWrapper { + /// Get the raw pointer to the underlying `struct module`. + /// + /// TODO: Should be only available for kernel create. + pub const fn as_ptr(&self) -> *mut bindings::module { + self.ptr + } + + /// Only meant to use in [`macros::module::module`]. + /// + /// # Safety + /// + /// - Only modules are allowed to create non null `ModuleWrapper`s. + /// - The pointer must point to a valid `struct module` provided by the + /// kernel. + #[doc(hidden)] + pub const unsafe fn from_ptr(ptr: *mut bindings::module) -> Self { + ModuleWrapper { ptr } + } } } +pub use this_module::*; #[cfg(not(testlib))] #[panic_handler]
diff --git a/rust/macros/module.rs b/rust/macros/module.rs
index 80cb9b16f5aa..6b8753d122cc 100644
--- a/rust/macros/module.rs
+++ b/rust/macros/module.rs@@ -371,20 +371,28 @@ pub(crate) fn module(ts: TokenStream) -> TokenStream { /// Used by the printing macros, e.g. [`info!`]. const __LOG_PREFIX: &[u8] = b\"{name}\\0\"; - // SAFETY: `__this_module` is constructed by the kernel at load time and will not be - // freed until the module is unloaded. - #[cfg(MODULE)] - static THIS_MODULE: ::kernel::ThisModule = unsafe {{ - extern \"C\" {{ - static __this_module: ::kernel::types::Opaque<::kernel::bindings::module>; - }} + /// THIS_MODULE for \"{name}\". See more at [`kernel::this_module`]. + #[allow(non_camel_case_types)] + pub struct THIS_MODULE; + + impl ::kernel::prelude::ThisModule for THIS_MODULE {{ + #[cfg(not(MODULE))] + const OWNER: ::kernel::this_module::ModuleWrapper = unsafe {{ + ::kernel::this_module::ModuleWrapper::from_ptr(::core::ptr::null_mut()) + }}; - ::kernel::ThisModule::from_ptr(__this_module.get()) - }}; - #[cfg(not(MODULE))] - static THIS_MODULE: ::kernel::ThisModule = unsafe {{ - ::kernel::ThisModule::from_ptr(::core::ptr::null_mut()) - }}; + #[cfg(MODULE)] + // SAFETY: + // - `__this_module` is constructed by the kernel at module load time. + // - We use check that we are module so we can create non-null ModuleWrapper. + const OWNER: ::kernel::this_module::ModuleWrapper = unsafe {{ + extern \"C\" {{ + static __this_module: ::kernel::types::Opaque<::kernel::bindings::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.
@@ -502,7 +510,7 @@ mod __module_init {{ /// This function must only be called once. unsafe fn __init() -> ::kernel::ffi::c_int {{ let initer = - <{type_} as ::kernel::InPlaceModule>::init(&super::super::THIS_MODULE); + <{type_} as ::kernel::InPlaceModule>::init::<super::super::THIS_MODULE>(); // SAFETY: No data race, since `__MOD` can only be accessed by this module // and there only `__init` and `__exit` access it. These functions are only // called once and `__exit` cannot be called before or during `__init`.
--
2.43.0