public inbox for rust-for-linux@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2] rust: cpumask: Bindings for core cpumasks and cpumask iterators
@ 2025-11-05 23:16 Mitchell Levy
  2025-11-05 23:16 ` [PATCH 1/2] rust: cpumask: Add a `Cpumask` iterator Mitchell Levy
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Mitchell Levy @ 2025-11-05 23:16 UTC (permalink / raw)
  To: Yury Norov, Miguel Ojeda, Alex Gaynor, Boqun Feng, Gary Guo,
	Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
	Trevor Gross, Danilo Krummrich, Viresh Kumar
  Cc: rust-for-linux, linux-kernel, Mitchell Levy

The kernel provides a number of very useful CPU masks from the C side,
including CPU masks for possible and online CPUs. In particular, these
are very useful when some operation must be done on each CPU (either
each possible CPU or each online CPU, etc). Therefore, it seems to make
sense to add both of these functionalities at once.

Signed-off-by: Mitchell Levy <levymitchell0@gmail.com>
---
These patches originated as part of my work on a Rust per-CPU API [1].
Boqun suggested to me that these may make sense to merge separately, and
it does seem like these might be useful beyond the per-CPU work.

[1]: https://lore.kernel.org/rust-for-linux/20251105-rust-percpu-v4-0-984b1470adcb@gmail.com/

---
Mitchell Levy (2):
      rust: cpumask: Add a `Cpumask` iterator
      rust: cpumask: Add getters for globally defined cpumasks

 rust/helpers/cpumask.c |  5 +++
 rust/kernel/cpumask.rs | 94 +++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 98 insertions(+), 1 deletion(-)
---
base-commit: f3f6b3664302e16ef1c6b91034a72df5564d6b8a
change-id: 20251105-cpumask-iter-ff0f1a5899b3

Best regards,
-- 
Mitchell Levy <levymitchell0@gmail.com>


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

* [PATCH 1/2] rust: cpumask: Add a `Cpumask` iterator
  2025-11-05 23:16 [PATCH 0/2] rust: cpumask: Bindings for core cpumasks and cpumask iterators Mitchell Levy
@ 2025-11-05 23:16 ` Mitchell Levy
  2025-11-05 23:16 ` [PATCH 2/2] rust: cpumask: Add getters for globally defined cpumasks Mitchell Levy
  2025-11-06  0:19 ` [PATCH 0/2] rust: cpumask: Bindings for core cpumasks and cpumask iterators John Hubbard
  2 siblings, 0 replies; 7+ messages in thread
From: Mitchell Levy @ 2025-11-05 23:16 UTC (permalink / raw)
  To: Yury Norov, Miguel Ojeda, Alex Gaynor, Boqun Feng, Gary Guo,
	Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
	Trevor Gross, Danilo Krummrich, Viresh Kumar
  Cc: rust-for-linux, linux-kernel, Mitchell Levy

Add an iterator for `Cpumask` making use of C's `cpumask_next`.

Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Mitchell Levy <levymitchell0@gmail.com>
---
 rust/helpers/cpumask.c |  5 +++++
 rust/kernel/cpumask.rs | 48 +++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 52 insertions(+), 1 deletion(-)

diff --git a/rust/helpers/cpumask.c b/rust/helpers/cpumask.c
index eb10598a0242..d95bfa111191 100644
--- a/rust/helpers/cpumask.c
+++ b/rust/helpers/cpumask.c
@@ -42,6 +42,11 @@ bool rust_helper_cpumask_full(struct cpumask *srcp)
 	return cpumask_full(srcp);
 }
 
+unsigned int rust_helper_cpumask_next(int n, struct cpumask *srcp)
+{
+	return cpumask_next(n, srcp);
+}
+
 unsigned int rust_helper_cpumask_weight(struct cpumask *srcp)
 {
 	return cpumask_weight(srcp);
diff --git a/rust/kernel/cpumask.rs b/rust/kernel/cpumask.rs
index 3fcbff438670..b7401848f59e 100644
--- a/rust/kernel/cpumask.rs
+++ b/rust/kernel/cpumask.rs
@@ -6,7 +6,7 @@
 
 use crate::{
     alloc::{AllocError, Flags},
-    cpu::CpuId,
+    cpu::{self, CpuId},
     prelude::*,
     types::Opaque,
 };
@@ -161,6 +161,52 @@ pub fn copy(&self, dstp: &mut Self) {
     }
 }
 
