From 3718938c1acc165ba98dce4cac1c75f93a740017 Mon Sep 17 00:00:00 2001 From: Karol Herbst Date: Thu, 20 Aug 2020 17:05:13 +0200 Subject: [PATCH] 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 Reviewed-by: Francisco Jerez Part-of: --- src/gallium/frontends/clover/api/memory.cpp | 8 +++++++- src/gallium/frontends/clover/api/transfer.cpp | 7 +++++-- src/gallium/frontends/clover/core/context.cpp | 29 +++++++++++++++++++++++++++ src/gallium/frontends/clover/core/context.hpp | 12 +++++++++++ 4 files changed, 53 insertions(+), 3 deletions(-) diff --git a/src/gallium/frontends/clover/api/memory.cpp b/src/gallium/frontends/clover/api/memory.cpp index 1ffe306..5014e7e 100644 --- a/src/gallium/frontends/clover/api/memory.cpp +++ b/src/gallium/frontends/clover/api/memory.cpp @@ -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"); diff --git a/src/gallium/frontends/clover/api/transfer.cpp b/src/gallium/frontends/clover/api/transfer.cpp index d1da88f..ff20431 100644 --- a/src/gallium/frontends/clover/api/transfer.cpp +++ b/src/gallium/frontends/clover/api/transfer.cpp @@ -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); + } }; } diff --git a/src/gallium/frontends/clover/core/context.cpp b/src/gallium/frontends/clover/core/context.cpp index e5255e7..d81fbec 100644 --- a/src/gallium/frontends/clover/core/context.cpp +++ b/src/gallium/frontends/clover/core/context.cpp @@ -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((*it).first); + uintptr_t end = (*it).second + base; + uintptr_t ptrv = reinterpret_cast(ptr); + if (ptrv >= base && ptrv < end) + return *it; + + return { nullptr, 0 }; +} diff --git a/src/gallium/frontends/clover/core/context.hpp b/src/gallium/frontends/clover/core/context.hpp index bbde48b..2ecde23 100644 --- a/src/gallium/frontends/clover/core/context.hpp +++ b/src/gallium/frontends/clover/core/context.hpp @@ -23,6 +23,7 @@ #ifndef CLOVER_CORE_CONTEXT_HPP #define CLOVER_CORE_CONTEXT_HPP +#include #include #include "core/object.hpp" @@ -41,6 +42,7 @@ namespace clover { ~context(); typedef std::function notify_action; + typedef std::map svm_pointer_map; context(const property_list &props, const ref_vector &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> devs; std::stack> _destroy_notify; + svm_pointer_map svm_ptrs; }; } -- 2.7.4