Skip to content

Commit 4c6e317

Browse files
Vitaly WoolKernel Patches Daemon
authored andcommitted
rust: support large alignments in allocations
Add support for large (> PAGE_SIZE) alignments in Rust allocators. All the preparations on the C side are already done, we just need to add bindings for <alloc>_node_align() functions and start using those. Signed-off-by: Vitaly Wool <[email protected]> Acked-by: Danilo Krummrich <[email protected]>
1 parent acf7355 commit 4c6e317

File tree

3 files changed

+18
-26
lines changed

3 files changed

+18
-26
lines changed

rust/helpers/slab.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@
33
#include <linux/slab.h>
44

55
void * __must_check __realloc_size(2)
6-
rust_helper_krealloc_node(const void *objp, size_t new_size, gfp_t flags, int node)
6+
rust_helper_krealloc_node_align(const void *objp, size_t new_size, unsigned long align,
7+
gfp_t flags, int node)
78
{
8-
return krealloc_node(objp, new_size, flags, node);
9+
return krealloc_node_align(objp, new_size, align, flags, node);
910
}
1011

1112
void * __must_check __realloc_size(2)
12-
rust_helper_kvrealloc_node(const void *p, size_t size, gfp_t flags, int node)
13+
rust_helper_kvrealloc_node_align(const void *p, size_t size, unsigned long align,
14+
gfp_t flags, int node)
1315
{
14-
return kvrealloc_node(p, size, flags, node);
16+
return kvrealloc_node_align(p, size, align, flags, node);
1517
}

rust/helpers/vmalloc.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
#include <linux/vmalloc.h>
44

55
void * __must_check __realloc_size(2)
6-
rust_helper_vrealloc_node(const void *p, size_t size, gfp_t flags, int node)
6+
rust_helper_vrealloc_node_align(const void *p, size_t size, unsigned long align,
7+
gfp_t flags, int node)
78
{
8-
return vrealloc_node(p, size, flags, node);
9+
return vrealloc_node_align(p, size, align, flags, node);
910
}

rust/kernel/alloc/allocator.rs

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -56,25 +56,26 @@ fn aligned_size(new_layout: Layout) -> usize {
5656

5757
/// # Invariants
5858
///
59-
/// One of the following: `krealloc_node`, `vrealloc_node`, `kvrealloc_node`.
59+
/// One of the following: `krealloc_node_align`, `vrealloc_node_align`, `kvrealloc_node_align`.
6060
struct ReallocFunc(
6161
unsafe extern "C" fn(
6262
*const crate::ffi::c_void,
6363
usize,
64+
crate::ffi::c_ulong,
6465
u32,
6566
crate::ffi::c_int,
6667
) -> *mut crate::ffi::c_void,
6768
);
6869

6970
impl ReallocFunc {
70-
// INVARIANT: `krealloc_node` satisfies the type invariants.
71-
const KREALLOC: Self = Self(bindings::krealloc_node);
71+
// INVARIANT: `krealloc_node_align` satisfies the type invariants.
72+
const KREALLOC: Self = Self(bindings::krealloc_node_align);
7273

73-
// INVARIANT: `vrealloc_node` satisfies the type invariants.
74-
const VREALLOC: Self = Self(bindings::vrealloc_node);
74+
// INVARIANT: `vrealloc_node_align` satisfies the type invariants.
75+
const VREALLOC: Self = Self(bindings::vrealloc_node_align);
7576

76-
// INVARIANT: `kvrealloc_node` satisfies the type invariants.
77-
const KVREALLOC: Self = Self(bindings::kvrealloc_node);
77+
// INVARIANT: `kvrealloc_node_align` satisfies the type invariants.
78+
const KVREALLOC: Self = Self(bindings::kvrealloc_node_align);
7879

7980
/// # Safety
8081
///
@@ -116,7 +117,7 @@ impl ReallocFunc {
116117
// - Those functions provide the guarantees of this function.
117118
let raw_ptr = unsafe {
118119
// If `size == 0` and `ptr != NULL` the memory behind the pointer is freed.
119-
self.0(ptr.cast(), size, flags.0, nid.0).cast()
120+
self.0(ptr.cast(), size, layout.align(), flags.0, nid.0).cast()
120121
};
121122

122123
let ptr = if size == 0 {
@@ -160,12 +161,6 @@ unsafe impl Allocator for Vmalloc {
160161
flags: Flags,
161162
nid: NumaNode,
162163
) -> Result<NonNull<[u8]>, AllocError> {
163-
// TODO: Support alignments larger than PAGE_SIZE.
164-
if layout.align() > bindings::PAGE_SIZE {
165-
pr_warn!("Vmalloc does not support alignments larger than PAGE_SIZE yet.\n");
166-
return Err(AllocError);
167-
}
168-
169164
// SAFETY: If not `None`, `ptr` is guaranteed to point to valid memory, which was previously
170165
// allocated with this `Allocator`.
171166
unsafe { ReallocFunc::VREALLOC.call(ptr, layout, old_layout, flags, nid) }
@@ -185,12 +180,6 @@ unsafe impl Allocator for KVmalloc {
185180
flags: Flags,
186181
nid: NumaNode,
187182
) -> Result<NonNull<[u8]>, AllocError> {
188-
// TODO: Support alignments larger than PAGE_SIZE.
189-
if layout.align() > bindings::PAGE_SIZE {
190-
pr_warn!("KVmalloc does not support alignments larger than PAGE_SIZE yet.\n");
191-
return Err(AllocError);
192-
}
193-
194183
// SAFETY: If not `None`, `ptr` is guaranteed to point to valid memory, which was previously
195184
// allocated with this `Allocator`.
196185
unsafe { ReallocFunc::KVREALLOC.call(ptr, layout, old_layout, flags, nid) }

0 commit comments

Comments
 (0)