+/// Iterator for a `Cpumask`.
+pub struct CpumaskIter<'a> {
+    mask: &'a Cpumask,
+    last: Option<u32>,
+}
+
+impl<'a> CpumaskIter<'a> {
+    /// Creates a new `CpumaskIter` for the given `Cpumask`.
+    fn new(mask: &'a Cpumask) -> CpumaskIter<'a> {
+        Self { mask, last: None }
+    }
+}
+
+impl<'a> Iterator for CpumaskIter<'a> {
+    type Item = CpuId;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        // SAFETY: By the type invariant, `self.mask.as_raw` is a `struct cpumask *`.
+        let next = unsafe {
+            bindings::cpumask_next(
+                if let Some(last) = self.last {
+                    last.try_into().unwrap()
+                } else {
+                    -1
+                },
+                self.mask.as_raw(),
+            )
+        };
+
+        if next == cpu::nr_cpu_ids() {
+            None
+        } else {
+            self.last = Some(next);
+            // SAFETY: `cpumask_next` returns either `nr_cpu_ids` or a valid CPU ID.
+            unsafe { Some(CpuId::from_u32_unchecked(next)) }
+        }
+    }
+}
+
+impl Cpumask {
+    /// Returns an iterator over the set bits in the cpumask.
+    pub fn iter(&self) -> CpumaskIter<'_> {
+        CpumaskIter::new(self)
+    }
+}
+
 /// A CPU Mask pointer.
 ///
 /// Rust abstraction for the C `struct cpumask_var_t`.

-- 
2.34.1


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

