From 13632ebbc9d11199454a630700dff39661d04717 Mon Sep 17 00:00:00 2001 From: Lukasz Jobczyk Date: Wed, 9 Jun 2021 08:03:22 +0000 Subject: [PATCH] Fix gpu address alignment for SVM CPU allocations Signed-off-by: Lukasz Jobczyk --- .../linux/drm_memory_manager_tests.cpp | 2 ++ .../os_interface/linux/drm_memory_manager.cpp | 23 +++++++++++++------ 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/opencl/test/unit_test/os_interface/linux/drm_memory_manager_tests.cpp b/opencl/test/unit_test/os_interface/linux/drm_memory_manager_tests.cpp index 9b50e294a9..4009434e11 100644 --- a/opencl/test/unit_test/os_interface/linux/drm_memory_manager_tests.cpp +++ b/opencl/test/unit_test/os_interface/linux/drm_memory_manager_tests.cpp @@ -3896,6 +3896,8 @@ TEST_F(DrmMemoryManagerTest, givenSvmCpuAllocationWhenSizeAndAlignmentProvidedTh EXPECT_EQ(reinterpret_cast(allocation->getGpuAddress()), alignUp(allocation->getReservedAddressPtr(), allocationData.alignment)); EXPECT_EQ(alignUp(allocationData.size, allocationData.alignment) + allocationData.alignment, allocation->getReservedAddressSize()); + EXPECT_GT(allocation->getReservedAddressSize(), bo->peekSize()); + memoryManager->freeGraphicsMemory(allocation); } diff --git a/shared/source/os_interface/linux/drm_memory_manager.cpp b/shared/source/os_interface/linux/drm_memory_manager.cpp index 82f2287cfa..5bb5c69588 100644 --- a/shared/source/os_interface/linux/drm_memory_manager.cpp +++ b/shared/source/os_interface/linux/drm_memory_manager.cpp @@ -252,27 +252,36 @@ DrmAllocation *DrmMemoryManager::allocateGraphicsMemoryWithAlignmentImpl(const A // It's needed to prevent overlapping pages with user pointers size_t cSize = std::max(alignUp(allocationData.size, minAlignment), minAlignment); - uint64_t gpuAddress = 0; - size_t alignedSize = cSize; + uint64_t gpuReservationAddress = 0; + uint64_t alignedGpuAddress = 0; + size_t alignedStorageSize = cSize; + size_t alignedVirtualAdressRangeSize = cSize; auto svmCpuAllocation = allocationData.type == GraphicsAllocation::AllocationType::SVM_CPU; if (svmCpuAllocation) { //add 2MB padding in case reserved addr is not 2MB aligned - alignedSize = alignUp(cSize, cAlignment) + cAlignment; + alignedStorageSize = alignUp(cSize, cAlignment); + alignedVirtualAdressRangeSize = alignedStorageSize + cAlignment; } // if limitedRangeAlloction is enabled, memory allocation for bo in the limited Range heap is required if ((isLimitedRange(allocationData.rootDeviceIndex) || svmCpuAllocation) && !allocationData.flags.isUSMHostAllocation) { - gpuAddress = acquireGpuRange(alignedSize, allocationData.rootDeviceIndex, HeapIndex::HEAP_STANDARD); - if (!gpuAddress) { + gpuReservationAddress = acquireGpuRange(alignedVirtualAdressRangeSize, allocationData.rootDeviceIndex, HeapIndex::HEAP_STANDARD); + if (!gpuReservationAddress) { return nullptr; } + alignedGpuAddress = gpuReservationAddress; if (svmCpuAllocation) { - gpuAddress = alignUp(gpuAddress, cAlignment); + alignedGpuAddress = alignUp(gpuReservationAddress, cAlignment); } } - return createAllocWithAlignment(allocationData, cSize, cAlignment, alignedSize, gpuAddress); + auto drmAllocation = createAllocWithAlignment(allocationData, cSize, cAlignment, alignedStorageSize, alignedGpuAddress); + if (drmAllocation != nullptr) { + drmAllocation->setReservedAddressRange(reinterpret_cast(gpuReservationAddress), alignedVirtualAdressRangeSize); + } + + return drmAllocation; } DrmAllocation *DrmMemoryManager::createAllocWithAlignmentFromUserptr(const AllocationData &allocationData, size_t size, size_t alignment, size_t alignedSVMSize, uint64_t gpuAddress) {