Skip to content

Commit a34822d

Browse files
Danilo Krummrichojeda
authored andcommitted
rust: alloc: implement Allocator for Kmalloc
Implement `Allocator` for `Kmalloc`, the kernel's default allocator, typically used for objects smaller than page size. All memory allocations made with `Kmalloc` end up in `krealloc()`. It serves as allocator for the subsequently introduced types `KBox` and `KVec`. 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-7-dakr@kernel.org Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
1 parent a87a36f commit a34822d

File tree

1 file changed

+28
-3
lines changed

1 file changed

+28
-3
lines changed

rust/kernel/alloc/allocator.rs

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,16 @@ use core::alloc::{GlobalAlloc, Layout};
1313
use core::ptr;
1414
use core::ptr::NonNull;
1515

16-
use crate::alloc::AllocError;
16+
use crate::alloc::{AllocError, Allocator};
1717
use crate::bindings;
1818

19-
struct Kmalloc;
19+
/// The contiguous kernel allocator.
20+
///
21+
/// `Kmalloc` is typically used for physically contiguous allocations up to page size, but also
22+
/// supports larger allocations up to `bindings::KMALLOC_MAX_SIZE`, which is hardware specific.
23+
///
24+
/// For more details see [self].
25+
pub struct Kmalloc;
2026

2127
/// Returns a proper size to alloc a new object aligned to `new_layout`'s alignment.
2228
fn aligned_size(new_layout: Layout) -> usize {
@@ -53,8 +59,10 @@ struct ReallocFunc(
5359
unsafe extern "C" fn(*const core::ffi::c_void, usize, u32) -> *mut core::ffi::c_void,
5460
);
5561

56-
#[expect(dead_code)]
5762
impl ReallocFunc {
63+
// INVARIANT: `krealloc` satisfies the type invariants.
64+
const KREALLOC: Self = Self(bindings::krealloc);
65+
5866
/// # Safety
5967
///
6068
/// This method has the same safety requirements as [`Allocator::realloc`].
@@ -106,6 +114,23 @@ impl ReallocFunc {
106114
}
107115
}
108116

117+
// SAFETY: `realloc` delegates to `ReallocFunc::call`, which guarantees that
118+
// - memory remains valid until it is explicitly freed,
119+
// - passing a pointer to a valid memory allocation is OK,
120+
// - `realloc` satisfies the guarantees, since `ReallocFunc::call` has the same.
121+
unsafe impl Allocator for Kmalloc {
122+
#[inline]
123+
unsafe fn realloc(
124+
ptr: Option<NonNull<u8>>,
125+
layout: Layout,
126+
old_layout: Layout,
127+
flags: Flags,
128+
) -> Result<NonNull<[u8]>, AllocError> {
129+
// SAFETY: `ReallocFunc::call` has the same safety requirements as `Allocator::realloc`.
130+
unsafe { ReallocFunc::KREALLOC.call(ptr, layout, old_layout, flags) }
131+
}
132+
}
133+
109134
// SAFETY: TODO.
110135
unsafe impl GlobalAlloc for Kmalloc {
111136
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {

0 commit comments

Comments
 (0)