Re: [PATCH v3 3/3] rust: alloc: move `NumaNode` to the `numa` module

From: Andreas Hindborg

Date: Wed Oct 28 2026 - 10:37:15 EST


"Gary Guo" <gary@xxxxxxxxxxx> writes:

> On Tue Sep 29, 2026 at 6:56 PM BST, Andreas Hindborg wrote:
>> `NumaNode` identifies a NUMA node and is not specific to the allocator API.
>> Move it from the `alloc` module to the `numa` module so that NUMA related
>> items live together.
>>
>> No functional change.
>>
>> Suggested-by: Alice Ryhl <aliceryhl@xxxxxxxxxx>
>> Link: https://lore.kernel.org/all/aiZvKPFCkqJUsP0a@xxxxxxxxxx/
>> Signed-off-by: Andreas Hindborg <a.hindborg@xxxxxxxxxx>
>> ---
>> rust/kernel/alloc.rs | 30 ++++--------------------------
>> rust/kernel/alloc/allocator.rs | 6 +++---
>> rust/kernel/alloc/kbox.rs | 4 ++--
>> rust/kernel/alloc/kvec.rs | 4 ++--
>> rust/kernel/numa.rs | 35 ++++++++++++++++++++++++++++++++++-
>> 5 files changed, 45 insertions(+), 34 deletions(-)
>>
>> diff --git a/rust/kernel/alloc.rs b/rust/kernel/alloc.rs
>> index 21067bde6860..9daddf540e7d 100644
>> --- a/rust/kernel/alloc.rs
>> +++ b/rust/kernel/alloc.rs
>> @@ -22,7 +22,10 @@
>> #[derive(Copy, Clone, PartialEq, Eq, Debug)]
>> pub struct AllocError;
>>
>> -use crate::prelude::*;
>> +use crate::{
>> + numa::NumaNode,
>> + prelude::*, //
>> +};
>>
>> use core::{
>> alloc::Layout,
>> @@ -114,31 +117,6 @@ pub mod flags {
>> pub const __GFP_NOWARN: Flags = Flags(bindings::__GFP_NOWARN);
>> }
>>
>> -/// Non Uniform Memory Access (NUMA) node identifier.
>> -#[derive(Clone, Copy, PartialEq)]
>> -pub struct NumaNode(i32);
>> -
>> -impl NumaNode {
>> - /// Create a new NUMA node identifier (non-negative integer).
>> - ///
>> - /// Returns [`EINVAL`] if a negative id or an id exceeding [`bindings::MAX_NUMNODES`] is
>> - /// specified.
>> - pub fn new(node: i32) -> Result<Self> {
>> - // MAX_NUMNODES never exceeds 2**10 because NODES_SHIFT is 0..10.
>> - if node < 0 || node >= bindings::MAX_NUMNODES as i32 {
>> - return Err(EINVAL);
>> - }
>> - Ok(Self(node))
>> - }
>> -}
>> -
>> -/// Specify necessary constant to pass the information to Allocator that the caller doesn't care
>> -/// about the NUMA node to allocate memory from.
>> -impl NumaNode {
>> - /// No node preference.
>> - pub const NO_NODE: NumaNode = NumaNode(bindings::NUMA_NO_NODE);
>> -}
>> -
>> /// The kernel's [`Allocator`] trait.
>> ///
>> /// An implementation of [`Allocator`] can allocate, re-allocate and free memory buffers described
>> diff --git a/rust/kernel/alloc/allocator.rs b/rust/kernel/alloc/allocator.rs
>> index cd4203f27aed..4af50e20933b 100644
>> --- a/rust/kernel/alloc/allocator.rs
>> +++ b/rust/kernel/alloc/allocator.rs
>> @@ -11,12 +11,12 @@
>> use super::{
>> AllocError,
>> Allocator,
>> - Flags,
>> - NumaNode, //
>> + Flags, //
>> };
>>
>> use crate::{
>> bindings,
>> + numa::NumaNode,
>> page, //
>> };
>>
>> @@ -122,7 +122,7 @@ unsafe fn call(
>> // - Those functions provide the guarantees of this function.
>> let raw_ptr = unsafe {
>> // If `size == 0` and `ptr != NULL` the memory behind the pointer is freed.
>> - self.0(ptr.cast(), size, layout.align(), flags.0, nid.0).cast()
>> + self.0(ptr.cast(), size, layout.align(), flags.0, nid.as_raw()).cast()
>> };
>>
>> let ptr = if size == 0 {
>> diff --git a/rust/kernel/alloc/kbox.rs b/rust/kernel/alloc/kbox.rs
>> index c63d6acdbb6f..0fa736c81287 100644
>> --- a/rust/kernel/alloc/kbox.rs
>> +++ b/rust/kernel/alloc/kbox.rs
>> @@ -13,12 +13,12 @@
>> use super::{
>> AllocError,
>> Allocator,
>> - Flags,
>> - NumaNode, //
>> + Flags, //
>> };
>>
>> use crate::{
>> fmt,
>> + numa::NumaNode,
>> page::AsPageIter,
>> prelude::*,
>> types::ForeignOwnable, //
>> diff --git a/rust/kernel/alloc/kvec.rs b/rust/kernel/alloc/kvec.rs
>> index c7546b9da4fa..b669ca10b3f7 100644
>> --- a/rust/kernel/alloc/kvec.rs
>> +++ b/rust/kernel/alloc/kvec.rs
>> @@ -14,12 +14,12 @@
>> AllocError,
>> Allocator,
>> Box,
>> - Flags,
>> - NumaNode, //
>> + Flags, //
>> };
>>
>> use crate::{
>> fmt,
>> + numa::NumaNode,
>> page::{
>> AsPageIter,
>> PAGE_SIZE, //
>> diff --git a/rust/kernel/numa.rs b/rust/kernel/numa.rs
>> index 164e622d325f..4a3a880308f3 100644
>> --- a/rust/kernel/numa.rs
>> +++ b/rust/kernel/numa.rs
>> @@ -4,12 +4,15 @@
>> //!
>> //! C header: [`include/linux/nodemask.h`](srctree/include/linux/nodemask.h)
>>
>> -use crate::bindings;
>> #[cfg(CONFIG_NUMA)]
>> use crate::sync::atomic::{
>> Atomic,
>> Relaxed, //
>> };
>> +use crate::{
>> + bindings,
>> + prelude::*, //
>> +};
>>
>> /// Returns the number of online NUMA nodes.
>> #[inline]
>> @@ -27,3 +30,33 @@ pub fn num_online_nodes() -> u32 {
>> bindings::nr_online_nodes
>> }
>> }
>> +
>> +/// Non Uniform Memory Access (NUMA) node identifier.
>> +#[derive(Clone, Copy, PartialEq)]
>> +pub struct NumaNode(i32);
>
> FWIW the C type is nodemask_t and this should have mask in the name too. It is
> not an identifier. That said, this is an existing issue, so shouldn't block the
> move.

What makes you say this? This is not a mask, it is a numa node id, which
is represented as i32. `NUMA_NO_NODE` is a valid id.

I am using this to specify domain for block mq queues. If you take a
look at the allocation path:

blk_mq_alloc_queue
blk_alloc_queue
slab_alloc_node

It's an id, named `numa_node`, `node_id`, `node`. Not a mask. Unless I
missed something?

Best regards,
Andreas Hindborg