[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20260207-binder-shrink-vec-v3-v3-1-8ff388563427@cock.li>
Date: Sat, 07 Feb 2026 17:02:47 +0530
From: Shivam Kalra via B4 Relay <devnull+shivamklr.cock.li@...nel.org>
To: Danilo Krummrich <dakr@...nel.org>,
Lorenzo Stoakes <lorenzo.stoakes@...cle.com>,
Vlastimil Babka <vbabka@...e.cz>,
"Liam R. Howlett" <Liam.Howlett@...cle.com>,
Uladzislau Rezki <urezki@...il.com>, Miguel Ojeda <ojeda@...nel.org>,
Boqun Feng <boqun.feng@...il.com>, Gary Guo <gary@...yguo.net>,
Björn Roy Baron <bjorn3_gh@...tonmail.com>,
Benno Lossin <lossin@...nel.org>, Andreas Hindborg <a.hindborg@...nel.org>,
Alice Ryhl <aliceryhl@...gle.com>, Trevor Gross <tmgross@...ch.edu>,
Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
Arve Hjønnevåg <arve@...roid.com>,
Todd Kjos <tkjos@...roid.com>, Christian Brauner <brauner@...nel.org>,
Carlos Llamas <cmllamas@...gle.com>
Cc: rust-for-linux@...r.kernel.org, linux-kernel@...r.kernel.org,
Shivam Kalra <shivamklr@...k.li>
Subject: [PATCH v3 1/4] rust: alloc: introduce Shrinkable trait
From: Shivam Kalra <shivamklr@...k.li>
Introduce the `Shrinkable` trait to identify allocators that can
meaningfully reclaim memory when an allocation is shrunk.
In the kernel, the slab allocator (`Kmalloc`) uses fixed-size buckets,
meaning a "shrink" operation often results in the same bucket size being
used, yielding no actual memory savings. However, page-based allocators
like `Vmalloc` can reclaim physical pages when the size reduction
crosses a page boundary.
This marker trait allows generic containers (like `KVec` or `KVVec`) to
determine at compile-time or run-time (via `is_shrinkable`) if a
shrinking operation is worth performing.
Signed-off-by: Shivam Kalra <shivamklr@...k.li>
---
rust/kernel/alloc/allocator.rs | 48 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 48 insertions(+)
diff --git a/rust/kernel/alloc/allocator.rs b/rust/kernel/alloc/allocator.rs
index 63bfb91b36712..615799b680b55 100644
--- a/rust/kernel/alloc/allocator.rs
+++ b/rust/kernel/alloc/allocator.rs
@@ -251,6 +251,54 @@ unsafe fn realloc(
}
}
+/// Marker trait for allocators that support meaningful shrinking.
+///
+/// Shrinking is only meaningful for allocators that can actually reclaim memory. The slab
+/// allocator (`Kmalloc`) uses fixed-size buckets and cannot reclaim memory when shrinking,
+/// so it does not implement this trait.
+///
+/// For `Vmalloc`, shrinking always makes sense since it uses page-granularity allocations.
+/// For `KVmalloc`, shrinking only makes sense if the allocation is backed by vmalloc (checked
+/// at runtime via `is_vmalloc_addr`).
+///
+/// # Note
+///
+/// Currently, shrinking vmalloc allocations requires explicit alloc+copy+free because
+/// `vrealloc` does not support in-place shrinking (see TODO at `mm/vmalloc.c:4316`).
+/// Once `vrealloc` gains this capability, the shrink implementation can be simplified.
+///
+/// # Safety
+///
+/// Implementors must ensure that [`Shrinkable::is_shrinkable`] returns `true` only when
+/// shrinking the allocation would actually reclaim memory.
+pub unsafe trait Shrinkable: Allocator {
+ /// Returns whether shrinking an allocation at the given pointer would reclaim memory.
+ ///
+ /// # Safety
+ ///
+ /// `ptr` must be a valid pointer to an allocation made by this allocator.
+ unsafe fn is_shrinkable(ptr: NonNull<u8>) -> bool;
+}
+
+// SAFETY: `Vmalloc` always uses vmalloc, which allocates at page granularity. Shrinking a
+// vmalloc allocation by at least one page will reclaim that memory.
+unsafe impl Shrinkable for Vmalloc {
+ #[inline]
+ unsafe fn is_shrinkable(_ptr: NonNull<u8>) -> bool {
+ true
+ }
+}
+
+// SAFETY: `KVmalloc` may use either kmalloc or vmalloc. We check at runtime using
+// `is_vmalloc_addr` to determine if shrinking would be meaningful.
+unsafe impl Shrinkable for KVmalloc {
+ #[inline]
+ unsafe fn is_shrinkable(ptr: NonNull<u8>) -> bool {
+ // SAFETY: `ptr` is a valid pointer by the safety requirements of this function.
+ unsafe { bindings::is_vmalloc_addr(ptr.as_ptr().cast()) }
+ }
+}
+
#[macros::kunit_tests(rust_allocator)]
mod tests {
use super::*;
--
2.43.0
Powered by blists - more mailing lists