diff --git a/rust/macros/module.rs b/rust/macros/module.rs index 6001fd692469be..c22634efebd53c 100644 --- a/rust/macros/module.rs +++ b/rust/macros/module.rs @@ -329,6 +329,7 @@ pub(crate) fn module(ts: TokenStream) -> TokenStream { assert_eq!(params.delimiter(), Delimiter::Brace); let mut it = params.stream().into_iter(); + let mut read_funcs = Vec::new(); loop { let param_name = match it.next() { @@ -388,7 +389,7 @@ pub(crate) fn module(ts: TokenStream) -> TokenStream { let read_func = if permissions_are_readonly(¶m_permissions) { format!( " - fn read(&self) + fn {param_name}(&self) -> &<{param_type_internal} as kernel::module_param::ModuleParam>::Value {{ // SAFETY: Parameters do not need to be locked because they are // read only or sysfs is not enabled. @@ -406,7 +407,7 @@ pub(crate) fn module(ts: TokenStream) -> TokenStream { } else { format!( " - fn read<'lck>(&self, lock: &'lck kernel::KParamGuard) + fn {param_name}<'lck>(&self, lock: &'lck kernel::KParamGuard) -> &'lck <{param_type_internal} as kernel::module_param::ModuleParam>::Value {{ // SAFETY: Parameters are locked by `KParamGuard`. unsafe {{ @@ -421,6 +422,8 @@ pub(crate) fn module(ts: TokenStream) -> TokenStream { param_type_internal = param_type_internal, ) }; + read_funcs.push(read_func); + let kparam = format!( " kernel::bindings::kernel_param__bindgen_ty_1 {{ @@ -436,12 +439,6 @@ pub(crate) fn module(ts: TokenStream) -> TokenStream { " static mut __{name}_{param_name}_value: {param_type_internal} = {param_default}; - struct __{name}_{param_name}; - - impl __{name}_{param_name} {{ {read_func} }} - - const {param_name}: __{name}_{param_name} = __{name}_{param_name}; - // Note: the C macro that generates the static structs for the `__param` section // asks for them to be `aligned(sizeof(void *))`. However, that was put in place // in 2003 in commit 38d5b085d2a0 (\"[PATCH] Fix over-alignment problem on x86-64\") @@ -483,7 +480,6 @@ pub(crate) fn module(ts: TokenStream) -> TokenStream { ", name = info.name, param_type_internal = param_type_internal, - read_func = read_func, param_default = param_default, param_name = param_name, ops = ops, @@ -492,6 +488,29 @@ pub(crate) fn module(ts: TokenStream) -> TokenStream { ) .unwrap(); } + + write!( + modinfo.buffer, + " + struct __MODPARAM; + + impl __MODPARAM {{ + " + ) + .unwrap(); + + read_funcs.iter().for_each(|read_func| { + writeln!(modinfo.buffer, "{}", read_func).unwrap(); + }); + + write!( + modinfo.buffer, + "}} + + const MODPARAM: __MODPARAM = __MODPARAM; + " + ) + .unwrap(); } let mut generated_array_types = String::new(); diff --git a/samples/rust/rust_module_parameters.rs b/samples/rust/rust_module_parameters.rs index 557cba7b4815d1..2804289660fa45 100644 --- a/samples/rust/rust_module_parameters.rs +++ b/samples/rust/rust_module_parameters.rs @@ -48,14 +48,14 @@ impl kernel::Module for RustModuleParameters { { let lock = module.kernel_param_lock(); pr_info!("Parameters:\n"); - pr_info!(" my_bool: {}\n", my_bool.read()); - pr_info!(" my_i32: {}\n", my_i32.read(&lock)); + pr_info!(" my_bool: {}\n", MODPARAM.my_bool()); + pr_info!(" my_i32: {}\n", MODPARAM.my_i32(&lock)); pr_info!( " my_str: {}\n", - core::str::from_utf8(my_str.read(&lock))? + core::str::from_utf8(MODPARAM.my_str(&lock))? ); - pr_info!(" my_usize: {}\n", my_usize.read(&lock)); - pr_info!(" my_array: {:?}\n", my_array.read()); + pr_info!(" my_usize: {}\n", MODPARAM.my_usize(&lock)); + pr_info!(" my_array: {:?}\n", MODPARAM.my_array()); } Ok(RustModuleParameters)