From: Miguel Ojeda <ojeda@kernel.org>
To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
Sasha Levin <sashal@kernel.org>,
stable@vger.kernel.org
Cc: Danilo Krummrich <dakr@kernel.org>,
Alice Ryhl <aliceryhl@google.com>, Alyssa Ross <hi@alyssa.is>,
NoisyCoil <noisycoil@disroot.org>,
patches@lists.linux.dev, Miguel Ojeda <ojeda@kernel.org>
Subject: [PATCH 6.12.y 28/60] rust: alloc: implement `KVmalloc` allocator
Date: Fri, 7 Mar 2025 23:49:35 +0100 [thread overview]
Message-ID: <20250307225008.779961-29-ojeda@kernel.org> (raw)
In-Reply-To: <20250307225008.779961-1-ojeda@kernel.org>
From: Danilo Krummrich <dakr@kernel.org>
commit 8362c2608ba1be635ffa22a256dfcfe51c6238cc upstream.
Implement `Allocator` for `KVmalloc`, an `Allocator` that tries to
allocate memory with `kmalloc` first and, on failure, falls back to
`vmalloc`.
All memory allocations made with `KVmalloc` end up in
`kvrealloc_noprof()`; all frees in `kvfree()`.
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Benno Lossin <benno.lossin@proton.me>
Reviewed-by: Gary Guo <gary@garyguo.net>
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
Link: https://lore.kernel.org/r/20241004154149.93856-10-dakr@kernel.org
[ Reworded typo. - Miguel ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
---
rust/helpers/slab.c | 6 +++++
rust/kernel/alloc/allocator.rs | 36 +++++++++++++++++++++++++++++
rust/kernel/alloc/allocator_test.rs | 1 +
3 files changed, 43 insertions(+)
diff --git a/rust/helpers/slab.c b/rust/helpers/slab.c
index f043e087f9d6..a842bfbddcba 100644
--- a/rust/helpers/slab.c
+++ b/rust/helpers/slab.c
@@ -7,3 +7,9 @@ rust_helper_krealloc(const void *objp, size_t new_size, gfp_t flags)
{
return krealloc(objp, new_size, flags);
}
+
+void * __must_check __realloc_size(2)
+rust_helper_kvrealloc(const void *p, size_t size, gfp_t flags)
+{
+ return kvrealloc(p, size, flags);
+}
diff --git a/rust/kernel/alloc/allocator.rs b/rust/kernel/alloc/allocator.rs
index ee4c828cbd58..f8a1f0feb25d 100644
--- a/rust/kernel/alloc/allocator.rs
+++ b/rust/kernel/alloc/allocator.rs
@@ -34,6 +34,15 @@
/// For more details see [self].
pub struct Vmalloc;
+/// The kvmalloc kernel allocator.
+///
+/// `KVmalloc` attempts to allocate memory with `Kmalloc` first, but falls back to `Vmalloc` upon
+/// failure. This allocator is typically used when the size for the requested allocation is not
+/// known and may exceed the capabilities of `Kmalloc`.
+///
+/// For more details see [self].
+pub struct KVmalloc;
+
/// Returns a proper size to alloc a new object aligned to `new_layout`'s alignment.
fn aligned_size(new_layout: Layout) -> usize {
// Customized layouts from `Layout::from_size_align()` can have size < align, so pad first.
@@ -76,6 +85,9 @@ impl ReallocFunc {
// INVARIANT: `vrealloc` satisfies the type invariants.
const VREALLOC: Self = Self(bindings::vrealloc);
+ // INVARIANT: `kvrealloc` satisfies the type invariants.
+ const KVREALLOC: Self = Self(bindings::kvrealloc);
+
/// # Safety
///
/// This method has the same safety requirements as [`Allocator::realloc`].
@@ -205,6 +217,30 @@ unsafe fn realloc(
}
}
+// SAFETY: `realloc` delegates to `ReallocFunc::call`, which guarantees that
+// - memory remains valid until it is explicitly freed,
+// - 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 {
+ #[inline]
+ unsafe fn realloc(
+ ptr: Option<NonNull<u8>>,
+ layout: Layout,
+ old_layout: Layout,
+ flags: Flags,
+ ) -> Result<NonNull<[u8]>, AllocError> {
+ // TODO: Support alignments larger than PAGE_SIZE.
+ if layout.align() > bindings::PAGE_SIZE {
+ pr_warn!("KVmalloc does not support alignments larger than PAGE_SIZE yet.\n");
+ return Err(AllocError);
+ }
+
+ // SAFETY: If not `None`, `ptr` is guaranteed to point to valid memory, which was previously
+ // allocated with this `Allocator`.
+ unsafe { ReallocFunc::KVREALLOC.call(ptr, layout, old_layout, flags) }
+ }
+}
+
#[global_allocator]
static ALLOCATOR: Kmalloc = Kmalloc;
diff --git a/rust/kernel/alloc/allocator_test.rs b/rust/kernel/alloc/allocator_test.rs
index 32a1450c4d39..bd0cbcd93e52 100644
--- a/rust/kernel/alloc/allocator_test.rs
+++ b/rust/kernel/alloc/allocator_test.rs
@@ -8,6 +8,7 @@
pub struct Kmalloc;
pub type Vmalloc = Kmalloc;
+pub type KVmalloc = Kmalloc;
unsafe impl Allocator for Kmalloc {
unsafe fn realloc(
--
2.48.1
next prev parent reply other threads:[~2025-03-07 22:51 UTC|newest]
Thread overview: 72+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-03-07 22:49 [PATCH 6.12.y 00/60] `alloc`, `#[expect]` and "Custom FFI" Miguel Ojeda
2025-03-07 22:49 ` [PATCH 6.12.y 01/60] rust: workqueue: remove unneeded ``#[allow(clippy::new_ret_no_self)]` Miguel Ojeda
2025-03-07 22:49 ` [PATCH 6.12.y 02/60] rust: sort global Rust flags Miguel Ojeda
2025-03-07 22:49 ` [PATCH 6.12.y 03/60] rust: types: avoid repetition in `{As,From}Bytes` impls Miguel Ojeda
2025-03-07 22:49 ` [PATCH 6.12.y 04/60] rust: enable `clippy::undocumented_unsafe_blocks` lint Miguel Ojeda
2025-03-07 22:49 ` [PATCH 6.12.y 05/60] rust: enable `clippy::unnecessary_safety_comment` lint Miguel Ojeda
2025-03-07 22:49 ` [PATCH 6.12.y 06/60] rust: enable `clippy::unnecessary_safety_doc` lint Miguel Ojeda
2025-03-07 22:49 ` [PATCH 6.12.y 07/60] rust: enable `clippy::ignored_unit_patterns` lint Miguel Ojeda
2025-03-07 22:49 ` [PATCH 6.12.y 08/60] rust: enable `rustdoc::unescaped_backticks` lint Miguel Ojeda
2025-03-07 22:49 ` [PATCH 6.12.y 09/60] rust: init: remove unneeded `#[allow(clippy::disallowed_names)]` Miguel Ojeda
2025-03-07 22:49 ` [PATCH 6.12.y 10/60] rust: sync: remove unneeded `#[allow(clippy::non_send_fields_in_send_ty)]` Miguel Ojeda
2025-03-07 22:49 ` [PATCH 6.12.y 11/60] rust: introduce `.clippy.toml` Miguel Ojeda
2025-03-07 22:49 ` [PATCH 6.12.y 12/60] rust: replace `clippy::dbg_macro` with `disallowed_macros` Miguel Ojeda
2025-03-07 22:49 ` [PATCH 6.12.y 13/60] rust: provide proper code documentation titles Miguel Ojeda
2025-03-07 22:49 ` [PATCH 6.12.y 14/60] rust: enable Clippy's `check-private-items` Miguel Ojeda
2025-03-07 22:49 ` [PATCH 6.12.y 15/60] Documentation: rust: add coding guidelines on lints Miguel Ojeda
2025-03-07 22:49 ` [PATCH 6.12.y 16/60] rust: start using the `#[expect(...)]` attribute Miguel Ojeda
2025-03-07 22:49 ` [PATCH 6.12.y 17/60] Documentation: rust: discuss `#[expect(...)]` in the guidelines Miguel Ojeda
2025-03-07 22:49 ` [PATCH 6.12.y 18/60] rust: error: make conversion functions public Miguel Ojeda
2025-03-07 22:49 ` [PATCH 6.12.y 19/60] rust: error: optimize error type to use nonzero Miguel Ojeda
2025-03-07 22:49 ` [PATCH 6.12.y 20/60] rust: alloc: add `Allocator` trait Miguel Ojeda
2025-03-07 22:49 ` [PATCH 6.12.y 21/60] rust: alloc: separate `aligned_size` from `krealloc_aligned` Miguel Ojeda
2025-03-07 22:49 ` [PATCH 6.12.y 22/60] rust: alloc: rename `KernelAllocator` to `Kmalloc` Miguel Ojeda
2025-03-07 22:49 ` [PATCH 6.12.y 23/60] rust: alloc: implement `ReallocFunc` Miguel Ojeda
2025-03-07 22:49 ` [PATCH 6.12.y 24/60] rust: alloc: make `allocator` module public Miguel Ojeda
2025-03-07 22:49 ` [PATCH 6.12.y 25/60] rust: alloc: implement `Allocator` for `Kmalloc` Miguel Ojeda
2025-03-07 22:49 ` [PATCH 6.12.y 26/60] rust: alloc: add module `allocator_test` Miguel Ojeda
2025-03-07 22:49 ` [PATCH 6.12.y 27/60] rust: alloc: implement `Vmalloc` allocator Miguel Ojeda
2025-03-07 22:49 ` Miguel Ojeda [this message]
2025-03-07 22:49 ` [PATCH 6.12.y 29/60] rust: alloc: add __GFP_NOWARN to `Flags` Miguel Ojeda
2025-03-07 22:49 ` [PATCH 6.12.y 30/60] rust: alloc: implement kernel `Box` Miguel Ojeda
2025-03-07 22:49 ` [PATCH 6.12.y 31/60] rust: treewide: switch to our kernel `Box` type Miguel Ojeda
2025-03-07 22:49 ` [PATCH 6.12.y 32/60] rust: alloc: remove extension of std's `Box` Miguel Ojeda
2025-03-07 22:49 ` [PATCH 6.12.y 33/60] rust: alloc: add `Box` to prelude Miguel Ojeda
2025-03-07 22:49 ` [PATCH 6.12.y 34/60] rust: alloc: introduce `ArrayLayout` Miguel Ojeda
2025-03-07 22:49 ` [PATCH 6.12.y 35/60] rust: alloc: implement kernel `Vec` type Miguel Ojeda
2025-03-07 22:49 ` [PATCH 6.12.y 36/60] rust: alloc: implement `IntoIterator` for `Vec` Miguel Ojeda
2025-03-07 22:49 ` [PATCH 6.12.y 37/60] rust: alloc: implement `collect` for `IntoIter` Miguel Ojeda
2025-03-07 22:49 ` [PATCH 6.12.y 38/60] rust: treewide: switch to the kernel `Vec` type Miguel Ojeda
2025-03-07 22:49 ` [PATCH 6.12.y 39/60] rust: alloc: remove `VecExt` extension Miguel Ojeda
2025-03-07 22:49 ` [PATCH 6.12.y 40/60] rust: alloc: add `Vec` to prelude Miguel Ojeda
2025-03-07 22:49 ` [PATCH 6.12.y 41/60] rust: error: use `core::alloc::LayoutError` Miguel Ojeda
2025-03-07 22:49 ` [PATCH 6.12.y 42/60] rust: error: check for config `test` in `Error::name` Miguel Ojeda
2025-03-07 22:49 ` [PATCH 6.12.y 43/60] rust: alloc: implement `contains` for `Flags` Miguel Ojeda
2025-03-07 22:49 ` [PATCH 6.12.y 44/60] rust: alloc: implement `Cmalloc` in module allocator_test Miguel Ojeda
2025-03-07 22:49 ` [PATCH 6.12.y 45/60] rust: str: test: replace `alloc::format` Miguel Ojeda
2025-03-07 22:49 ` [PATCH 6.12.y 46/60] rust: alloc: update module comment of alloc.rs Miguel Ojeda
2025-03-07 22:49 ` [PATCH 6.12.y 47/60] kbuild: rust: remove the `alloc` crate and `GlobalAlloc` Miguel Ojeda
2025-03-07 22:49 ` [PATCH 6.12.y 48/60] MAINTAINERS: add entry for the Rust `alloc` module Miguel Ojeda
2025-03-07 22:49 ` [PATCH 6.12.y 49/60] drm/panic: avoid reimplementing Iterator::find Miguel Ojeda
2025-03-07 22:49 ` [PATCH 6.12.y 50/60] drm/panic: remove unnecessary borrow in alignment_pattern Miguel Ojeda
2025-03-07 22:49 ` [PATCH 6.12.y 51/60] drm/panic: prefer eliding lifetimes Miguel Ojeda
2025-03-07 22:49 ` [PATCH 6.12.y 52/60] drm/panic: remove redundant field when assigning value Miguel Ojeda
2025-03-07 22:50 ` [PATCH 6.12.y 53/60] drm/panic: correctly indent continuation of line in list item Miguel Ojeda
2025-03-07 22:50 ` [PATCH 6.12.y 54/60] drm/panic: allow verbose boolean for clarity Miguel Ojeda
2025-03-07 22:50 ` [PATCH 6.12.y 55/60] drm/panic: allow verbose version check Miguel Ojeda
2025-03-07 22:50 ` [PATCH 6.12.y 56/60] rust: kbuild: expand rusttest target for macros Miguel Ojeda
2025-03-07 22:50 ` [PATCH 6.12.y 57/60] rust: fix size_t in bindgen prototypes of C builtins Miguel Ojeda
2025-03-07 22:50 ` [PATCH 6.12.y 58/60] rust: map `__kernel_size_t` and friends also to usize/isize Miguel Ojeda
2025-03-07 22:50 ` [PATCH 6.12.y 59/60] rust: use custom FFI integer types Miguel Ojeda
2025-03-07 22:50 ` [PATCH 6.12.y 60/60] rust: alloc: Fix `ArrayLayout` allocations Miguel Ojeda
2025-03-09 9:47 ` [PATCH 6.12.y 00/60] `alloc`, `#[expect]` and "Custom FFI" Greg Kroah-Hartman
2025-03-09 12:41 ` Ilya K
2025-03-09 14:20 ` Miguel Ojeda
2025-03-09 16:27 ` Greg Kroah-Hartman
2025-03-09 20:42 ` [PATCH 6.12.y 0/2] The two missing ones Miguel Ojeda
2025-03-09 20:42 ` [PATCH 6.12.y 1/2] rust: finish using custom FFI integer types Miguel Ojeda
2025-03-13 9:01 ` Sasha Levin
2025-03-09 20:42 ` [PATCH 6.12.y 2/2] rust: map `long` to `isize` and `char` to `u8` Miguel Ojeda
2025-03-13 9:01 ` Sasha Levin
2025-03-13 10:59 ` Miguel Ojeda
2025-03-09 21:02 ` [PATCH 6.12.y 0/2] The two missing ones Greg Kroah-Hartman
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250307225008.779961-29-ojeda@kernel.org \
--to=ojeda@kernel.org \
--cc=aliceryhl@google.com \
--cc=dakr@kernel.org \
--cc=gregkh@linuxfoundation.org \
--cc=hi@alyssa.is \
--cc=noisycoil@disroot.org \
--cc=patches@lists.linux.dev \
--cc=sashal@kernel.org \
--cc=stable@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox