rust-for-linux.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v5 0/2] rust: alloc: kvec doc example and allocator unit tests
@ 2025-07-25  7:02 Hui Zhu
  2025-07-25  7:02 ` [PATCH v5 1/2] rust: allocator: add KUnit tests for alignment guarantees Hui Zhu
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Hui Zhu @ 2025-07-25  7:02 UTC (permalink / raw)
  To: Danilo Krummrich, Lorenzo Stoakes, Vlastimil Babka,
	Liam R . Howlett, Uladzislau Rezki, Miguel Ojeda, Alex Gaynor,
	Boqun Feng, Gary Guo, bjorn3_gh, Benno Lossin, Andreas Hindborg,
	Alice Ryhl, Trevor Gross, rust-for-linux, linux-kernel
  Cc: Hui Zhu

From: Hui Zhu <zhuhui@kylinos.cn>

This series includes two Rust patches:

Patch 1 adds KUnit tests for alignment guarantees in Rust allocators.
Validates kmalloc handling of standard (128B) and page-size (8KB)
alignments.
Confirms vmalloc/kvmalloc reject oversized alignment requests.
Ensures Rust allocators respect kernel allocation constraints.

Patch 2 improves the documentation for KVec::as_slice() by adding a
code example. This shows how to use the method with push operations and
assertions.

Both patches are co-developed with Geliang Tang. Tested on x86_64 using
KUnit.

Changelog:
v5:
According to the comments of Danilo, change to use generic struct and
allocator Generics in allocator.rs.
v4:
According to the comments of, add the error check for push.
v3:
According to the comments of Danilo and Boqun, move KVec test to doc
example and move VBox to allocator unit tests.
v2:
According to the comments of Danilo, updated the commit to samples the
usage of VBox and KVec.

Hui Zhu (2):
  rust: allocator: add KUnit tests for alignment guarantees
  rust: alloc: kvec: add doc example for as_slice method

 rust/kernel/alloc/allocator.rs | 58 ++++++++++++++++++++++++++++++++++
 rust/kernel/alloc/kvec.rs      | 10 ++++++
 2 files changed, 68 insertions(+)

-- 
2.43.0


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

* [PATCH v5 1/2] rust: allocator: add KUnit tests for alignment guarantees
  2025-07-25  7:02 [PATCH v5 0/2] rust: alloc: kvec doc example and allocator unit tests Hui Zhu
@ 2025-07-25  7:02 ` Hui Zhu
  2025-07-25  9:50   ` Danilo Krummrich
  2025-07-25  7:02 ` [PATCH v5 2/2] rust: alloc: kvec: add doc example for as_slice method Hui Zhu
  2025-07-27  7:16 ` [PATCH v5 0/2] rust: alloc: kvec doc example and allocator unit tests Alice Ryhl
  2 siblings, 1 reply; 7+ messages in thread
From: Hui Zhu @ 2025-07-25  7:02 UTC (permalink / raw)
  To: Danilo Krummrich, Lorenzo Stoakes, Vlastimil Babka,
	Liam R . Howlett, Uladzislau Rezki, Miguel Ojeda, Alex Gaynor,
	Boqun Feng, Gary Guo, bjorn3_gh, Benno Lossin, Andreas Hindborg,
	Alice Ryhl, Trevor Gross, rust-for-linux, linux-kernel
  Cc: Hui Zhu, Geliang Tang

From: Hui Zhu <zhuhui@kylinos.cn>

Add comprehensive tests to verify correct alignment handling in Rust
allocator wrappers. The tests validate:

That kmalloc respects both standard (128-byte) and page-size
(8192-byte) alignments when allocating structs with explicit alignment
attributes.

That vmalloc correctly handles standard alignments but intentionally
rejects allocations requiring alignments larger than its capabilities.

That kvmalloc mirrors vmalloc's constraints, accepting standard
alignments but rejecting excessive alignment requirements.

The test infrastructure uses specialized aligned structs (Blob and
LargeAlignBlob) and a test harness (TestAlign) to validate pointer
alignment through different allocation paths. This ensures our Rust
allocators correctly propagate kernel allocation constraints.

Co-developed-by: Geliang Tang <geliang@kernel.org>
Signed-off-by: Geliang Tang <geliang@kernel.org>
Signed-off-by: Hui Zhu <zhuhui@kylinos.cn>
---
 rust/kernel/alloc/allocator.rs | 58 ++++++++++++++++++++++++++++++++++
 1 file changed, 58 insertions(+)

diff --git a/rust/kernel/alloc/allocator.rs b/rust/kernel/alloc/allocator.rs
index aa2dfa9dca4c..bcc916240f11 100644
--- a/rust/kernel/alloc/allocator.rs
+++ b/rust/kernel/alloc/allocator.rs
@@ -187,3 +187,61 @@ unsafe fn realloc(
         unsafe { ReallocFunc::KVREALLOC.call(ptr, layout, old_layout, flags) }
     }
 }
+
+#[macros::kunit_tests(rust_allocator_kunit)]
+mod tests {
+    use super::*;
+    use core::mem::MaybeUninit;
+    use kernel::prelude::*;
+
+    const TEST_SIZE: usize = 1024;
+    const TEST_LARGE_ALIGN_SIZE: usize = kernel::page::PAGE_SIZE * 4;
+
+    // These two structs are used to test allocating aligned memory.
+    // they don't need to be accessed, so they're marked as dead_code.
+    #[allow(dead_code)]
+    #[repr(align(128))]
+    struct Blob([u8; TEST_SIZE]);
+    #[allow(dead_code)]
+    #[repr(align(8192))]
+    struct LargeAlignBlob([u8; TEST_LARGE_ALIGN_SIZE]);
+
+    struct TestAlign<T, A: Allocator>(Box<MaybeUninit<T>, A>);
+    impl<T, A: Allocator> TestAlign<T, A> {
+        fn new() -> Result<Self> {
+            Ok(Self(Box::<_, A>::new_uninit(GFP_KERNEL)?))
+        }
+
+        fn alignment_valid(&self, align: usize) -> bool {
+            assert!(align.is_power_of_two());
+
+            let addr = self.0.as_ptr() as usize;
+            if addr & (align - 1) != 0 {
+                false
+            } else {
+                true
+            }
+        }
+    }
+
+    #[test]
+    fn test_alignment() -> Result<()> {
+        let ta = TestAlign::<Blob, Kmalloc>::new()?;
+        assert!(ta.alignment_valid(128));
+
+        let ta = TestAlign::<LargeAlignBlob, Kmalloc>::new()?;
+        assert!(ta.alignment_valid(8192));
+
+        let ta = TestAlign::<Blob, Vmalloc>::new()?;
+        assert!(ta.alignment_valid(128));
+
+        assert!(TestAlign::<LargeAlignBlob, Vmalloc>::new().is_err());
+
+        let ta = TestAlign::<Blob, KVmalloc>::new()?;
+        assert!(ta.alignment_valid(128));
+
+        assert!(TestAlign::<LargeAlignBlob, KVmalloc>::new().is_err());
+
+        Ok(())
+    }
+}
-- 
2.43.0


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

* [PATCH v5 2/2] rust: alloc: kvec: add doc example for as_slice method
  2025-07-25  7:02 [PATCH v5 0/2] rust: alloc: kvec doc example and allocator unit tests Hui Zhu
  2025-07-25  7:02 ` [PATCH v5 1/2] rust: allocator: add KUnit tests for alignment guarantees Hui Zhu
