SWDEV-495987 - Use shared mutex for MemObj maps

- Remove binning logic, although useful it doesnt work in current
  scenario as there is no upper limit on the size of allocation. If an
app or framework uses entire VRAM and then creates suballocs, binning
would result in failure.

Change-Id: Icc27c13e433bb4a1f03e82028d8718488b43bfa5
此提交包含在:
Saleel Kudchadker
2024-11-12 17:25:09 +00:00
提交者 Rakesh Roy
父節點 0fa632c52c
當前提交 e4d29e228d
共有 2 個檔案被更改,包括 40 行新增 和 58 行删除
+35 -44
查看文件
@@ -305,13 +305,13 @@ Context* Device::glb_ctx_ = nullptr;
Monitor Device::p2p_stage_ops_(true);
Memory* Device::p2p_stage_ = nullptr;
std::array<MemObjMap::Bin, MemObjMap::kNumBins> MemObjMap::MemObjBin_ ROCCLR_INIT_PRIORITY(101) = {} ;
std::array<MemObjMap::Bin, MemObjMap::kNumBins> MemObjMap::VirtualMemObjBin_ ROCCLR_INIT_PRIORITY(101) = {} ;
std::shared_mutex MemObjMap::AllocatedLock_ ROCCLR_INIT_PRIORITY(101);
std::map<uintptr_t, amd::Memory*> MemObjMap::MemObjMap_ ROCCLR_INIT_PRIORITY(101);
std::map<uintptr_t, amd::Memory*> MemObjMap::VirtualMemObjMap_ ROCCLR_INIT_PRIORITY(101);
void MemObjMap::AddMemObj(const void* k, amd::Memory* v) {
auto& bin = getMapBin(k, MemObjBin_);
std::unique_lock lock(bin.AllocatedLock_);
auto rval = bin.map_.insert({ reinterpret_cast<uintptr_t>(k), v });
std::unique_lock lock(AllocatedLock_);
auto rval = MemObjMap_.insert({ reinterpret_cast<uintptr_t>(k), v });
if (!rval.second) {
DevLogPrintfError("Memobj map already has an entry for ptr: 0x%x",
reinterpret_cast<uintptr_t>(k));
@@ -319,19 +319,17 @@ void MemObjMap::AddMemObj(const void* k, amd::Memory* v) {
}
void MemObjMap::RemoveMemObj(const void* k) {
auto& bin = getMapBin(k, MemObjBin_);
std::unique_lock lock(bin.AllocatedLock_);
auto rval = bin.map_.erase(reinterpret_cast<uintptr_t>(k));
std::unique_lock lock(AllocatedLock_);
auto rval = MemObjMap_.erase(reinterpret_cast<uintptr_t>(k));
guarantee(rval == 1, "Memobj map does not have ptr: 0x%x",
reinterpret_cast<uintptr_t>(k));
}
amd::Memory* MemObjMap::FindMemObj(const void* k, size_t* offset) {
auto& bin = getMapBin(k, MemObjBin_);
std::shared_lock lock(bin.AllocatedLock_);
std::shared_lock lock(AllocatedLock_);
uintptr_t key = reinterpret_cast<uintptr_t>(k);
auto it = bin.map_.upper_bound(key);
if (it == bin.map_.begin()) {
auto it = MemObjMap_.upper_bound(key);
if (it == MemObjMap_.begin()) {
return nullptr;
}
@@ -354,16 +352,14 @@ void MemObjMap::UpdateAccess(amd::Device *peerDev) {
}
// Provides access to all memory allocated on peerDev but
// hsa_amd_agents_allow_access was not called because there was no peer
for (auto& bin : MemObjBin_) {
std::shared_lock lock(bin.AllocatedLock_);
for (auto it : bin.map_) {
const std::vector<Device*>& devices = it.second->getContext().devices();
if (devices.size() == 1 && devices[0] == peerDev) {
device::Memory* devMem = it.second->getDeviceMemory(*devices[0]);
if (!devMem->getAllowedPeerAccess()) {
peerDev->deviceAllowAccess(reinterpret_cast<void*>(it.first));
devMem->setAllowedPeerAccess(true);
}
std::shared_lock lock(AllocatedLock_);
for (auto it : MemObjMap_) {
const std::vector<Device*>& devices = it.second->getContext().devices();
if (devices.size() == 1 && devices[0] == peerDev) {
device::Memory* devMem = it.second->getDeviceMemory(*devices[0]);
if (!devMem->getAllowedPeerAccess()) {
peerDev->deviceAllowAccess(reinterpret_cast<void*>(it.first));
devMem->setAllowedPeerAccess(true);
}
}
}
@@ -371,26 +367,23 @@ void MemObjMap::UpdateAccess(amd::Device *peerDev) {
void MemObjMap::Purge(amd::Device* dev) {
assert(dev != nullptr);
for (auto& bin : MemObjBin_) {
std::unique_lock lock(bin.AllocatedLock_);
for (auto it = bin.map_.cbegin(); it != bin.map_.cend(); ) {
amd::Memory* memObj = it->second;
unsigned int flags = memObj->getMemFlags();
const std::vector<Device*>& devices = memObj->getContext().devices();
if (devices.size() == 1 && devices[0] == dev && !(flags & ROCCLR_MEM_INTERNAL_MEMORY)) {
memObj->release();
it = bin.map_.erase(it);
} else {
++it;
}
std::unique_lock lock(AllocatedLock_);
for (auto it = MemObjMap_.cbegin(); it != MemObjMap_.cend(); ) {
amd::Memory* memObj = it->second;
unsigned int flags = memObj->getMemFlags();
const std::vector<Device*>& devices = memObj->getContext().devices();
if (devices.size() == 1 && devices[0] == dev && !(flags & ROCCLR_MEM_INTERNAL_MEMORY)) {
memObj->release();
it = MemObjMap_.erase(it);
} else {
++it;
}
}
}
void MemObjMap::AddVirtualMemObj(const void* k, amd::Memory* v) {
auto& bin = getMapBin(k, VirtualMemObjBin_);
std::unique_lock lock(bin.AllocatedLock_);
auto rval = bin.map_.insert({ reinterpret_cast<uintptr_t>(k), v });
std::unique_lock lock(AllocatedLock_);
auto rval = VirtualMemObjMap_.insert({ reinterpret_cast<uintptr_t>(k), v });
if (!rval.second) {
DevLogPrintfError("Virtual Memobj map already has an entry for ptr: 0x%x",
reinterpret_cast<uintptr_t>(k));
@@ -398,19 +391,17 @@ void MemObjMap::AddVirtualMemObj(const void* k, amd::Memory* v) {
}
void MemObjMap::RemoveVirtualMemObj(const void* k) {
auto& bin = getMapBin(k, VirtualMemObjBin_);
std::unique_lock lock(bin.AllocatedLock_);
auto rval = bin.map_.erase(reinterpret_cast<uintptr_t>(k));
std::unique_lock lock(AllocatedLock_);
auto rval = VirtualMemObjMap_.erase(reinterpret_cast<uintptr_t>(k));
guarantee(rval == 1, "Virtual Memobj map does not have ptr: 0x%x",
reinterpret_cast<uintptr_t>(k));
}
amd::Memory* MemObjMap::FindVirtualMemObj(const void* k) {
auto& bin = getMapBin(k, VirtualMemObjBin_);
std::shared_lock lock(bin.AllocatedLock_);
std::shared_lock lock(AllocatedLock_);
uintptr_t key = reinterpret_cast<uintptr_t>(k);
auto it = bin.map_.upper_bound(key);
if (it == bin.map_.begin()) {
auto it = VirtualMemObjMap_.upper_bound(key);
if (it == VirtualMemObjMap_.begin()) {
return nullptr;
}