* [PATCH 2/2] rust: cpumask: Add getters for globally defined cpumasks
  2025-11-05 23:16 [PATCH 0/2] rust: cpumask: Bindings for core cpumasks and cpumask iterators Mitchell Levy
  2025-11-05 23:16 ` [PATCH 1/2] rust: cpumask: Add a `Cpumask` iterator Mitchell Levy
@ 2025-11-05 23:16 ` Mitchell Levy
  2025-11-06  0:19 ` [PATCH 0/2] rust: cpumask: Bindings for core cpumasks and cpumask iterators John Hubbard
  2 siblings, 0 replies; 7+ messages in thread
From: Mitchell Levy @ 2025-11-05 23:16 UTC (permalink / raw)
  To: Yury Norov, Miguel Ojeda, Alex Gaynor, Boqun Feng, Gary Guo,
	Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
	Trevor Gross, Danilo Krummrich, Viresh Kumar
  Cc: rust-for-linux, linux-kernel, Mitchell Levy

Add getters for the global cpumasks documented in
`include/linux/cpumask.h`, specifically:
- cpu_possible_mask
- cpu_online_mask
- cpu_enabled_mask
- cpu_present_mask
- cpu_active_mask

Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Suggested-by: Yury Norov <yury.norov@gmail.com>
Signed-off-by: Mitchell Levy <levymitchell0@gmail.com>
---
 rust/kernel/cpumask.rs | 46 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 46 insertions(+)

diff --git a/rust/kernel/cpumask.rs b/rust/kernel/cpumask.rs
index b7401848f59e..a6a130092fcb 100644
--- a/rust/kernel/cpumask.rs
+++ b/rust/kernel/cpumask.rs
@@ -77,6 +77,52 @@ pub unsafe fn as_ref<'a>(ptr: *const bindings::cpumask) -> &'a Self {
         unsafe { &*ptr.cast() }
     }
 
+    /// Get a CPU mask representing possible CPUs; has bit `cpu` set iff cpu is populatable
+    #[inline]
+    pub fn possible_cpus() -> &'static Self {
+        // SAFETY: `__cpu_possible_mask` is a valid global provided by the kernel that lives
+        // forever.
+        unsafe { Cpumask::as_ref(&raw const bindings::__cpu_possible_mask) }
+    }
+
+    /// Get a CPU mask representing online CPUs; has bit `cpu` set iff cpu available to the
+    /// scheduler
+    #[inline]
+    pub fn online_cpus() -> &'static Self {
+        // SAFETY: `__cpu_online_mask` is a valid global provided by the kernel that lives forever.
+        // Since we wrap the returned pointer in an `Opaque`, it's ok that `__cpu_online_mask`
+        // may change its value.
+        unsafe { Cpumask::as_ref(&raw const bindings::__cpu_online_mask) }
+    }
+
+    /// Get a CPU mask representing enabled CPUs; has bit `cpu` set iff cpu can be brought online
+    #[inline]
+    pub fn enabled_cpus() -> &'static Self {
+        // SAFETY: `__cpu_enabled_mask` is a valid global provided by the kernel that lives forever.
+        // Since we wrap the returned pointer in an `Opaque`, it's ok that `__cpu_enabled_mask`
+        // may change its value.
+        unsafe { Cpumask::as_ref(&raw const bindings::__cpu_enabled_mask) }
+    }
+
+    /// Get a CPU mask representing present CPUs; has bit `cpu` set iff cpu is populated
+    #[inline]
+    pub fn present_cpus() -> &'static Self {
+        // SAFETY: `__cpu_present_mask` is a valid global provided by the kernel that lives
+        // forever. Since we wrap the returned pointer in an `Opaque`, it's ok that
+        // `__cpu_present_mask` may change its value.
+        unsafe { Cpumask::as_ref(&raw const bindings::__cpu_present_mask) }
+    }
+
+    /// Get a CPU mask representing active CPUs; has bit `cpu` set iff cpu is available to
+    /// migration.
+    #[inline]
+    pub fn active_cpus() -> &'static Self {
+        // SAFETY: `__cpu_active_mask` is a valid global provided by the kernel that lives forever.
+        // Since we wrap the returned pointer in an `Opaque`, it's ok that `__cpu_active_mask`
+        // may change its value.
+        unsafe { Cpumask::as_ref(&raw const bindings::__cpu_active_mask) }
+    }
+
     /// Obtain the raw `struct cpumask` pointer.
     pub fn as_raw(&self) -> *mut bindings::cpumask {
         let this: *const Self = self;

-- 
2.34.1


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

* Re: [PATCH 0/2] rust: cpumask: Bindings for core cpumasks and cpumask iterators
  2025-11-05 23:16 [PATCH 0/2] rust: cpumask: Bindings for core cpumasks and cpumask iterators Mitchell Levy
  2025-11-05 23:16 ` [PATCH 1/2] rust: cpumask: Add a `Cpumask` iterator Mitchell Levy
  2025-11-05 23:16 ` [PATCH 2/2] rust: cpumask: Add getters for globally defined cpumasks Mitchell Levy
@ 2025-11-06  0:19 ` John Hubbard
  2025-11-07  1:38   ` Yury Norov
  2 siblings, 1 reply; 7+ messages in thread
From: John Hubbard @ 2025-11-06  0:19 UTC (permalink / raw)
  To: Mitchell Levy, Yury Norov, Miguel Ojeda, Alex Gaynor, Boqun Feng,
	Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg,
	Alice Ryhl, Trevor Gross, Danilo Krummrich, Viresh Kumar
  Cc: rust-for-linux, linux-kernel

On 11/5/25 3:16 PM, Mitchell Levy wrote:
> The kernel provides a number of very useful CPU masks from the C side,
> including CPU masks for possible and online CPUs. In particular, these
> are very useful when some operation must be done on each CPU (either
> each possible CPU or each online CPU, etc). Therefore, it seems to make
> sense to add both of these functionalities at once.
> 
> Signed-off-by: Mitchell Levy <levymitchell0@gmail.com>
> ---
> These patches originated as part of my work on a Rust per-CPU API [1].
> Boqun suggested to me that these may make sense to merge separately, and
> it does seem like these might be useful beyond the per-CPU work.
> 
> [1]: https://lore.kernel.org/rust-for-linux/20251105-rust-percpu-v4-0-984b1470adcb@gmail.com/

Even though you are trying to get these two patches merged separately,
I think it's best (for reviewers) if you post a patchset that shows
these things being used. Otherwise it is potentially too unmoored from 
reality, and hard to be sure that it's exactly right from a caller's
point of view.

In this case, just posting that 9-patch series might work, and just
say in the cover letter that patches 3 through 9 are not ready for
merging.

Something like that.

I realize that Rust for Linux is being built from scratch right
now, but including calling code in a patchset is a really valuable
kernel convention that helps validate the code.

I say this for the benefit of others who may be reading. :)


thanks,
-- 
John Hubbard


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

* Re: [PATCH 0/2] rust: cpumask: Bindings for core cpumasks and cpumask iterators
  2025-11-06  0:19 ` [PATCH 0/2] rust: cpumask: Bindings for core cpumasks and cpumask iterators John Hubbard
@ 2025-11-07  1:38   ` Yury Norov
  2025-11-07 23:56     ` Mitchell Levy
  0 siblings, 1 reply; 7+ messages in thread
From: Yury Norov @ 2025-11-07  1:38 UTC (permalink / raw)
  To: John Hubbard
  Cc: Mitchell Levy, Miguel Ojeda, Alex Gaynor, Boqun Feng, Gary Guo,
	Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
	Trevor Gross, Danilo Krummrich, Viresh Kumar, rust-for-linux,
	linux-kernel

