From 5cf453074814ac8d58959face0c808dbea98e8fc Mon Sep 17 00:00:00 2001 From: Maciej Plewka Date: Tue, 26 Jan 2021 10:06:44 +0000 Subject: [PATCH] Munmap unaligned part from mmap Releated-To: NEO-5397 Signed-off-by: Maciej Plewka --- ...ager_allocate_in_device_pool_tests_dg1.cpp | 76 +++++++++++++++++++ ...ry_manager_allocate_in_device_pool_dg1.cpp | 21 +++-- .../mocks/linux/mock_drm_memory_manager.h | 4 +- 3 files changed, 93 insertions(+), 8 deletions(-) diff --git a/opencl/test/unit_test/os_interface/linux/drm_memory_manager_allocate_in_device_pool_tests_dg1.cpp b/opencl/test/unit_test/os_interface/linux/drm_memory_manager_allocate_in_device_pool_tests_dg1.cpp index 7abb74b2a4..e321afbec9 100644 --- a/opencl/test/unit_test/os_interface/linux/drm_memory_manager_allocate_in_device_pool_tests_dg1.cpp +++ b/opencl/test/unit_test/os_interface/linux/drm_memory_manager_allocate_in_device_pool_tests_dg1.cpp @@ -1261,4 +1261,80 @@ TEST_F(DrmMemoryManagerLocalMemoryTest, givenGraphicsAllocationInDevicePoolIsAll memoryManager->freeGraphicsMemory(allocation); } +static bool munmapWasCalled = false; + +TEST_F(DrmMemoryManagerLocalMemoryTest, givenAlignmentAndSizeWhenMmapReturnsUnalignedPointerThenCreateAllocWithAlignmentUnmapUnalignedPart) { + DebugManagerStateRestore restorer; + DebugManager.flags.EnableBOMmapCreate.set(-1); + + drm_i915_memory_region_info regionInfo[2] = {}; + regionInfo[0].region = {I915_MEMORY_CLASS_SYSTEM, 0}; + regionInfo[1].region = {I915_MEMORY_CLASS_DEVICE, 0}; + + mock->memoryInfo.reset(new MemoryInfoImpl(regionInfo, 2)); + mock->ioctlCallsCount = 0; + + AllocationData allocationData; + allocationData.size = MemoryConstants::pageSize64k; + + memoryManager->mmapFunction = [](void *addr, size_t len, int prot, + int flags, int fd, off_t offset) __THROW { + if (addr == 0) { + return reinterpret_cast(0x12345678); + } else { + return addr; + } + }; + + memoryManager->munmapFunction = [](void *addr, size_t len) __THROW { + munmapWasCalled = true; + return 0; + }; + + munmapWasCalled = false; + auto allocation = memoryManager->createAllocWithAlignment(allocationData, MemoryConstants::pageSize, MemoryConstants::pageSize64k, MemoryConstants::pageSize64k, 0u); + + EXPECT_EQ(alignUp(reinterpret_cast(0x12345678), MemoryConstants::pageSize64k), allocation->getMmapPtr()); + EXPECT_TRUE(munmapWasCalled); + munmapWasCalled = false; + memoryManager->freeGraphicsMemory(allocation); +} + +TEST_F(DrmMemoryManagerLocalMemoryTest, givenAlignmentAndSizeWhenMmapReturnsAlignedThenCreateAllocWithAlignmentDoesntCallUnmap) { + DebugManagerStateRestore restorer; + DebugManager.flags.EnableBOMmapCreate.set(-1); + + drm_i915_memory_region_info regionInfo[2] = {}; + regionInfo[0].region = {I915_MEMORY_CLASS_SYSTEM, 0}; + regionInfo[1].region = {I915_MEMORY_CLASS_DEVICE, 0}; + + mock->memoryInfo.reset(new MemoryInfoImpl(regionInfo, 2)); + mock->ioctlCallsCount = 0; + + AllocationData allocationData; + allocationData.size = MemoryConstants::pageSize64k; + + memoryManager->mmapFunction = [](void *addr, size_t len, int prot, + int flags, int fd, __off_t offset) __THROW { + if (addr == 0) { + return reinterpret_cast(0x12345678); + } else { + return addr; + } + }; + + memoryManager->munmapFunction = [](void *addr, size_t len) __THROW { + munmapWasCalled = true; + return 0; + }; + + munmapWasCalled = false; + auto allocation = memoryManager->createAllocWithAlignment(allocationData, MemoryConstants::pageSize, 1u, MemoryConstants::pageSize64k, 0u); + + EXPECT_EQ(reinterpret_cast(0x12345678), allocation->getMmapPtr()); + EXPECT_FALSE(munmapWasCalled); + munmapWasCalled = false; + memoryManager->freeGraphicsMemory(allocation); +} + } // namespace NEO diff --git a/shared/source/os_interface/linux/drm_memory_manager_allocate_in_device_pool_dg1.cpp b/shared/source/os_interface/linux/drm_memory_manager_allocate_in_device_pool_dg1.cpp index 336880af02..954795efd7 100644 --- a/shared/source/os_interface/linux/drm_memory_manager_allocate_in_device_pool_dg1.cpp +++ b/shared/source/os_interface/linux/drm_memory_manager_allocate_in_device_pool_dg1.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020 Intel Corporation + * Copyright (C) 2020-2021 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -82,7 +82,9 @@ DrmAllocation *DrmMemoryManager::createAllocWithAlignment(const AllocationData & auto cpuBasePointer = cpuPointer; cpuPointer = alignUp(cpuPointer, alignment); - std::unique_ptr bo(this->createBufferObjectInMemoryRegion(&this->getDrm(allocationData.rootDeviceIndex), reinterpret_cast(cpuPointer), alignedSize, 0u, maxOsContextCount)); + auto pointerDiff = ptrDiff(cpuPointer, cpuBasePointer); + auto allocSize = totalSizeToAlloc - pointerDiff; + std::unique_ptr bo(this->createBufferObjectInMemoryRegion(&this->getDrm(allocationData.rootDeviceIndex), reinterpret_cast(cpuPointer), allocSize, 0u, maxOsContextCount)); if (!bo) { this->munmapFunction(cpuBasePointer, totalSizeToAlloc); @@ -99,15 +101,20 @@ DrmAllocation *DrmMemoryManager::createAllocWithAlignment(const AllocationData & return nullptr; } - this->mmapFunction(cpuPointer, alignedSize, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, getDrm(allocationData.rootDeviceIndex).getFileDescriptor(), static_cast(gemMmap.offset)); + [[maybe_unused]] auto retPtr = this->mmapFunction(cpuPointer, allocSize, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, getDrm(allocationData.rootDeviceIndex).getFileDescriptor(), static_cast(gemMmap.offset)); + DEBUG_BREAK_IF(retPtr != cpuPointer); obtainGpuAddress(allocationData, bo.get(), gpuAddress); emitPinningRequest(bo.get(), allocationData); - auto allocation = new DrmAllocation(allocationData.rootDeviceIndex, allocationData.type, bo.get(), cpuPointer, bo->gpuAddress, alignedSize, MemoryPool::System4KBPages); - allocation->setMmapPtr(cpuBasePointer); - allocation->setMmapSize(totalSizeToAlloc); - allocation->setReservedAddressRange(reinterpret_cast(gpuAddress), alignedSize); + auto allocation = new DrmAllocation(allocationData.rootDeviceIndex, allocationData.type, bo.get(), cpuPointer, bo->gpuAddress, allocSize, MemoryPool::System4KBPages); + allocation->setMmapPtr(cpuPointer); + allocation->setMmapSize(allocSize); + if (pointerDiff != 0) { + [[maybe_unused]] auto retCode = this->munmapFunction(cpuBasePointer, pointerDiff); + DEBUG_BREAK_IF(retCode != 0); + } + allocation->setReservedAddressRange(reinterpret_cast(gpuAddress), allocSize); bo.release(); diff --git a/shared/test/unit_test/mocks/linux/mock_drm_memory_manager.h b/shared/test/unit_test/mocks/linux/mock_drm_memory_manager.h index 9166ebca4a..2993b1135c 100644 --- a/shared/test/unit_test/mocks/linux/mock_drm_memory_manager.h +++ b/shared/test/unit_test/mocks/linux/mock_drm_memory_manager.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2020 Intel Corporation + * Copyright (C) 2018-2021 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -64,6 +64,7 @@ class TestedDrmMemoryManager : public MemoryManagerCreate { using DrmMemoryManager::allocateGraphicsMemoryWithHostPtr; using DrmMemoryManager::allocateShareableMemory; using DrmMemoryManager::allocUserptr; + using DrmMemoryManager::createAllocWithAlignment; using DrmMemoryManager::createGraphicsAllocation; using DrmMemoryManager::createSharedBufferObject; using DrmMemoryManager::eraseSharedBufferObject; @@ -75,6 +76,7 @@ class TestedDrmMemoryManager : public MemoryManagerCreate { using DrmMemoryManager::lockResourceInLocalMemoryImpl; using DrmMemoryManager::memoryForPinBBs; using DrmMemoryManager::mmapFunction; + using DrmMemoryManager::munmapFunction; using DrmMemoryManager::pinBBs; using DrmMemoryManager::pinThreshold; using DrmMemoryManager::pushSharedBufferObject;