@ 2025-07-25  7:02 ` Hui Zhu
  2025-07-27  7:16 ` [PATCH v5 0/2] rust: alloc: kvec doc example and allocator unit tests Alice Ryhl
  2 siblings, 0 replies; 7+ messages in thread
From: Hui Zhu @ 2025-07-25  7:02 UTC (permalink / raw)
  To: Danilo Krummrich, Lorenzo Stoakes, Vlastimil Babka,
	Liam R . Howlett, Uladzislau Rezki, Miguel Ojeda, Alex Gaynor,
	Boqun Feng, Gary Guo, bjorn3_gh, Benno Lossin, Andreas Hindborg,
	Alice Ryhl, Trevor Gross, rust-for-linux, linux-kernel
  Cc: Hui Zhu, Geliang Tang

From: Hui Zhu <zhuhui@kylinos.cn>

Add a practical usage example to the documentation of KVec::as_slice()
showing how to:
Create a new KVec.
Push elements into it.
Convert to a slice via as_slice().

Co-developed-by: Geliang Tang <geliang@kernel.org>
Signed-off-by: Geliang Tang <geliang@kernel.org>
Signed-off-by: Hui Zhu <zhuhui@kylinos.cn>
---
 rust/kernel/alloc/kvec.rs | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/rust/kernel/alloc/kvec.rs b/rust/kernel/alloc/kvec.rs
