rust: alloc: kvec doc example and allocator unit tests
Subsystems (2)
v6 cover rust: alloc: kvec doc example and allocator unit tests
From: Hui Zhu <[email protected]>
This patchset adds KUnit tests for allocator alignment guarantees and improves kvec documentation.
Patch 1 adds KUnit tests for verifying alignment guarantees in Rust kernel allocators. Tests cover Kmalloc, Vmalloc and KVmalloc with both standard (128B) and large page-aligned (8192B) allocations.
Patch 2 adds a practical usage example for KVec::as_slice method, showing how to create KVec, push elements and convert to a slice.
Both patches are co-developed with Geliang Tang. Based on [1]. Tested on x86_64 using KUnit.
Changelog:
v6:
According to the comments of Danilo, updated test for allocator.rs and allocator rebase onto [1].
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.
[1] https://lore.kernel.org/lkml/[email protected]/
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 | 56 ++++++++++++++++++++++++++++++++++ rust/kernel/alloc/kvec.rs | 10 ++++++ 2 files changed, 66 insertions(+)
Signature · 1 line
2.43.0
PATCH v6 1/2 rust: allocator: add KUnit tests for alignment guarantees
From: Hui Zhu <[email protected]>
Add a test module to verify memory alignment guarantees for Rust kernel allocators.
The tests cover Kmalloc, Vmalloc and KVmalloc allocators with both standard and large page-aligned allocations.
Key features of the tests:
1. Creates alignment-constrained types:
- 128-byte aligned Blob
- 8192-byte (4-page) aligned LargeAlignBlob
2. Validates allocators using TestAlign helper which:
- Checks address alignment masks
- Supports uninitialized allocations
3. Tests all three allocators with both alignment requirements:
- Kmalloc with 128B and 8192B
- Vmalloc with 128B and 8192B
- KVmalloc with 128B and 8192B
--- rust/kernel/alloc/allocator.rs | 56 ++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+)
rust/kernel/alloc/allocator.rs +56 -0
@@ -184,3 +184,59 @@ unsafe fn realloc(unsafe {ReallocFunc ::KVREALLOC .call (ptr, layout, old_layout, flags, nid) } } } + +#[macros::kunit_tests(rust_allocator_kunit)] +mod tests { +use super ::*; +use core::mem::MaybeUninit ; +use kernel::prelude::*; + +#[test] +fn test_alignment () ->Result <()> { +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. +#[expect(dead_code)] +#[repr(align( 128 ))] +struct Blob ([u8 ;TEST_SIZE ]); +#[expect(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 ; + addr & (align -1 ) ==0 + } + } + +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 )); + +let ta =TestAlign ::<LargeAlignBlob ,Vmalloc >::new ()?; +assert! (ta.alignment_valid (8192 )); + +let ta =TestAlign ::<Blob ,KVmalloc >::new ()?; +assert! (ta.alignment_valid (128 )); + +let ta =TestAlign ::<LargeAlignBlob ,KVmalloc >::new ()?; +assert! (ta.alignment_valid (8192 )); + +Ok (()) + } +}
Signature · 1 line
2.43.0
PATCH v6 2/2 rust: alloc: kvec: add doc example for as_slice method
In reply to Hui ZhuFrom: Hui Zhu <[email protected]>
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().
--- rust/kernel/alloc/kvec.rs | 10 ++++++++++ 1 file changed, 10 insertions(+)
rust/kernel/alloc/kvec.rs +10 -0
@@ -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
Signature · 1 line
2.43.0
Re: [PATCH v6 1/2] rust: allocator: add KUnit tests for alignment guarantees
In reply to Hui ZhuQuoted 19 lines · Hui Zhu
From: Hui Zhu <[email protected]>
Add a test module to verify memory alignment guarantees for Rust kernel allocators.
The tests coverKmalloc,VmallocandKVmallocallocators with both standard and large page-aligned allocations.Key features of the tests:
1. Creates alignment-constrained types:
- 128-byte alignedBlob
- 8192-byte (4-page) alignedLargeAlignBlob
2. Validates allocators usingTestAlignhelper which:
- Checks address alignment masks
- Supports uninitialized allocations
3. Tests all three allocators with both alignment requirements:
- Kmalloc with 128B and 8192B
- Vmalloc with 128B and 8192B
- KVmalloc with 128B and 8192B
Quoted 3 lines
Co-developed-by Geliang Tang <[email protected]>Signed-off-by Geliang Tang <[email protected]>Signed-off-by Hui Zhu <[email protected]>
Re: [PATCH v6 2/2] rust: alloc: kvec: add doc example for as_slice method
In reply to Hui ZhuQuoted 11 lines · Hui Zhu
From: Hui Zhu <[email protected]>
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 viaas_slice().Co-developed-by Geliang Tang <[email protected]>Signed-off-by Geliang Tang <[email protected]>Signed-off-by Hui Zhu <[email protected]>
It looks like this did not change since v5 where I gave my
tag. Please make sure to include the tag in future versions if you have not made any changes.
Alice
Re: [PATCH v6 1/2] rust: allocator: add KUnit tests for alignment guarantees
In reply to Hui ZhuQuoted 80 lines · Hui Zhu
From: Hui Zhu <[email protected]>
Add a test module to verify memory alignment guarantees for Rust kernel allocators.
The tests coverKmalloc,VmallocandKVmallocallocators with both standard and large page-aligned allocations.Key features of the tests:
1. Creates alignment-constrained types:
- 128-byte alignedBlob
- 8192-byte (4-page) alignedLargeAlignBlob
2. Validates allocators usingTestAlignhelper which:
- Checks address alignment masks
- Supports uninitialized allocations
3. Tests all three allocators with both alignment requirements:
- Kmalloc with 128B and 8192B
- Vmalloc with 128B and 8192B
- KVmalloc with 128B and 8192BCo-developed-by Geliang Tang <[email protected]>Signed-off-by Geliang Tang <[email protected]>Signed-off-by Hui Zhu <[email protected]>--- rust/kernel/alloc/allocator.rs | 56 ++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+)rust/kernel/alloc/allocator.rs +46
-0@@ -184,3 +184,59 @@ unsafe fn realloc(unsafe {ReallocFunc ::KVREALLOC .call (ptr, layout, old_layout, flags, nid) } } } + +#[macros::kunit_tests(rust_allocator_kunit)] +mod tests { +use super ::*; +use core::mem::MaybeUninit ; +use kernel::prelude::*; + +#[test] +fn test_alignment () ->Result <()> { +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. +#[expect(dead_code)] +#[repr(align( 128 ))] +struct Blob ([u8 ;TEST_SIZE ]); +#[expect(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 ; + addr & (align -1 ) ==0 + } + } + +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 )); + +let ta =TestAlign ::<LargeAlignBlob ,Vmalloc >::new ()?; +assert! (ta.alignment_valid (8192 ));
rust/kernel/alloc/allocator.rs unsafe fn realloc( · line 242
Quoted 10 lines
rust/kernel/alloc/allocator.rs +10
-0+ +let ta =TestAlign ::<Blob ,KVmalloc >::new ()?; +assert! (ta.alignment_valid (128 )); + +let ta =TestAlign ::<LargeAlignBlob ,KVmalloc >::new ()?; +assert! (ta.alignment_valid (8192 )); + +Ok (()) + } +}
Signature · 2 lines
Thanks, Kunwu.Chan(Tao.Chan)
Re: [PATCH v6 2/2] rust: alloc: kvec: add doc example for as_slice method
In reply to Hui ZhuQuoted 26 lines · Hui Zhu
From: Hui Zhu <[email protected]>
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 viaas_slice().Co-developed-by Geliang Tang <[email protected]>Signed-off-by Geliang Tang <[email protected]>Signed-off-by Hui Zhu <[email protected]>--- rust/kernel/alloc/kvec.rs | 10 ++++++++++ 1 file changed, 10 insertions(+)rust/kernel/alloc/kvec.rs +3
-0@@ -224,6 +224,16 @@ unsafe fn dec_len(&mut self, count: usize) -> &mut [T] { }/// Returns a slice of the entire vector. +/// +/// # Examples +///
rust/kernel/alloc/kvec.rs unsafe fn dec_len(&mut self, count: usize) -> &mut [T] { · line 239
Quoted 10 lines
rust/kernel/alloc/kvec.rs +7
-0+/// ``` +/// 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
LGTM.
Signature · 2 lines
Thanks, Kunwu.Chan(Tao.Chan)
Danilo Krummrich
maintainerRe: [PATCH v6 2/2] rust: alloc: kvec: add doc example for as_slice method
In reply to Hui ZhuQuoted 11 lines · Hui Zhu
From: Hui Zhu <[email protected]>
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 viaas_slice().Co-developed-by Geliang Tang <[email protected]>Signed-off-by Geliang Tang <[email protected]>Signed-off-by Hui Zhu <[email protected]>
Thanks -- I will pick this one up after -rc1 is out.
Re: [PATCH v6 1/2] rust: allocator: add KUnit tests for alignment guarantees
In reply to Hui ZhuQuoted 2 lines · Hui Zhu
+#[macros::kunit_tests(rust_allocator_kunit)]
Is there any reason for the _kunit suffix? If not, then we should avoid suffixing _kunit to every suite name.
I see we already have rust_kernel_kunit, but that one is because it is the KUnit file itself.
There is also rust_kvec_kunit, but we should clean that one up.
Quoted 1 line
+ fn
test_alignment()-> Result<()> {
-> Result since the prelude is available.
Quoted 1 line
+ fn
alignment_valid(&self, align: usize)-> bool {
We typically prefix these with is_.
I would also call it is_aligned_to, to match the upstream Rust one, which we could perhaps use if it becomes stable.
Cheers,
Miguel
Re: [PATCH v6 2/2] rust: alloc: kvec: add doc example for as_slice method
In reply to Alice Ryhl2025年7月30日 16:03, "Alice Ryhl" <[email protected] mailto:[email protected]?to=%22Alice%20Ryhl%22%20%3Caliceryhl%40google.com%3E > 写到:
Quoted 16 lines · Hui Zhu
Quoted 10 lines
From: Hui Zhu <[email protected]>
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 viaas_slice().Quoted 4 lines
Co-developed-by Geliang Tang <[email protected]>Signed-off-by Geliang Tang <[email protected]>Signed-off-by Hui Zhu <[email protected]>
Quoted 6 lines
It looks like this did not change since v5 where I gave my
Reviewed-by Alice Ryhl <[email protected]>tag. Please make sure to include the tag in future versions if you have not made any changes.
Oops!
Sorry for that. Fixed in the v7 version.
Best,
Hui
Quoted 3 lines
Alice
Re: [PATCH v6 1/2] rust: allocator: add KUnit tests for alignment guarantees
In reply to Miguel Ojeda2025年7月30日 17:16, "Miguel Ojeda" <[email protected] mailto:[email protected]?to=%22Miguel%20Ojeda%22%20%3Cmiguel.ojeda.sandonis%40gmail.com%3E > 写到:
Quoted 20 lines · Hui Zhu
Quoted 4 lines
+#[macros::kunit_tests(rust_allocator_kunit)]
Is there any reason for the
_kunitsuffix? If not, then we should avoid suffixing_kunitto every suite name.I see we already have
rust_kernel_kunit, but that one is because it is the KUnit file itself.There is also
rust_kvec_kunit, but we should clean that one up.Quoted 3 lines
+ fn
test_alignment()-> Result<()> {
-> Resultsince the prelude is available.Quoted 1 line
Quoted 7 lines
Quoted 2 lines
+ fn
alignment_valid(&self, align: usize)-> bool {We typically prefix these with
is_.I would also call it
is_aligned_to, to match the upstream Rust one, which we could perhaps use if it becomes stable.
Hi Miguel,
I sent the v7 version according to your comments.
Thanks,
Hui
Quoted 3 lines
Cheers,
Miguel