Commit f74cf399 authored by Boqun Feng's avatar Boqun Feng
Browse files

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: default avatarMatthew Maurer <mmaurer@google.com>
Acked-by: default avatarDanilo Krummrich <dakr@kernel.org>
Tested-by: default avatarDavid Gow <davidgow@google.com>
Acked-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: default avatarBoqun Feng <boqun.feng@gmail.com>
Link: https://patch.msgid.link/20251022035324.70785-4-boqun.feng@gmail.com
parent 013f912e
Loading
Loading
Loading
Loading
+17 −36
Original line number Diff line number Diff line
@@ -4,14 +4,11 @@
//! Traits for rendering or updating values exported to DebugFS.

use crate::prelude::*;
use crate::sync::atomic::{Atomic, AtomicBasicOps, AtomicType, Relaxed};
use crate::sync::Mutex;
use crate::uaccess::UserSliceReader;
use core::fmt::{self, Debug, Formatter};
use core::str::FromStr;
use core::sync::atomic::{
    AtomicI16, AtomicI32, AtomicI64, AtomicI8, AtomicIsize, AtomicU16, AtomicU32, AtomicU64,
    AtomicU8, AtomicUsize, Ordering,
};

/// A trait for types that can be written into a string.
///
@@ -66,10 +63,10 @@ fn read_from_slice(&self, reader: &mut UserSliceReader) -> Result {
    }
}

macro_rules! impl_reader_for_atomic {
    ($(($atomic_type:ty, $int_type:ty)),*) => {
        $(
            impl Reader for $atomic_type {
impl<T: AtomicType + FromStr> Reader for Atomic<T>
where
    T::Repr: AtomicBasicOps,
{
    fn read_from_slice(&self, reader: &mut UserSliceReader) -> Result {
        let mut buf = [0u8; 21]; // Enough for a 64-bit number.
        if reader.len() > buf.len() {
@@ -79,24 +76,8 @@ fn read_from_slice(&self, reader: &mut UserSliceReader) -> Result {
        reader.read_slice(&mut buf[..n])?;

        let s = core::str::from_utf8(&buf[..n]).map_err(|_| EINVAL)?;
                    let val = s.trim().parse::<$int_type>().map_err(|_| EINVAL)?;
                    self.store(val, Ordering::Relaxed);
        let val = s.trim().parse::<T>().map_err(|_| EINVAL)?;
        self.store(val, Relaxed);
        Ok(())
    }
}
        )*
    };
}

impl_reader_for_atomic!(
    (AtomicI16, i16),
    (AtomicI32, i32),
    (AtomicI64, i64),
    (AtomicI8, i8),
    (AtomicIsize, isize),
    (AtomicU16, u16),
    (AtomicU32, u32),
    (AtomicU64, u64),
    (AtomicU8, u8),
    (AtomicUsize, usize)
);
+5 −7
Original line number Diff line number Diff line
@@ -32,14 +32,12 @@
//! ```

use core::str::FromStr;
use core::sync::atomic::AtomicUsize;
use core::sync::atomic::Ordering;
use kernel::c_str;
use kernel::debugfs::{Dir, File};
use kernel::new_mutex;
use kernel::prelude::*;
use kernel::sync::atomic::{Atomic, Relaxed};
use kernel::sync::Mutex;

use kernel::{acpi, device::Core, of, platform, str::CString, types::ARef};

kernel::module_platform_driver! {
@@ -59,7 +57,7 @@ struct RustDebugFs {
    #[pin]
    _compatible: File<CString>,
    #[pin]
    counter: File<AtomicUsize>,
    counter: File<Atomic<usize>>,
    #[pin]
    inner: File<Mutex<Inner>>,
}
@@ -109,7 +107,7 @@ fn probe(
    ) -> Result<Pin<KBox<Self>>> {
        let result = KBox::try_pin_init(RustDebugFs::new(pdev), GFP_KERNEL)?;
        // We can still mutate fields through the files which are atomic or mutexed:
        result.counter.store(91, Ordering::Relaxed);
        result.counter.store(91, Relaxed);
        {
            let mut guard = result.inner.lock();
            guard.x = guard.y;
@@ -120,8 +118,8 @@ fn probe(
}

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

    fn build_inner(dir: &Dir) -> impl PinInit<File<Mutex<Inner>>> + '_ {
+3 −3
Original line number Diff line number Diff line
@@ -6,9 +6,9 @@
//! `Scope::dir` to create a variety of files without the need to separately
//! track them all.

use core::sync::atomic::AtomicUsize;
use kernel::debugfs::{Dir, Scope};
use kernel::prelude::*;
use kernel::sync::atomic::Atomic;
use kernel::sync::Mutex;
use kernel::{c_str, new_mutex, str::CString};

@@ -62,7 +62,7 @@ fn create_file_write(
    let file_name = CString::try_from_fmt(fmt!("{name_str}"))?;
    for sub in items {
        nums.push(
            AtomicUsize::new(sub.parse().map_err(|_| EINVAL)?),
            Atomic::<usize>::new(sub.parse().map_err(|_| EINVAL)?),
            GFP_KERNEL,
        )?;
    }
@@ -109,7 +109,7 @@ fn init(device_dir: Dir) -> impl PinInit<Self> {

struct DeviceData {
    name: CString,
    nums: KVec<AtomicUsize>,
    nums: KVec<Atomic<usize>>,
}

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