index 3c72e0bdddb8..fa04cc0987d6 100644
--- a/rust/kernel/alloc/kvec.rs
+++ b/rust/kernel/alloc/kvec.rs
@@ -224,6 +224,16 @@ unsafe fn dec_len(&mut self, count: usize) -> &mut [T] {
     }
 
     /// Returns a slice of the entire vector.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let mut v = KVec::new();
+    /// v.push(1, GFP_KERNEL)?;
+    /// v.push(2, GFP_KERNEL)?;
+    /// assert_eq!(v.as_slice(), &[1, 2]);
+    /// # Ok::<(), Error>(())
+    /// ```
     #[inline]
     pub fn as_slice(&self) -> &[T] {
         self
-- 
2.43.0


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

* Re: [PATCH v5 1/2] rust: allocator: add KUnit tests for alignment guarantees
  2025-07-25  7:02 ` [PATCH v5 1/2] rust: allocator: add KUnit tests for alignment guarantees Hui Zhu
@ 2025-07-25  9:50   ` Danilo Krummrich
  2025-07-25 10:02     ` Danilo Krummrich
  0 siblings, 1 reply; 7+ messages in thread
From: Danilo Krummrich @ 2025-07-25  9:50 UTC (permalink / raw)
  To: Hui Zhu
  Cc: Lorenzo Stoakes, Vlastimil Babka, Liam R . Howlett,
	Uladzislau Rezki, Miguel Ojeda, Alex Gaynor, Boqun Feng, Gary Guo,
	bjorn3_gh, Benno Lossin, Andreas Hindborg, Alice Ryhl,
	Trevor Gross, rust-for-linux, linux-kernel, Hui Zhu, Geliang Tang

On Fri Jul 25, 2025 at 9:02 AM CEST, Hui Zhu wrote:
> From: Hui Zhu <zhuhui@kylinos.cn>
>
> Add comprehensive tests to verify correct alignment handling in Rust
> allocator wrappers. The tests validate:
>
> That kmalloc respects both standard (128-byte) and page-size
> (8192-byte) alignments when allocating structs with explicit alignment
> attributes.
>
> That vmalloc correctly handles standard alignments but intentionally
> rejects allocations requiring alignments larger than its capabilities.
>
> That kvmalloc mirrors vmalloc's constraints, accepting standard
> alignments but rejecting excessive alignment requirements.
>
> The test infrastructure uses specialized aligned structs (Blob and
> LargeAlignBlob) and a test harness (TestAlign) to validate pointer
> alignment through different allocation paths. This ensures our Rust
> allocators correctly propagate kernel allocation constraints.
>
> Co-developed-by: Geliang Tang <geliang@kernel.org>
> Signed-off-by: Geliang Tang <geliang@kernel.org>
> Signed-off-by: Hui Zhu <zhuhui@kylinos.cn>

Thanks, this looks good. I think it would be good to rebase onto [1], since it
will likely land in the same cycle. Additionally, two nits below.

As a follow-up we could also test alignment in the context of
Allocator::realloc(), i.e. when growing and shrinking buffers or requesting a
different NUMA node.

[1] https://lore.kernel.org/lkml/20250715135645.2230065-1-vitaly.wool@konsulko.se/

> ---
>  rust/kernel/alloc/allocator.rs | 58 ++++++++++++++++++++++++++++++++++
>  1 file changed, 58 insertions(+)
>
> diff --git a/rust/kernel/alloc/allocator.rs b/rust/kernel/alloc/allocator.rs
> index aa2dfa9dca4c..bcc916240f11 100644
> --- a/rust/kernel/alloc/allocator.rs
> +++ b/rust/kernel/alloc/allocator.rs
> @@ -187,3 +187,61 @@ unsafe fn realloc(
>          unsafe { ReallocFunc::KVREALLOC.call(ptr, layout, old_layout, flags) }
>      }
>  }
> +
> +#[macros::kunit_tests(rust_allocator_kunit)]
> +mod tests {
> +    use super::*;
> +    use core::mem::MaybeUninit;
> +    use kernel::prelude::*;
> +

--8<--

> +    const TEST_SIZE: usize = 1024;
> +    const TEST_LARGE_ALIGN_SIZE: usize = kernel::page::PAGE_SIZE * 4;
> +
> +    // These two structs are used to test allocating aligned memory.
> +    // they don't need to be accessed, so they're marked as dead_code.
> +    #[allow(dead_code)]

This should be #[expect(dead_code)].

> +    #[repr(align(128))]
> +    struct Blob([u8; TEST_SIZE]);
> +    #[allow(dead_code)]
> +    #[repr(align(8192))]
> +    struct LargeAlignBlob([u8; TEST_LARGE_ALIGN_SIZE]);
> +
> +    struct TestAlign<T, A: Allocator>(Box<MaybeUninit<T>, A>);
> +    impl<T, A: Allocator> TestAlign<T, A> {
> +        fn new() -> Result<Self> {
> +            Ok(Self(Box::<_, A>::new_uninit(GFP_KERNEL)?))
> +        }
> +
> +        fn alignment_valid(&self, align: usize) -> bool {
> +            assert!(align.is_power_of_two());
> +
> +            let addr = self.0.as_ptr() as usize;
> +            if addr & (align - 1) != 0 {
> +                false
> +            } else {
> +                true
> +            }

This can just be

	addr & (align - 1) == 0

instead of the conditional clause.

> +        }
> +    }

We could move all the above into test_alignment() given that it's likely only
needed from there.

> +
> +    #[test]
> +    fn test_alignment() -> Result<()> {
> +        let ta = TestAlign::<Blob, Kmalloc>::new()?;
> +        assert!(ta.alignment_valid(128));
> +
> +        let ta = TestAlign::<LargeAlignBlob, Kmalloc>::new()?;
> +        assert!(ta.alignment_valid(8192));
> +
> +        let ta = TestAlign::<Blob, Vmalloc>::new()?;
> +        assert!(ta.alignment_valid(128));
> +
> +        assert!(TestAlign::<LargeAlignBlob, Vmalloc>::new().is_err());
> +
> +        let ta = TestAlign::<Blob, KVmalloc>::new()?;
> +        assert!(ta.alignment_valid(128));
> +
> +        assert!(TestAlign::<LargeAlignBlob, KVmalloc>::new().is_err());
> +
> +        Ok(())
> +    }
> +}
> -- 
> 2.43.0


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

* Re: [PATCH v5 1/2] rust: allocator: add KUnit tests for alignment guarantees
  2025-07-25  9:50   ` Danilo Krummrich
@ 2025-07-25 10:02     ` Danilo Krummrich
  2025-07-30  3:59       ` Hui Zhu
  0 siblings, 1 reply; 7+ messages in thread
From: Danilo Krummrich @ 2025-07-25 10:02 UTC (permalink / raw)
  To: Hui Zhu
  Cc: Lorenzo Stoakes, Vlastimil Babka, Liam R . Howlett,
	Uladzislau Rezki, Miguel Ojeda, Alex Gaynor, Boqun Feng, Gary Guo,
	bjorn3_gh, Benno Lossin, Andreas Hindborg, Alice Ryhl,
	Trevor Gross, rust-for-linux, linux-kernel, Hui Zhu, Geliang Tang,
	Andrew Morton

(Cc: Andrew)

On Fri Jul 25, 2025 at 11:50 AM CEST, Danilo Krummrich wrote:
> On Fri Jul 25, 2025 at 9:02 AM CEST, Hui Zhu wrote:
>> From: Hui Zhu <zhuhui@kylinos.cn>
>>
>> Add comprehensive tests to verify correct alignment handling in Rust
>> allocator wrappers. The tests validate:
>>
>> That kmalloc respects both standard (128-byte) and page-size
>> (8192-byte) alignments when allocating structs with explicit alignment
>> attributes.
>>
>> That vmalloc correctly handles standard alignments but intentionally
>> rejects allocations requiring alignments larger than its capabilities.
>>
>> That kvmalloc mirrors vmalloc's constraints, accepting standard
>> alignments but rejecting excessive alignment requirements.
>>
>> The test infrastructure uses specialized aligned structs (Blob and
>> LargeAlignBlob) and a test harness (TestAlign) to validate pointer
>> alignment through different allocation paths. This ensures our Rust
>> allocators correctly propagate kernel allocation constraints.
>>
>> Co-developed-by: Geliang Tang <geliang@kernel.org>
>> Signed-off-by: Geliang Tang <geliang@kernel.org>
>> Signed-off-by: Hui Zhu <zhuhui@kylinos.cn>
>
> Thanks, this looks good. I think it would be good to rebase onto [1], since it
> will likely land in the same cycle. Additionally, two nits below.

Please also Cc: Andrew for subsequent submissions, since this will, due to the
interaction with [1] likely go through his tree.

> As a follow-up we could also test alignment in the context of
> Allocator::realloc(), i.e. when growing and shrinking buffers or requesting a
> different NUMA node.
>
> [1] https://lore.kernel.org/lkml/20250715135645.2230065-1-vitaly.wool@konsulko.se/
>
>> ---
>>  rust/kernel/alloc/allocator.rs | 58 ++++++++++++++++++++++++++++++++++
>>  1 file changed, 58 insertions(+)
>>
>> diff --git a/rust/kernel/alloc/allocator.rs b/rust/kernel/alloc/allocator.rs
>> index aa2dfa9dca4c..bcc916240f11 100644
>> --- a/rust/kernel/alloc/allocator.rs
>> +++ b/rust/kernel/alloc/allocator.rs
>> @@ -187,3 +187,61 @@ unsafe fn realloc(
>>          unsafe { ReallocFunc::KVREALLOC.call(ptr, layout, old_layout, flags) }
>>      }
>>  }
>> +
>> +#[macros::kunit_tests(rust_allocator_kunit)]
>> +mod tests {
>> +    use super::*;
>> +    use core::mem::MaybeUninit;
>> +    use kernel::prelude::*;
>> +
>
> --8<--
>
>> +    const TEST_SIZE: usize = 1024;
>> +    const TEST_LARGE_ALIGN_SIZE: usize = kernel::page::PAGE_SIZE * 4;
>> +
>> +    // These two structs are used to test allocating aligned memory.
>> +    // they don't need to be accessed, so they're marked as dead_code.
>> +    #[allow(dead_code)]
>
> This should be #[expect(dead_code)].
>
>> +    #[repr(align(128))]
>> +    struct Blob([u8; TEST_SIZE]);
>> +    #[allow(dead_code)]
>> +    #[repr(align(8192))]
>> +    struct LargeAlignBlob([u8; TEST_LARGE_ALIGN_SIZE]);
>> +
>> +    struct TestAlign<T, A: Allocator>(Box<MaybeUninit<T>, A>);
>> +    impl<T, A: Allocator> TestAlign<T, A> {
>> +        fn new() -> Result<Self> {
>> +            Ok(Self(Box::<_, A>::new_uninit(GFP_KERNEL)?))
>> +        }
>> +
>> +        fn alignment_valid(&self, align: usize) -> bool {
>> +            assert!(align.is_power_of_two());
>> +
>> +            let addr = self.0.as_ptr() as usize;
>> +            if addr & (align - 1) != 0 {
>> +                false
>> +            } else {
>> +                true
>> +            }
>
> This can just be
>
> 	addr & (align - 1) == 0
>
> instead of the conditional clause.
>
>> +        }
>> +    }
>
> We could move all the above into test_alignment() given that it's likely only
> needed from there.
>
>> +
>> +    #[test]
>> +    fn test_alignment() -> Result<()> {
>> +        let ta = TestAlign::<Blob, Kmalloc>::new()?;
>> +        assert!(ta.alignment_valid(128));
>> +
>> +        let ta = TestAlign::<LargeAlignBlob, Kmalloc>::new()?;
>> +        assert!(ta.alignment_valid(8192));
>> +
>> +        let ta = TestAlign::<Blob, Vmalloc>::new()?;
>> +        assert!(ta.alignment_valid(128));
>> +
>> +        assert!(TestAlign::<LargeAlignBlob, Vmalloc>::new().is_err());
>> +
>> +        let ta = TestAlign::<Blob, KVmalloc>::new()?;
>> +        assert!(ta.alignment_valid(128));
>> +
>> +        assert!(TestAlign::<LargeAlignBlob, KVmalloc>::new().is_err());
>> +
>> +        Ok(())
>> +    }
>> +}
>> -- 
>> 2.43.0


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

