rusticl: move SVM allocation into core

Reviewed-by: Adam Jackson <ajax@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/32942>
This commit is contained in:
Karol Herbst
2024-09-11 16:37:29 +02:00
committed by Marge Bot
parent b65652b4be
commit 2fb8bb3c49
2 changed files with 40 additions and 44 deletions
+3 -40
View File
@@ -19,8 +19,6 @@ use rusticl_opencl_gen::*;
use rusticl_proc_macros::cl_entrypoint;
use rusticl_proc_macros::cl_info_entrypoint;
use std::alloc;
use std::alloc::Layout;
use std::cmp;
use std::cmp::Ordering;
use std::mem::{self, MaybeUninit};
@@ -2386,32 +2384,7 @@ pub fn svm_alloc(
mem::size_of::<[u64; 16]>()
};
// clSVMAlloc will fail if alignment is not a power of two.
// `from_size_align()` verifies this condition is met.
let layout = Layout::from_size_align(size, alignment).or(Err(CL_INVALID_VALUE))?;
// clSVMAlloc will fail if size is 0 or > CL_DEVICE_MAX_MEM_ALLOC_SIZE value
// for any device in context.
// Verify that the requested size, once adjusted to be a multiple of
// alignment, fits within the maximum allocation size. While
// `from_size_align()` ensures that the allocation will fit in host memory,
// the maximum allocation may be smaller due to limitations from gallium or
// devices.
let size_aligned = layout.pad_to_align().size();
if size == 0 || checked_compare(size_aligned, Ordering::Greater, c.max_mem_alloc()) {
return Err(CL_INVALID_VALUE);
}
// SAFETY: `size` is verified to be non-zero and the returned pointer is not
// expected to point to initialized memory.
let ptr = unsafe { alloc::alloc(layout) };
if ptr.is_null() {
return Err(CL_OUT_OF_HOST_MEMORY);
}
c.add_svm_ptr(ptr as usize, layout);
Ok(ptr.cast())
c.alloc_svm_ptr(size, alignment)
// Values specified in flags do not follow rules described for supported values in the SVM Memory Flags table.
// CL_MEM_SVM_FINE_GRAIN_BUFFER or CL_MEM_SVM_ATOMICS is specified in flags and these are not supported by at least one device in context.
@@ -2420,19 +2393,9 @@ pub fn svm_alloc(
// There was a failure to allocate resources.
}
fn svm_free_impl(c: &Context, svm_pointer: usize) {
if let Some(layout) = c.remove_svm_ptr(svm_pointer) {
// SAFETY: we make sure that svm_pointer is a valid allocation and reuse the same layout
// from the allocation
unsafe {
alloc::dealloc(svm_pointer as *mut u8, layout);
}
}
}
pub fn svm_free(context: cl_context, svm_pointer: usize) -> CLResult<()> {
let c = Context::ref_from_raw(context)?;
svm_free_impl(c, svm_pointer);
c.remove_svm_ptr(svm_pointer);
Ok(())
}
@@ -2493,7 +2456,7 @@ fn enqueue_svm_free_impl(
cb.call(q, &mut svm_pointers);
} else {
for ptr in svm_pointers {
svm_free_impl(&q.context, ptr);
q.context.remove_svm_ptr(ptr);
}
}
+37 -4
View File
@@ -1,5 +1,6 @@
use crate::api::icd::*;
use crate::api::types::DeleteContextCB;
use crate::api::util::checked_compare;
use crate::core::device::*;
use crate::core::format::*;
use crate::core::gl::*;
@@ -16,7 +17,9 @@ use mesa_rust_util::ptr::AllocSize;
use mesa_rust_util::ptr::TrackedPointers;
use rusticl_opencl_gen::*;
use std::alloc;
use std::alloc::Layout;
use std::cmp::Ordering;
use std::collections::HashMap;
use std::convert::TryInto;
use std::mem;
@@ -207,8 +210,32 @@ impl Context {
self.devs.iter().any(|dev| dev.svm_supported())
}
pub fn add_svm_ptr(&self, ptr: usize, layout: Layout) {
self.svm_ptrs.lock().unwrap().insert(ptr, layout);
pub fn alloc_svm_ptr(&self, size: usize, alignment: usize) -> CLResult<*mut c_void> {
// clSVMAlloc will fail if alignment is not a power of two.
// `from_size_align()` verifies this condition is met.
let layout = Layout::from_size_align(size, alignment).or(Err(CL_INVALID_VALUE))?;
// clSVMAlloc will fail if size is 0 or > CL_DEVICE_MAX_MEM_ALLOC_SIZE value
// for any device in context.
// Verify that the requested size, once adjusted to be a multiple of
// alignment, fits within the maximum allocation size. While
// `from_size_align()` ensures that the allocation will fit in host memory,
// the maximum allocation may be smaller due to limitations from gallium or
// devices.
let size_aligned = layout.pad_to_align().size();
if size == 0 || checked_compare(size_aligned, Ordering::Greater, self.max_mem_alloc()) {
return Err(CL_INVALID_VALUE);
}
// SAFETY: `size` is verified to be non-zero and the returned pointer is not
// expected to point to initialized memory.
let ptr = unsafe { alloc::alloc(layout) };
if ptr.is_null() {
Err(CL_OUT_OF_HOST_MEMORY)
} else {
Ok(ptr.cast())
}
}
pub fn find_svm_alloc(&self, ptr: usize) -> Option<(*const c_void, usize)> {
@@ -219,8 +246,14 @@ impl Context {
.map(|(ptr, layout)| (ptr as *const c_void, layout.size()))
}
pub fn remove_svm_ptr(&self, ptr: usize) -> Option<Layout> {
self.svm_ptrs.lock().unwrap().remove(ptr)
pub fn remove_svm_ptr(&self, ptr: usize) {
if let Some(layout) = self.svm_ptrs.lock().unwrap().remove(ptr) {
// SAFETY: we make sure that svm_pointer is a valid allocation and reuse the same layout
// from the allocation
unsafe {
alloc::dealloc(ptr as *mut u8, layout);
}
}
}
pub fn add_bda_ptr(&self, buffer: &Arc<Buffer>) {