rust: add a sample alloc usage
PATCH v2 1/1 rust: add a sample alloc usage
From: Hui Zhu <[email protected]>
Add a sample to the samples memory alloc usage.
It will samples the usage of VBox and KVec.
It also includes a test for allocating alignments larger than PAGE_SIZE using VBox.
Since this feature is currently unsupported, it will report errors even when successful.
Changelog:
v2:
According to the comments of Danilo, updated the commit to samples the usage of VBox and KVec.
--- samples/rust/Kconfig | 10 +++++ samples/rust/Makefile | 1 + samples/rust/rust_alloc.rs | 88 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 99 insertions(+) create mode 100644 samples/rust/rust_alloc.rs
samples/rust/Kconfig +10 -0
@@ -105,6 +105,16 @@ config SAMPLE_RUST_DRIVER_AUXILIARY If unsure, say N. +config SAMPLE_RUST_ALLOC + tristate "Alloc Test Driver" + help + This option builds the Rust alloc Test driver sample. + + To compile this as a module, choose M here: + the module will be called rust_alloc. + + If unsure, say N. + config SAMPLE_RUST_HOSTPROGS bool "Host programs" help
samples/rust/Makefile +1 -0
@@ -10,6 +10,7 @@ obj-$(CONFIG_SAMPLE_RUST_DRIVER_PLATFORM) += rust_driver_platform.o obj-$(CONFIG_SAMPLE_RUST_DRIVER_FAUX) += rust_driver_faux.o obj-$(CONFIG_SAMPLE_RUST_DRIVER_AUXILIARY) += rust_driver_auxiliary.o obj-$(CONFIG_SAMPLE_RUST_CONFIGFS) += rust_configfs.o +obj-$(CONFIG_SAMPLE_RUST_ALLOC) += rust_alloc.o rust_print-y := rust_print_main.o rust_print_events.o
samples/rust/rust_alloc.rs new file +88 -0
88 lines not on this page · raw message
Signature · 1 line
2.43.0
Danilo Krummrich
reviewer(Cc: Lorenzo, Vlastimil, Liam, Uladzislau)
samples/rust/Makefile obj-$(CONFIG_SAMPLE_RUST_DRIVER_PLATFORM) += rust_driver_platform.o · line 13
Quoted 9 lines · Hui Zhu
samples/rust/Makefile +1
-0@@ -10,6 +10,7 @@ obj-$(CONFIG_SAMPLE_RUST_DRIVER_PLATFORM) += rust_driver_platform.o obj-$(CONFIG_SAMPLE_RUST_DRIVER_FAUX) += rust_driver_faux.o obj-$(CONFIG_SAMPLE_RUST_DRIVER_AUXILIARY) += rust_driver_auxiliary.o obj-$(CONFIG_SAMPLE_RUST_CONFIGFS) += rust_configfs.o +obj-$(CONFIG_SAMPLE_RUST_ALLOC) += rust_alloc.o
I think adding an example for large alignment is fine, but let's do this in a doc-test on VBox in rust/kernel/alloc/kbox.rs. I think adding a separate module for this is overkill.
Note that doc-tests are executed on boot if CONFIG_RUST_KERNEL_DOCTESTS=y.
Quoted 15 lines
samples/rust/rust_alloc.rs new file +9
-0@@ -0,0 +1,88 @@ +// SPDX-License-Identifier: GPL-2.0 + +// Copyright (c) 2025, Kylin Software + +//! Rust alloc sample. + +use kernel::bindings; +use kernel::prelude::*; +
samples/rust/rust_alloc.rs line 19
Quoted 10 lines
samples/rust/rust_alloc.rs new file +10
-0+module! { +type :RustAlloc , + name:"rust_alloc" , + authors: ["Rust for Linux Contributors" ], + description:"Rust alloc sample" , + license:"GPL" , +} + +const VBOX_SIZE :usize =1024 ; +const VBOX_LARGE_ALIGN :usize = bindings::PAGE_SIZE *4 ;
Please use kernel::page::PAGE_SIZE instead.
Quoted 17 lines
samples/rust/rust_alloc.rs new file +17
-0+const KVEC_VAL : [usize ;3 ] = [10 ,20 ,30 ]; + +#[repr(align( 128 ))] +struct VboxBlob ([u8 ;VBOX_SIZE ]); + +// This structure is used to test the allocation of alignments larger +// than PAGE_SIZE. +// Since this is not yet supported, avoid accessing the contents of +// the structure for now. +#[allow(dead_code)] +#[repr(align( 8192 ))] +struct VboxLargeAlignBlob ([u8 ;VBOX_LARGE_ALIGN ]); + +struct RustAlloc { + vbox_blob:VBox <VboxBlob >, + kvec_blob:KVec <usize >, +}
samples/rust/rust_alloc.rs line 46
Quoted 10 lines
samples/rust/rust_alloc.rs new file +10
-0+ +fn check_align (addr:usize , align:usize ) ->bool { +debug_assert! (align.is_power_of_two ()); +if addr & (align -1 ) !=0 { +pr_err! ("Address {:#x} is not aligned with {:#x}.\n" , addr, align); +false + }else { +true + } +}
I think check_align() is unnecessary -- we don't need to test this in this context.
Instead, I suggest to add some doc-tests to the Allocator impls for Kmalloc, Vmalloc and KVmalloc in rust/kernel/alloc/allocator.rs testing that they return the expected alignment. This would be a valuable test case for those. If you're interested in adding them, please feel free to do so. :)
samples/rust/rust_alloc.rs line 56
Quoted 9 lines
samples/rust/rust_alloc.rs new file +9
-0+impl kernel::Module for RustAlloc { +fn init (_module: &'staticThisModule ) ->Result <Self > { +pr_info! ("Rust allocator sample (init)\n" ); + +let vbox_blob =VBox ::<VboxBlob >::new_uninit (GFP_KERNEL )?; +if !check_align (vbox_blob.as_ptr ()as usize ,128 ) { +return Err (EINVAL ); + } +let vbox_blob = vbox_blob.write (VboxBlob ([0xfeu8 ;VBOX_SIZE ]));
Given that you initialize it with a value anyways, you can just do
let blob = VBox::new(Blob([0xfeu8; SIZE]), GFP_KERNEL)?;
instead.
samples/rust/rust_alloc.rs line 61
Quoted 4 lines
samples/rust/rust_alloc.rs new file +4
-0+if let Ok (_) =VBox ::<VboxLargeAlignBlob >::new_uninit (GFP_KERNEL ) { +pr_err! ("Allocations for VBox with alignments larger than PAGE_SIZE should fail, but here it succeeded.\n" ); +return Err (EINVAL ); + }
This can just be
assert!(VBox::<VboxLargeAlignBlob>::new_uninit(GFP_KERNEL).is_err());
within a doc-test.
samples/rust/rust_alloc.rs line 64
Quoted 2 lines
samples/rust/rust_alloc.rs new file +2
-0+let mut kvec_blob =KVec ::new (); + kvec_blob.extend_from_slice (&KVEC_VAL ,GFP_KERNEL )?;
We already have doc-tests for KVec::new() and KVec::extend_from_slice() in rust/kernel/alloc/kvec.rs.
Quoted 11 lines
samples/rust/rust_alloc.rs new file +11
-0+Ok (Self { + vbox_blob, + kvec_blob, + }) + } +} + +impl Drop for RustAlloc { +fn drop (&mut self) { +pr_info! ("Rust allocator sample (exit)\n" ); +
samples/rust/rust_alloc.rs line 86
Quoted 10 lines
samples/rust/rust_alloc.rs new file +10
-0+// check the values +for bin self.vbox_blob.0 .as_slice ().iter () { +if *b !=0xfeu8 { +pr_err! ("vbox_blob contains wrong values\n" ); + } + } + +if self.kvec_blob.as_slice () !=KVEC_VAL { +pr_err! ("kvec_blob contains wrong values\n" ); + }
Here you're basically testing Vec::as_slice(). We don't have doc-tests for as_slice() and as_slice_mut() in rust/kernel/alloc/kvec.rs. Please feel free to add them. :)
Quoted 2 lines
samples/rust/rust_alloc.rs new file +2
-0+ } +}
Quoted 15 lines · Danilo Krummrich
(Cc: Lorenzo, Vlastimil, Liam, Uladzislau)
samples/rust/Makefile obj-$(CONFIG_SAMPLE_RUST_DRIVER_PLATFORM) += rust_driver_platform.o · line 13
Quoted 9 lines · Hui Zhu
samples/rust/Makefile +1
-0@@ -10,6 +10,7 @@ obj-$(CONFIG_SAMPLE_RUST_DRIVER_PLATFORM) += rust_driver_platform.o obj-$(CONFIG_SAMPLE_RUST_DRIVER_FAUX) += rust_driver_faux.o obj-$(CONFIG_SAMPLE_RUST_DRIVER_AUXILIARY) += rust_driver_auxiliary.o obj-$(CONFIG_SAMPLE_RUST_CONFIGFS) += rust_configfs.o +obj-$(CONFIG_SAMPLE_RUST_ALLOC) += rust_alloc.oI think adding an example for large alignment is fine, but let's do this in a doc-test on VBox in
rust/kernel/alloc/kbox.rs. I think adding a separate module
I would suggest using #[kunit_tests(..)], which is similar to how doc-test run, for it if we only use it for test purposes.
Regards,
Boqun
Quoted 4 lines
for this is overkill.
Note that doc-tests are executed on boot if
CONFIG_RUST_KERNEL_DOCTESTS=y.
[...]
Hi Danilo and Boqun,
Quoted 20 lines · Boqun Feng
Quoted 15 lines · Danilo Krummrich
(Cc: Lorenzo, Vlastimil, Liam, Uladzislau)
samples/rust/Makefile obj-$(CONFIG_SAMPLE_RUST_DRIVER_PLATFORM) += rust_driver_platform.o · line 13
Quoted 9 lines · Hui Zhu
samples/rust/Makefile +1
-0@@ -10,6 +10,7 @@ obj-$(CONFIG_SAMPLE_RUST_DRIVER_PLATFORM) += rust_driver_platform.o obj-$(CONFIG_SAMPLE_RUST_DRIVER_FAUX) += rust_driver_faux.o obj-$(CONFIG_SAMPLE_RUST_DRIVER_AUXILIARY) += rust_driver_auxiliary.o obj-$(CONFIG_SAMPLE_RUST_CONFIGFS) += rust_configfs.o +obj-$(CONFIG_SAMPLE_RUST_ALLOC) += rust_alloc.oI think adding an example for large alignment is fine, but let's do this in a doc-test on VBox in
rust/kernel/alloc/kbox.rs. I think adding a separate moduleI would suggest using #[kunit_tests(..)], which is similar to how doc-test run, for it if we only use it for test purposes.
Quoted 8 lines
Regards,
BoqunQuoted 4 lines
for this is overkill.
Note that doc-tests are executed on boot if
CONFIG_RUST_KERNEL_DOCTESTS=y.[...]
I sent version v3 that move vbox code to allocator as unit tests and add move kvec::as_slice to doc example.
Best,
Hui