rust-for-linux.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH V3 0/3] rust: Introduce CpuId and fix cpumask doctest
@ 2025-06-10 13:21 Viresh Kumar
  2025-06-10 13:21 ` [PATCH V3 1/3] rust: cpu: Introduce CpuId abstraction Viresh Kumar
                   ` (3 more replies)
  0 siblings, 4 replies; 12+ messages in thread
From: Viresh Kumar @ 2025-06-10 13:21 UTC (permalink / raw)
  To: Boqun Feng, Rafael J. Wysocki, Alex Gaynor, Alice Ryhl,
	Andreas Hindborg, Benno Lossin, Björn Roy Baron,
	Danilo Krummrich, Gary Guo, Miguel Ojeda, Peter Zijlstra,
	Thomas Gleixner, Trevor Gross, Viresh Kumar, Yury Norov
  Cc: Vincent Guittot, rust-for-linux, linux-kernel, linux-pm

Hello,

Here is another attempt at fixing the cpumask doctest. This series creates a new
abstraction `CpuId`, which is used to write a cleaner cpumask example which
doesn't fail in those corner cases.

Rebased over v6.16-rc1 + [1].

V2->V3:
- Include the separately sent patch as 3/3 and clarify about `unstable` CpuId.
- Add few debug_assert!().
- Improved comments, commit log.

V1->V2:
- Introduce CpuId.
- Use CpuId in cpufreq, opp, cpumask abstractions.
- Fix cpumask example.

--
Viresh

[1] https://lore.kernel.org/all/4823a58093c6dfa20df62b5c18da613621b9716e.1749554599.git.viresh.kumar@linaro.org/

Viresh Kumar (3):
  rust: cpu: Introduce CpuId abstraction
  rust: Use CpuId in place of raw CPU numbers
  rust: cpu: Add CpuId::current() to retrieve current CPU ID

 MAINTAINERS                    |   1 +
 drivers/cpufreq/rcpufreq_dt.rs |   4 +-
 rust/helpers/cpu.c             |   8 +++
 rust/helpers/helpers.c         |   1 +
 rust/kernel/cpu.rs             | 124 ++++++++++++++++++++++++++++++++-
 rust/kernel/cpufreq.rs         |  27 ++++---
 rust/kernel/cpumask.rs         |  51 ++++++++++----
 7 files changed, 189 insertions(+), 27 deletions(-)
 create mode 100644 rust/helpers/cpu.c


base-commit: 19272b37aa4f83ca52bdf9c16d5d81bdd1354494
prerequisite-patch-id: 1917103231ee798c4217f6da8bafa603b00e554c
-- 
2.31.1.272.g89b43f80a514


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH V3 1/3] rust: cpu: Introduce CpuId abstraction
  2025-06-10 13:21 [PATCH V3 0/3] rust: Introduce CpuId and fix cpumask doctest Viresh Kumar
@ 2025-06-10 13:21 ` Viresh Kumar
  2025-06-11 16:07   ` Boqun Feng
  2025-06-10 13:21 ` [PATCH V3 2/3] rust: Use CpuId in place of raw CPU numbers Viresh Kumar
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 12+ messages in thread
From: Viresh Kumar @ 2025-06-10 13:21 UTC (permalink / raw)
  To: Boqun Feng, Rafael J. Wysocki, Thomas Gleixner, Peter Zijlstra,
	Miguel Ojeda, Alex Gaynor, Gary Guo, Björn Roy Baron,
	Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
	Danilo Krummrich
  Cc: Viresh Kumar, Vincent Guittot, Yury Norov, rust-for-linux,
	linux-kernel

This adds abstraction for representing a CPU identifier.

Suggested-by: Boqun Feng <boqun.feng@gmail.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 rust/kernel/cpu.rs | 110 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 110 insertions(+)

diff --git a/rust/kernel/cpu.rs b/rust/kernel/cpu.rs
index 10c5c3b25873..6a3aecb12468 100644
--- a/rust/kernel/cpu.rs
+++ b/rust/kernel/cpu.rs
@@ -6,6 +6,116 @@
 
 use crate::{bindings, device::Device, error::Result, prelude::ENODEV};
 
+/// Returns the maximum number of possible CPUs in the current system configuration.
+#[inline]
+pub fn nr_cpu_ids() -> u32 {
+    #[cfg(any(NR_CPUS_1, CONFIG_FORCE_NR_CPUS))]
+    {
+        bindings::NR_CPUS
+    }
+
+    #[cfg(not(any(NR_CPUS_1, CONFIG_FORCE_NR_CPUS)))]
+    // SAFETY: `nr_cpu_ids` is a valid global provided by the kernel.
+    unsafe {
+        bindings::nr_cpu_ids
+    }
+}
+
+/// The CPU ID.
+///
+/// Represents a CPU identifier as a wrapper around an [`u32`].
+///
+/// # Invariants
+///
+/// The CPU ID lies within the range `[0, nr_cpu_ids())`.
+///
+/// # Examples
+///
+/// ```
+/// use kernel::cpu::CpuId;
+///
+/// let cpu = 0;
+///
+/// // SAFETY: 0 is always a valid CPU number.
+/// let id = unsafe { CpuId::from_u32_unchecked(cpu) };
+///
+/// assert_eq!(id.as_u32(), cpu);
+/// assert!(CpuId::from_i32(0).is_some());
+/// assert!(CpuId::from_i32(-1).is_none());
+/// ```
+#[derive(Copy, Clone, PartialEq, Eq, Debug)]
+pub struct CpuId(u32);
+
+impl CpuId {
+    /// Creates a new [`CpuId`] from the given `id` without checking bounds.
+    ///
+    /// # Safety
+    ///
+    /// The caller must ensure that `id` is a valid CPU ID (i.e., `0 <= id < nr_cpu_ids()`).
+    #[inline]
+    pub unsafe fn from_i32_unchecked(id: i32) -> Self {
+        debug_assert!(id >= 0);
+        debug_assert!((id as u32) < nr_cpu_ids());
+
+        // INVARIANT: The function safety guarantees `id` is a valid CPU id.
+        Self(id as u32)
+    }
+
+    /// Creates a new [`CpuId`] from the given `id`, checking that it is valid.
+    pub fn from_i32(id: i32) -> Option<Self> {
+        if id < 0 || id as u32 >= nr_cpu_ids() {
+            None
+        } else {
+            // INVARIANT: `id` has just been checked as a valid CPU ID.
+            Some(Self(id as u32))
+        }
+    }
+
+    /// Creates a new [`CpuId`] from the given `id` without checking bounds.
+    ///
+    /// # Safety
+    ///
+    /// The caller must ensure that `id` is a valid CPU ID (i.e., `0 <= id < nr_cpu_ids()`).
+    #[inline]
+    pub unsafe fn from_u32_unchecked(id: u32) -> Self {
+        debug_assert!(id < nr_cpu_ids());
+
+        // Ensure the `id` fits in an [`i32`] as it's also representable that way.
+        debug_assert!(id <= i32::MAX as u32);
+
+        // INVARIANT: The function safety guarantees `id` is a valid CPU id.
+        Self(id)
+    }
+
+    /// Creates a new [`CpuId`] from the given `id`, checking that it is valid.
+    pub fn from_u32(id: u32) -> Option<Self> {
+        if id >= nr_cpu_ids() {
+            None
+        } else {
+            // INVARIANT: `id` has just been checked as a valid CPU ID.
+            Some(Self(id))
+        }
+    }
+
+    /// Returns CPU number.
+    #[inline]
+    pub fn as_u32(&self) -> u32 {
+        self.0
+    }
+}
+
+impl From<CpuId> for u32 {
+    fn from(id: CpuId) -> Self {
+        id.as_u32()
+    }
+}
+
+impl From<CpuId> for i32 {
+    fn from(id: CpuId) -> Self {
+        id.as_u32() as i32
+    }
+}
+
 /// Creates a new instance of CPU's device.
 ///
 /// # Safety
