Pass preferred GPU virtual address to mapMultiHandleAllocationWithRetry()

Related-To: NEO-4479

Change-Id: I4591b013e3c9bf459e944c34f3617aaa11a66baf
Signed-off-by: Igor Venevtsev <igor.venevtsev@intel.com>
This commit is contained in:
Igor Venevtsev 2020-06-29 10:59:34 +02:00 committed by sys_ocldev
parent 1543fd6103
commit 1f63f39d77
5 changed files with 54 additions and 19 deletions

View File

@ -15,8 +15,9 @@ namespace NEO {
class MockWddmAllocation : public WddmAllocation {
public:
MockWddmAllocation() : WddmAllocation(0, EngineLimits::maxHandleCount, GraphicsAllocation::AllocationType::UNKNOWN, nullptr, 0, nullptr, MemoryPool::MemoryNull), gpuPtr(gpuAddress), handle(handles[0]) {
for (uint32_t i = 0; i < EngineLimits::maxHandleCount; i++) {
MockWddmAllocation() : MockWddmAllocation(EngineLimits::maxHandleCount) {}
MockWddmAllocation(uint32_t numGmms) : WddmAllocation(0, numGmms, GraphicsAllocation::AllocationType::UNKNOWN, nullptr, 0, nullptr, MemoryPool::MemoryNull), gpuPtr(gpuAddress), handle(handles[0]) {
for (uint32_t i = 0; i < numGmms; i++) {
setGmm(new MockGmm, i);
setHandle(ALLOCATION_HANDLE, i);
}

View File

@ -1882,6 +1882,31 @@ TEST_F(WddmMemoryManagerSimpleTest, givenAllocationWithReservedGpuVirtualAddress
EXPECT_EQ(sizeForFree, wddm->freeGpuVirtualAddressResult.sizePassed);
}
TEST_F(WddmMemoryManagerSimpleTest, givenMultiHandleAllocationAndPreferredGpuVaIsSpecifiedWhenCreateAllocationIsCalledThenAllocationHasProperGpuAddressAndHeapSvmIsUsed) {
if (memoryManager->isLimitedRange(0)) {
GTEST_SKIP();
}
uint32_t numGmms = 10;
MockWddmAllocation allocation(numGmms);
allocation.setAllocationType(GraphicsAllocation::AllocationType::BUFFER);
allocation.storageInfo.multiStorage = true;
wddm->callBaseMapGpuVa = true;
uint64_t gpuPreferredVa = 0x20000ull;
memoryManager->createWddmAllocation(&allocation, reinterpret_cast<void *>(gpuPreferredVa));
EXPECT_EQ(gpuPreferredVa, allocation.getGpuAddress());
EXPECT_EQ(numGmms, wddm->mapGpuVirtualAddressResult.called);
auto gmmSize = allocation.getDefaultGmm()->gmmResourceInfo->getSizeAllocation();
auto lastRequiredAddress = (numGmms - 1) * gmmSize + gpuPreferredVa;
EXPECT_EQ(lastRequiredAddress, wddm->mapGpuVirtualAddressResult.uint64ParamPassed);
EXPECT_GT(lastRequiredAddress, memoryManager->getGfxPartition(0)->getHeapMinimalAddress(HeapIndex::HEAP_SVM));
EXPECT_LT(lastRequiredAddress, memoryManager->getGfxPartition(0)->getHeapLimit(HeapIndex::HEAP_SVM));
}
TEST_F(WddmMemoryManagerSimpleTest, givenSvmCpuAllocationWhenSizeAndAlignmentProvidedThenAllocateMemoryReserveGpuVa) {
size_t size = 2 * MemoryConstants::megaByte;
MockAllocationProperties properties{csr->getRootDeviceIndex(), true, size, GraphicsAllocation::AllocationType::SVM_CPU, mockDeviceBitfield};

View File

@ -595,31 +595,40 @@ bool WddmMemoryManager::mapGpuVaForOneHandleAllocation(WddmAllocation *allocatio
return true;
}
bool WddmMemoryManager::mapMultiHandleAllocationWithRetry(WddmAllocation *allocation, Wddm *wddm, DeferredDeleter *deferredDeleter, GfxPartition &gfxPartition) {
bool WddmMemoryManager::mapMultiHandleAllocationWithRetry(WddmAllocation *allocation, const void *preferredGpuVirtualAddress) {
Wddm &wddm = getWddm(allocation->getRootDeviceIndex());
auto gfxPartition = getGfxPartition(allocation->getRootDeviceIndex());
auto alignedSize = allocation->getAlignedSize();
allocation->reservedSizeForGpuVirtualAddress = alignUp(alignedSize, MemoryConstants::pageSize64k);
allocation->reservedGpuVirtualAddress = wddm->reserveGpuVirtualAddress(gfxPartition.getHeapMinimalAddress(HeapIndex::HEAP_STANDARD64KB),
gfxPartition.getHeapLimit(HeapIndex::HEAP_STANDARD64KB),
allocation->reservedSizeForGpuVirtualAddress);
allocation->getGpuAddressToModify() = allocation->reservedGpuVirtualAddress;
auto addressToMap = allocation->reservedGpuVirtualAddress;
uint64_t addressToMap = 0;
HeapIndex heapIndex = preferredGpuVirtualAddress ? HeapIndex::HEAP_SVM : HeapIndex::HEAP_STANDARD64KB;
if (preferredGpuVirtualAddress) {
addressToMap = castToUint64(preferredGpuVirtualAddress);
allocation->getGpuAddressToModify() = addressToMap;
} else {
allocation->reservedSizeForGpuVirtualAddress = alignUp(alignedSize, MemoryConstants::pageSize64k);
allocation->reservedGpuVirtualAddress = wddm.reserveGpuVirtualAddress(gfxPartition->getHeapMinimalAddress(heapIndex), gfxPartition->getHeapLimit(heapIndex),
allocation->reservedSizeForGpuVirtualAddress);
allocation->getGpuAddressToModify() = allocation->reservedGpuVirtualAddress;
addressToMap = allocation->reservedGpuVirtualAddress;
}
for (auto currentHandle = 0u; currentHandle < allocation->getNumGmms(); currentHandle++) {
uint64_t gpuAddress = 0;
auto status = wddm->mapGpuVirtualAddress(allocation->getGmm(currentHandle), allocation->getHandles()[currentHandle],
gfxPartition.getHeapMinimalAddress(HeapIndex::HEAP_STANDARD64KB), gfxPartition.getHeapLimit(HeapIndex::HEAP_STANDARD64KB),
addressToMap, gpuAddress);
auto status = wddm.mapGpuVirtualAddress(allocation->getGmm(currentHandle), allocation->getHandles()[currentHandle],
gfxPartition->getHeapMinimalAddress(heapIndex), gfxPartition->getHeapLimit(heapIndex), addressToMap, gpuAddress);
if (!status && deferredDeleter) {
deferredDeleter->drain(true);
status = wddm->mapGpuVirtualAddress(allocation->getGmm(currentHandle), allocation->getHandles()[currentHandle],
gfxPartition.getHeapMinimalAddress(HeapIndex::HEAP_STANDARD64KB), gfxPartition.getHeapLimit(HeapIndex::HEAP_STANDARD64KB),
addressToMap, gpuAddress);
status = wddm.mapGpuVirtualAddress(allocation->getGmm(currentHandle), allocation->getHandles()[currentHandle],
gfxPartition->getHeapMinimalAddress(heapIndex), gfxPartition->getHeapLimit(heapIndex), addressToMap, gpuAddress);
}
if (!status) {
if (allocation->reservedGpuVirtualAddress) {
wddm->freeGpuVirtualAddress(allocation->reservedGpuVirtualAddress, allocation->reservedSizeForGpuVirtualAddress);
wddm.freeGpuVirtualAddress(allocation->reservedGpuVirtualAddress, allocation->reservedSizeForGpuVirtualAddress);
}
wddm->destroyAllocations(&allocation->getHandles()[0], allocation->getNumGmms(), allocation->resourceHandle);
wddm.destroyAllocations(&allocation->getHandles()[0], allocation->getNumGmms(), allocation->resourceHandle);
return false;
}
gpuAddress = GmmHelper::decanonize(gpuAddress);

View File

@ -84,7 +84,7 @@ class WddmMemoryManager : public MemoryManager {
bool createWddmAllocation(WddmAllocation *allocation, void *requiredGpuPtr);
bool mapGpuVirtualAddress(WddmAllocation *graphicsAllocation, const void *requiredGpuPtr);
bool mapGpuVaForOneHandleAllocation(WddmAllocation *graphicsAllocation, const void *requiredGpuPtr);
bool mapMultiHandleAllocationWithRetry(WddmAllocation *allocation, Wddm *wddm, DeferredDeleter *deferredDeleter, GfxPartition &gfxPartition);
bool mapMultiHandleAllocationWithRetry(WddmAllocation *allocation, const void *requiredGpuPtr);
bool createGpuAllocationsWithRetry(WddmAllocation *graphicsAllocation);
AlignedMallocRestrictions mallocRestrictions;

View File

@ -18,7 +18,7 @@ bool WddmMemoryManager::copyMemoryToAllocation(GraphicsAllocation *graphicsAlloc
}
bool WddmMemoryManager::mapGpuVirtualAddress(WddmAllocation *allocation, const void *requiredPtr) {
if (allocation->getNumGmms() > 1) {
return mapMultiHandleAllocationWithRetry(allocation, &getWddm(allocation->getRootDeviceIndex()), this->getDeferredDeleter(), *getGfxPartition(allocation->getRootDeviceIndex()));
return mapMultiHandleAllocationWithRetry(allocation, requiredPtr);
}
return mapGpuVaForOneHandleAllocation(allocation, requiredPtr);
}