The kernel's allocators sometimes provide a higher alignment than the
end-user requested, so add a new constant on the Allocator trait to let
the allocator specify what its minimum guaranteed alignment is.
This allows the ForeignOwnable trait to provide a more accurate value of
FOREIGN_ALIGN when using a pointer type such as Box, which will be
useful with certain collections such as XArray that store its own data
in the low bits of pointers.
Signed-off-by: Alice Ryhl <aliceryhl@google.com>
---
rust/kernel/alloc.rs | 8 ++++++++
rust/kernel/alloc/allocator.rs | 8 ++++++++
2 files changed, 16 insertions(+)
diff --git a/rust/kernel/alloc.rs b/rust/kernel/alloc.rs
index a2c49e5494d334bfde67328464dafcdb31052947..c12753a5fb1c7423a4063553674b537a775c860e 100644
--- a/rust/kernel/alloc.rs
+++ b/rust/kernel/alloc.rs
@@ -137,6 +137,14 @@ pub mod flags {
/// - Implementers must ensure that all trait functions abide by the guarantees documented in the
/// `# Guarantees` sections.
pub unsafe trait Allocator {
+ /// The minimum alignment satisfied by all allocations from this allocator.
+ ///
+ /// # Guarantees
+ ///
+ /// Any pointer allocated by this allocator must be aligned to `MIN_ALIGN` even if the
+ /// requested layout has a smaller alignment.
+ const MIN_ALIGN: usize;
+
/// Allocate memory based on `layout` and `flags`.
///
/// On success, returns a buffer represented as `NonNull<[u8]>` that satisfies the layout
diff --git a/rust/kernel/alloc/allocator.rs b/rust/kernel/alloc/allocator.rs
index aa2dfa9dca4c309e5a9eafc7da6a8a9bd7b54b11..25fc9f9ae3b4e471a08d77130b374bd1397f7384 100644
--- a/rust/kernel/alloc/allocator.rs
+++ b/rust/kernel/alloc/allocator.rs
@@ -17,6 +17,8 @@
use crate::bindings;
use crate::pr_warn;
+const ARCH_KMALLOC_MINALIGN: usize = bindings::ARCH_KMALLOC_MINALIGN as usize;
+
/// The contiguous kernel allocator.
///
/// `Kmalloc` is typically used for physically contiguous allocations up to page size, but also
@@ -128,6 +130,8 @@ unsafe fn call(
// - passing a pointer to a valid memory allocation is OK,
// - `realloc` satisfies the guarantees, since `ReallocFunc::call` has the same.
unsafe impl Allocator for Kmalloc {
+ const MIN_ALIGN: usize = ARCH_KMALLOC_MINALIGN;
+
#[inline]
unsafe fn realloc(
ptr: Option<NonNull<u8>>,
@@ -145,6 +149,8 @@ unsafe fn realloc(
// - passing a pointer to a valid memory allocation is OK,
// - `realloc` satisfies the guarantees, since `ReallocFunc::call` has the same.
unsafe impl Allocator for Vmalloc {
+ const MIN_ALIGN: usize = kernel::page::PAGE_SIZE;
+
#[inline]
unsafe fn realloc(
ptr: Option<NonNull<u8>>,
@@ -169,6 +175,8 @@ unsafe fn realloc(
// - passing a pointer to a valid memory allocation is OK,
// - `realloc` satisfies the guarantees, since `ReallocFunc::call` has the same.
unsafe impl Allocator for KVmalloc {
+ const MIN_ALIGN: usize = ARCH_KMALLOC_MINALIGN;
+
#[inline]
unsafe fn realloc(
ptr: Option<NonNull<u8>>,
--
2.50.0.727.gbf7dc18ff4-goog
On Tue Jul 15, 2025 at 3:46 PM CEST, Alice Ryhl wrote: > The kernel's allocators sometimes provide a higher alignment than the > end-user requested, so add a new constant on the Allocator trait to let > the allocator specify what its minimum guaranteed alignment is. > > This allows the ForeignOwnable trait to provide a more accurate value of > FOREIGN_ALIGN when using a pointer type such as Box, which will be > useful with certain collections such as XArray that store its own data > in the low bits of pointers. > > Signed-off-by: Alice Ryhl <aliceryhl@google.com> With the wording changed according to Danilo's suggestion: Reviewed-by: Benno Lossin <lossin@kernel.org> --- Cheers, Benno > --- > rust/kernel/alloc.rs | 8 ++++++++ > rust/kernel/alloc/allocator.rs | 8 ++++++++ > 2 files changed, 16 insertions(+)
On Tue Jul 15, 2025 at 3:46 PM CEST, Alice Ryhl wrote: > diff --git a/rust/kernel/alloc.rs b/rust/kernel/alloc.rs > index a2c49e5494d334bfde67328464dafcdb31052947..c12753a5fb1c7423a4063553674b537a775c860e 100644 > --- a/rust/kernel/alloc.rs > +++ b/rust/kernel/alloc.rs > @@ -137,6 +137,14 @@ pub mod flags { > /// - Implementers must ensure that all trait functions abide by the guarantees documented in the > /// `# Guarantees` sections. > pub unsafe trait Allocator { > + /// The minimum alignment satisfied by all allocations from this allocator. > + /// > + /// # Guarantees > + /// > + /// Any pointer allocated by this allocator must be aligned to `MIN_ALIGN` even if the > + /// requested layout has a smaller alignment. I'd say "is guaranteed to be aligned to" instead, "must be" reads like a requirement. Speaking of which, I think this also needs to be expressed as a safety requirement of the Allocator trait itself, which the specific allocator implementations need to justify. > + const MIN_ALIGN: usize; > + > /// Allocate memory based on `layout` and `flags`. > /// > /// On success, returns a buffer represented as `NonNull<[u8]>` that satisfies the layout > diff --git a/rust/kernel/alloc/allocator.rs b/rust/kernel/alloc/allocator.rs > index aa2dfa9dca4c309e5a9eafc7da6a8a9bd7b54b11..25fc9f9ae3b4e471a08d77130b374bd1397f7384 100644 > --- a/rust/kernel/alloc/allocator.rs > +++ b/rust/kernel/alloc/allocator.rs > @@ -17,6 +17,8 @@ > use crate::bindings; > use crate::pr_warn; > > +const ARCH_KMALLOC_MINALIGN: usize = bindings::ARCH_KMALLOC_MINALIGN as usize; > + > /// The contiguous kernel allocator. > /// > /// `Kmalloc` is typically used for physically contiguous allocations up to page size, but also > @@ -128,6 +130,8 @@ unsafe fn call( > // - passing a pointer to a valid memory allocation is OK, > // - `realloc` satisfies the guarantees, since `ReallocFunc::call` has the same. > unsafe impl Allocator for Kmalloc { > + const MIN_ALIGN: usize = ARCH_KMALLOC_MINALIGN; > + > #[inline] > unsafe fn realloc( > ptr: Option<NonNull<u8>>, > @@ -145,6 +149,8 @@ unsafe fn realloc( > // - passing a pointer to a valid memory allocation is OK, > // - `realloc` satisfies the guarantees, since `ReallocFunc::call` has the same. > unsafe impl Allocator for Vmalloc { > + const MIN_ALIGN: usize = kernel::page::PAGE_SIZE; > + > #[inline] > unsafe fn realloc( > ptr: Option<NonNull<u8>>, > @@ -169,6 +175,8 @@ unsafe fn realloc( > // - passing a pointer to a valid memory allocation is OK, > // - `realloc` satisfies the guarantees, since `ReallocFunc::call` has the same. > unsafe impl Allocator for KVmalloc { > + const MIN_ALIGN: usize = ARCH_KMALLOC_MINALIGN; > + > #[inline] > unsafe fn realloc( > ptr: Option<NonNull<u8>>,
On Tue, Jul 15, 2025 at 4:05 PM Danilo Krummrich <dakr@kernel.org> wrote: > > On Tue Jul 15, 2025 at 3:46 PM CEST, Alice Ryhl wrote: > > diff --git a/rust/kernel/alloc.rs b/rust/kernel/alloc.rs > > index a2c49e5494d334bfde67328464dafcdb31052947..c12753a5fb1c7423a4063553674b537a775c860e 100644 > > --- a/rust/kernel/alloc.rs > > +++ b/rust/kernel/alloc.rs > > @@ -137,6 +137,14 @@ pub mod flags { > > /// - Implementers must ensure that all trait functions abide by the guarantees documented in the > > /// `# Guarantees` sections. > > pub unsafe trait Allocator { > > + /// The minimum alignment satisfied by all allocations from this allocator. > > + /// > > + /// # Guarantees > > + /// > > + /// Any pointer allocated by this allocator must be aligned to `MIN_ALIGN` even if the > > + /// requested layout has a smaller alignment. > > I'd say "is guaranteed to be aligned to" instead, "must be" reads like a > requirement. Yes I agree that sounds better. > Speaking of which, I think this also needs to be expressed as a safety > requirement of the Allocator trait itself, which the specific allocator > implementations need to justify. The trait safety requirements already says that the implementation must provide the guarantee listed on each item in the trait. Alice
On Tue Jul 15, 2025 at 4:35 PM CEST, Alice Ryhl wrote: > On Tue, Jul 15, 2025 at 4:05 PM Danilo Krummrich <dakr@kernel.org> wrote: >> >> On Tue Jul 15, 2025 at 3:46 PM CEST, Alice Ryhl wrote: >> > diff --git a/rust/kernel/alloc.rs b/rust/kernel/alloc.rs >> > index a2c49e5494d334bfde67328464dafcdb31052947..c12753a5fb1c7423a4063553674b537a775c860e 100644 >> > --- a/rust/kernel/alloc.rs >> > +++ b/rust/kernel/alloc.rs >> > @@ -137,6 +137,14 @@ pub mod flags { >> > /// - Implementers must ensure that all trait functions abide by the guarantees documented in the >> > /// `# Guarantees` sections. >> > pub unsafe trait Allocator { >> > + /// The minimum alignment satisfied by all allocations from this allocator. >> > + /// >> > + /// # Guarantees >> > + /// >> > + /// Any pointer allocated by this allocator must be aligned to `MIN_ALIGN` even if the >> > + /// requested layout has a smaller alignment. >> >> I'd say "is guaranteed to be aligned to" instead, "must be" reads like a >> requirement. > > Yes I agree that sounds better. > >> Speaking of which, I think this also needs to be expressed as a safety >> requirement of the Allocator trait itself, which the specific allocator >> implementations need to justify. > > The trait safety requirements already says that the implementation > must provide the guarantee listed on each item in the trait. Oh, indeed, that's fine then. :)
© 2016 - 2025 Red Hat, Inc.