Refactor: Consolidate calls to hsaKmtAllocMemory
Route all device-visible system memory allocations through system_allocator.
Change-Id: I5e90a1bf491e432678a6d8ab1f9f3770734cbda1
[ROCm/ROCR-Runtime commit: 74f5aca93d]
This commit is contained in:
@@ -266,21 +266,12 @@ AqlQueue::AqlQueue(GpuAgent* agent, size_t req_size_pkts, HSAuint32 node_id,
|
||||
SignalGuard.Dismiss();
|
||||
#endif
|
||||
|
||||
HsaMemFlags pm4_ib_buf_flags = {0};
|
||||
pm4_ib_buf_flags.ui32.HostAccess = 1;
|
||||
pm4_ib_buf_flags.ui32.ExecuteAccess = 1;
|
||||
pm4_ib_buf_flags.ui32.NoSubstitute = 1;
|
||||
|
||||
HSAKMT_STATUS err =
|
||||
hsaKmtAllocMemory(agent_->node_id(), pm4_ib_size_b_, pm4_ib_buf_flags, &pm4_ib_buf_);
|
||||
assert(err == HSAKMT_STATUS_SUCCESS && "hsaKmtAllocMemory(PM4 IB) failed");
|
||||
|
||||
err = hsaKmtMapMemoryToGPU(pm4_ib_buf_, pm4_ib_size_b_, NULL);
|
||||
assert(err == HSAKMT_STATUS_SUCCESS && "hsaKmtMapMemoryToGPU(PM4 IB) failed");
|
||||
pm4_ib_buf_ = core::Runtime::runtime_singleton_->system_allocator()(
|
||||
pm4_ib_size_b_, 0x1000, core::MemoryRegion::AllocateExecutable);
|
||||
if (pm4_ib_buf_ == NULL) return;
|
||||
|
||||
MAKE_NAMED_SCOPE_GUARD(PM4IBGuard, [&]() {
|
||||
hsaKmtUnmapMemoryToGPU(pm4_ib_buf_);
|
||||
hsaKmtFreeMemory(pm4_ib_buf_, pm4_ib_size_b_);
|
||||
core::Runtime::runtime_singleton_->system_deallocator()(pm4_ib_buf_);
|
||||
});
|
||||
|
||||
valid_ = true;
|
||||
@@ -314,8 +305,7 @@ AqlQueue::~AqlQueue() {
|
||||
}
|
||||
#endif
|
||||
|
||||
hsaKmtUnmapMemoryToGPU(pm4_ib_buf_);
|
||||
hsaKmtFreeMemory(pm4_ib_buf_, pm4_ib_size_b_);
|
||||
core::Runtime::runtime_singleton_->system_deallocator()(pm4_ib_buf_);
|
||||
}
|
||||
|
||||
uint64_t AqlQueue::LoadReadIndexAcquire() {
|
||||
@@ -631,34 +621,19 @@ void AqlQueue::AllocRegisteredRingBuffer(uint32_t queue_size_pkts) {
|
||||
#endif
|
||||
} else {
|
||||
// Allocate storage for the ring buffer.
|
||||
HsaMemFlags flags;
|
||||
flags.Value = 0;
|
||||
flags.ui32.HostAccess = 1;
|
||||
flags.ui32.AtomicAccessPartial = 1;
|
||||
flags.ui32.ExecuteAccess = 1;
|
||||
flags.ui32.AQLQueueMemory = 1;
|
||||
|
||||
ring_buf_alloc_bytes_ = AlignUp(
|
||||
queue_size_pkts * static_cast<uint32_t>(sizeof(core::AqlPacket)), 4096);
|
||||
auto err = hsaKmtAllocMemory(agent_->node_id(), ring_buf_alloc_bytes_,
|
||||
flags, (void**)&ring_buf_);
|
||||
|
||||
if (err != HSAKMT_STATUS_SUCCESS) {
|
||||
assert(false && "AQL queue memory allocation failure.");
|
||||
return;
|
||||
}
|
||||
ring_buf_ = core::Runtime::runtime_singleton_->system_allocator()(
|
||||
ring_buf_alloc_bytes_, 0x1000,
|
||||
core::MemoryRegion::AllocateExecutable |
|
||||
core::MemoryRegion::AllocateDoubleMap);
|
||||
|
||||
HSAuint64 alternate_va;
|
||||
err = hsaKmtMapMemoryToGPU(ring_buf_, ring_buf_alloc_bytes_, &alternate_va);
|
||||
assert(ring_buf_ != NULL && "AQL queue memory allocation failure");
|
||||
|
||||
if (err != HSAKMT_STATUS_SUCCESS) {
|
||||
assert(false && "AQL queue memory map failure.");
|
||||
hsaKmtFreeMemory(ring_buf_, ring_buf_alloc_bytes_);
|
||||
ring_buf_ = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
ring_buf_alloc_bytes_ = 2 * ring_buf_alloc_bytes_;
|
||||
// The virtual ring allocation is twice as large as requested.
|
||||
// Each half maps to the same set of physical pages.
|
||||
ring_buf_alloc_bytes_ *= 2;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -673,8 +648,7 @@ void AqlQueue::FreeRegisteredRingBuffer() {
|
||||
(void*)(uintptr_t(ring_buf_) + (ring_buf_alloc_bytes_ / 2)));
|
||||
#endif
|
||||
} else {
|
||||
hsaKmtUnmapMemoryToGPU(ring_buf_);
|
||||
hsaKmtFreeMemory(ring_buf_, ring_buf_alloc_bytes_ / 2);
|
||||
core::Runtime::runtime_singleton_->system_deallocator()(ring_buf_);
|
||||
}
|
||||
|
||||
ring_buf_ = NULL;
|
||||
|
||||
@@ -537,7 +537,8 @@ hsa_status_t BlitKernel::Initialize(const core::Agent& agent) {
|
||||
|
||||
kernarg_async_ = reinterpret_cast<KernelArgs*>(
|
||||
core::Runtime::runtime_singleton_->system_allocator()(
|
||||
queue_->public_handle()->size * AlignUp(sizeof(KernelArgs), 16), 16));
|
||||
queue_->public_handle()->size * AlignUp(sizeof(KernelArgs), 16), 16,
|
||||
core::MemoryRegion::AllocateNoFlags));
|
||||
|
||||
kernarg_async_mask_ = queue_->public_handle()->size - 1;
|
||||
|
||||
|
||||
@@ -447,26 +447,11 @@ hsa_status_t BlitSdma::Initialize(const core::Agent& agent) {
|
||||
// Allocate queue buffer.
|
||||
queue_size_ = kQueueSize;
|
||||
|
||||
HsaMemFlags flags;
|
||||
flags.Value = 0;
|
||||
flags.ui32.HostAccess = 1;
|
||||
flags.ui32.AtomicAccessPartial = 1;
|
||||
flags.ui32.ExecuteAccess = 1;
|
||||
queue_start_addr_ =
|
||||
(char*)core::Runtime::runtime_singleton_->system_allocator()(
|
||||
queue_size_, 0x1000, core::MemoryRegion::AllocateExecutable);
|
||||
|
||||
auto err = hsaKmtAllocMemory(amd_gpu_agent.node_id(), queue_size_, flags,
|
||||
reinterpret_cast<void**>(&queue_start_addr_));
|
||||
|
||||
if (err != HSAKMT_STATUS_SUCCESS) {
|
||||
assert(false && "SDMA queue memory allocation failure.");
|
||||
return HSA_STATUS_ERROR_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
HSAuint64 alternate_va;
|
||||
err = hsaKmtMapMemoryToGPU(queue_start_addr_, queue_size_, &alternate_va);
|
||||
|
||||
if (err != HSAKMT_STATUS_SUCCESS) {
|
||||
assert(false && "AQL queue memory map failure.");
|
||||
Destroy(agent);
|
||||
if (queue_start_addr_ == NULL) {
|
||||
return HSA_STATUS_ERROR_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
@@ -494,7 +479,8 @@ hsa_status_t BlitSdma::Initialize(const core::Agent& agent) {
|
||||
|
||||
fence_base_addr_ = reinterpret_cast<uint32_t*>(
|
||||
core::Runtime::runtime_singleton_->system_allocator()(
|
||||
fence_pool_size_ * sizeof(uint32_t), 256));
|
||||
fence_pool_size_ * sizeof(uint32_t), 256,
|
||||
core::MemoryRegion::AllocateNoFlags));
|
||||
|
||||
if (fence_base_addr_ == NULL) {
|
||||
Destroy(agent);
|
||||
@@ -516,8 +502,7 @@ hsa_status_t BlitSdma::Destroy(const core::Agent& agent) {
|
||||
|
||||
if (queue_start_addr_ != NULL && queue_size_ != 0) {
|
||||
// Release queue buffer.
|
||||
hsaKmtUnmapMemoryToGPU(queue_start_addr_);
|
||||
hsaKmtFreeMemory(queue_start_addr_, queue_size_);
|
||||
core::Runtime::runtime_singleton_->system_deallocator()(queue_start_addr_);
|
||||
}
|
||||
|
||||
if (fence_base_addr_ != NULL) {
|
||||
|
||||
@@ -124,14 +124,8 @@ GpuAgent::GpuAgent(HSAuint32 node, const HsaNodeProperties& node_props)
|
||||
// Populate region list.
|
||||
InitRegionList();
|
||||
|
||||
// Reserve memory for scratch.
|
||||
InitScratchPool();
|
||||
|
||||
// Populate cache list.
|
||||
InitCacheList();
|
||||
|
||||
// Bind the second-level trap handler to this node.
|
||||
BindTrapHandler();
|
||||
}
|
||||
|
||||
GpuAgent::~GpuAgent() {
|
||||
@@ -214,21 +208,13 @@ void GpuAgent::AssembleShader(const char* src_sp3, const char* func_name,
|
||||
}
|
||||
|
||||
// Allocate a GPU-visible buffer for the shader.
|
||||
HsaMemFlags code_buf_flags = {0};
|
||||
code_buf_flags.ui32.HostAccess = 1;
|
||||
code_buf_flags.ui32.ExecuteAccess = 1;
|
||||
code_buf_flags.ui32.NoSubstitute = 1;
|
||||
|
||||
size_t header_size =
|
||||
(assemble_target == AssembleTarget::AQL ? sizeof(amd_kernel_code_t) : 0);
|
||||
code_buf_size = AlignUp(header_size + asic_shader->size, 0x1000);
|
||||
|
||||
HSAKMT_STATUS err =
|
||||
hsaKmtAllocMemory(node_id(), code_buf_size, code_buf_flags, &code_buf);
|
||||
assert(err == HSAKMT_STATUS_SUCCESS && "hsaKmtAllocMemory(Trap) failed");
|
||||
|
||||
err = hsaKmtMapMemoryToGPU(code_buf, code_buf_size, NULL);
|
||||
assert(err == HSAKMT_STATUS_SUCCESS && "hsaKmtMapMemoryToGPU(Trap) failed");
|
||||
code_buf = core::Runtime::runtime_singleton_->system_allocator()(
|
||||
code_buf_size, 0x1000, core::MemoryRegion::AllocateExecutable);
|
||||
assert(code_buf != NULL && "Code buffer allocation failed");
|
||||
|
||||
memset(code_buf, 0, code_buf_size);
|
||||
|
||||
@@ -265,8 +251,7 @@ void GpuAgent::AssembleShader(const char* src_sp3, const char* func_name,
|
||||
}
|
||||
|
||||
void GpuAgent::ReleaseShader(void* code_buf, size_t code_buf_size) const {
|
||||
hsaKmtUnmapMemoryToGPU(code_buf);
|
||||
hsaKmtFreeMemory(code_buf, code_buf_size);
|
||||
core::Runtime::runtime_singleton_->system_deallocator()(code_buf);
|
||||
}
|
||||
|
||||
void GpuAgent::InitRegionList() {
|
||||
@@ -415,7 +400,8 @@ bool GpuAgent::InitEndTsPool() {
|
||||
|
||||
uint64_t* buff = NULL;
|
||||
if (HSA_STATUS_SUCCESS !=
|
||||
runtime->AllocateMemory(true, local_region_, alloc_size,
|
||||
runtime->AllocateMemory(local_region_, alloc_size,
|
||||
MemoryRegion::AllocateRestrict,
|
||||
reinterpret_cast<void**>(&buff))) {
|
||||
return false;
|
||||
}
|
||||
@@ -589,6 +575,10 @@ void GpuAgent::InitDma() {
|
||||
}
|
||||
|
||||
hsa_status_t GpuAgent::PostToolsInit() {
|
||||
// Defer memory allocation until agents have been discovered.
|
||||
InitScratchPool();
|
||||
BindTrapHandler();
|
||||
|
||||
// Defer utility queue creation to allow tools to intercept.
|
||||
queues_[QueueUtility] = CreateInterceptibleQueue();
|
||||
|
||||
|
||||
@@ -149,11 +149,7 @@ MemoryRegion::MemoryRegion(bool fine_grain, bool full_profile,
|
||||
|
||||
MemoryRegion::~MemoryRegion() {}
|
||||
|
||||
hsa_status_t MemoryRegion::Allocate(size_t size, void** address) const {
|
||||
return Allocate(false, size, address);
|
||||
}
|
||||
|
||||
hsa_status_t MemoryRegion::Allocate(bool restrict_access, size_t size,
|
||||
hsa_status_t MemoryRegion::Allocate(size_t size, AllocateFlags alloc_flags,
|
||||
void** address) const {
|
||||
if (address == NULL) {
|
||||
return HSA_STATUS_ERROR_INVALID_ARGUMENT;
|
||||
@@ -169,7 +165,13 @@ hsa_status_t MemoryRegion::Allocate(bool restrict_access, size_t size,
|
||||
|
||||
size = AlignUp(size, kPageSize_);
|
||||
|
||||
*address = AllocateKfdMemory(mem_flag_, owner()->node_id(), size);
|
||||
HsaMemFlags kmt_alloc_flags(mem_flag_);
|
||||
kmt_alloc_flags.ui32.ExecuteAccess =
|
||||
(alloc_flags & AllocateExecutable ? 1 : 0);
|
||||
kmt_alloc_flags.ui32.AQLQueueMemory =
|
||||
(alloc_flags & AllocateDoubleMap ? 1 : 0);
|
||||
|
||||
*address = AllocateKfdMemory(kmt_alloc_flags, owner()->node_id(), size);
|
||||
|
||||
if (*address != NULL) {
|
||||
// Commit the memory.
|
||||
@@ -184,7 +186,7 @@ hsa_status_t MemoryRegion::Allocate(bool restrict_access, size_t size,
|
||||
const uint32_t* map_node_id = &owner_node_id;
|
||||
|
||||
if (IsSystem()) {
|
||||
if (!restrict_access) {
|
||||
if ((alloc_flags & AllocateRestrict) == 0) {
|
||||
// Map to all GPU agents.
|
||||
map_node_count = core::Runtime::runtime_singleton_->gpu_ids().size();
|
||||
|
||||
|
||||
@@ -903,8 +903,8 @@ hsa_status_t
|
||||
const core::MemoryRegion* mem_region = core::MemoryRegion::Convert(region);
|
||||
IS_VALID(mem_region);
|
||||
|
||||
return core::Runtime::runtime_singleton_->AllocateMemory(mem_region, size,
|
||||
ptr);
|
||||
return core::Runtime::runtime_singleton_->AllocateMemory(
|
||||
mem_region, size, core::MemoryRegion::AllocateNoFlags, ptr);
|
||||
}
|
||||
|
||||
hsa_status_t hsa_memory_free(void* ptr) {
|
||||
|
||||
@@ -464,8 +464,8 @@ hsa_status_t
|
||||
return (hsa_status_t)HSA_STATUS_ERROR_INVALID_MEMORY_POOL;
|
||||
}
|
||||
|
||||
return core::Runtime::runtime_singleton_->AllocateMemory(true, mem_region,
|
||||
size, ptr);
|
||||
return core::Runtime::runtime_singleton_->AllocateMemory(
|
||||
mem_region, size, core::MemoryRegion::AllocateRestrict, ptr);
|
||||
}
|
||||
|
||||
hsa_status_t hsa_amd_memory_pool_free(void* ptr) {
|
||||
|
||||
@@ -159,29 +159,22 @@ void Runtime::RegisterAgent(Agent* agent) {
|
||||
// Init default fine grain system region allocator using fine grain
|
||||
// system region of the first discovered CPU agent.
|
||||
if (cpu_agents_.size() == 1) {
|
||||
if (system_regions_fine_[0]->full_profile()) {
|
||||
system_allocator_ = [](size_t size, size_t alignment) -> void * {
|
||||
return _aligned_malloc(size, alignment);
|
||||
};
|
||||
// Might need memory pooling to cover allocation that
|
||||
// requires less than 4096 bytes.
|
||||
system_allocator_ =
|
||||
[&](size_t size, size_t alignment,
|
||||
MemoryRegion::AllocateFlags alloc_flags) -> void* {
|
||||
assert(alignment <= 4096);
|
||||
void* ptr = NULL;
|
||||
return (HSA_STATUS_SUCCESS ==
|
||||
core::Runtime::runtime_singleton_->AllocateMemory(
|
||||
system_regions_fine_[0], size, alloc_flags, &ptr))
|
||||
? ptr
|
||||
: NULL;
|
||||
};
|
||||
|
||||
system_deallocator_ = [](void* ptr) { _aligned_free(ptr); };
|
||||
} else {
|
||||
// Might need memory pooling to cover allocation that
|
||||
// requires less than 4096 bytes.
|
||||
system_allocator_ = [&](size_t size, size_t alignment) -> void * {
|
||||
assert(alignment <= 4096);
|
||||
void* ptr = NULL;
|
||||
return (HSA_STATUS_SUCCESS ==
|
||||
core::Runtime::runtime_singleton_->AllocateMemory(
|
||||
system_regions_fine_[0], size, &ptr))
|
||||
? ptr
|
||||
: NULL;
|
||||
};
|
||||
|
||||
system_deallocator_ = [](void* ptr) {
|
||||
core::Runtime::runtime_singleton_->FreeMemory(ptr);
|
||||
};
|
||||
}
|
||||
system_deallocator_ =
|
||||
[](void* ptr) { core::Runtime::runtime_singleton_->FreeMemory(ptr); };
|
||||
|
||||
BaseShared::SetAllocateAndFree(system_allocator_, system_deallocator_);
|
||||
}
|
||||
@@ -307,16 +300,9 @@ hsa_status_t Runtime::IterateAgent(hsa_status_t (*callback)(hsa_agent_t agent,
|
||||
}
|
||||
|
||||
hsa_status_t Runtime::AllocateMemory(const MemoryRegion* region, size_t size,
|
||||
void** ptr) {
|
||||
return AllocateMemory(false, region, size, ptr);
|
||||
}
|
||||
|
||||
hsa_status_t Runtime::AllocateMemory(bool restrict_access,
|
||||
const MemoryRegion* region, size_t size,
|
||||
MemoryRegion::AllocateFlags alloc_flags,
|
||||
void** address) {
|
||||
const amd::MemoryRegion* amd_region =
|
||||
reinterpret_cast<const amd::MemoryRegion*>(region);
|
||||
hsa_status_t status = amd_region->Allocate(restrict_access, size, address);
|
||||
hsa_status_t status = region->Allocate(size, alloc_flags, address);
|
||||
|
||||
// Track the allocation result so that it could be freed properly.
|
||||
if (status == HSA_STATUS_SUCCESS) {
|
||||
|
||||
Reference in New Issue
Block a user