diff --git a/shared/source/memory_manager/memory_manager.h b/shared/source/memory_manager/memory_manager.h index d5aa99740d..2eab32adf7 100644 --- a/shared/source/memory_manager/memory_manager.h +++ b/shared/source/memory_manager/memory_manager.h @@ -164,7 +164,7 @@ class MemoryManager { MOCKABLE_VIRTUAL uint64_t getInternalHeapBaseAddress(uint32_t rootDeviceIndex, bool useLocalMemory); uint64_t getExternalHeapBaseAddress(uint32_t rootDeviceIndex, bool useLocalMemory); - bool isLimitedRange(uint32_t rootDeviceIndex); + MOCKABLE_VIRTUAL bool isLimitedRange(uint32_t rootDeviceIndex); bool peek64kbPagesEnabled(uint32_t rootDeviceIndex) const; bool peekForce32BitAllocations() const { return force32bitAllocations; } diff --git a/shared/source/os_interface/linux/drm_memory_manager.cpp b/shared/source/os_interface/linux/drm_memory_manager.cpp index 064d0061ec..a0937a0151 100644 --- a/shared/source/os_interface/linux/drm_memory_manager.cpp +++ b/shared/source/os_interface/linux/drm_memory_manager.cpp @@ -517,12 +517,17 @@ GraphicsAllocation *DrmMemoryManager::allocateGraphicsMemoryForNonSvmHostPtr(con auto realAllocationSize = alignedSize; auto offsetInPage = ptrDiff(allocationData.hostPtr, alignedPtr); auto rootDeviceIndex = allocationData.rootDeviceIndex; + uint64_t gpuVirtualAddress = 0; + if (this->isLimitedRange(allocationData.rootDeviceIndex)) { + gpuVirtualAddress = acquireGpuRange(alignedSize, rootDeviceIndex, HeapIndex::heapStandard); + } else { + alignedSize = alignUp(alignedSize, MemoryConstants::pageSize2M); + gpuVirtualAddress = acquireGpuRangeWithCustomAlignment(alignedSize, rootDeviceIndex, HeapIndex::heapStandard, MemoryConstants::pageSize2M); + } - auto gpuVirtualAddress = acquireGpuRange(alignedSize, rootDeviceIndex, HeapIndex::heapStandard); if (!gpuVirtualAddress) { return nullptr; } - std::unique_ptr bo(allocUserptr(reinterpret_cast(alignedPtr), realAllocationSize, rootDeviceIndex)); if (!bo) { releaseGpuRange(reinterpret_cast(gpuVirtualAddress), alignedSize, rootDeviceIndex); diff --git a/shared/test/common/mocks/linux/mock_drm_memory_manager.h b/shared/test/common/mocks/linux/mock_drm_memory_manager.h index bc2a4a7258..a8c341cabd 100644 --- a/shared/test/common/mocks/linux/mock_drm_memory_manager.h +++ b/shared/test/common/mocks/linux/mock_drm_memory_manager.h @@ -11,6 +11,7 @@ #include "shared/source/os_interface/linux/sys_calls.h" #include "shared/test/common/mocks/mock_memory_manager.h" #include "shared/test/common/os_interface/linux/device_command_stream_fixture.h" +#include "shared/test/common/test_macros/mock_method_macros.h" #include @@ -30,6 +31,7 @@ class DrmGemCloseWorker; class TestedDrmMemoryManager : public MemoryManagerCreate { public: + using BaseClass = MemoryManagerCreate; using DrmMemoryManager::acquireGpuRange; using DrmMemoryManager::alignmentSelector; using DrmMemoryManager::allocateGraphicsMemory; @@ -154,11 +156,14 @@ class TestedDrmMemoryManager : public MemoryManagerCreate { uint64_t acquireGpuRangeWithCustomAlignment(size_t &size, uint32_t rootDeviceIndex, HeapIndex heapIndex, size_t alignment) override { acquireGpuRangeWithCustomAlignmenCalledTimes++; + acquireGpuRangeWithCustomAlignmenPassedAlignment = alignment; return DrmMemoryManager::acquireGpuRangeWithCustomAlignment(size, rootDeviceIndex, heapIndex, alignment); } + ADDMETHOD(isLimitedRange, bool, true, false, (uint32_t rootDeviceIndex), (rootDeviceIndex)); uint32_t acquireGpuRangeCalledTimes = 0u; uint32_t acquireGpuRangeWithCustomAlignmenCalledTimes = 0u; + size_t acquireGpuRangeWithCustomAlignmenPassedAlignment = 0u; ExecutionEnvironment *executionEnvironment = nullptr; protected: diff --git a/shared/test/unit_test/os_interface/linux/drm_memory_manager_tests.cpp b/shared/test/unit_test/os_interface/linux/drm_memory_manager_tests.cpp index df63fccef3..e3e8a3fe6e 100644 --- a/shared/test/unit_test/os_interface/linux/drm_memory_manager_tests.cpp +++ b/shared/test/unit_test/os_interface/linux/drm_memory_manager_tests.cpp @@ -3226,11 +3226,12 @@ TEST_F(DrmMemoryManagerBasic, givenDrmMemoryManagerWhenAllocateGraphicsMemoryFor memoryManager->freeGraphicsMemory(allocation1); } -TEST_F(DrmMemoryManagerBasic, givenDrmMemoryManagerWhenAllocateGraphicsMemoryForNonSvmHostPtrThenAcquireGpuRangeCalled) { +TEST_F(DrmMemoryManagerBasic, givenDrmMemoryManagerWithLimitedRangeWhenAllocateGraphicsMemoryForNonSvmHostPtrThenAcquireGpuRangeCalled) { AllocationData allocationData; allocationData.rootDeviceIndex = rootDeviceIndex; std::unique_ptr memoryManager(new (std::nothrow) TestedDrmMemoryManager(false, false, false, executionEnvironment)); - + memoryManager->isLimitedRangeCallBase = false; + memoryManager->isLimitedRangeResult = true; memoryManager->forceLimitedRangeAllocator(0xFFFFFFFFF); allocationData.size = 2 * MemoryConstants::kiloByte; @@ -3242,6 +3243,37 @@ TEST_F(DrmMemoryManagerBasic, givenDrmMemoryManagerWhenAllocateGraphicsMemoryFor memoryManager->freeGraphicsMemory(allocation); } +TEST_F(DrmMemoryManagerBasic, givenDrmMemoryManagerWithoutLimitedRangeWhenAllocateGraphicsMemoryForNonSvmHostPtrThenAcquireGpuRangeWithCustomRangeCalled) { + AllocationData allocationData; + allocationData.rootDeviceIndex = rootDeviceIndex; + std::unique_ptr memoryManager(new (std::nothrow) TestedDrmMemoryManager(false, false, false, executionEnvironment)); + memoryManager->isLimitedRangeCallBase = false; + memoryManager->isLimitedRangeResult = false; + + allocationData.size = 2 * MemoryConstants::kiloByte; + allocationData.hostPtr = reinterpret_cast(0x1234); + auto allocation = static_cast(memoryManager->allocateGraphicsMemoryForNonSvmHostPtr(allocationData)); + + EXPECT_EQ(memoryManager->acquireGpuRangeCalledTimes, 0u); + EXPECT_EQ(memoryManager->acquireGpuRangeWithCustomAlignmenCalledTimes, 1u); + memoryManager->freeGraphicsMemory(allocation); +} + +TEST_F(DrmMemoryManagerBasic, givenDrmMemoryManagerWithoutLimitedRangeWhenAllocateGraphicsMemoryForNonSvmHostPtrThen2MBAlignmentUsed) { + AllocationData allocationData; + allocationData.rootDeviceIndex = rootDeviceIndex; + std::unique_ptr memoryManager(new (std::nothrow) TestedDrmMemoryManager(false, false, false, executionEnvironment)); + memoryManager->isLimitedRangeCallBase = false; + memoryManager->isLimitedRangeResult = false; + + allocationData.size = 2 * MemoryConstants::kiloByte; + allocationData.hostPtr = reinterpret_cast(0x1234); + auto allocation = static_cast(memoryManager->allocateGraphicsMemoryForNonSvmHostPtr(allocationData)); + + EXPECT_EQ(memoryManager->acquireGpuRangeWithCustomAlignmenPassedAlignment, MemoryConstants::pageSize2M); + memoryManager->freeGraphicsMemory(allocation); +} + TEST_F(DrmMemoryManagerBasic, givenDrmMemoryManagerWhenAllocateGraphicsMemoryForNonSvmHostPtrIsCalledButAllocationFailedThenNullPtrReturned) { AllocationData allocationData; allocationData.rootDeviceIndex = rootDeviceIndex;