Skip to content

Commit bee8e1d

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 db31011 commit bee8e1d

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
@@ -66,7 +66,7 @@ const __LOG_PREFIX: &[u8] = b"rust_kernel\0";
6666
/// The top level entrypoint to implementing a kernel module.
6767
///
6868
/// For any teardown or cleanup operations, your type may implement [`Drop`].
69-
pub trait Module: Sized + Sync {
69+
pub trait Module: Sized + Sync + Send {
7070
/// Called at module initialization time.
7171
///
7272
/// Use this method to perform whatever setup or registration your module
@@ -76,6 +76,29 @@ pub trait Module: Sized + Sync {
7676
fn init(module: &'static ThisModule) -> error::Result<Self>;
7777
}
7878

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