-- 
2.31.1.272.g89b43f80a514


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH V3 2/3] rust: Use CpuId in place of raw CPU numbers
  2025-06-10 13:21 [PATCH V3 0/3] rust: Introduce CpuId and fix cpumask doctest Viresh Kumar
  2025-06-10 13:21 ` [PATCH V3 1/3] rust: cpu: Introduce CpuId abstraction Viresh Kumar
@ 2025-06-10 13:21 ` Viresh Kumar
  2025-06-11 16:12   ` Boqun Feng
  2025-06-10 13:21 ` [PATCH V3 3/3] rust: cpu: Add CpuId::current() to retrieve current CPU ID Viresh Kumar
  2025-06-10 17:10 ` [PATCH V3 0/3] rust: Introduce CpuId and fix cpumask doctest Miguel Ojeda
  3 siblings, 1 reply; 12+ messages in thread
From: Viresh Kumar @ 2025-06-10 13:21 UTC (permalink / raw)
  To: Boqun Feng, Rafael J. Wysocki, Viresh Kumar, Thomas Gleixner,
	Peter Zijlstra, Miguel Ojeda, Alex Gaynor, Gary Guo,
	Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
	Trevor Gross, Danilo Krummrich, Yury Norov
  Cc: Vincent Guittot, rust-for-linux, linux-pm, linux-kernel

Use the newly defined `CpuId` abstraction instead of raw CPU numbers.

This also fixes a doctest failure for configurations where `nr_cpu_ids <
4`.

The C `cpumask_{set|clear}_cpu()` APIs emit a warning when given an
invalid CPU number — but only if `CONFIG_DEBUG_PER_CPU_MAPS=y` is set.

Meanwhile, `cpumask_weight()` only considers CPUs up to `nr_cpu_ids`,
which can cause inconsistencies: a CPU number greater than `nr_cpu_ids`
may be set in the mask, yet the weight calculation won't reflect it.

This leads to doctest failures when `nr_cpu_ids < 4`, as the test tries
to set CPUs 2 and 3:

  rust_doctest_kernel_cpumask_rs_0.location: rust/kernel/cpumask.rs:180
  rust_doctest_kernel_cpumask_rs_0: ASSERTION FAILED at rust/kernel/cpumask.rs:190

Fixes: 8961b8cb3099 ("rust: cpumask: Add initial abstractions")
Reported-by: Miguel Ojeda <ojeda@kernel.org>
Closes: https://lore.kernel.org/rust-for-linux/CANiq72k3ozKkLMinTLQwvkyg9K=BeRxs1oYZSKhJHY-veEyZdg@mail.gmail.com/
Reported-by: Andreas Hindborg <a.hindborg@kernel.org>
Closes: https://lore.kernel.org/all/87qzzy3ric.fsf@kernel.org/
Suggested-by: Boqun Feng <boqun.feng@gmail.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 drivers/cpufreq/rcpufreq_dt.rs |  4 +--
 rust/kernel/cpu.rs             |  4 +--
 rust/kernel/cpufreq.rs         | 27 ++++++++++++------
 rust/kernel/cpumask.rs         | 51 ++++++++++++++++++++++++----------
 4 files changed, 59 insertions(+), 27 deletions(-)

diff --git a/drivers/cpufreq/rcpufreq_dt.rs b/drivers/cpufreq/rcpufreq_dt.rs
index 94ed81644fe1..43c87d0259b6 100644
--- a/drivers/cpufreq/rcpufreq_dt.rs
+++ b/drivers/cpufreq/rcpufreq_dt.rs
@@ -26,9 +26,9 @@ fn find_supply_name_exact(dev: &Device, name: &str) -> Option<CString> {
 }
 
 /// Finds supply name for the CPU from DT.
-fn find_supply_names(dev: &Device, cpu: u32) -> Option<KVec<CString>> {
+fn find_supply_names(dev: &Device, cpu: cpu::CpuId) -> Option<KVec<CString>> {
     // Try "cpu0" for older DTs, fallback to "cpu".
-    let name = (cpu == 0)
+    let name = (cpu.as_u32() == 0)
         .then(|| find_supply_name_exact(dev, "cpu0"))
         .flatten()
         .or_else(|| find_supply_name_exact(dev, "cpu"))?;
diff --git a/rust/kernel/cpu.rs b/rust/kernel/cpu.rs
index 6a3aecb12468..7549594fad7f 100644
--- a/rust/kernel/cpu.rs
+++ b/rust/kernel/cpu.rs
@@ -127,9 +127,9 @@ fn from(id: CpuId) -> Self {
 /// Callers must ensure that the CPU device is not used after it has been unregistered.
 /// This can be achieved, for example, by registering a CPU hotplug notifier and removing
 /// any references to the CPU device within the notifier's callback.
-pub unsafe fn from_cpu(cpu: u32) -> Result<&'static Device> {
+pub unsafe fn from_cpu(cpu: CpuId) -> Result<&'static Device> {
     // SAFETY: It is safe to call `get_cpu_device()` for any CPU.
-    let ptr = unsafe { bindings::get_cpu_device(cpu) };
+    let ptr = unsafe { bindings::get_cpu_device(cpu.into()) };
     if ptr.is_null() {
         return Err(ENODEV);
     }
diff --git a/rust/kernel/cpufreq.rs b/rust/kernel/cpufreq.rs
index 9b995f18aac6..ea6106db5c29 100644
--- a/rust/kernel/cpufreq.rs
+++ b/rust/kernel/cpufreq.rs
@@ -10,6 +10,7 @@
 
 use crate::{
     clk::Hertz,
+    cpu::CpuId,
     cpumask,
     device::{Bound, Device},
     devres::Devres,
@@ -465,8 +466,9 @@ fn as_mut_ref(&mut self) -> &mut bindings::cpufreq_policy {
 
     /// Returns the primary CPU for the [`Policy`].
     #[inline]
-    pub fn cpu(&self) -> u32 {
-        self.as_ref().cpu
+    pub fn cpu(&self) -> CpuId {
+        // SAFETY: The C API guarantees that `cpu` refers to a valid CPU number.
+        unsafe { CpuId::from_u32_unchecked(self.as_ref().cpu) }
     }
 
     /// Returns the minimum frequency for the [`Policy`].
@@ -525,7 +527,7 @@ pub fn generic_suspend(&mut self) -> Result {
     #[inline]
     pub fn generic_get(&self) -> Result<u32> {
         // SAFETY: By the type invariant, the pointer stored in `self` is valid.
-        Ok(unsafe { bindings::cpufreq_generic_get(self.cpu()) })
+        Ok(unsafe { bindings::cpufreq_generic_get(self.cpu().into()) })
     }
 
     /// Provides a wrapper to the register with energy model using the OPP core.
@@ -678,9 +680,9 @@ fn clear_data<T: ForeignOwnable>(&mut self) -> Option<T> {
 struct PolicyCpu<'a>(&'a mut Policy);
 
 impl<'a> PolicyCpu<'a> {
-    fn from_cpu(cpu: u32) -> Result<Self> {
+    fn from_cpu(cpu: CpuId) -> Result<Self> {
         // SAFETY: It is safe to call `cpufreq_cpu_get` for any valid CPU.
-        let ptr = from_err_ptr(unsafe { bindings::cpufreq_cpu_get(cpu) })?;
+        let ptr = from_err_ptr(unsafe { bindings::cpufreq_cpu_get(cpu.into()) })?;
 
         Ok(Self(
             // SAFETY: The `ptr` is guaranteed to be valid and remains valid for the lifetime of
@@ -1266,7 +1268,10 @@ impl<T: Driver> Registration<T> {
         target_perf: usize,
         capacity: usize,
     ) {
-        if let Ok(mut policy) = PolicyCpu::from_cpu(cpu) {
+        // SAFETY: The C API guarantees that `cpu` refers to a valid CPU number.
+        let cpu_id = unsafe { CpuId::from_u32_unchecked(cpu) };
+
+        if let Ok(mut policy) = PolicyCpu::from_cpu(cpu_id) {
             T::adjust_perf(&mut policy, min_perf, target_perf, capacity);
         }
     }
@@ -1321,7 +1326,10 @@ impl<T: Driver> Registration<T> {
     ///
     /// - This function may only be called from the cpufreq C infrastructure.
     unsafe extern "C" fn get_callback(cpu: u32) -> kernel::ffi::c_uint {
-        PolicyCpu::from_cpu(cpu).map_or(0, |mut policy| T::get(&mut policy).map_or(0, |f| f))
+        // SAFETY: The C API guarantees that `cpu` refers to a valid CPU number.
+        let cpu_id = unsafe { CpuId::from_u32_unchecked(cpu) };
+
+        PolicyCpu::from_cpu(cpu_id).map_or(0, |mut policy| T::get(&mut policy).map_or(0, |f| f))
     }
 
     /// Driver's `update_limit` callback.
@@ -1344,8 +1352,11 @@ impl<T: Driver> Registration<T> {
     /// - This function may only be called from the cpufreq C infrastructure.
     /// - The pointer arguments must be valid pointers.
     unsafe extern "C" fn bios_limit_callback(cpu: i32, limit: *mut u32) -> kernel::ffi::c_int {
+        // SAFETY: The C API guarantees that `cpu` refers to a valid CPU number.
+        let cpu_id = unsafe { CpuId::from_i32_unchecked(cpu) };
+
         from_result(|| {
-            let mut policy = PolicyCpu::from_cpu(cpu as u32)?;
+            let mut policy = PolicyCpu::from_cpu(cpu_id)?;
 
             // SAFETY: `limit` is guaranteed by the C code to be valid.
             T::bios_limit(&mut policy, &mut (unsafe { *limit })).map(|()| 0)
diff --git a/rust/kernel/cpumask.rs b/rust/kernel/cpumask.rs
index c90bfac9346a..11ddd43edcb5 100644
--- a/rust/kernel/cpumask.rs
+++ b/rust/kernel/cpumask.rs
@@ -6,6 +6,7 @@
 
 use crate::{
     alloc::{AllocError, Flags},
+    cpu::CpuId,
     prelude::*,
     types::Opaque,
 };
@@ -35,9 +36,10 @@
 ///
 /// ```
 /// use kernel::bindings;
