mirror of
https://github.com/torvalds/linux.git
synced 2026-03-08 01:04:41 +01:00
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. Link: https://lkml.kernel.org/r/20250806125552.1727073-1-vitaly.wool@konsulko.se Signed-off-by: Vitaly Wool <vitaly.wool@konsulko.se> Acked-by: Danilo Krummrich <dakr@kernel.org> Acked-by: Alice Ryhl <aliceryhl@google.com> Cc: Herbert Xu <herbert@gondor.apana.org.au> Cc: Jann Horn <jannh@google.com> Cc: Kent Overstreet <kent.overstreet@linux.dev> Cc: Liam Howlett <liam.howlett@oracle.com> Cc: Lorenzo Stoakes <lorenzo.stoakes@oracle.com> Cc: Uladzislau Rezki (Sony) <urezki@gmail.com> Cc: Vlastimil Babka <vbabka@suse.cz> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
parent
7760b6421b
commit
1738796994
3 changed files with 18 additions and 27 deletions
|
|
@ -3,13 +3,15 @@
|
|||
#include <linux/slab.h>
|
||||
|
||||
void * __must_check __realloc_size(2)
|
||||
rust_helper_krealloc_node(const void *objp, size_t new_size, gfp_t flags, int node)
|
||||
rust_helper_krealloc_node_align(const void *objp, size_t new_size, unsigned long align,
|
||||
gfp_t flags, int node)
|
||||
{
|
||||
return krealloc_node(objp, new_size, flags, node);
|
||||
return krealloc_node_align(objp, new_size, align, flags, node);
|
||||
}
|
||||
|
||||
void * __must_check __realloc_size(2)
|
||||
rust_helper_kvrealloc_node(const void *p, size_t size, gfp_t flags, int node)
|
||||
rust_helper_kvrealloc_node_align(const void *p, size_t size, unsigned long align,
|
||||
gfp_t flags, int node)
|
||||
{
|
||||
return kvrealloc_node(p, size, flags, node);
|
||||
return kvrealloc_node_align(p, size, align, flags, node);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,8 @@
|
|||
#include <linux/vmalloc.h>
|
||||
|
||||
void * __must_check __realloc_size(2)
|
||||
rust_helper_vrealloc_node(const void *p, size_t size, gfp_t flags, int node)
|
||||
rust_helper_vrealloc_node_align(const void *p, size_t size, unsigned long align,
|
||||
gfp_t flags, int node)
|
||||
{
|
||||
return vrealloc_node(p, size, flags, node);
|
||||
return vrealloc_node_align(p, size, align, flags, node);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ use core::ptr::NonNull;
|
|||
|
||||
use crate::alloc::{AllocError, Allocator, NumaNode};
|
||||
use crate::bindings;
|
||||
use crate::pr_warn;
|
||||
|
||||
/// The contiguous kernel allocator.
|
||||
///
|
||||
|
|
@ -45,25 +44,26 @@ pub struct KVmalloc;
|
|||
|
||||
/// # Invariants
|
||||
///
|
||||
/// One of the following: `krealloc_node`, `vrealloc_node`, `kvrealloc_node`.
|
||||
/// One of the following: `krealloc_node_align`, `vrealloc_node_align`, `kvrealloc_node_align`.
|
||||
struct ReallocFunc(
|
||||
unsafe extern "C" fn(
|
||||
*const crate::ffi::c_void,
|
||||
usize,
|
||||
crate::ffi::c_ulong,
|
||||
u32,
|
||||
crate::ffi::c_int,
|
||||
) -> *mut crate::ffi::c_void,
|
||||
);
|
||||
|
||||
impl ReallocFunc {
|
||||
// INVARIANT: `krealloc_node` satisfies the type invariants.
|
||||
const KREALLOC: Self = Self(bindings::krealloc_node);
|
||||
// INVARIANT: `krealloc_node_align` satisfies the type invariants.
|
||||
const KREALLOC: Self = Self(bindings::krealloc_node_align);
|
||||
|
||||
// INVARIANT: `vrealloc_node` satisfies the type invariants.
|
||||
const VREALLOC: Self = Self(bindings::vrealloc_node);
|
||||
// INVARIANT: `vrealloc_node_align` satisfies the type invariants.
|
||||
const VREALLOC: Self = Self(bindings::vrealloc_node_align);
|
||||
|
||||
// INVARIANT: `kvrealloc_node` satisfies the type invariants.
|
||||
const KVREALLOC: Self = Self(bindings::kvrealloc_node);
|
||||
// INVARIANT: `kvrealloc_node_align` satisfies the type invariants.
|
||||
const KVREALLOC: Self = Self(bindings::kvrealloc_node_align);
|
||||
|
||||
/// # Safety
|
||||
///
|
||||
|
|
@ -105,7 +105,7 @@ impl ReallocFunc {
|
|||
// - Those functions provide the guarantees of this function.
|
||||
let raw_ptr = unsafe {
|
||||
// If `size == 0` and `ptr != NULL` the memory behind the pointer is freed.
|
||||
self.0(ptr.cast(), size, flags.0, nid.0).cast()
|
||||
self.0(ptr.cast(), size, layout.align(), flags.0, nid.0).cast()
|
||||
};
|
||||
|
||||
let ptr = if size == 0 {
|
||||
|
|
@ -162,12 +162,6 @@ unsafe impl Allocator for Vmalloc {
|
|||
flags: Flags,
|
||||
nid: NumaNode,
|
||||
) -> Result<NonNull<[u8]>, AllocError> {
|
||||
// TODO: Support alignments larger than PAGE_SIZE.
|
||||
if layout.align() > bindings::PAGE_SIZE {
|
||||
pr_warn!("Vmalloc 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::VREALLOC.call(ptr, layout, old_layout, flags, nid) }
|
||||
|
|
@ -191,12 +185,6 @@ unsafe impl Allocator for KVmalloc {
|
|||
// compatible layout.
|
||||
let layout = Kmalloc::aligned_layout(layout);
|
||||
|
||||
// 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, nid) }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue