[llvm-branch-commits] [compiler-rt] [compiler-rt] Add more common HSA utilities for memory and symbolization (PR #228297)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Thu Oct 1 18:12:54 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-compiler-rt-sanitizer
Author: Joseph Huber (jhuber6)
<details>
<summary>Changes</summary>
Summary:
Adds memory pool management for different kinds of allocation. Intended
to be used for the in-progress concurrency sanitizer.
RFC: discourse.llvm.org/t/rfc-a-thread-concurrency-sanitizer-for-gpus-in-compiler-rt/91113
---
<sub>Stack created with <a href="https://github.com/github/gh-stack">GitHub Stacks CLI</a> • <a href="https://gh.io/stacks-feedback">Give Feedback 💬</a></sub>
---
Full diff: https://github.com/llvm/llvm-project/pull/228297.diff
6 Files Affected:
- (modified) compiler-rt/lib/sanitizer_common/sanitizer_offload.cpp (+46-3)
- (modified) compiler-rt/lib/sanitizer_common/sanitizer_offload.h (+3)
- (modified) compiler-rt/lib/sanitizer_common/sanitizer_offload_hsa.h (+2)
- (modified) compiler-rt/lib/sanitizer_common/sanitizer_offload_image.cpp (+21)
- (modified) compiler-rt/lib/sanitizer_common/sanitizer_symbolizer.h (+4)
- (modified) compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cpp (+15)
``````````diff
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_offload.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_offload.cpp
index 57255546ea888..adb515e38b848 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_offload.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_offload.cpp
@@ -102,7 +102,7 @@ bool Offload::Discover() {
Out) == HSA_STATUS_SUCCESS;
};
auto Pool = [&](hsa_agent_t Agent) {
- hsa_amd_memory_pool_t Found{};
+ hsa_amd_memory_pool_t Fine{};
Iterate<hsa_amd_memory_pool_t>(
Api.hsa_amd_agent_iterate_memory_pools, Agent,
[&](hsa_amd_memory_pool_t Mem) {
@@ -118,10 +118,10 @@ bool Offload::Discover() {
HSA_STATUS_SUCCESS)
return HSA_STATUS_SUCCESS;
if (Flags & HSA_AMD_MEMORY_POOL_GLOBAL_FLAG_FINE_GRAINED)
- Found = Mem;
+ Fine = Mem;
return HSA_STATUS_SUCCESS;
});
- return Found;
+ return Fine;
};
CheckHsa(Iterate<hsa_agent_t>(Api.hsa_iterate_agents, [&](hsa_agent_t Agent) {
@@ -296,6 +296,49 @@ bool Offload::Alloc(const Device& D, uptr Bytes, void** Out) {
return true;
}
+bool Offload::GetMemoryPool(hsa_agent_t Agent, hsa_amd_memory_pool_t* Pool) {
+ Lock L(&OffloadMtx);
+ if (!Ready() || !Pool)
+ return false;
+ *Pool = {};
+ hsa_status_t Status = Iterate<hsa_amd_memory_pool_t>(
+ Api.hsa_amd_agent_iterate_memory_pools, Agent,
+ [&](hsa_amd_memory_pool_t Mem) {
+ hsa_amd_segment_t Segment;
+ u32 Flags = 0;
+ bool Allowed = false;
+ if (Api.hsa_amd_memory_pool_get_info(Mem,
+ HSA_AMD_MEMORY_POOL_INFO_SEGMENT,
+ &Segment) != HSA_STATUS_SUCCESS ||
+ Segment != HSA_AMD_SEGMENT_GLOBAL ||
+ Api.hsa_amd_memory_pool_get_info(
+ Mem, HSA_AMD_MEMORY_POOL_INFO_GLOBAL_FLAGS, &Flags) !=
+ HSA_STATUS_SUCCESS ||
+ !(Flags & HSA_AMD_MEMORY_POOL_GLOBAL_FLAG_COARSE_GRAINED) ||
+ Api.hsa_amd_memory_pool_get_info(
+ Mem, HSA_AMD_MEMORY_POOL_INFO_RUNTIME_ALLOC_ALLOWED,
+ &Allowed) != HSA_STATUS_SUCCESS ||
+ !Allowed)
+ return HSA_STATUS_SUCCESS;
+ *Pool = Mem;
+ return HSA_STATUS_SUCCESS;
+ });
+ return Status == HSA_STATUS_SUCCESS && Pool->handle;
+}
+
+bool Offload::Allocate(hsa_amd_memory_pool_t Pool, uptr Bytes, void** Out) {
+ Lock L(&OffloadMtx);
+ if (!Ready() || !Pool.handle || !Bytes || !Out)
+ return false;
+ void* P = nullptr;
+ if (Api.hsa_amd_memory_pool_allocate(Pool, Bytes, 0, &P) !=
+ HSA_STATUS_SUCCESS ||
+ !P)
+ return false;
+ *Out = P;
+ return true;
+}
+
void Offload::Free(void* P) { Api.hsa_amd_memory_pool_free(P); }
bool Offload::Copy(void* Dst, const void* Src, uptr N) {
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_offload.h b/compiler-rt/lib/sanitizer_common/sanitizer_offload.h
index 4df2a2ca11f05..5a39e4103546c 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_offload.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_offload.h
@@ -40,7 +40,10 @@ class Offload {
void TrackExecutable(hsa_executable_t Exec);
void UntrackExecutable(hsa_executable_t Exec);
void UntrackImages();
+ bool GetMemoryPool(hsa_agent_t Agent, hsa_amd_memory_pool_t* Pool);
+ bool Allocate(hsa_amd_memory_pool_t Pool, uptr Bytes, void** Out);
SymbolizedStack* Symbolize(uptr PC);
+ bool SymbolizeData(uptr Addr, DataInfo* Info);
private:
friend struct OffloadRpc;
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_offload_hsa.h b/compiler-rt/lib/sanitizer_common/sanitizer_offload_hsa.h
index 2300f9fa2bfab..d2a92832539f2 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_offload_hsa.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_offload_hsa.h
@@ -78,10 +78,12 @@ typedef enum { HSA_AMD_SEGMENT_GLOBAL = 0 } hsa_amd_segment_t;
typedef enum {
HSA_AMD_MEMORY_POOL_INFO_SEGMENT = 0,
HSA_AMD_MEMORY_POOL_INFO_GLOBAL_FLAGS = 1,
+ HSA_AMD_MEMORY_POOL_INFO_RUNTIME_ALLOC_ALLOWED = 5,
} hsa_amd_memory_pool_info_t;
typedef enum {
HSA_AMD_MEMORY_POOL_GLOBAL_FLAG_FINE_GRAINED = 2,
+ HSA_AMD_MEMORY_POOL_GLOBAL_FLAG_COARSE_GRAINED = 4,
} hsa_amd_memory_pool_global_flag_t;
typedef enum {
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_offload_image.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_offload_image.cpp
index eb0c5a468c5f2..09c54f7ea5c06 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_offload_image.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_offload_image.cpp
@@ -145,4 +145,25 @@ SymbolizedStack* Offload::Symbolize(uptr PC) {
return Frames;
}
+bool Offload::SymbolizeData(uptr Addr, DataInfo* Info) {
+ if (!Addr || !Info)
+ return false;
+
+ char* Path = nullptr;
+ uptr Offset = 0;
+ if (!SnapshotImage(Addr, &Path, &Offset) || !Path)
+ return false;
+
+ bool Symbolized =
+ Symbolizer::GetOrInit()->SymbolizeModuleData(Path, Offset, Info);
+ InternalFree(Path);
+ if (!Symbolized)
+ return false;
+ if (!Info->name || !Info->name[0] || Info->name[0] == '?') {
+ Info->Clear();
+ return false;
+ }
+ return true;
+}
+
} // namespace __sanitizer
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer.h b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer.h
index d2aa2288f483c..d40df017bdda6 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer.h
@@ -143,6 +143,10 @@ class Symbolizer final {
// current executing process, such as an offloading device.
SymbolizedStack* SymbolizeModuleOffset(const char* module_name,
uptr module_offset);
+ // Like SymbolizeData, but the module is not mapped in this process
+ // (offload device images).
+ bool SymbolizeModuleData(const char* module_name, uptr module_offset,
+ DataInfo* info);
bool SymbolizeData(uptr address, DataInfo *info);
bool SymbolizeFrame(uptr address, FrameInfo *info);
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cpp
index b5a85c05efde7..8ba6a14b420cb 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cpp
@@ -114,6 +114,21 @@ SymbolizedStack* Symbolizer::SymbolizeModuleOffset(const char* module_name,
return res;
}
+bool Symbolizer::SymbolizeModuleData(const char* module_name,
+ uptr module_offset, DataInfo* info) {
+ Lock l(&mu_);
+ info->Clear();
+ info->module = internal_strdup(module_name);
+ info->module_offset = module_offset;
+ info->module_arch = kModuleArchUnknown;
+ for (auto& tool : tools_) {
+ SymbolizerScope sym_scope(this);
+ if (tool.SymbolizeData(module_offset, info))
+ return true;
+ }
+ return false;
+}
+
bool Symbolizer::SymbolizeData(uptr addr, DataInfo *info) {
Lock l(&mu_);
const char *module_name = nullptr;
``````````
</details>
https://github.com/llvm/llvm-project/pull/228297
More information about the llvm-branch-commits
mailing list