+/// use kernel::cpu::CpuId;
 /// use kernel::cpumask::Cpumask;
 ///
-/// fn set_clear_cpu(ptr: *mut bindings::cpumask, set_cpu: u32, clear_cpu: i32) {
+/// fn set_clear_cpu(ptr: *mut bindings::cpumask, set_cpu: CpuId, clear_cpu: CpuId) {
 ///     // SAFETY: The `ptr` is valid for writing and remains valid for the lifetime of the
 ///     // returned reference.
 ///     let mask = unsafe { Cpumask::as_mut_ref(ptr) };
@@ -90,9 +92,9 @@ pub fn as_raw(&self) -> *mut bindings::cpumask {
     /// This mismatches kernel naming convention and corresponds to the C
     /// function `__cpumask_set_cpu()`.
     #[inline]
-    pub fn set(&mut self, cpu: u32) {
+    pub fn set(&mut self, cpu: CpuId) {
         // SAFETY: By the type invariant, `self.as_raw` is a valid argument to `__cpumask_set_cpu`.
-        unsafe { bindings::__cpumask_set_cpu(cpu, self.as_raw()) };
+        unsafe { bindings::__cpumask_set_cpu(cpu.into(), self.as_raw()) };
     }
 
     /// Clear `cpu` in the cpumask.
@@ -101,19 +103,19 @@ pub fn set(&mut self, cpu: u32) {
     /// This mismatches kernel naming convention and corresponds to the C
     /// function `__cpumask_clear_cpu()`.
     #[inline]
-    pub fn clear(&mut self, cpu: i32) {
+    pub fn clear(&mut self, cpu: CpuId) {
         // SAFETY: By the type invariant, `self.as_raw` is a valid argument to
         // `__cpumask_clear_cpu`.
-        unsafe { bindings::__cpumask_clear_cpu(cpu, self.as_raw()) };
+        unsafe { bindings::__cpumask_clear_cpu(cpu.into(), self.as_raw()) };
     }
 
     /// Test `cpu` in the cpumask.
     ///
     /// Equivalent to the kernel's `cpumask_test_cpu` API.
     #[inline]
-    pub fn test(&self, cpu: i32) -> bool {
+    pub fn test(&self, cpu: CpuId) -> bool {
         // SAFETY: By the type invariant, `self.as_raw` is a valid argument to `cpumask_test_cpu`.
-        unsafe { bindings::cpumask_test_cpu(cpu, self.as_raw()) }
+        unsafe { bindings::cpumask_test_cpu(cpu.into(), self.as_raw()) }
     }
 
     /// Set all CPUs in the cpumask.
@@ -178,21 +180,40 @@ pub fn copy(&self, dstp: &mut Self) {
 /// The following example demonstrates how to create and update a [`CpumaskVar`].
 ///
 /// ```
+/// use kernel::cpu::CpuId;
 /// use kernel::cpumask::CpumaskVar;
 ///
 /// let mut mask = CpumaskVar::new_zero(GFP_KERNEL).unwrap();
 ///
 /// assert!(mask.empty());
-/// mask.set(2);
-/// assert!(mask.test(2));
-/// mask.set(3);
-/// assert!(mask.test(3));
-/// assert_eq!(mask.weight(), 2);
+/// let mut count = 0;
+///
+/// let cpu2 = CpuId::from_u32(2);
+/// if let Some(cpu) = cpu2 {
+///     mask.set(cpu);
+///     assert!(mask.test(cpu));
+///     count += 1;
+/// }
+///
+/// let cpu3 = CpuId::from_u32(3);
+/// if let Some(cpu) = cpu3 {
+///     mask.set(cpu);
+///     assert!(mask.test(cpu));
+///     count += 1;
+/// }
+///
+/// assert_eq!(mask.weight(), count);
 ///
 /// let mask2 = CpumaskVar::try_clone(&mask).unwrap();
-/// assert!(mask2.test(2));
-/// assert!(mask2.test(3));
-/// assert_eq!(mask2.weight(), 2);
+///
+/// if let Some(cpu) = cpu2 {
+///     assert!(mask2.test(cpu));
+/// }
+///
+/// if let Some(cpu) = cpu3 {
+///     assert!(mask2.test(cpu));
+/// }
+/// assert_eq!(mask2.weight(), count);
 /// ```
 pub struct CpumaskVar {
     #[cfg(CONFIG_CPUMASK_OFFSTACK)]
-- 
2.31.1.272.g89b43f80a514


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH V3 3/3] rust: cpu: Add CpuId::current() to retrieve current CPU ID
  2025-06-10 13:21 [PATCH V3 0/3] rust: Introduce CpuId and fix cpumask doctest Viresh Kumar
  2025-06-10 13:21 ` [PATCH V3 1/3] rust: cpu: Introduce CpuId abstraction Viresh Kumar
  2025-06-10 13:21 ` [PATCH V3 2/3] rust: Use CpuId in place of raw CPU numbers Viresh Kumar
@ 2025-06-10 13:21 ` Viresh Kumar
  2025-06-10 21:23   ` Boqun Feng
  2025-06-10 17:10 ` [PATCH V3 0/3] rust: Introduce CpuId and fix cpumask doctest Miguel Ojeda
  3 siblings, 1 reply; 12+ messages in thread
From: Viresh Kumar @ 2025-06-10 13:21 UTC (permalink / raw)
  To: Boqun Feng, Rafael J. Wysocki, Miguel Ojeda, Alex Gaynor,
	Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg,
	Alice Ryhl, Trevor Gross, Danilo Krummrich, Thomas Gleixner,
	Peter Zijlstra
  Cc: Viresh Kumar, Vincent Guittot, Yury Norov, rust-for-linux,
	linux-kernel

Introduce `CpuId::current()`, a constructor that wraps the C function
`raw_smp_processor_id()` to retrieve the current CPU identifier without
guaranteeing stability.

This function should be used only when the caller can ensure that
the CPU ID won't change unexpectedly due to preemption or migration.

Suggested-by: Boqun Feng <boqun.feng@gmail.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 MAINTAINERS            |  1 +
 rust/helpers/cpu.c     |  8 ++++++++
 rust/helpers/helpers.c |  1 +
 rust/kernel/cpu.rs     | 10 ++++++++++
 4 files changed, 20 insertions(+)
 create mode 100644 rust/helpers/cpu.c

diff --git a/MAINTAINERS b/MAINTAINERS
index a92290fffa16..4255186784c4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6254,6 +6254,7 @@ F:	include/linux/cpuhotplug.h
 F:	include/linux/smpboot.h
 F:	kernel/cpu.c
 F:	kernel/smpboot.*
+F:	rust/helper/cpu.c
 F:	rust/kernel/cpu.rs
 
 CPU IDLE TIME MANAGEMENT FRAMEWORK
diff --git a/rust/helpers/cpu.c b/rust/helpers/cpu.c
new file mode 100644
index 000000000000..824e0adb19d4
--- /dev/null
+++ b/rust/helpers/cpu.c
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/smp.h>
+
+unsigned int rust_helper_raw_smp_processor_id(void)
+{
+	return raw_smp_processor_id();
+}
diff --git a/rust/helpers/helpers.c b/rust/helpers/helpers.c
index 0f1b5d115985..16fa9bca5949 100644
--- a/rust/helpers/helpers.c
+++ b/rust/helpers/helpers.c
@@ -13,6 +13,7 @@
 #include "build_assert.c"
 #include "build_bug.c"
 #include "clk.c"
+#include "cpu.c"
 #include "cpufreq.c"
 #include "cpumask.c"
 #include "cred.c"
diff --git a/rust/kernel/cpu.rs b/rust/kernel/cpu.rs
index 7549594fad7f..a946c8a9d1a2 100644
--- a/rust/kernel/cpu.rs
+++ b/rust/kernel/cpu.rs
@@ -102,6 +102,16 @@ pub fn from_u32(id: u32) -> Option<Self> {
     pub fn as_u32(&self) -> u32 {
         self.0
     }
+
+    /// Returns the ID of the CPU the code is currently running on.
+    ///
+    /// The returned value is considered unstable because it may change
+    /// unexpectedly due to preemption or CPU migration. It should only be
+    /// used when the context ensures that the task remains on the same CPU.
+    pub fn current() -> Self {
+        // SAFETY: raw_smp_processor_id() always returns a valid CPU ID.
+        unsafe { Self::from_u32_unchecked(bindings::raw_smp_processor_id()) }
+    }
 }
 
 impl From<CpuId> for u32 {
-- 
2.31.1.272.g89b43f80a514


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH V3 0/3] rust: Introduce CpuId and fix cpumask doctest
  2025-06-10 13:21 [PATCH V3 0/3] rust: Introduce CpuId and fix cpumask doctest Viresh Kumar
                   ` (2 preceding siblings ...)
  2025-06-10 13:21 ` [PATCH V3 3/3] rust: cpu: Add CpuId::current() to retrieve current CPU ID Viresh Kumar
@ 2025-06-10 17:10 ` Miguel Ojeda
  2025-06-11  2:18   ` Viresh Kumar
  3 siblings, 1 reply; 12+ messages in thread
From: Miguel Ojeda @ 2025-06-10 17:10 UTC (permalink / raw)
  To: Viresh Kumar
  Cc: Boqun Feng, Rafael J. Wysocki, Alex Gaynor, Alice Ryhl,
	Andreas Hindborg, Benno Lossin, Björn Roy Baron,
	Danilo Krummrich, Gary Guo, Miguel Ojeda, Peter Zijlstra,
	Thomas Gleixner, Trevor Gross, Yury Norov, Vincent Guittot,
	rust-for-linux, linux-kernel, linux-pm

On Tue, Jun 10, 2025 at 3:22 PM Viresh Kumar <viresh.kumar@linaro.org> wrote:
>
> Here is another attempt at fixing the cpumask doctest. This series creates a new
> abstraction `CpuId`, which is used to write a cleaner cpumask example which
> doesn't fail in those corner cases.
>
> Rebased over v6.16-rc1 + [1].

Given this is growing, should we apply something trivial right away as
a fix meanwhile? Or are you planning to send this as a fix during the
-rcs?

Thanks!

Cheers,
Miguel

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH V3 3/3] rust: cpu: Add CpuId::current() to retrieve current CPU ID
  2025-06-10 13:21 ` [PATCH V3 3/3] rust: cpu: Add CpuId::current() to retrieve current CPU ID Viresh Kumar
@ 2025-06-10 21:23   ` Boqun Feng
  2025-06-11  2:28     ` Viresh Kumar
  0 siblings, 1 reply; 12+ messages in thread
From: Boqun Feng @ 2025-06-10 21:23 UTC (permalink / raw)
  To: Viresh Kumar
  Cc: Rafael J. Wysocki, Miguel Ojeda, Alex Gaynor, Gary Guo,
	Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
	Trevor Gross, Danilo Krummrich, Thomas Gleixner, Peter Zijlstra,
	Vincent Guittot, Yury Norov, rust-for-linux, linux-kernel

On Tue, Jun 10, 2025 at 06:51:58PM +0530, Viresh Kumar wrote:
> Introduce `CpuId::current()`, a constructor that wraps the C function
> `raw_smp_processor_id()` to retrieve the current CPU identifier without
> guaranteeing stability.
> 
> This function should be used only when the caller can ensure that
> the CPU ID won't change unexpectedly due to preemption or migration.
> 
> Suggested-by: Boqun Feng <boqun.feng@gmail.com>
> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
> ---
>  MAINTAINERS            |  1 +
>  rust/helpers/cpu.c     |  8 ++++++++
>  rust/helpers/helpers.c |  1 +
>  rust/kernel/cpu.rs     | 10 ++++++++++
>  4 files changed, 20 insertions(+)
>  create mode 100644 rust/helpers/cpu.c
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index a92290fffa16..4255186784c4 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -6254,6 +6254,7 @@ F:	include/linux/cpuhotplug.h
>  F:	include/linux/smpboot.h
>  F:	kernel/cpu.c
>  F:	kernel/smpboot.*
> +F:	rust/helper/cpu.c
>  F:	rust/kernel/cpu.rs
>  
>  CPU IDLE TIME MANAGEMENT FRAMEWORK
> diff --git a/rust/helpers/cpu.c b/rust/helpers/cpu.c
> new file mode 100644
> index 000000000000..824e0adb19d4
> --- /dev/null
> +++ b/rust/helpers/cpu.c
> @@ -0,0 +1,8 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +#include <linux/smp.h>
> +
> +unsigned int rust_helper_raw_smp_processor_id(void)
> +{
> +	return raw_smp_processor_id();
> +}
> diff --git a/rust/helpers/helpers.c b/rust/helpers/helpers.c
> index 0f1b5d115985..16fa9bca5949 100644
> --- a/rust/helpers/helpers.c
> +++ b/rust/helpers/helpers.c
> @@ -13,6 +13,7 @@
>  #include "build_assert.c"
>  #include "build_bug.c"
>  #include "clk.c"
> +#include "cpu.c"
>  #include "cpufreq.c"
>  #include "cpumask.c"
>  #include "cred.c"
> diff --git a/rust/kernel/cpu.rs b/rust/kernel/cpu.rs
> index 7549594fad7f..a946c8a9d1a2 100644
> --- a/rust/kernel/cpu.rs
> +++ b/rust/kernel/cpu.rs
> @@ -102,6 +102,16 @@ pub fn from_u32(id: u32) -> Option<Self> {
>      pub fn as_u32(&self) -> u32 {
>          self.0
>      }
> +
> +    /// Returns the ID of the CPU the code is currently running on.
> +    ///
> +    /// The returned value is considered unstable because it may change
> +    /// unexpectedly due to preemption or CPU migration. It should only be
> +    /// used when the context ensures that the task remains on the same CPU.

I would also add "or the users could use a stale (yet valid) CPU ID",
because there are such usages in kernel arleady, e.g.
kvm_pmu_probe_armpmu() in arch/arm64/kvm/pmu-emul.c.

With that, feel free to add:

Reviewed-by: Boqun Feng <boqun.feng@gmail.com>

Regards,
Boqun

> +    pub fn current() -> Self {
> +        // SAFETY: raw_smp_processor_id() always returns a valid CPU ID.
> +        unsafe { Self::from_u32_unchecked(bindings::raw_smp_processor_id()) }
> +    }
>  }
>  
>  impl From<CpuId> for u32 {
> -- 
> 2.31.1.272.g89b43f80a514
> 

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH V3 0/3] rust: Introduce CpuId and fix cpumask doctest
  2025-06-10 17:10 ` [PATCH V3 0/3] rust: Introduce CpuId and fix cpumask doctest Miguel Ojeda
@ 2025-06-11  2:18   ` Viresh Kumar
  0 siblings, 0 replies; 12+ messages in thread
From: Viresh Kumar @ 2025-06-11  2:18 UTC (permalink / raw)
  To: Miguel Ojeda
  Cc: Boqun Feng, Rafael J. Wysocki, Alex Gaynor, Alice Ryhl,
	Andreas Hindborg, Benno Lossin, Björn Roy Baron,
	Danilo Krummrich, Gary Guo, Miguel Ojeda, Peter Zijlstra,
	Thomas Gleixner, Trevor Gross, Yury Norov, Vincent Guittot,
	rust-for-linux, linux-kernel, linux-pm

On 10-06-25, 19:10, Miguel Ojeda wrote:
> On Tue, Jun 10, 2025 at 3:22 PM Viresh Kumar <viresh.kumar@linaro.org> wrote:
> >
> > Here is another attempt at fixing the cpumask doctest. This series creates a new
> > abstraction `CpuId`, which is used to write a cleaner cpumask example which
> > doesn't fail in those corner cases.
> >
> > Rebased over v6.16-rc1 + [1].
> 
> Given this is growing, should we apply something trivial right away as
> a fix meanwhile? Or are you planning to send this as a fix during the
> -rcs?

Yeah, I am planning to send this for rc2 or rc3.

-- 
viresh

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH V3 3/3] rust: cpu: Add CpuId::current() to retrieve current CPU ID
  2025-06-10 21:23   ` Boqun Feng
@ 2025-06-11  2:28     ` Viresh Kumar
  0 siblings, 0 replies; 12+ messages in thread
From: Viresh Kumar @ 2025-06-11  2:28 UTC (permalink / raw)
  To: Boqun Feng
  Cc: Rafael J. Wysocki, Miguel Ojeda, Alex Gaynor, Gary Guo,
	Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
	Trevor Gross, Danilo Krummrich, Thomas Gleixner, Peter Zijlstra,
	Vincent Guittot, Yury Norov, rust-for-linux, linux-kernel

On 10-06-25, 14:23, Boqun Feng wrote:
> I would also add "or the users could use a stale (yet valid) CPU ID",
> because there are such usages in kernel arleady, e.g.
> kvm_pmu_probe_armpmu() in arch/arm64/kvm/pmu-emul.c.

Done.

> With that, feel free to add:
> 
> Reviewed-by: Boqun Feng <boqun.feng@gmail.com>

Thanks Boqun. I have queued this series for linux-next to get some
testing while the reviews are going on. It would be nice if I can get
some reviews on the other patches, especially the one that adds the
`CpuId` abstraction.

-- 
viresh

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH V3 1/3] rust: cpu: Introduce CpuId abstraction
  2025-06-10 13:21 ` [PATCH V3 1/3] rust: cpu: Introduce CpuId abstraction Viresh Kumar
@ 2025-06-11 16:07   ` Boqun Feng
  0 siblings, 0 replies; 12+ messages in thread
From: Boqun Feng @ 2025-06-11 16:07 UTC (permalink / raw)
  To: Viresh Kumar
  Cc: Rafael J. Wysocki, Thomas Gleixner, Peter Zijlstra, Miguel Ojeda,
	Alex Gaynor, Gary Guo, Björn Roy Baron, Benno Lossin,
	Andreas Hindborg, Alice Ryhl, Trevor Gross, Danilo Krummrich,
	Vincent Guittot, Yury Norov, rust-for-linux, linux-kernel

On Tue, Jun 10, 2025 at 06:51:56PM +0530, Viresh Kumar wrote:
> This adds abstraction for representing a CPU identifier.
> 
> Suggested-by: Boqun Feng <boqun.feng@gmail.com>
> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>

Reviewed-by: Boqun Feng <boqun.feng@gmail.com>

Regards,
Boqun

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH V3 2/3] rust: Use CpuId in place of raw CPU numbers
  2025-06-10 13:21 ` [PATCH V3 2/3] rust: Use CpuId in place of raw CPU numbers Viresh Kumar
@ 2025-06-11 16:12   ` Boqun Feng
  2025-06-12  5:01     ` Viresh Kumar
  0 siblings, 1 reply; 12+ messages in thread
From: Boqun Feng @ 2025-06-11 16:12 UTC (permalink / raw)
  To: Viresh Kumar
  Cc: Rafael J. Wysocki, Thomas Gleixner, Peter Zijlstra, Miguel Ojeda,
	Alex Gaynor, Gary Guo, Björn Roy Baron, Benno Lossin,
	Andreas Hindborg, Alice Ryhl, Trevor Gross, Danilo Krummrich,
	Yury Norov, Vincent Guittot, rust-for-linux, linux-pm,
	linux-kernel

On Tue, Jun 10, 2025 at 06:51:57PM +0530, Viresh Kumar wrote:
> Use the newly defined `CpuId` abstraction instead of raw CPU numbers.
> 
> This also fixes a doctest failure for configurations where `nr_cpu_ids <
> 4`.
> 
> The C `cpumask_{set|clear}_cpu()` APIs emit a warning when given an
> invalid CPU number - but only if `CONFIG_DEBUG_PER_CPU_MAPS=y` is set.
> 
> Meanwhile, `cpumask_weight()` only considers CPUs up to `nr_cpu_ids`,
> which can cause inconsistencies: a CPU number greater than `nr_cpu_ids`
> may be set in the mask, yet the weight calculation won't reflect it.
> 
> This leads to doctest failures when `nr_cpu_ids < 4`, as the test tries
> to set CPUs 2 and 3:
> 
>   rust_doctest_kernel_cpumask_rs_0.location: rust/kernel/cpumask.rs:180
>   rust_doctest_kernel_cpumask_rs_0: ASSERTION FAILED at rust/kernel/cpumask.rs:190
> 
> Fixes: 8961b8cb3099 ("rust: cpumask: Add initial abstractions")
> Reported-by: Miguel Ojeda <ojeda@kernel.org>
> Closes: https://lore.kernel.org/rust-for-linux/CANiq72k3ozKkLMinTLQwvkyg9K=BeRxs1oYZSKhJHY-veEyZdg@mail.gmail.com/
> Reported-by: Andreas Hindborg <a.hindborg@kernel.org>
> Closes: https://lore.kernel.org/all/87qzzy3ric.fsf@kernel.org/
> Suggested-by: Boqun Feng <boqun.feng@gmail.com>
> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>

Reviewed-by: Boqun Feng <boqun.feng@gmail.com>

One nit below..

> ---
>  drivers/cpufreq/rcpufreq_dt.rs |  4 +--
>  rust/kernel/cpu.rs             |  4 +--
>  rust/kernel/cpufreq.rs         | 27 ++++++++++++------
>  rust/kernel/cpumask.rs         | 51 ++++++++++++++++++++++++----------
>  4 files changed, 59 insertions(+), 27 deletions(-)
> 
> diff --git a/drivers/cpufreq/rcpufreq_dt.rs b/drivers/cpufreq/rcpufreq_dt.rs
> index 94ed81644fe1..43c87d0259b6 100644
> --- a/drivers/cpufreq/rcpufreq_dt.rs
> +++ b/drivers/cpufreq/rcpufreq_dt.rs
> @@ -26,9 +26,9 @@ fn find_supply_name_exact(dev: &Device, name: &str) -> Option<CString> {
>  }
>  
>  /// Finds supply name for the CPU from DT.
> -fn find_supply_names(dev: &Device, cpu: u32) -> Option<KVec<CString>> {
> +fn find_supply_names(dev: &Device, cpu: cpu::CpuId) -> Option<KVec<CString>> {
>      // Try "cpu0" for older DTs, fallback to "cpu".
> -    let name = (cpu == 0)
> +    let name = (cpu.as_u32() == 0)
>          .then(|| find_supply_name_exact(dev, "cpu0"))
>          .flatten()
>          .or_else(|| find_supply_name_exact(dev, "cpu"))?;
> diff --git a/rust/kernel/cpu.rs b/rust/kernel/cpu.rs
> index 6a3aecb12468..7549594fad7f 100644
> --- a/rust/kernel/cpu.rs
> +++ b/rust/kernel/cpu.rs
> @@ -127,9 +127,9 @@ fn from(id: CpuId) -> Self {
>  /// Callers must ensure that the CPU device is not used after it has been unregistered.
>  /// This can be achieved, for example, by registering a CPU hotplug notifier and removing
>  /// any references to the CPU device within the notifier's callback.
> -pub unsafe fn from_cpu(cpu: u32) -> Result<&'static Device> {
> +pub unsafe fn from_cpu(cpu: CpuId) -> Result<&'static Device> {
>      // SAFETY: It is safe to call `get_cpu_device()` for any CPU.
> -    let ptr = unsafe { bindings::get_cpu_device(cpu) };
> +    let ptr = unsafe { bindings::get_cpu_device(cpu.into()) };


I generally found that `u32::from(cpu)` is more clear than `cpu.into()`,
but it's up to you. Same for the rest of `cpu.into()` cases.

Regards,
Boqun

>      if ptr.is_null() {
>          return Err(ENODEV);
>      }
[...]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH V3 2/3] rust: Use CpuId in place of raw CPU numbers
  2025-06-11 16:12   ` Boqun Feng
@ 2025-06-12  5:01     ` Viresh Kumar
  2025-06-13 15:40       ` Boqun Feng
  0 siblings, 1 reply; 12+ messages in thread
From: Viresh Kumar @ 2025-06-12  5:01 UTC (permalink / raw)
  To: Boqun Feng
  Cc: Rafael J. Wysocki, Thomas Gleixner, Peter Zijlstra, Miguel Ojeda,
	Alex Gaynor, Gary Guo, Björn Roy Baron, Benno Lossin,
	Andreas Hindborg, Alice Ryhl, Trevor Gross, Danilo Krummrich,
	Yury Norov, Vincent Guittot, rust-for-linux, linux-pm,
	linux-kernel

On 11-06-25, 09:12, Boqun Feng wrote:
> I generally found that `u32::from(cpu)` is more clear than `cpu.into()`,
> but it's up to you. Same for the rest of `cpu.into()` cases.

Updated as:

diff --git a/rust/kernel/cpu.rs b/rust/kernel/cpu.rs
index 7549594fad7f..abc780d7a8ec 100644
--- a/rust/kernel/cpu.rs
+++ b/rust/kernel/cpu.rs
@@ -129,7 +129,7 @@ fn from(id: CpuId) -> Self {
 /// any references to the CPU device within the notifier's callback.
 pub unsafe fn from_cpu(cpu: CpuId) -> Result<&'static Device> {
     // SAFETY: It is safe to call `get_cpu_device()` for any CPU.
-    let ptr = unsafe { bindings::get_cpu_device(cpu.into()) };
+    let ptr = unsafe { bindings::get_cpu_device(u32::from(cpu)) };
     if ptr.is_null() {
         return Err(ENODEV);
     }
diff --git a/rust/kernel/cpufreq.rs b/rust/kernel/cpufreq.rs
index ea6106db5c29..11b03e9d7e89 100644
--- a/rust/kernel/cpufreq.rs
+++ b/rust/kernel/cpufreq.rs
@@ -527,7 +527,7 @@ pub fn generic_suspend(&mut self) -> Result {
     #[inline]
     pub fn generic_get(&self) -> Result<u32> {
         // SAFETY: By the type invariant, the pointer stored in `self` is valid.
-        Ok(unsafe { bindings::cpufreq_generic_get(self.cpu().into()) })
+        Ok(unsafe { bindings::cpufreq_generic_get(u32::from(self.cpu())) })
     }
 
     /// Provides a wrapper to the register with energy model using the OPP core.
@@ -682,7 +682,7 @@ fn clear_data<T: ForeignOwnable>(&mut self) -> Option<T> {
 impl<'a> PolicyCpu<'a> {
     fn from_cpu(cpu: CpuId) -> Result<Self> {
         // SAFETY: It is safe to call `cpufreq_cpu_get` for any valid CPU.
-        let ptr = from_err_ptr(unsafe { bindings::cpufreq_cpu_get(cpu.into()) })?;
+        let ptr = from_err_ptr(unsafe { bindings::cpufreq_cpu_get(u32::from(cpu)) })?;
 
         Ok(Self(
             // SAFETY: The `ptr` is guaranteed to be valid and remains valid for the lifetime of
diff --git a/rust/kernel/cpumask.rs b/rust/kernel/cpumask.rs
index 11ddd43edcb5..19c607709b5f 100644
--- a/rust/kernel/cpumask.rs
+++ b/rust/kernel/cpumask.rs
@@ -94,7 +94,7 @@ pub fn as_raw(&self) -> *mut bindings::cpumask {
     #[inline]
     pub fn set(&mut self, cpu: CpuId) {
         // SAFETY: By the type invariant, `self.as_raw` is a valid argument to `__cpumask_set_cpu`.
-        unsafe { bindings::__cpumask_set_cpu(cpu.into(), self.as_raw()) };
+        unsafe { bindings::__cpumask_set_cpu(u32::from(cpu), self.as_raw()) };
     }
 
     /// Clear `cpu` in the cpumask.
@@ -106,7 +106,7 @@ pub fn set(&mut self, cpu: CpuId) {
     pub fn clear(&mut self, cpu: CpuId) {
         // SAFETY: By the type invariant, `self.as_raw` is a valid argument to
         // `__cpumask_clear_cpu`.
-        unsafe { bindings::__cpumask_clear_cpu(cpu.into(), self.as_raw()) };
+        unsafe { bindings::__cpumask_clear_cpu(i32::from(cpu), self.as_raw()) };
     }
 
     /// Test `cpu` in the cpumask.
@@ -115,7 +115,7 @@ pub fn clear(&mut self, cpu: CpuId) {
     #[inline]
     pub fn test(&self, cpu: CpuId) -> bool {
         // SAFETY: By the type invariant, `self.as_raw` is a valid argument to `cpumask_test_cpu`.
-        unsafe { bindings::cpumask_test_cpu(cpu.into(), self.as_raw()) }
+        unsafe { bindings::cpumask_test_cpu(i32::from(cpu), self.as_raw()) }
     }
 
     /// Set all CPUs in the cpumask.

-- 
viresh

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH V3 2/3] rust: Use CpuId in place of raw CPU numbers
  2025-06-12  5:01     ` Viresh Kumar
@ 2025-06-13 15:40       ` Boqun Feng
  0 siblings, 0 replies; 12+ messages in thread
From: Boqun Feng @ 2025-06-13 15:40 UTC (permalink / raw)
  To: Viresh Kumar
  Cc: Rafael J. Wysocki, Thomas Gleixner, Peter Zijlstra, Miguel Ojeda,
	Alex Gaynor, Gary Guo, Björn Roy Baron, Benno Lossin,
	Andreas Hindborg, Alice Ryhl, Trevor Gross, Danilo Krummrich,
	Yury Norov, Vincent Guittot, rust-for-linux, linux-pm,
	linux-kernel

On Thu, Jun 12, 2025 at 10:31:17AM +0530, Viresh Kumar wrote:
> On 11-06-25, 09:12, Boqun Feng wrote:
> > I generally found that `u32::from(cpu)` is more clear than `cpu.into()`,
> > but it's up to you. Same for the rest of `cpu.into()` cases.
> 
> Updated as:
> 
> diff --git a/rust/kernel/cpu.rs b/rust/kernel/cpu.rs
> index 7549594fad7f..abc780d7a8ec 100644
> --- a/rust/kernel/cpu.rs
> +++ b/rust/kernel/cpu.rs
> @@ -129,7 +129,7 @@ fn from(id: CpuId) -> Self {
>  /// any references to the CPU device within the notifier's callback.
>  pub unsafe fn from_cpu(cpu: CpuId) -> Result<&'static Device> {
>      // SAFETY: It is safe to call `get_cpu_device()` for any CPU.
> -    let ptr = unsafe { bindings::get_cpu_device(cpu.into()) };
> +    let ptr = unsafe { bindings::get_cpu_device(u32::from(cpu)) };
>      if ptr.is_null() {
>          return Err(ENODEV);
>      }
> diff --git a/rust/kernel/cpufreq.rs b/rust/kernel/cpufreq.rs
> index ea6106db5c29..11b03e9d7e89 100644
> --- a/rust/kernel/cpufreq.rs
> +++ b/rust/kernel/cpufreq.rs
> @@ -527,7 +527,7 @@ pub fn generic_suspend(&mut self) -> Result {
>      #[inline]
>      pub fn generic_get(&self) -> Result<u32> {
>          // SAFETY: By the type invariant, the pointer stored in `self` is valid.
> -        Ok(unsafe { bindings::cpufreq_generic_get(self.cpu().into()) })
> +        Ok(unsafe { bindings::cpufreq_generic_get(u32::from(self.cpu())) })
>      }
>  
>      /// Provides a wrapper to the register with energy model using the OPP core.
> @@ -682,7 +682,7 @@ fn clear_data<T: ForeignOwnable>(&mut self) -> Option<T> {
>  impl<'a> PolicyCpu<'a> {
>      fn from_cpu(cpu: CpuId) -> Result<Self> {
>          // SAFETY: It is safe to call `cpufreq_cpu_get` for any valid CPU.
> -        let ptr = from_err_ptr(unsafe { bindings::cpufreq_cpu_get(cpu.into()) })?;
> +        let ptr = from_err_ptr(unsafe { bindings::cpufreq_cpu_get(u32::from(cpu)) })?;
>  
>          Ok(Self(
>              // SAFETY: The `ptr` is guaranteed to be valid and remains valid for the lifetime of
> diff --git a/rust/kernel/cpumask.rs b/rust/kernel/cpumask.rs
> index 11ddd43edcb5..19c607709b5f 100644
> --- a/rust/kernel/cpumask.rs
> +++ b/rust/kernel/cpumask.rs
> @@ -94,7 +94,7 @@ pub fn as_raw(&self) -> *mut bindings::cpumask {
>      #[inline]
>      pub fn set(&mut self, cpu: CpuId) {
>          // SAFETY: By the type invariant, `self.as_raw` is a valid argument to `__cpumask_set_cpu`.
> -        unsafe { bindings::__cpumask_set_cpu(cpu.into(), self.as_raw()) };
> +        unsafe { bindings::__cpumask_set_cpu(u32::from(cpu), self.as_raw()) };
>      }
>  
>      /// Clear `cpu` in the cpumask.
> @@ -106,7 +106,7 @@ pub fn set(&mut self, cpu: CpuId) {
>      pub fn clear(&mut self, cpu: CpuId) {
>          // SAFETY: By the type invariant, `self.as_raw` is a valid argument to
>          // `__cpumask_clear_cpu`.
> -        unsafe { bindings::__cpumask_clear_cpu(cpu.into(), self.as_raw()) };
> +        unsafe { bindings::__cpumask_clear_cpu(i32::from(cpu), self.as_raw()) };
>      }
>  
>      /// Test `cpu` in the cpumask.
> @@ -115,7 +115,7 @@ pub fn clear(&mut self, cpu: CpuId) {
>      #[inline]
>      pub fn test(&self, cpu: CpuId) -> bool {
>          // SAFETY: By the type invariant, `self.as_raw` is a valid argument to `cpumask_test_cpu`.
> -        unsafe { bindings::cpumask_test_cpu(cpu.into(), self.as_raw()) }
> +        unsafe { bindings::cpumask_test_cpu(i32::from(cpu), self.as_raw()) }
>      }
>  

LGTM,thanks!

Regards,
Boqun

>      /// Set all CPUs in the cpumask.
> 
> -- 
> viresh

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2025-06-13 15:40 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-06-10 13:21 [PATCH V3 0/3] rust: Introduce CpuId and fix cpumask doctest Viresh Kumar
2025-06-10 13:21 ` [PATCH V3 1/3] rust: cpu: Introduce CpuId abstraction Viresh Kumar
2025-06-11 16:07   ` Boqun Feng
2025-06-10 13:21 ` [PATCH V3 2/3] rust: Use CpuId in place of raw CPU numbers Viresh Kumar
2025-06-11 16:12   ` Boqun Feng
2025-06-12  5:01     ` Viresh Kumar
2025-06-13 15:40       ` Boqun Feng
2025-06-10 13:21 ` [PATCH V3 3/3] rust: cpu: Add CpuId::current() to retrieve current CPU ID Viresh Kumar
2025-06-10 21:23   ` Boqun Feng
2025-06-11  2:28     ` Viresh Kumar
2025-06-10 17:10 ` [PATCH V3 0/3] rust: Introduce CpuId and fix cpumask doctest Miguel Ojeda
2025-06-11  2:18   ` Viresh Kumar

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).