fix: exceptions to TBX faultable types

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>
This commit is contained in:
Jack Myers
2025-01-16 03:54:02 +00:00
committed by Compute-Runtime-Automation
parent 3d247d75ec
commit d62122a656
3 changed files with 54 additions and 31 deletions

View File

@ -89,7 +89,7 @@ bool TbxCommandStreamReceiverHw<GfxFamily>::isAllocTbxFaultable(GraphicsAllocati
return false;
}
auto allocType = gfxAlloc->getAllocationType();
return AubHelper::isOneTimeAubWritableAllocationType(allocType) && allocType != AllocationType::gpuTimestampDeviceBuffer;
return AubHelper::isOneTimeAubWritableAllocationType(allocType) && GraphicsAllocation::isLockable(allocType);
}
template <typename GfxFamily>

View File

@ -39,7 +39,6 @@ void TbxPageFaultManager::handlePageFault(void *ptr, PageFaultDataTbx &faultData
} else {
graphicsAllocation.setTbxWritable(true, bank);
this->allowCPUMemoryAccess(ptr, size);
this->memoryDataTbx.erase(ptr);
}
}

View File

@ -1547,7 +1547,29 @@ HWTEST_F(TbxCommandStreamTests, givenTbxModeWhenPageFaultManagerIsNotAvailableTh
memoryManager->freeGraphicsMemory(gfxAlloc1);
}
HWTEST_F(TbxCommandStreamTests, givenTbxModeWhenPageFaultManagerIsAvailableThenTbxFaultableTypesShouldReturnTrue) {
static constexpr std::array onceWritableAllocTypesForTbx{
AllocationType::pipe,
AllocationType::constantSurface,
AllocationType::globalSurface,
AllocationType::kernelIsa,
AllocationType::kernelIsaInternal,
AllocationType::privateSurface,
AllocationType::scratchSurface,
AllocationType::workPartitionSurface,
AllocationType::buffer,
AllocationType::image,
AllocationType::timestampPacketTagBuffer,
AllocationType::externalHostPtr,
AllocationType::mapAllocation,
AllocationType::svmGpu,
AllocationType::gpuTimestampDeviceBuffer,
AllocationType::assertBuffer,
AllocationType::tagBuffer,
AllocationType::syncDispatchToken,
AllocationType::bufferHostMemory,
};
HWTEST_F(TbxCommandStreamTests, givenAubOneTimeWritableAllocWhenTbxFaultManagerIsAvailableAndAllocIsLockableThenTbxFaultableTypesShouldReturnTrue) {
DebugManagerStateRestore stateRestore;
debugManager.flags.SetCommandStreamReceiver.set(static_cast<int32_t>(CommandStreamReceiverType::tbx));
debugManager.flags.EnableTbxPageFaultManager.set(true);
@ -1564,36 +1586,38 @@ HWTEST_F(TbxCommandStreamTests, givenTbxModeWhenPageFaultManagerIsAvailableThenT
auto backupAllocType = gfxAlloc1->getAllocationType();
std::array onceWritableTypes{
AllocationType::pipe,
AllocationType::constantSurface,
AllocationType::globalSurface,
AllocationType::kernelIsa,
AllocationType::kernelIsaInternal,
AllocationType::privateSurface,
AllocationType::scratchSurface,
AllocationType::workPartitionSurface,
AllocationType::buffer,
AllocationType::image,
AllocationType::timestampPacketTagBuffer,
AllocationType::externalHostPtr,
AllocationType::mapAllocation,
AllocationType::svmGpu,
AllocationType::gpuTimestampDeviceBuffer,
AllocationType::assertBuffer,
AllocationType::tagBuffer,
AllocationType::syncDispatchToken,
AllocationType::bufferHostMemory,
};
std::set<AllocationType> unsupportedOnceWritableTypes{AllocationType::gpuTimestampDeviceBuffer};
for (const auto &allocType : onceWritableTypes) {
for (const auto &allocType : onceWritableAllocTypesForTbx) {
gfxAlloc1->setAllocationType(allocType);
auto isSupportedOnceWritableType = unsupportedOnceWritableTypes.count(allocType) == 0;
if (isSupportedOnceWritableType) {
if (GraphicsAllocation::isLockable(allocType)) {
EXPECT_TRUE(tbxCsr->isAllocTbxFaultable(gfxAlloc1));
} else {
}
}
gfxAlloc1->setAllocationType(backupAllocType);
memoryManager->freeGraphicsMemory(gfxAlloc1);
}
HWTEST_F(TbxCommandStreamTests, givenAubOneTimeWritableAllocWhenTbxFaultManagerIsAvailableAndAllocIsNotLockableThenTbxFaultableTypesShouldReturnFalse) {
DebugManagerStateRestore stateRestore;
debugManager.flags.SetCommandStreamReceiver.set(static_cast<int32_t>(CommandStreamReceiverType::tbx));
debugManager.flags.EnableTbxPageFaultManager.set(true);
std::unique_ptr<MockTbxCsrForPageFaultTests<FamilyType>> tbxCsr(new MockTbxCsrForPageFaultTests<FamilyType>(*pDevice->executionEnvironment, pDevice->getDeviceBitfield()));
tbxCsr->setupContext(*pDevice->getDefaultEngine().osContext);
auto memoryManager = pDevice->getMemoryManager();
NEO::GraphicsAllocation *gfxAlloc1 = memoryManager->allocateGraphicsMemoryWithProperties(
{pDevice->getRootDeviceIndex(),
MemoryConstants::pageSize,
AllocationType::bufferHostMemory,
pDevice->getDeviceBitfield()});
auto backupAllocType = gfxAlloc1->getAllocationType();
for (const auto &allocType : onceWritableAllocTypesForTbx) {
gfxAlloc1->setAllocationType(allocType);
if (!GraphicsAllocation::isLockable(allocType)) {
EXPECT_FALSE(tbxCsr->isAllocTbxFaultable(gfxAlloc1));
}
}