* Re: [PATCH v5 0/2] rust: alloc: kvec doc example and allocator unit tests
  2025-07-25  7:02 [PATCH v5 0/2] rust: alloc: kvec doc example and allocator unit tests Hui Zhu
  2025-07-25  7:02 ` [PATCH v5 1/2] rust: allocator: add KUnit tests for alignment guarantees Hui Zhu
  2025-07-25  7:02 ` [PATCH v5 2/2] rust: alloc: kvec: add doc example for as_slice method Hui Zhu
@ 2025-07-27  7:16 ` Alice Ryhl
  2 siblings, 0 replies; 7+ messages in thread
From: Alice Ryhl @ 2025-07-27  7:16 UTC (permalink / raw)
  To: Hui Zhu
  Cc: Danilo Krummrich, Lorenzo Stoakes, Vlastimil Babka,
	Liam R . Howlett, Uladzislau Rezki, Miguel Ojeda, Alex Gaynor,
	Boqun Feng, Gary Guo, bjorn3_gh, Benno Lossin, Andreas Hindborg,
	Trevor Gross, rust-for-linux, linux-kernel, Hui Zhu

On Fri, Jul 25, 2025 at 03:02:19PM +0800, Hui Zhu wrote:
> From: Hui Zhu <zhuhui@kylinos.cn>
> 
> This series includes two Rust patches:
> 
> Patch 1 adds KUnit tests for alignment guarantees in Rust allocators.
> Validates kmalloc handling of standard (128B) and page-size (8KB)
> alignments.
> Confirms vmalloc/kvmalloc reject oversized alignment requests.
> Ensures Rust allocators respect kernel allocation constraints.
> 
> Patch 2 improves the documentation for KVec::as_slice() by adding a
> code example. This shows how to use the method with push operations and
> assertions.
> 
> Both patches are co-developed with Geliang Tang. Tested on x86_64 using
> KUnit.

Reviewed-by: Alice Ryhl <aliceryhl@google.com>

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

* Re: [PATCH v5 1/2] rust: allocator: add KUnit tests for alignment guarantees
  2025-07-25 10:02     ` Danilo Krummrich
