---
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