Skip to content

Commit f74cf39

Browse files
committed
rust: debugfs: Replace the usage of Rust native atomics
Rust native atomics are not allowed to use in kernel due to the mismatch of memory model with Linux kernel memory model, hence remove the usage of Rust native atomics in debufs. Reviewed-by: Matthew Maurer <mmaurer@google.com> Acked-by: Danilo Krummrich <dakr@kernel.org> Tested-by: David Gow <davidgow@google.com> Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Boqun Feng <boqun.feng@gmail.com> Link: https://patch.msgid.link/20251022035324.70785-4-boqun.feng@gmail.com
1 parent 013f912 commit f74cf39

3 files changed

Lines changed: 25 additions & 46 deletions

File tree

rust/kernel/debugfs/traits.rs

Lines changed: 17 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,11 @@
44
//! Traits for rendering or updating values exported to DebugFS.
55
66
use crate::prelude::*;
7+
use crate::sync::atomic::{Atomic, AtomicBasicOps, AtomicType, Relaxed};
78
use crate::sync::Mutex;
89
use crate::uaccess::UserSliceReader;
910
use core::fmt::{self, Debug, Formatter};
1011
use core::str::FromStr;
11-
use core::sync::atomic::{
12-
AtomicI16, AtomicI32, AtomicI64, AtomicI8, AtomicIsize, AtomicU16, AtomicU32, AtomicU64,
13-
AtomicU8, AtomicUsize, Ordering,
14-
};
1512

1613
/// A trait for types that can be written into a string.
1714
///
@@ -66,37 +63,21 @@ impl<T: FromStr + Unpin> Reader for Mutex<T> {
6663
}
6764
}
6865

69-
macro_rules! impl_reader_for_atomic {
70-
($(($atomic_type:ty, $int_type:ty)),*) => {
71-
$(
72-
impl Reader for $atomic_type {
73-
fn read_from_slice(&self, reader: &mut UserSliceReader) -> Result {
74-
let mut buf = [0u8; 21]; // Enough for a 64-bit number.
75-
if reader.len() > buf.len() {
76-
return Err(EINVAL);
77-
}
78-
let n = reader.len();
79-
reader.read_slice(&mut buf[..n])?;
66+
impl<T: AtomicType + FromStr> Reader for Atomic<T>
67+
where
68+
T::Repr: AtomicBasicOps,
69+
{
70+
fn read_from_slice(&self, reader: &mut UserSliceReader) -> Result {
71+
let mut buf = [0u8; 21]; // Enough for a 64-bit number.
72+
if reader.len() > buf.len() {
73+
return Err(EINVAL);
74+
}
75+
let n = reader.len();
76+
reader.read_slice(&mut buf[..n])?;
8077

81-
let s = core::str::from_utf8(&buf[..n]).map_err(|_| EINVAL)?;
82-
let val = s.trim().parse::<$int_type>().map_err(|_| EINVAL)?;
83-
self.store(val, Ordering::Relaxed);
84-
Ok(())
85-
}
86-
}
87-
)*
88-
};
78+
let s = core::str::from_utf8(&buf[..n]).map_err(|_| EINVAL)?;
79+
let val = s.trim().parse::<T>().map_err(|_| EINVAL)?;
80+
self.store(val, Relaxed);
81+
Ok(())
82+
}
8983
}
90-
91-
impl_reader_for_atomic!(
92-
(AtomicI16, i16),
93-
(AtomicI32, i32),
94-
(AtomicI64, i64),
95-
(AtomicI8, i8),
96-
(AtomicIsize, isize),
97-
(AtomicU16, u16),
98-
(AtomicU32, u32),
99-
(AtomicU64, u64),
100-
(AtomicU8, u8),
101-
(AtomicUsize, usize)
102-
);

samples/rust/rust_debugfs.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,12 @@
3232
//! ```
3333
3434
use core::str::FromStr;
35-
use core::sync::atomic::AtomicUsize;
36-
use core::sync::atomic::Ordering;
3735
use kernel::c_str;
3836
use kernel::debugfs::{Dir, File};
3937
use kernel::new_mutex;
4038
use kernel::prelude::*;
39+
use kernel::sync::atomic::{Atomic, Relaxed};
4140
use kernel::sync::Mutex;
42-
4341
use kernel::{acpi, device::Core, of, platform, str::CString, types::ARef};
4442

4543
kernel::module_platform_driver! {
@@ -59,7 +57,7 @@ struct RustDebugFs {
5957
#[pin]
6058
_compatible: File<CString>,
6159
#[pin]
62-
counter: File<AtomicUsize>,
60+
counter: File<Atomic<usize>>,
6361
#[pin]
6462
inner: File<Mutex<Inner>>,
6563
}
@@ -109,7 +107,7 @@ impl platform::Driver for RustDebugFs {
109107
) -> Result<Pin<KBox<Self>>> {
110108
let result = KBox::try_pin_init(RustDebugFs::new(pdev), GFP_KERNEL)?;
111109
// We can still mutate fields through the files which are atomic or mutexed:
112-
result.counter.store(91, Ordering::Relaxed);
110+
result.counter.store(91, Relaxed);
113111
{
114112
let mut guard = result.inner.lock();
115113
guard.x = guard.y;
@@ -120,8 +118,8 @@ impl platform::Driver for RustDebugFs {
120118
}
121119

122120
impl RustDebugFs {
123-
fn build_counter(dir: &Dir) -> impl PinInit<File<AtomicUsize>> + '_ {
124-
dir.read_write_file(c_str!("counter"), AtomicUsize::new(0))
121+
fn build_counter(dir: &Dir) -> impl PinInit<File<Atomic<usize>>> + '_ {
122+
dir.read_write_file(c_str!("counter"), Atomic::<usize>::new(0))
125123
}
126124

127125
fn build_inner(dir: &Dir) -> impl PinInit<File<Mutex<Inner>>> + '_ {

samples/rust/rust_debugfs_scoped.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66
//! `Scope::dir` to create a variety of files without the need to separately
77
//! track them all.
88
9-
use core::sync::atomic::AtomicUsize;
109
use kernel::debugfs::{Dir, Scope};
1110
use kernel::prelude::*;
11+
use kernel::sync::atomic::Atomic;
1212
use kernel::sync::Mutex;
1313
use kernel::{c_str, new_mutex, str::CString};
1414

@@ -62,7 +62,7 @@ fn create_file_write(
6262
let file_name = CString::try_from_fmt(fmt!("{name_str}"))?;
6363
for sub in items {
6464
nums.push(
65-
AtomicUsize::new(sub.parse().map_err(|_| EINVAL)?),
65+
Atomic::<usize>::new(sub.parse().map_err(|_| EINVAL)?),
6666
GFP_KERNEL,
6767
)?;
6868
}
@@ -109,7 +109,7 @@ impl ModuleData {
109109

110110
struct DeviceData {
111111
name: CString,
112-
nums: KVec<AtomicUsize>,
112+
nums: KVec<Atomic<usize>>,
113113
}
114114

115115
fn init_control(base_dir: &Dir, dyn_dirs: Dir) -> impl PinInit<Scope<ModuleData>> + '_ {

0 commit comments

Comments
 (0)