On Wed, Nov 05, 2025 at 04:19:36PM -0800, John Hubbard wrote:
> On 11/5/25 3:16 PM, Mitchell Levy wrote:
> > The kernel provides a number of very useful CPU masks from the C side,
> > including CPU masks for possible and online CPUs. In particular, these
> > are very useful when some operation must be done on each CPU (either
> > each possible CPU or each online CPU, etc). Therefore, it seems to make
> > sense to add both of these functionalities at once.
> > 
> > Signed-off-by: Mitchell Levy <levymitchell0@gmail.com>
> > ---
> > These patches originated as part of my work on a Rust per-CPU API [1].
> > Boqun suggested to me that these may make sense to merge separately, and
> > it does seem like these might be useful beyond the per-CPU work.
> > 
> > [1]: https://lore.kernel.org/rust-for-linux/20251105-rust-percpu-v4-0-984b1470adcb@gmail.com/
> 
> Even though you are trying to get these two patches merged separately,
> I think it's best (for reviewers) if you post a patchset that shows
> these things being used. Otherwise it is potentially too unmoored from 
> reality, and hard to be sure that it's exactly right from a caller's
> point of view.
> 
> In this case, just posting that 9-patch series might work, and just
> say in the cover letter that patches 3 through 9 are not ready for
> merging.
> 
> Something like that.
> 
> I realize that Rust for Linux is being built from scratch right
> now, but including calling code in a patchset is a really valuable
> kernel convention that helps validate the code.
> 
> I say this for the benefit of others who may be reading. :)

Not a big deal. Those two patches are self-consistent enough to take
them separately. But I agree that examples are always welcome.

Mitchell, can you resend this small series after addressing my
comments to the big one, and also can you illustrate it with the
usage examples?

Maybe a small test doing:
        
        for cpu in CpuMask::possible_cpus().iter()
                ncpus++;

        assert_eq!(ncpus == CpuMask::num_possible_cpus());

Thanks,
Yury

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

* Re: [PATCH 0/2] rust: cpumask: Bindings for core cpumasks and cpumask iterators
  2025-11-07  1:38   ` Yury Norov
@ 2025-11-07 23:56     ` Mitchell Levy
  2025-11-08  3:30       ` Yury Norov
  0 siblings, 1 reply; 7+ messages in thread
From: Mitchell Levy @ 2025-11-07 23:56 UTC (permalink / raw)
  To: Yury Norov
  Cc: John Hubbard, Miguel Ojeda, Alex Gaynor, Boqun Feng, Gary Guo,
	Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
	Trevor Gross, Danilo Krummrich, Viresh Kumar, rust-for-linux,
	linux-kernel

On Thu, Nov 06, 2025 at 08:38:54PM -0500, Yury Norov wrote:
> On Wed, Nov 05, 2025 at 04:19:36PM -0800, John Hubbard wrote:
> > On 11/5/25 3:16 PM, Mitchell Levy wrote:
> > > The kernel provides a number of very useful CPU masks from the C side,
> > > including CPU masks for possible and online CPUs. In particular, these
> > > are very useful when some operation must be done on each CPU (either
> > > each possible CPU or each online CPU, etc). Therefore, it seems to make
> > > sense to add both of these functionalities at once.
> > > 
> > > Signed-off-by: Mitchell Levy <levymitchell0@gmail.com>
> > > ---
> > > These patches originated as part of my work on a Rust per-CPU API [1].
> > > Boqun suggested to me that these may make sense to merge separately, and
> > > it does seem like these might be useful beyond the per-CPU work.
> > > 
> > > [1]: https://lore.kernel.org/rust-for-linux/20251105-rust-percpu-v4-0-984b1470adcb@gmail.com/
> > 
> > Even though you are trying to get these two patches merged separately,
> > I think it's best (for reviewers) if you post a patchset that shows
> > these things being used. Otherwise it is potentially too unmoored from 
> > reality, and hard to be sure that it's exactly right from a caller's
> > point of view.
> > 
> > In this case, just posting that 9-patch series might work, and just
> > say in the cover letter that patches 3 through 9 are not ready for
> > merging.
> > 
> > Something like that.
> > 
> > I realize that Rust for Linux is being built from scratch right
> > now, but including calling code in a patchset is a really valuable
> > kernel convention that helps validate the code.
> > 
> > I say this for the benefit of others who may be reading. :)
> 
> Not a big deal. Those two patches are self-consistent enough to take
> them separately. But I agree that examples are always welcome.
> 
> Mitchell, can you resend this small series after addressing my
> comments to the big one, and also can you illustrate it with the
> usage examples?
> 
> Maybe a small test doing:
>         
>         for cpu in CpuMask::possible_cpus().iter()
>                 ncpus++;
> 
>         assert_eq!(ncpus == CpuMask::num_possible_cpus());

Sure, will do. My current plan is to do rustdoc tests that will double
as examples in the generated documentation. However, if you'd prefer
something in `samples/rust` instead (or in addition), please let me
know.

Thanks,
Mitchell

> Thanks,
> Yury

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

* Re: [PATCH 0/2] rust: cpumask: Bindings for core cpumasks and cpumask iterators
  2025-11-07 23:56     ` Mitchell Levy
