rusticl/context: complete conversion of SVM pointers to usize

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27747>
This commit is contained in:
Karol Herbst 2024-02-21 04:49:46 +01:00 committed by Marge Bot
parent ebde7d5e87
commit 1753b59cfd
6 changed files with 24 additions and 23 deletions

View file

@ -570,7 +570,7 @@ extern "C" fn cl_svm_alloc(
}
extern "C" fn cl_svm_free(context: cl_context, svm_pointer: *mut ::std::os::raw::c_void) {
svm_free(context, svm_pointer).ok();
svm_free(context, svm_pointer as usize).ok();
}
extern "C" fn cl_get_kernel_sub_group_info(

View file

@ -2296,7 +2296,7 @@ pub fn svm_alloc(
return Err(CL_OUT_OF_HOST_MEMORY);
}
c.add_svm_ptr(ptr.cast(), layout);
c.add_svm_ptr(ptr as usize, layout);
Ok(ptr.cast())
// Values specified in flags do not follow rules described for supported values in the SVM Memory Flags table.
@ -2306,17 +2306,17 @@ pub fn svm_alloc(
// There was a failure to allocate resources.
}
fn svm_free_impl(c: &Context, svm_pointer: *mut c_void) {
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.cast(), layout);
alloc::dealloc(svm_pointer as *mut u8, layout);
}
}
}
pub fn svm_free(context: cl_context, svm_pointer: *mut c_void) -> CLResult<()> {
pub fn svm_free(context: cl_context, svm_pointer: usize) -> CLResult<()> {
let c = Context::ref_from_raw(context)?;
svm_free_impl(c, svm_pointer);
Ok(())
@ -2353,7 +2353,7 @@ fn enqueue_svm_free_impl(
// function returns so we have to make a copy.
// SAFETY: num_svm_pointers specifies the amount of elements in svm_pointers
let mut svm_pointers =
unsafe { slice::from_raw_parts(svm_pointers, num_svm_pointers as usize) }.to_vec();
unsafe { slice::from_raw_parts(svm_pointers.cast(), num_svm_pointers as usize) }.to_vec();
// SAFETY: The requirements on `SVMFreeCb::new` match the requirements
// imposed by the OpenCL specification. It is the caller's duty to uphold them.
let cb_opt = unsafe { SVMFreeCb::new(pfn_free_func, user_data) }.ok();
@ -2884,8 +2884,8 @@ fn enqueue_svm_migrate_mem(
let num_svm_pointers = num_svm_pointers as usize;
// SAFETY: Just hoping the application is alright.
let mut svm_pointers =
unsafe { cl_slice::from_raw_parts(svm_pointers, num_svm_pointers)? }.to_owned();
let mut svm_pointers: Vec<usize> =
unsafe { cl_slice::from_raw_parts(svm_pointers.cast(), num_svm_pointers)? }.to_owned();
// if sizes is NULL, every allocation containing the pointers need to be migrated
let mut sizes = if sizes.is_null() {
vec![0; num_svm_pointers]
@ -2896,15 +2896,15 @@ fn enqueue_svm_migrate_mem(
// CL_INVALID_VALUE if sizes[i] is non-zero range [svm_pointers[i], svm_pointers[i]+sizes[i]) is
// not contained within an existing clSVMAlloc allocation.
for (ptr, size) in svm_pointers.iter_mut().zip(&mut sizes) {
if let Some((alloc, layout)) = q.context.find_svm_alloc(ptr.cast()) {
let ptr_addr = *ptr as usize;
if let Some((alloc, layout)) = q.context.find_svm_alloc(*ptr) {
let ptr_addr = *ptr;
let alloc_addr = alloc as usize;
// if the offset + size is bigger than the allocation we are out of bounds
if (ptr_addr - alloc_addr) + *size <= layout.size() {
// if the size is 0, the entire allocation should be migrated
if *size == 0 {
*ptr = alloc.cast();
*ptr = alloc as usize;
*size = layout.size();
}
continue;

View file

@ -187,7 +187,7 @@ cl_callback!(
);
impl SVMFreeCb {
pub fn call(self, queue: &Queue, svm_pointers: &mut [*mut c_void]) {
pub fn call(self, queue: &Queue, svm_pointers: &mut [usize]) {
let cl = cl_command_queue::from_ptr(queue);
// SAFETY: `cl` must be a valid pointer to an OpenCL queue, which is where we just got it from.
// All other requirements are covered by this callback's type invariants.
@ -195,7 +195,7 @@ impl SVMFreeCb {
(self.func)(
cl,
svm_pointers.len() as u32,
svm_pointers.as_mut_ptr(),
svm_pointers.as_mut_ptr().cast(),
self.data,
)
};

View file

@ -187,19 +187,19 @@ impl Context {
self.devs.iter().any(|dev| dev.svm_supported())
}
pub fn add_svm_ptr(&self, ptr: *mut c_void, layout: Layout) {
self.svm_ptrs.lock().unwrap().insert(ptr as usize, layout);
pub fn add_svm_ptr(&self, ptr: usize, layout: Layout) {
self.svm_ptrs.lock().unwrap().insert(ptr, layout);
}
pub fn find_svm_alloc(&self, ptr: *const c_void) -> Option<(*const c_void, Layout)> {
pub fn find_svm_alloc(&self, ptr: usize) -> Option<(*const c_void, Layout)> {
let lock = self.svm_ptrs.lock().unwrap();
if let Some((&base, layout)) = lock.range(..=ptr as usize).next_back() {
if let Some((&base, layout)) = lock.range(..=ptr).next_back() {
// SAFETY: we really just do some pointer math here...
unsafe {
let base = base as *const c_void;
// we check if ptr is within [base..base+size)
// means we can check if ptr - (base + size) < 0
if ptr.offset_from(base.add(layout.size())) < 0 {
if ptr < (base.add(layout.size()) as usize) {
return Some((base, *layout));
}
}
@ -207,8 +207,7 @@ impl Context {
None
}
pub fn remove_svm_ptr(&self, ptr: *const c_void) -> Option<Layout> {
let ptr = ptr as usize;
pub fn remove_svm_ptr(&self, ptr: usize) -> Option<Layout> {
self.svm_ptrs.lock().unwrap().remove(&ptr)
}

View file

@ -654,7 +654,9 @@ impl MemBase {
// implement this.
pub fn is_svm(&self) -> bool {
let mem = self.get_parent();
self.context.find_svm_alloc(mem.host_ptr.cast()).is_some()
self.context
.find_svm_alloc(mem.host_ptr as usize)
.is_some()
&& bit_check(mem.flags, CL_MEM_USE_HOST_PTR)
}

View file

@ -604,7 +604,7 @@ impl PipeContext {
pub fn svm_migrate(
&self,
ptrs: &[*const c_void],
ptrs: &[usize],
sizes: &[usize],
to_device: bool,
content_undefined: bool,
@ -615,7 +615,7 @@ impl PipeContext {
cb(
self.pipe.as_ptr(),
ptrs.len() as u32,
ptrs.as_ptr(),
ptrs.as_ptr().cast(),
sizes.as_ptr(),
to_device,
content_undefined,