mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-26 17:10:11 +01:00
clover: track allocated svm pointers
We need those to proper validate the SVM API. v2: use std::map instead of std::unordered_map v3: guard against segfaults on std::prev with empty containers Signed-off-by: Karol Herbst <kherbst@redhat.com> Reviewed-by: Francisco Jerez <currojerez@riseup.net> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6401>
This commit is contained in:
parent
e3c2432b37
commit
3718938c1a
4 changed files with 53 additions and 3 deletions
|
|
@ -519,6 +519,10 @@ clSVMAlloc(cl_context d_ctx,
|
|||
if (alignment < sizeof(void*))
|
||||
alignment = sizeof(void*);
|
||||
posix_memalign(&ptr, alignment, size);
|
||||
|
||||
if (ptr)
|
||||
ctx.add_svm_allocation(ptr, size);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -540,8 +544,10 @@ clSVMFree(cl_context d_ctx,
|
|||
|
||||
bool can_emulate = all_of(std::mem_fn(&device::has_system_svm), ctx.devices());
|
||||
|
||||
if (can_emulate)
|
||||
if (can_emulate) {
|
||||
ctx.remove_svm_allocation(svm_pointer);
|
||||
return free(svm_pointer);
|
||||
}
|
||||
|
||||
CLOVER_NOT_SUPPORTED_UNTIL("2.0");
|
||||
|
||||
|
|
|
|||
|
|
@ -969,10 +969,13 @@ clover::EnqueueSVMFree(cl_command_queue d_q,
|
|||
CLOVER_NOT_SUPPORTED_UNTIL("2.0");
|
||||
return CL_INVALID_VALUE;
|
||||
}
|
||||
pfn_free_func = [](cl_command_queue, cl_uint num_svm_pointers,
|
||||
pfn_free_func = [](cl_command_queue d_q, cl_uint num_svm_pointers,
|
||||
void *svm_pointers[], void *) {
|
||||
for (void *p : range(svm_pointers, num_svm_pointers))
|
||||
clover::context &ctx = obj(d_q).context();
|
||||
for (void *p : range(svm_pointers, num_svm_pointers)) {
|
||||
ctx.remove_svm_allocation(p);
|
||||
free(p);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -61,3 +61,32 @@ context::device_range
|
|||
context::devices() const {
|
||||
return map(evals(), devs);
|
||||
}
|
||||
|
||||
void
|
||||
context::add_svm_allocation(const void *ptr, size_t size) {
|
||||
svm_ptrs.emplace(ptr, size);
|
||||
}
|
||||
|
||||
void
|
||||
context::remove_svm_allocation(const void *ptr) {
|
||||
svm_ptrs.erase(ptr);
|
||||
}
|
||||
|
||||
context::svm_pointer_map::value_type
|
||||
context::find_svm_allocation(const void *ptr) const {
|
||||
// std::prev on an iterator of an empty container causes SIGSEGVs
|
||||
if (svm_ptrs.empty())
|
||||
return { nullptr, 0 };
|
||||
|
||||
auto it = std::prev(svm_ptrs.upper_bound(ptr));
|
||||
if (it == svm_ptrs.end())
|
||||
return { nullptr, 0 };
|
||||
|
||||
uintptr_t base = reinterpret_cast<uintptr_t>((*it).first);
|
||||
uintptr_t end = (*it).second + base;
|
||||
uintptr_t ptrv = reinterpret_cast<uintptr_t>(ptr);
|
||||
if (ptrv >= base && ptrv < end)
|
||||
return *it;
|
||||
|
||||
return { nullptr, 0 };
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#ifndef CLOVER_CORE_CONTEXT_HPP
|
||||
#define CLOVER_CORE_CONTEXT_HPP
|
||||
|
||||
#include <map>
|
||||
#include <stack>
|
||||
|
||||
#include "core/object.hpp"
|
||||
|
|
@ -41,6 +42,7 @@ namespace clover {
|
|||
~context();
|
||||
|
||||
typedef std::function<void (const char *)> notify_action;
|
||||
typedef std::map<const void *, size_t> svm_pointer_map;
|
||||
|
||||
context(const property_list &props, const ref_vector<device> &devs,
|
||||
const notify_action ¬ify);
|
||||
|
|
@ -62,12 +64,22 @@ namespace clover {
|
|||
device_range
|
||||
devices() const;
|
||||
|
||||
void
|
||||
add_svm_allocation(const void *ptr, size_t size);
|
||||
|
||||
void
|
||||
remove_svm_allocation(const void *ptr);
|
||||
|
||||
svm_pointer_map::value_type
|
||||
find_svm_allocation(const void *ptr) const;
|
||||
|
||||
const notify_action notify;
|
||||
|
||||
private:
|
||||
property_list props;
|
||||
const std::vector<intrusive_ref<device>> devs;
|
||||
std::stack<std::function<void ()>> _destroy_notify;
|
||||
svm_pointer_map svm_ptrs;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue