Skip to content

Commit 70d0f68

Browse files
committed
Make interface independent of CONFIG_SYSFS
1 parent 29ec325 commit 70d0f68

File tree

6 files changed

+83
-157
lines changed

6 files changed

+83
-157
lines changed

drivers/char/rust_example.rs

Lines changed: 11 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -55,38 +55,21 @@ struct RustExample {
5555
_dev: Pin<Box<miscdev::Registration>>,
5656
}
5757

58-
#[cfg(CONFIG_SYSFS)]
59-
fn print_params() -> KernelResult<()> {
60-
let lock = THIS_MODULE.kernel_param_lock();
61-
println!("Parameters:");
62-
println!(" my_bool: {}", my_bool.nonlocking_read());
63-
println!(" my_i32: {}", my_i32.locking_read(&lock));
64-
println!(
65-
" my_str: {}",
66-
core::str::from_utf8(my_str.locking_read(&lock))?
67-
);
68-
println!(" my_invbool: {}", my_invbool.locking_read(&lock));
69-
Ok(())
70-
}
71-
72-
#[cfg(not(CONFIG_SYSFS))]
73-
fn print_params() -> KernelResult<()> {
74-
println!("Parameters:");
75-
println!(" my_bool: {}", my_bool.nonlocking_read());
76-
println!(" my_i32: {}", my_i32.nonlocking_read());
77-
println!(
78-
" my_str: {}",
79-
core::str::from_utf8(my_str.nonlocking_read())?
80-
);
81-
println!(" my_invbool: {}", my_invbool.nonlocking_read());
82-
Ok(())
83-
}
84-
8558
impl KernelModule for RustExample {
8659
fn init() -> KernelResult<Self> {
8760
println!("Rust Example (init)");
8861
println!("Am I built-in? {}", !cfg!(MODULE));
89-
print_params()?;
62+
{
63+
let lock = THIS_MODULE.kernel_param_lock();
64+
println!("Parameters:");
65+
println!(" my_bool: {}", my_bool.read());
66+
println!(" my_i32: {}", my_i32.read(&lock));
67+
println!(
68+
" my_str: {}",
69+
core::str::from_utf8(my_str.read(&lock))?
70+
);
71+
println!(" my_invbool: {}", my_invbool.read(&lock));
72+
}
9073

9174
// Including this large variable on the stack will trigger
9275
// stack probing on the supported archs.

drivers/char/rust_example_2.rs

Lines changed: 11 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -40,38 +40,21 @@ struct RustExample2 {
4040
message: String,
4141
}
4242

43-
#[cfg(CONFIG_SYSFS)]
44-
fn print_params() -> KernelResult<()> {
45-
let lock = THIS_MODULE.kernel_param_lock();
46-
println!("[2] Parameters:");
47-
println!("[2] my_bool: {}", my_bool.nonlocking_read());
48-
println!("[2] my_i32: {}", my_i32.locking_read(&lock));
49-
println!(
50-
"[2] my_str: {}",
51-
core::str::from_utf8(my_str.locking_read(&lock))?
52-
);
53-
println!("[2] my_invbool: {}", my_invbool.locking_read(&lock));
54-
Ok(())
55-
}
56-
57-
#[cfg(not(CONFIG_SYSFS))]
58-
fn print_params() -> KernelResult<()> {
59-
println!("[2] Parameters:");
60-
println!("[2] my_bool: {}", my_bool.nonlocking_read());
61-
println!("[2] my_i32: {}", my_i32.nonlocking_read());
62-
println!(
63-
"[2] my_str: {}",
64-
core::str::from_utf8(my_str.nonlocking_read())?
65-
);
66-
println!("[2] my_invbool: {}", my_invbool.nonlocking_read());
67-
Ok(())
68-
}
69-
7043
impl KernelModule for RustExample2 {
7144
fn init() -> KernelResult<Self> {
7245
println!("[2] Rust Example (init)");
7346
println!("[2] Am I built-in? {}", !cfg!(MODULE));
74-
print_params()?;
47+
{
48+
let lock = THIS_MODULE.kernel_param_lock();
49+
println!("[2] Parameters:");
50+
println!("[2] my_bool: {}", my_bool.read());
51+
println!("[2] my_i32: {}", my_i32.read(&lock));
52+
println!(
53+
"[2] my_str: {}",
54+
core::str::from_utf8(my_str.read(&lock))?
55+
);
56+
println!("[2] my_invbool: {}", my_invbool.read(&lock));
57+
}
7558

7659
// Including this large variable on the stack will trigger
7760
// stack probing on the supported archs.

drivers/char/rust_example_3.rs

Lines changed: 11 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -40,38 +40,21 @@ struct RustExample3 {
4040
message: String,
4141
}
4242

43-
#[cfg(CONFIG_SYSFS)]
44-
fn print_params() -> KernelResult<()> {
45-
let lock = THIS_MODULE.kernel_param_lock();
46-
println!("[3] Parameters:");
47-
println!("[3] my_bool: {}", my_bool.nonlocking_read());
48-
println!("[3] my_i32: {}", my_i32.locking_read(&lock));
49-
println!(
50-
"[3] my_str: {}",
51-
core::str::from_utf8(my_str.locking_read(&lock))?
52-
);
53-
println!("[3] my_invbool: {}", my_invbool.locking_read(&lock));
54-
Ok(())
55-
}
56-
57-
#[cfg(not(CONFIG_SYSFS))]
58-
fn print_params() -> KernelResult<()> {
59-
println!("[3] Parameters:");
60-
println!("[3] my_bool: {}", my_bool.nonlocking_read());
61-
println!("[3] my_i32: {}", my_i32.nonlocking_read());
62-
println!(
63-
"[3] my_str: {}",
64-
core::str::from_utf8(my_str.nonlocking_read())?
65-
);
66-
println!("[3] my_invbool: {}", my_invbool.nonlocking_read());
67-
Ok(())
68-
}
69-
7043
impl KernelModule for RustExample3 {
7144
fn init() -> KernelResult<Self> {
7245
println!("[3] Rust Example (init)");
7346
println!("[3] Am I built-in? {}", !cfg!(MODULE));
74-
print_params()?;
47+
{
48+
let lock = THIS_MODULE.kernel_param_lock();
49+
println!("[3] Parameters:");
50+
println!("[3] my_bool: {}", my_bool.read());
51+
println!("[3] my_i32: {}", my_i32.read(&lock));
52+
println!(
53+
"[3] my_str: {}",
54+
core::str::from_utf8(my_str.read(&lock))?
55+
);
56+
println!("[3] my_invbool: {}", my_invbool.read(&lock));
57+
}
7558

7659
// Including this large variable on the stack will trigger
7760
// stack probing on the supported archs.

drivers/char/rust_example_4.rs

Lines changed: 11 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -40,38 +40,21 @@ struct RustExample4 {
4040
message: String,
4141
}
4242

43-
#[cfg(CONFIG_SYSFS)]
44-
fn print_params() -> KernelResult<()> {
45-
let lock = THIS_MODULE.kernel_param_lock();
46-
println!("[4] Parameters:");
47-
println!("[4] my_bool: {}", my_bool.nonlocking_read());
48-
println!("[4] my_i32: {}", my_i32.locking_read(&lock));
49-
println!(
50-
"[4] my_str: {}",
51-
core::str::from_utf8(my_str.locking_read(&lock))?
52-
);
53-
println!("[4] my_invbool: {}", my_invbool.locking_read(&lock));
54-
Ok(())
55-
}
56-
57-
#[cfg(not(CONFIG_SYSFS))]
58-
fn print_params() -> KernelResult<()> {
59-
println!("[4] Parameters:");
60-
println!("[4] my_bool: {}", my_bool.nonlocking_read());
61-
println!("[4] my_i32: {}", my_i32.nonlocking_read());
62-
println!(
63-
"[4] my_str: {}",
64-
core::str::from_utf8(my_str.nonlocking_read())?
65-
);
66-
println!("[4] my_invbool: {}", my_invbool.nonlocking_read());
67-
Ok(())
68-
}
69-
7043
impl KernelModule for RustExample4 {
7144
fn init() -> KernelResult<Self> {
7245
println!("[4] Rust Example (init)");
7346
println!("[4] Am I built-in? {}", !cfg!(MODULE));
74-
print_params()?;
47+
{
48+
let lock = THIS_MODULE.kernel_param_lock();
49+
println!("[4] Parameters:");
50+
println!("[4] my_bool: {}", my_bool.read());
51+
println!("[4] my_i32: {}", my_i32.read(&lock));
52+
println!(
53+
"[4] my_str: {}",
54+
core::str::from_utf8(my_str.read(&lock))?
55+
);
56+
println!("[4] my_invbool: {}", my_invbool.read(&lock));
57+
}
7558

7659
// Including this large variable on the stack will trigger
7760
// stack probing on the supported archs.

rust/kernel/lib.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,12 @@ impl ThisModule {
6262
unsafe { bindings::kernel_param_lock(self.0) }
6363
KParamGuard { this_module: self }
6464
}
65+
66+
#[cfg(not(CONFIG_SYSFS))]
67+
/// Locking is not required when sysfs is not enabled.
68+
pub fn kernel_param_lock(&self) -> KParamGuard<'_> {
69+
KParamGuard { this_module: self }
70+
}
6571
}
6672

6773
/// Scoped lock on the kernel parameters of `ThisModule`. Lock will be released
@@ -72,11 +78,16 @@ pub struct KParamGuard<'a> {
7278

7379
#[cfg(CONFIG_SYSFS)]
7480
impl<'a> Drop for KParamGuard<'a> {
81+
#[cfg(CONFIG_SYSFS)]
7582
fn drop(&mut self) {
7683
// SAFETY: `kernel_param_lock` will check if the pointer is null and use the built-in mutex
7784
// in that case. The existance of `self` guarantees that the lock is held.
7885
unsafe { bindings::kernel_param_unlock(self.this_module.0) }
7986
}
87+
88+
#[cfg(not(CONFIG_SYSFS))]
89+
/// Unlocking is not required when sysfs is not enabled.
90+
fn drop(&mut self) {}
8091
}
8192

8293
extern "C" {

rust/module.rs

Lines changed: 28 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,11 @@ fn permissions_are_readonly(perms: &str) -> bool {
189189
/// params: {
190190
/// my_i32: i32 {
191191
/// default: 42,
192+
/// permissions: 0o000,
193+
/// description: b"Example of i32",
194+
/// },
195+
/// writeable_i32: i32 {
196+
/// default: 42,
192197
/// permissions: 0o644,
193198
/// description: b"Example of i32",
194199
/// },
@@ -199,15 +204,15 @@ fn permissions_are_readonly(perms: &str) -> bool {
199204
///
200205
/// impl KernelModule for MyKernelModule {
201206
/// fn init() -> KernelResult<Self> {
202-
/// // If `CONFIG_SYSFS` is enabled and the parameter is writeable, then
203-
/// // the kparam lock must be taken to read the parameter:
207+
/// // If the parameter is writeable, then the kparam lock must be
208+
/// // taken to read the parameter:
204209
/// {
205210
/// let lock = THIS_MODULE.kernel_param_lock();
206-
/// println!("i32 param is: {}", my_i32.nonlocking_read());
211+
/// println!("i32 param is: {}", writeable_i32.read(&lock));
207212
/// }
208-
/// // If `CONFIG_SYSFS` is not enabled or the parameter is read only, it
209-
/// // can be read without locking the kernel parameters:
210-
/// println!("i32 param is: {}", my_i32.nonlocking_read());
213+
/// // If the parameter is read only, it can be read without locking
214+
/// // the kernel parameters:
215+
/// println!("i32 param is: {}", my_i32.read());
211216
/// Ok(MyKernelModule)
212217
/// }
213218
/// }
@@ -305,10 +310,10 @@ pub fn module(ts: TokenStream) -> TokenStream {
305310
"str" => format!("b\"{}\0\" as *const _ as *mut kernel::c_types::c_char", param_default),
306311
_ => param_default,
307312
};
308-
let locking_read_func = match param_type.as_ref() {
309-
"str" => format!(
313+
let read_func = match (param_type.as_ref(), permissions_are_readonly(&param_permissions)) {
314+
("str", false) => format!(
310315
"
311-
fn locking_read<'par: 'val, 'lck: 'val, 'val>(&'par self, lock: &'lck kernel::KParamGuard) -> &'val [u8] {{
316+
fn read<'par: 'val, 'lck: 'val, 'val>(&'par self, lock: &'lck kernel::KParamGuard) -> &'val [u8] {{
312317
// SAFETY: The pointer is provided either in `param_default` when building the module,
313318
// or by the kernel through `param_set_charp`. Both will be valid C strings.
314319
// Parameters are locked by `KParamGuard`.
@@ -320,22 +325,9 @@ pub fn module(ts: TokenStream) -> TokenStream {
320325
name = name,
321326
param_name = param_name,
322327
),
323-
_ => format!(
324-
"
325-
// SAFETY: Parameters are locked by `KParamGuard`.
326-
fn locking_read<'par: 'val, 'lck: 'val, 'val>(&'par self, lock: &'lck kernel::KParamGuard) -> &'val {param_type_internal} {{
327-
unsafe {{ &__{name}_{param_name}_value }}
328-
}}
329-
",
330-
name = name,
331-
param_name = param_name,
332-
param_type_internal = param_type_internal,
333-
),
334-
};
335-
let nonlocking_read_func = match param_type.as_ref() {
336-
"str" => format!(
328+
("str", true) => format!(
337329
"
338-
fn nonlocking_read(&self) -> &[u8] {{
330+
fn read(&self) -> &[u8] {{
339331
// SAFETY: The pointer is provided either in `param_default` when building the module,
340332
// or by the kernel through `param_set_charp`. Both will be valid C strings.
341333
// Parameters do not need to be locked because they are read only or sysfs is not enabled.
@@ -347,37 +339,28 @@ pub fn module(ts: TokenStream) -> TokenStream {
347339
name = name,
348340
param_name = param_name,
349341
),
350-
_ => format!(
342+
(_, false) => format!(
351343
"
352-
// SAFETY: Parameters do not need to be locked because they are read only or sysfs is not enabled.
353-
fn nonlocking_read(&self) -> &{param_type_internal} {{
344+
// SAFETY: Parameters are locked by `KParamGuard`.
345+
fn read<'par: 'val, 'lck: 'val, 'val>(&'par self, lock: &'lck kernel::KParamGuard) -> &'val {param_type_internal} {{
354346
unsafe {{ &__{name}_{param_name}_value }}
355347
}}
356348
",
357349
name = name,
358350
param_name = param_name,
359351
param_type_internal = param_type_internal,
360352
),
361-
};
362-
let read_func = if permissions_are_readonly(&param_permissions) {
363-
format!(
353+
(_, true) => format!(
364354
"
365-
{locking_read_func}
366-
{nonlocking_read_func}
367-
",
368-
locking_read_func = locking_read_func,
369-
nonlocking_read_func = nonlocking_read_func
370-
)
371-
} else {
372-
format!(
373-
"
374-
{locking_read_func}
375-
#[cfg(not(CONFIG_SYSFS))]
376-
{nonlocking_read_func}
355+
// SAFETY: Parameters do not need to be locked because they are read only or sysfs is not enabled.
356+
fn read(&self) -> &{param_type_internal} {{
357+
unsafe {{ &__{name}_{param_name}_value }}
358+
}}
377359
",
378-
locking_read_func = locking_read_func,
379-
nonlocking_read_func = nonlocking_read_func,
380-
)
360+
name = name,
361+
param_name = param_name,
362+
param_type_internal = param_type_internal,
363+
),
381364
};
382365
let kparam = format!(
383366
"

0 commit comments

Comments
 (0)