Skip to content

Commit 675309b

Browse files
author
Valentin Obst
committed
rust: add in-place module
IMPORTANT: This work is by Wedson A.F.! This patch will not be send to the lists. If patches are send to the list, they will be based on a tree that contains these patches.
1 parent be6f418 commit 675309b

2 files changed

Lines changed: 30 additions & 13 deletions

File tree

rust/kernel/lib.rs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ const __LOG_PREFIX: &[u8] = b"rust_kernel\0";
6565
/// The top level entrypoint to implementing a kernel module.
6666
///
6767
/// For any teardown or cleanup operations, your type may implement [`Drop`].
68-
pub trait Module: Sized + Sync {
68+
pub trait Module: Sized + Sync + Send {
6969
/// Called at module initialization time.
7070
///
7171
/// Use this method to perform whatever setup or registration your module
@@ -75,6 +75,29 @@ pub trait Module: Sized + Sync {
7575
fn init(module: &'static ThisModule) -> error::Result<Self>;
7676
}
7777

78+
/// A module that is pinned and initialised in-place.
79+
pub trait InPlaceModule: Sync + Send {
80+
/// Creates an initialiser for the module.
81+
///
82+
/// It is called when the module is loaded.
83+
fn init(module: &'static ThisModule) -> impl init::PinInit<Self, error::Error>;
84+
}
85+
86+
impl<T: Module> InPlaceModule for T {
87+
fn init(module: &'static ThisModule) -> impl init::PinInit<Self, error::Error> {
88+
let initer = move |slot: *mut Self| {
89+
let m = <Self as Module>::init(module)?;
90+
91+
// SAFETY: `slot` is valid for write per the contract with `pin_init_from_closure`.
92+
unsafe { slot.write(m) };
93+
Ok(())
94+
};
95+
96+
// SAFETY: On success, `initer` always fully initialises an instance of `Self`.
97+
unsafe { init::pin_init_from_closure(initer) }
98+
}
99+
}
100+
78101
/// Equivalent to `THIS_MODULE` in the C API.
79102
///
80103
/// C header: [`include/linux/export.h`](srctree/include/linux/export.h)

rust/macros/module.rs

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ pub(crate) fn module(ts: TokenStream) -> TokenStream {
208208
#[used]
209209
static __IS_RUST_MODULE: () = ();
210210
211-
static mut __MOD: Option<{type_}> = None;
211+
static mut __MOD: core::mem::MaybeUninit<{type_}> = core::mem::MaybeUninit::uninit();
212212
213213
// SAFETY: `__this_module` is constructed by the kernel at load time and will not be
214214
// freed until the module is unloaded.
@@ -270,23 +270,17 @@ pub(crate) fn module(ts: TokenStream) -> TokenStream {
270270
}}
271271
272272
fn __init() -> core::ffi::c_int {{
273-
match <{type_} as kernel::Module>::init(&THIS_MODULE) {{
274-
Ok(m) => {{
275-
unsafe {{
276-
__MOD = Some(m);
277-
}}
278-
return 0;
279-
}}
280-
Err(e) => {{
281-
return e.to_errno();
282-
}}
273+
let initer = <{type_} as kernel::InPlaceModule>::init(&THIS_MODULE);
274+
match unsafe {{ initer.__pinned_init(__MOD.as_mut_ptr()) }} {{
275+
Ok(m) => 0,
276+
Err(e) => e.to_errno(),
283277
}}
284278
}}
285279
286280
fn __exit() {{
287281
unsafe {{
288282
// Invokes `drop()` on `__MOD`, which should be used for cleanup.
289-
__MOD = None;
283+
__MOD.assume_init_drop();
290284
}}
291285
}}
292286

0 commit comments

Comments
 (0)