From 7f15c46a57c31956591f85b713d7e63cccb25556 Mon Sep 17 00:00:00 2001 From: Wedson Almeida Filho Date: Tue, 22 Oct 2024 23:31:39 +0200 Subject: rust: introduce `InPlaceModule` This allows modules to be initialised in-place in pinned memory, which enables the usage of pinned types (e.g., mutexes, spinlocks, driver registrations, etc.) in modules without any extra allocations. Signed-off-by: Wedson Almeida Filho Signed-off-by: Danilo Krummrich Acked-by: Miguel Ojeda Link: https://lore.kernel.org/r/20241022213221.2383-3-dakr@kernel.org Signed-off-by: Greg Kroah-Hartman --- rust/kernel/lib.rs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'rust/kernel/lib.rs') diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs index 8a228bcbbe85..638c8db4ce54 100644 --- a/rust/kernel/lib.rs +++ b/rust/kernel/lib.rs @@ -82,6 +82,29 @@ pub trait Module: Sized + Sync + Send { fn init(module: &'static ThisModule) -> error::Result; } +/// A module that is pinned and initialised in-place. +pub trait InPlaceModule: Sync + Send { + /// Creates an initialiser for the module. + /// + /// It is called when the module is loaded. + fn init(module: &'static ThisModule) -> impl init::PinInit; +} + +impl InPlaceModule for T { + fn init(module: &'static ThisModule) -> impl init::PinInit { + let initer = move |slot: *mut Self| { + let m = ::init(module)?; + + // SAFETY: `slot` is valid for write per the contract with `pin_init_from_closure`. + unsafe { slot.write(m) }; + Ok(()) + }; + + // SAFETY: On success, `initer` always fully initialises an instance of `Self`. + unsafe { init::pin_init_from_closure(initer) } + } +} + /// Equivalent to `THIS_MODULE` in the C API. /// /// C header: [`include/linux/export.h`](srctree/include/linux/export.h) -- cgit v1.2.3