Re: [PATCH v13 3/4] rust: add support for NUMA ids in allocations

"Danilo Krummrich" <[email protected]>
Newsgroups org.kernel.vger.linux-bcachefs,org.kernel.vger.bpf,org.kernel.vger.linux-kernel,org.kernel.vger.rust-for-linux,org.kvack.linux-mm
Message-ID <[email protected]>
On Tue Jul 15, 2025 at 3:58 PM CEST, Vitaly Wool wrote:
>  pub unsafe trait Allocator {
> -    /// Allocate memory based on `layout` and `flags`.
> +    /// Allocate memory based on `layout`, `flags` and `nid`.
>      ///
>      /// On success, returns a buffer represented as `NonNull<[u8]>` that satisfies the layout
>      /// constraints (i.e. minimum size and alignment as specified by `layout`).
> @@ -153,13 +180,21 @@ pub unsafe trait Allocator {
>      ///
>      /// Additionally, `Flags` are honored as documented in
>      /// <https://docs.kernel.org/core-api/mm-api.html#mm-api-gfp-flags>.
> -    fn alloc(layout: Layout, flags: Flags) -> Result<NonNull<[u8]>, AllocError> {
> +    fn alloc(layout: Layout, flags: Flags, nid: NumaNode) -> Result<NonNull<[u8]>, AllocError> {
>          // SAFETY: Passing `None` to `realloc` is valid by its safety requirements and asks for a
>          // new memory allocation.
> -        unsafe { Self::realloc(None, layout, Layout::new::<()>(), flags) }
> +        unsafe { Self::realloc(None, layout, Layout::new::<()>(), flags, nid) }
>      }
>  
> -    /// Re-allocate an existing memory allocation to satisfy the requested `layout`.
> +    /// Re-allocate an existing memory allocation to satisfy the requested `layout` and
> +    /// a specific NUMA node request to allocate the memory for.
> +    ///
> +    /// Systems employing a Non Uniform Memory Access (NUMA) architecture contain collections of
> +    /// hardware resources including processors, memory, and I/O buses, that comprise what is
> +    /// commonly known as a NUMA node.
> +    ///
> +    /// `nid` stands for NUMA id, i. e. NUMA node identifier, which is a non-negative integer
> +    /// if a node needs to be specified, or [`NumaNode::NO_NODE`] if the caller doesn't care.
>      ///
>      /// If the requested size is zero, `realloc` behaves equivalent to `free`.
>      ///
> @@ -196,6 +231,7 @@ unsafe fn realloc(
>          layout: Layout,
>          old_layout: Layout,
>          flags: Flags,
> +        nid: NumaNode,
>      ) -> Result<NonNull<[u8]>, AllocError>;
>  
>      /// Free an existing memory allocation.
> @@ -211,7 +247,15 @@ unsafe fn free(ptr: NonNull<u8>, layout: Layout) {
>          // SAFETY: The caller guarantees that `ptr` points at a valid allocation created by this
>          // allocator. We are passing a `Layout` with the smallest possible alignment, so it is
>          // smaller than or equal to the alignment previously used with this allocation.
> -        let _ = unsafe { Self::realloc(Some(ptr), Layout::new::<()>(), layout, Flags(0)) };
> +        let _ = unsafe {
> +            Self::realloc(
> +                Some(ptr),
> +                Layout::new::<()>(),
> +                layout,
> +                Flags(0),
> +                NumaNode::NO_NODE,
> +            )
> +        };
>      }
>  }

Regarding the change in the Allocator trait, we also have to consider
the Cmalloc allocator in rust/kernel/alloc/allocator_test.rs, which is there to
support userspace tests.

While we're planning to remove this (see also [1]), we still have to consider
it for now.

[1] https://lore.kernel.org/rust-for-linux/[email protected]/
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.