Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+25 -46
+17 -36
rust/kernel/debugfs/traits.rs
··· 4 4 //! Traits for rendering or updating values exported to DebugFS. 5 5 6 6 use crate::prelude::*; 7 + use crate::sync::atomic::{Atomic, AtomicBasicOps, AtomicType, Relaxed}; 7 8 use crate::sync::Mutex; 8 9 use crate::uaccess::UserSliceReader; 9 10 use core::fmt::{self, Debug, Formatter}; 10 11 use core::str::FromStr; 11 - use core::sync::atomic::{ 12 - AtomicI16, AtomicI32, AtomicI64, AtomicI8, AtomicIsize, AtomicU16, AtomicU32, AtomicU64, 13 - AtomicU8, AtomicUsize, Ordering, 14 - }; 15 12 16 13 /// A trait for types that can be written into a string. 17 14 /// ··· 63 66 } 64 67 } 65 68 66 - macro_rules! impl_reader_for_atomic { 67 - ($(($atomic_type:ty, $int_type:ty)),*) => { 68 - $( 69 - impl Reader for $atomic_type { 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])?; 69 + impl<T: AtomicType + FromStr> Reader for Atomic<T> 70 + where 71 + T::Repr: AtomicBasicOps, 72 + { 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])?; 77 80 78 - let s = core::str::from_utf8(&buf[..n]).map_err(|_| EINVAL)?; 79 - let val = s.trim().parse::<$int_type>().map_err(|_| EINVAL)?; 80 - self.store(val, Ordering::Relaxed); 81 - Ok(()) 82 - } 83 - } 84 - )* 85 - }; 81 + let s = core::str::from_utf8(&buf[..n]).map_err(|_| EINVAL)?; 82 + let val = s.trim().parse::<T>().map_err(|_| EINVAL)?; 83 + self.store(val, Relaxed); 84 + Ok(()) 85 + } 86 86 } 87 - 88 - impl_reader_for_atomic!( 89 - (AtomicI16, i16), 90 - (AtomicI32, i32), 91 - (AtomicI64, i64), 92 - (AtomicI8, i8), 93 - (AtomicIsize, isize), 94 - (AtomicU16, u16), 95 - (AtomicU32, u32), 96 - (AtomicU64, u64), 97 - (AtomicU8, u8), 98 - (AtomicUsize, usize) 99 - );
+5 -7
samples/rust/rust_debugfs.rs
··· 32 32 //! ``` 33 33 34 34 use core::str::FromStr; 35 - use core::sync::atomic::AtomicUsize; 36 - use core::sync::atomic::Ordering; 37 35 use kernel::c_str; 38 36 use kernel::debugfs::{Dir, File}; 39 37 use kernel::new_mutex; 40 38 use kernel::prelude::*; 39 + use kernel::sync::atomic::{Atomic, Relaxed}; 41 40 use kernel::sync::Mutex; 42 - 43 41 use kernel::{acpi, device::Core, of, platform, str::CString, types::ARef}; 44 42 45 43 kernel::module_platform_driver! { ··· 57 59 #[pin] 58 60 _compatible: File<CString>, 59 61 #[pin] 60 - counter: File<AtomicUsize>, 62 + counter: File<Atomic<usize>>, 61 63 #[pin] 62 64 inner: File<Mutex<Inner>>, 63 65 } ··· 107 109 ) -> Result<Pin<KBox<Self>>> { 108 110 let result = KBox::try_pin_init(RustDebugFs::new(pdev), GFP_KERNEL)?; 109 111 // We can still mutate fields through the files which are atomic or mutexed: 110 - result.counter.store(91, Ordering::Relaxed); 112 + result.counter.store(91, Relaxed); 111 113 { 112 114 let mut guard = result.inner.lock(); 113 115 guard.x = guard.y; ··· 118 120 } 119 121 120 122 impl RustDebugFs { 121 - fn build_counter(dir: &Dir) -> impl PinInit<File<AtomicUsize>> + '_ { 122 - dir.read_write_file(c_str!("counter"), AtomicUsize::new(0)) 123 + fn build_counter(dir: &Dir) -> impl PinInit<File<Atomic<usize>>> + '_ { 124 + dir.read_write_file(c_str!("counter"), Atomic::<usize>::new(0)) 123 125 } 124 126 125 127 fn build_inner(dir: &Dir) -> impl PinInit<File<Mutex<Inner>>> + '_ {
+3 -3
samples/rust/rust_debugfs_scoped.rs
··· 6 6 //! `Scope::dir` to create a variety of files without the need to separately 7 7 //! track them all. 8 8 9 - use core::sync::atomic::AtomicUsize; 10 9 use kernel::debugfs::{Dir, Scope}; 11 10 use kernel::prelude::*; 11 + use kernel::sync::atomic::Atomic; 12 12 use kernel::sync::Mutex; 13 13 use kernel::{c_str, new_mutex, str::CString}; 14 14 ··· 62 62 let file_name = CString::try_from_fmt(fmt!("{name_str}"))?; 63 63 for sub in items { 64 64 nums.push( 65 - AtomicUsize::new(sub.parse().map_err(|_| EINVAL)?), 65 + Atomic::<usize>::new(sub.parse().map_err(|_| EINVAL)?), 66 66 GFP_KERNEL, 67 67 )?; 68 68 } ··· 109 109 110 110 struct DeviceData { 111 111 name: CString, 112 - nums: KVec<AtomicUsize>, 112 + nums: KVec<Atomic<usize>>, 113 113 } 114 114 115 115 fn init_control(base_dir: &Dir, dyn_dirs: Dir) -> impl PinInit<Scope<ModuleData>> + '_ {