mirror of
https://github.com/intel/compute-runtime.git
synced 2025-09-20 13:11:34 +08:00

This commit addresses a bug in the previous implementation where almost all once writable types, except `gpuTimestampBuffers`, were incorrectly enabled for TBX faultable checks. The fix ensures that only the subset of once writable types that are also lockable are considered TBX faultable, using the lockable check to avoid manual exceptions and re-inventing the wheel. Changes: - Updated `isAllocTbxFaultable` method to check if the allocation type is lockable in addition to being once writable. - Refactored unit tests to include separate checks for lockable and non-lockable allocation types. Performance optimization: - Removed unnecessary memory data erasure in `handlePageFault` to avoid constant erase/insert operations, leveraging the O(1) search time of unordered maps. Related-To: NEO-12319 Signed-off-by: Jack Myers <jack.myers@intel.com>
75 lines
2.5 KiB
C++
75 lines
2.5 KiB
C++
/*
|
|
* Copyright (C) 2024-2025 Intel Corporation
|
|
*
|
|
* SPDX-License-Identifier: MIT
|
|
*
|
|
*/
|
|
|
|
#include "shared/source/page_fault_manager/tbx_page_fault_manager.h"
|
|
|
|
#include "shared/source/command_stream/command_stream_receiver.h"
|
|
#include "shared/source/memory_manager/graphics_allocation.h"
|
|
#include "shared/source/page_fault_manager/cpu_page_fault_manager.h"
|
|
|
|
namespace NEO {
|
|
|
|
bool TbxPageFaultManager::verifyAndHandlePageFault(void *ptr, bool handleFault) {
|
|
std::unique_lock<SpinLock> lock{mtxTbx};
|
|
auto allocPtr = getFaultData(memoryDataTbx, ptr, handleFault);
|
|
if (allocPtr == nullptr) {
|
|
return CpuPageFaultManager::verifyAndHandlePageFault(ptr, handleFault);
|
|
}
|
|
if (handleFault) {
|
|
handlePageFault(allocPtr, memoryDataTbx[allocPtr]);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void TbxPageFaultManager::handlePageFault(void *ptr, PageFaultDataTbx &faultData) {
|
|
auto &graphicsAllocation = *faultData.gfxAllocation;
|
|
auto bank = faultData.bank;
|
|
auto hasBeenDownloaded = faultData.hasBeenDownloaded;
|
|
auto size = faultData.size;
|
|
auto csr = faultData.csr;
|
|
if (!hasBeenDownloaded) {
|
|
this->allowCPUMemoryAccess(ptr, size);
|
|
csr->downloadAllocation(graphicsAllocation);
|
|
this->protectCpuMemoryFromWrites(ptr, size);
|
|
faultData.hasBeenDownloaded = true;
|
|
} else {
|
|
graphicsAllocation.setTbxWritable(true, bank);
|
|
this->allowCPUMemoryAccess(ptr, size);
|
|
}
|
|
}
|
|
|
|
void TbxPageFaultManager::removeAllocation(GraphicsAllocation *alloc) {
|
|
std::unique_lock<SpinLock> lock{mtxTbx};
|
|
for (auto &data : memoryDataTbx) {
|
|
auto allocPtr = data.first;
|
|
auto faultData = data.second;
|
|
if (faultData.gfxAllocation == alloc) {
|
|
memoryDataTbx.erase(allocPtr);
|
|
this->allowCPUMemoryAccess(allocPtr, faultData.size);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
void TbxPageFaultManager::insertAllocation(CommandStreamReceiver *csr, GraphicsAllocation *alloc, uint32_t bank, void *ptr, size_t size) {
|
|
std::unique_lock<SpinLock> lock{mtxTbx};
|
|
|
|
if (this->memoryDataTbx.find(ptr) == this->memoryDataTbx.end()) {
|
|
PageFaultDataTbx pageFaultData{};
|
|
pageFaultData.size = size;
|
|
pageFaultData.gfxAllocation = alloc;
|
|
pageFaultData.bank = bank;
|
|
pageFaultData.csr = csr;
|
|
memoryDataTbx[ptr] = pageFaultData;
|
|
}
|
|
auto &faultData = this->memoryDataTbx[ptr];
|
|
faultData.hasBeenDownloaded = false;
|
|
this->protectCPUMemoryAccess(ptr, size);
|
|
}
|
|
|
|
} // namespace NEO
|