2
0

Dayatsin/develop vmm pointer info (#305)

* rocr: hsa_amd_pointer_info to support VMEM pointers

Extend hsa_amd_pointer_info to support virtual memory addresses.

If hsa_amd_pointer_info is called on an address that is reserved but not
mapped to memory, then the pointer type will be reported as
HSA_EXT_POINTER_TYPE_RESERVED_ADDR.

If hsa_amd_pointer_info is called on an address that is mapped, then the
pointer type will be reported as HSA_EXT_POINTER_TYPE_HSA_VMEM

* rocrtst: VirtMemory_Basic_Test test for pointer info

Extend rocrtstFunc.VirtMemory_Basic_Test to test for
hsa_amd_pointer_info

* rocrtst: Add SVM Memory Test
Este cometimento está contido em:
David Yat Sin
2025-08-13 14:21:47 -04:00
cometido por GitHub
ascendente fe52f0ed06
cometimento 875fb40a03
7 ficheiros modificados com 624 adições e 37 eliminações
@@ -906,6 +906,10 @@ class Runtime {
};
std::map<const void*, MappedHandle> mapped_handle_map_; // Indexed by VA
AddressHandle* VMemoryFindReservedAddressHandle(const void* va);
hsa_status_t VMemoryPtrInfo(const void* ptr, hsa_amd_pointer_info_t* info, void* (*alloc)(size_t),
uint32_t* num_agents_accessible, hsa_agent_t** accessible);
hsa_status_t VMemoryMapAllowAccess(const void *va,
hsa_access_permission_t perm,
const hsa_agent_t *agents,
@@ -924,6 +924,80 @@ hsa_status_t Runtime::InteropUnmap(void* ptr) {
return HSA_STATUS_SUCCESS;
}
/* This should be called memory_lock_ held */
Runtime::AddressHandle* Runtime::VMemoryFindReservedAddressHandle(const void* va) {
auto reservedAddressIt = reserved_address_map_.upper_bound(va);
if (reservedAddressIt != reserved_address_map_.begin()) {
reservedAddressIt--;
if ((reservedAddressIt->first <= va) &&
((reinterpret_cast<const uint8_t*>(va)) <=
(reinterpret_cast<const uint8_t*>(reservedAddressIt->first) +
reservedAddressIt->second.size))) {
return &(reservedAddressIt->second);
}
}
return nullptr;
}
/* This should be called memory_lock_ held */
hsa_status_t Runtime::VMemoryPtrInfo(const void* ptr, hsa_amd_pointer_info_t* info,
void* (*alloc)(size_t), uint32_t* num_agents_accessible,
hsa_agent_t** accessible) {
/* Check if this memory was allocated via VMM */
auto mappedHandleIt = mapped_handle_map_.upper_bound(ptr);
if (mappedHandleIt != mapped_handle_map_.begin()) {
mappedHandleIt--;
if ((reinterpret_cast<const uint8_t*>(mappedHandleIt->first) + mappedHandleIt->second.size) >
ptr) {
/* Allocation found */
info->type = HSA_EXT_POINTER_TYPE_HSA_VMEM;
info->agentBaseAddress = const_cast<void*>(ptr);
info->hostBaseAddress = const_cast<void*>(ptr);
info->sizeInBytes = mappedHandleIt->second.size;
info->agentOwner = mappedHandleIt->second.mem_handle->agentOwner()->public_handle();
if (alloc && num_agents_accessible && accessible) {
std::vector<hsa_agent_t> allowed_agents;
for (auto agentPermsIt = mappedHandleIt->second.allowed_agents.begin();
agentPermsIt != mappedHandleIt->second.allowed_agents.end(); agentPermsIt++) {
allowed_agents.push_back((*agentPermsIt).second.targetAgent->public_handle());
}
AMD::callback_t<decltype(alloc)> Alloc(alloc);
*accessible = (hsa_agent_t*)Alloc(sizeof(hsa_agent_t) * allowed_agents.size());
if ((*accessible) == nullptr) return HSA_STATUS_ERROR_OUT_OF_RESOURCES;
*num_agents_accessible = allowed_agents.size();
memcpy(*accessible, allowed_agents.data(), sizeof(hsa_agent_t) * allowed_agents.size());
}
return HSA_STATUS_SUCCESS;
}
}
/* This is not a mapped address. Check if it is a reserved address range */
auto addressHandle = VMemoryFindReservedAddressHandle(ptr);
if (addressHandle) {
info->type = HSA_EXT_POINTER_TYPE_RESERVED_ADDR;
info->agentBaseAddress = NULL;
info->hostBaseAddress = addressHandle->os_addr;
info->sizeInBytes = addressHandle->size;
info->agentOwner = {};
if (num_agents_accessible) {
*num_agents_accessible = 0;
}
return HSA_STATUS_SUCCESS;
}
/* Allocation not found */
info->type = HSA_EXT_POINTER_TYPE_UNKNOWN;
return HSA_STATUS_SUCCESS;
}
hsa_status_t Runtime::PtrInfo(const void* ptr, hsa_amd_pointer_info_t* info, void* (*alloc)(size_t),
uint32_t* num_agents_accessible, hsa_agent_t** accessible,
PtrInfoBlockData* block_info) {
@@ -955,6 +1029,12 @@ hsa_status_t Runtime::PtrInfo(const void* ptr, hsa_amd_pointer_info_t* info, voi
// change with calls to memory APIs.
ScopedAcquire<KernelSharedMutex> lock(&memory_lock_);
if (VMemoryPtrInfo(ptr, &retInfo, alloc, num_agents_accessible, accessible) ==
HSA_STATUS_SUCCESS) {
memcpy(info, &retInfo, retInfo.size);
return HSA_STATUS_SUCCESS;
}
// We don't care if this returns an error code.
// The type will be HSA_EXT_POINTER_TYPE_UNKNOWN if so.
auto err = HSAKMT_CALL(hsaKmtQueryPointerInfo(ptr, &thunkInfo));
@@ -3269,19 +3349,14 @@ hsa_status_t Runtime::VMemoryHandleMap(void* va, size_t size, size_t in_offset,
int drm_fd, dmabuf_fd = 0;
uint64_t offset = 0, ret;
uint64_t drm_cpu_addr = 0;
bool reservedAddressFound = false;
ScopedAcquire<KernelSharedMutex> lock(&memory_lock_);
auto reservedAddressIt = reserved_address_map_.upper_bound(va);
if (reservedAddressIt != reserved_address_map_.begin()) {
reservedAddressIt--;
if ((reservedAddressIt->first <= va) &&
((reinterpret_cast<uint8_t*>(va) + size) <=
(reinterpret_cast<const uint8_t*>(reservedAddressIt->first) + reservedAddressIt->second.size))) {
reservedAddressFound = true;
}
auto addressHandle = VMemoryFindReservedAddressHandle(va);
if (addressHandle == nullptr ||
reinterpret_cast<uint8_t*>(va) + size >
reinterpret_cast<uint8_t*>(addressHandle->os_addr) + addressHandle->size) {
return HSA_STATUS_ERROR_INVALID_ARGUMENT;
}
if (!reservedAddressFound) return HSA_STATUS_ERROR_INVALID_ARGUMENT;
/* Confirm that this VA range has not been mapped yet */
auto upperMappedHandleIt = mapped_handle_map_.upper_bound(va);
@@ -3329,12 +3404,11 @@ hsa_status_t Runtime::VMemoryHandleMap(void* va, size_t size, size_t in_offset,
mapped_handle_map_.emplace(
std::piecewise_construct, std::forward_as_tuple(va),
std::forward_as_tuple(&memoryHandleIt->second, &reservedAddressIt->second,
offset, size, drm_fd,
reinterpret_cast<void *>(drm_cpu_addr),
HSA_ACCESS_PERMISSION_NONE, shareable_handle));
std::forward_as_tuple(&memoryHandleIt->second, addressHandle, offset, size, drm_fd,
reinterpret_cast<void*>(drm_cpu_addr), HSA_ACCESS_PERMISSION_NONE,
shareable_handle));
reservedAddressIt->second.use_count++;
addressHandle->use_count++;
memoryHandleIt->second.use_count++;
return HSA_STATUS_SUCCESS;
@@ -3519,7 +3593,6 @@ hsa_status_t Runtime::VMemorySetAccess(void* va, size_t size,
const hsa_amd_memory_access_desc_t* desc,
const size_t desc_cnt) {
std::list<std::pair<void*, MappedHandle*>> mappedHandles;
bool reservedAddressFound = false;
// Validate all agents
for (int i = 0; i < desc_cnt; i++) {
@@ -3530,17 +3603,12 @@ hsa_status_t Runtime::VMemorySetAccess(void* va, size_t size,
ScopedAcquire<KernelSharedMutex> lock(&memory_lock_);
auto reservedAddressIt = reserved_address_map_.upper_bound(va);
if (reservedAddressIt != reserved_address_map_.begin()) {
reservedAddressIt--;
if ((reservedAddressIt->first <= va) &&
((reinterpret_cast<uint8_t*>(va) + size) <=
(reinterpret_cast<const uint8_t*>(reservedAddressIt->first) +
reservedAddressIt->second.size))) {
reservedAddressFound = true;
}
auto addressHandle = VMemoryFindReservedAddressHandle(va);
if (addressHandle == nullptr ||
reinterpret_cast<uint8_t*>(va) + size >
reinterpret_cast<uint8_t*>(addressHandle->os_addr) + addressHandle->size) {
return HSA_STATUS_ERROR_INVALID_ARGUMENT;
}
if (!reservedAddressFound) return HSA_STATUS_ERROR_INVALID_ARGUMENT;
// va + size may consist of multiple MappedHandle's. Build a list lf MappedHandles within this VA
// range
+7 -2
Ver ficheiro
@@ -62,9 +62,10 @@
* - 1.9 - hsa_amd_portable_export_dmabuf_v2
* - 1.10 - hsa_amd_vmem_address_reserve: HSA_AMD_VMEM_ADDRESS_NO_REGISTER
* - 1.11 - hsa_amd_agent_info_t: HSA_AMD_AGENT_INFO_CLOCK_COUNTERS
* - 1.12 - hsa_amd_pointer_info: HSA_EXT_POINTER_TYPE_HSA_VMEM and HSA_EXT_POINTER_TYPE_RESERVED_ADDR
*/
#define HSA_AMD_INTERFACE_VERSION_MAJOR 1
#define HSA_AMD_INTERFACE_VERSION_MINOR 11
#define HSA_AMD_INTERFACE_VERSION_MINOR 12
#ifdef __cplusplus
extern "C" {
@@ -2362,7 +2363,11 @@ typedef enum {
/*
No backend memory but virtual address
*/
HSA_EXT_POINTER_TYPE_RESERVED_ADDR = 5
HSA_EXT_POINTER_TYPE_RESERVED_ADDR = 5,
/*
Memory was allocated with an HSA virtual memory allocator
*/
HSA_EXT_POINTER_TYPE_HSA_VMEM = 6
} hsa_amd_pointer_type_t;
/**