@ 2025-07-30  3:59       ` Hui Zhu
  0 siblings, 0 replies; 7+ messages in thread
From: Hui Zhu @ 2025-07-30  3:59 UTC (permalink / raw)
  To: Danilo Krummrich
  Cc: Lorenzo Stoakes, Vlastimil Babka, Liam R . Howlett,
	Uladzislau  Rezki, Miguel Ojeda, Alex Gaynor, Boqun Feng,
	Gary Guo, bjorn3_gh, Benno Lossin, Andreas Hindborg, Alice  Ryhl,
	Trevor Gross, rust-for-linux, linux-kernel, Hui Zhu, Geliang Tang,
	Andrew Morton, vitaly.wool

2025年7月25日 18:02, "Danilo Krummrich" <dakr@kernel.org mailto:dakr@kernel.org?to=%22Danilo%20Krummrich%22%20%3Cdakr%40kernel.org%3E > 写到:


> 
> (Cc: Andrew)
> 
> On Fri Jul 25, 2025 at 11:50 AM CEST, Danilo Krummrich wrote:
> 
> > 
> > On Fri Jul 25, 2025 at 9:02 AM CEST, Hui Zhu wrote:
> > 
> > > 
> > > From: Hui Zhu <zhuhui@kylinos.cn>
> > > 
> > >  Add comprehensive tests to verify correct alignment handling in Rust
> > >  allocator wrappers. The tests validate:
> > > 
> > >  That kmalloc respects both standard (128-byte) and page-size
> > >  (8192-byte) alignments when allocating structs with explicit alignment
> > >  attributes.
> > > 
> > >  That vmalloc correctly handles standard alignments but intentionally
> > >  rejects allocations requiring alignments larger than its capabilities.
> > > 
> > >  That kvmalloc mirrors vmalloc's constraints, accepting standard
> > >  alignments but rejecting excessive alignment requirements.
> > > 
> > >  The test infrastructure uses specialized aligned structs (Blob and
> > >  LargeAlignBlob) and a test harness (TestAlign) to validate pointer
> > >  alignment through different allocation paths. This ensures our Rust
> > >  allocators correctly propagate kernel allocation constraints.
> > > 
> > >  Co-developed-by: Geliang Tang <geliang@kernel.org>
> > >  Signed-off-by: Geliang Tang <geliang@kernel.org>
> > >  Signed-off-by: Hui Zhu <zhuhui@kylinos.cn>
> > > 
> >  Thanks, this looks good. I think it would be good to rebase onto [1], since it
> >  will likely land in the same cycle. Additionally, two nits below.
> > 
> Please also Cc: Andrew for subsequent submissions, since this will, due to the
> interaction with [1] likely go through his tree.
> 
> > 
> > As a follow-up we could also test alignment in the context of
> >  Allocator::realloc(), i.e. when growing and shrinking buffers or requesting a
> >  different NUMA node.
> > 
> >  [1] https://lore.kernel.org/lkml/20250715135645.2230065-1-vitaly.wool@konsulko.se/
> > 
> > > 
> > > ---
> > >  rust/kernel/alloc/allocator.rs | 58 ++++++++++++++++++++++++++++++++++
> > >  1 file changed, 58 insertions(+)
> > > 
> > >  diff --git a/rust/kernel/alloc/allocator.rs b/rust/kernel/alloc/allocator.rs
> > >  index aa2dfa9dca4c..bcc916240f11 100644
> > >  --- a/rust/kernel/alloc/allocator.rs
> > >  +++ b/rust/kernel/alloc/allocator.rs
> > >  @@ -187,3 +187,61 @@ unsafe fn realloc(
> > >  unsafe { ReallocFunc::KVREALLOC.call(ptr, layout, old_layout, flags) }
> > >  }
> > >  }
> > >  +
> > >  +#[macros::kunit_tests(rust_allocator_kunit)]
> > >  +mod tests {
> > >  + use super::*;
> > >  + use core::mem::MaybeUninit;
> > >  + use kernel::prelude::*;
> > >  +
> > > 
> >  --8<--
> > 
> > > 
> > > + const TEST_SIZE: usize = 1024;
> > >  + const TEST_LARGE_ALIGN_SIZE: usize = kernel::page::PAGE_SIZE * 4;
> > >  +
> > >  + // These two structs are used to test allocating aligned memory.
> > >  + // they don't need to be accessed, so they're marked as dead_code.
> > >  + #[allow(dead_code)]
> > > 
> >  This should be #[expect(dead_code)].
> > 
> > > 
> > > + #[repr(align(128))]
> > >  + struct Blob([u8; TEST_SIZE]);
> > >  + #[allow(dead_code)]
> > >  + #[repr(align(8192))]
> > >  + struct LargeAlignBlob([u8; TEST_LARGE_ALIGN_SIZE]);
> > >  +
> > >  + struct TestAlign<T, A: Allocator>(Box<MaybeUninit<T>, A>);
> > >  + impl<T, A: Allocator> TestAlign<T, A> {
> > >  + fn new() -> Result<Self> {
> > >  + Ok(Self(Box::<_, A>::new_uninit(GFP_KERNEL)?))
> > >  + }
> > >  +
> > >  + fn alignment_valid(&self, align: usize) -> bool {
> > >  + assert!(align.is_power_of_two());
> > >  +
> > >  + let addr = self.0.as_ptr() as usize;
> > >  + if addr & (align - 1) != 0 {
> > >  + false
> > >  + } else {
> > >  + true
> > >  + }
> > > 
> >  This can just be
> > 
> >  addr & (align - 1) == 0
> > 
> >  instead of the conditional clause.
> > 
> > > 
> > > + }
> > >  + }
> > > 
> >  We could move all the above into test_alignment() given that it's likely only
> >  needed from there.
> > 
> > > 

Hi Danilo,

Thanks!

I sent v6 version that rebased on [1].

Best,
Hui

[1] https://lore.kernel.org/lkml/20250715135645.2230065-1-vitaly.wool@konsulko.se/

> > > +
> > >  + #[test]
> > >  + fn test_alignment() -> Result<()> {
> > >  + let ta = TestAlign::<Blob, Kmalloc>::new()?;
> > >  + assert!(ta.alignment_valid(128));
> > >  +
> > >  + let ta = TestAlign::<LargeAlignBlob, Kmalloc>::new()?;
> > >  + assert!(ta.alignment_valid(8192));
> > >  +
> > >  + let ta = TestAlign::<Blob, Vmalloc>::new()?;
> > >  + assert!(ta.alignment_valid(128));
> > >  +
> > >  + assert!(TestAlign::<LargeAlignBlob, Vmalloc>::new().is_err());
> > >  +
> > >  + let ta = TestAlign::<Blob, KVmalloc>::new()?;
> > >  + assert!(ta.alignment_valid(128));
> > >  +
> > >  + assert!(TestAlign::<LargeAlignBlob, KVmalloc>::new().is_err());
> > >  +
> > >  + Ok(())
> > >  + }
> > >  +}
> > >  -- 
> > >  2.43.0
> > >
> >
>

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

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

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-07-25  7:02 [PATCH v5 0/2] rust: alloc: kvec doc example and allocator unit tests Hui Zhu
2025-07-25  7:02 ` [PATCH v5 1/2] rust: allocator: add KUnit tests for alignment guarantees Hui Zhu
2025-07-25  9:50   ` Danilo Krummrich
2025-07-25 10:02     ` Danilo Krummrich
2025-07-30  3:59       ` Hui Zhu
2025-07-25  7:02 ` [PATCH v5 2/2] rust: alloc: kvec: add doc example for as_slice method Hui Zhu
2025-07-27  7:16 ` [PATCH v5 0/2] rust: alloc: kvec doc example and allocator unit tests Alice Ryhl

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).