@ 2025-11-08  3:30       ` Yury Norov
  0 siblings, 0 replies; 7+ messages in thread
From: Yury Norov @ 2025-11-08  3:30 UTC (permalink / raw)
  To: Mitchell Levy
  Cc: John Hubbard, Miguel Ojeda, Alex Gaynor, Boqun Feng, Gary Guo,
	Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
	Trevor Gross, Danilo Krummrich, Viresh Kumar, rust-for-linux,
	linux-kernel

On Fri, Nov 07, 2025 at 03:56:54PM -0800, Mitchell Levy wrote:
> On Thu, Nov 06, 2025 at 08:38:54PM -0500, Yury Norov wrote:
> > On Wed, Nov 05, 2025 at 04:19:36PM -0800, John Hubbard wrote:
> > > On 11/5/25 3:16 PM, Mitchell Levy wrote:
> > > > The kernel provides a number of very useful CPU masks from the C side,
> > > > including CPU masks for possible and online CPUs. In particular, these
> > > > are very useful when some operation must be done on each CPU (either
> > > > each possible CPU or each online CPU, etc). Therefore, it seems to make
> > > > sense to add both of these functionalities at once.
> > > > 
> > > > Signed-off-by: Mitchell Levy <levymitchell0@gmail.com>
> > > > ---
> > > > These patches originated as part of my work on a Rust per-CPU API [1].
> > > > Boqun suggested to me that these may make sense to merge separately, and
> > > > it does seem like these might be useful beyond the per-CPU work.
> > > > 
> > > > [1]: https://lore.kernel.org/rust-for-linux/20251105-rust-percpu-v4-0-984b1470adcb@gmail.com/
> > > 
> > > Even though you are trying to get these two patches merged separately,
> > > I think it's best (for reviewers) if you post a patchset that shows
> > > these things being used. Otherwise it is potentially too unmoored from 
> > > reality, and hard to be sure that it's exactly right from a caller's
> > > point of view.
> > > 
> > > In this case, just posting that 9-patch series might work, and just
> > > say in the cover letter that patches 3 through 9 are not ready for
> > > merging.
> > > 
> > > Something like that.
> > > 
> > > I realize that Rust for Linux is being built from scratch right
> > > now, but including calling code in a patchset is a really valuable
> > > kernel convention that helps validate the code.
> > > 
> > > I say this for the benefit of others who may be reading. :)
> > 
> > Not a big deal. Those two patches are self-consistent enough to take
> > them separately. But I agree that examples are always welcome.
> > 
> > Mitchell, can you resend this small series after addressing my
> > comments to the big one, and also can you illustrate it with the
> > usage examples?
> > 
> > Maybe a small test doing:
> >         
> >         for cpu in CpuMask::possible_cpus().iter()
> >                 ncpus++;
> > 
> >         assert_eq!(ncpus == CpuMask::num_possible_cpus());
> 
> Sure, will do. My current plan is to do rustdoc tests that will double
> as examples in the generated documentation. However, if you'd prefer
> something in `samples/rust` instead (or in addition), please let me
> know.

I like traditional tests. If you do both - even better.

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

end of thread, other threads:[~2025-11-08  3:30 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-11-05 23:16 [PATCH 0/2] rust: cpumask: Bindings for core cpumasks and cpumask iterators Mitchell Levy
2025-11-05 23:16 ` [PATCH 1/2] rust: cpumask: Add a `Cpumask` iterator Mitchell Levy
2025-11-05 23:16 ` [PATCH 2/2] rust: cpumask: Add getters for globally defined cpumasks Mitchell Levy
2025-11-06  0:19 ` [PATCH 0/2] rust: cpumask: Bindings for core cpumasks and cpumask iterators John Hubbard
2025-11-07  1:38   ` Yury Norov
2025-11-07 23:56     ` Mitchell Levy
2025-11-08  3:30       ` Yury Norov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox