Improve mmap logic in createAllocWithAlignment

Group small allocations and reuse mapped memory in order to keep map
count small.

Related-To: NEO-6417

Signed-off-by: Filip Hazubski <filip.hazubski@intel.com>
This commit is contained in:
Filip Hazubski
2022-01-24 16:44:38 +00:00
committed by Compute-Runtime-Automation
parent f064f7dd67
commit 0424f30782
8 changed files with 187 additions and 20 deletions

View File

@ -961,12 +961,12 @@ HWTEST2_F(DrmMemoryManagerLocalMemoryTest, givenAlignmentAndSizeWhenMmapReturnsU
};
munmapCalledCount = 0;
auto allocation = memoryManager->createAllocWithAlignment(allocationData, MemoryConstants::pageSize, MemoryConstants::pageSize64k, MemoryConstants::pageSize64k, 0u);
auto allocation = memoryManager->createAllocWithAlignment(allocationData, 5 * MemoryConstants::megaByte,
MemoryConstants::pageSize64k, 5 * MemoryConstants::megaByte, 0u);
EXPECT_EQ(alignUp(reinterpret_cast<void *>(0x12345678), MemoryConstants::pageSize64k), allocation->getMmapPtr());
EXPECT_EQ(1u, munmapCalledCount);
EXPECT_EQ(2u, munmapCalledCount);
memoryManager->freeGraphicsMemory(allocation);
EXPECT_EQ(3u, munmapCalledCount);
munmapCalledCount = 0u;
}
@ -999,7 +999,8 @@ HWTEST2_F(DrmMemoryManagerLocalMemoryTest, givenAlignmentAndSizeWhenMmapReturnsA
};
munmapCalledCount = 0u;
auto allocation = memoryManager->createAllocWithAlignment(allocationData, MemoryConstants::pageSize, 4u, MemoryConstants::pageSize64k, 0u);
auto allocation = memoryManager->createAllocWithAlignment(allocationData, 5 * MemoryConstants::megaByte,
4u, 5 * MemoryConstants::megaByte, 0u);
EXPECT_EQ(reinterpret_cast<void *>(0x12345678), allocation->getMmapPtr());
EXPECT_EQ(1u, munmapCalledCount);

View File

@ -5915,4 +5915,116 @@ HWTEST_F(DrmMemoryManagerTest, givenCompletionFenceEnabledWhenHandlingCompletion
memoryManager->freeGraphicsMemory(allocation);
}
static uint32_t mmapCallCount = 0u;
static uint32_t munmapCallCount = 0u;
HWTEST_F(DrmMemoryManagerTest, WhenMappingMemoryForMultipleSharedAllocationsThenMapMemoryOnce) {
auto mockMmap = [](void *addr, size_t len, int prot,
int flags, int fd, off_t offset) throw() {
mmapCallCount++;
return reinterpret_cast<void *>(0x1000000);
};
VariableBackup<decltype(memoryManager->mmapFunction)> mmapBackup{&memoryManager->mmapFunction, mockMmap};
mmapCallCount = 0;
for (int i = 0; i < 10; i++) {
memoryManager->mapCpuPointerOrReuse(MemoryConstants::pageSize2Mb, MemoryConstants::pageSize2Mb);
}
EXPECT_EQ(1u, mmapCallCount);
}
HWTEST_F(DrmMemoryManagerTest, givenMapReuseBufferUsedUpWhenMappingMemoryForMultipleSharedAllocationsThenReleaseLeftoverMemoryAndMapNewMapReuseBuffer) {
auto mockMmap = [](void *addr, size_t len, int prot,
int flags, int fd, off_t offset) throw() {
mmapCallCount++;
return reinterpret_cast<void *>(0x1000000);
};
auto mockMunmap = [](void *addr, size_t len) throw() {
munmapCallCount++;
return 0;
};
VariableBackup<decltype(memoryManager->mmapFunction)> mmapBackup{&memoryManager->mmapFunction, mockMmap};
VariableBackup<decltype(memoryManager->munmapFunction)> munmapBackup{&memoryManager->munmapFunction, mockMunmap};
mmapCallCount = 0;
munmapCallCount = 0;
memoryManager->mapCpuPointerOrReuse(MemoryConstants::pageSize, MemoryConstants::pageSize);
EXPECT_EQ(1u, mmapCallCount);
EXPECT_EQ(1u, munmapCallCount);
memoryManager->remainingMapBufferSize = 0;
memoryManager->mapCpuPointerOrReuse(MemoryConstants::pageSize, MemoryConstants::pageSize);
EXPECT_EQ(2u, mmapCallCount);
EXPECT_EQ(2u, munmapCallCount);
memoryManager->remainingMapBufferSize = MemoryConstants::pageSize - 1;
memoryManager->mapCpuPointerOrReuse(MemoryConstants::pageSize, MemoryConstants::pageSize);
EXPECT_EQ(3u, mmapCallCount);
EXPECT_EQ(4u, munmapCallCount);
}
HWTEST_F(DrmMemoryManagerTest, givenMapReuseBufferAllocatedWhenMemoryManagerIsDeletedThenReleaseLeftoverMapping) {
auto mockMunmap = [](void *addr, size_t len) throw() {
munmapCallCount++;
return 0;
};
munmapCallCount = 0;
auto pMemoryManager = new TestedDrmMemoryManager(false, false, false, *executionEnvironment);
pMemoryManager->munmapFunction = mockMunmap;
delete pMemoryManager;
EXPECT_EQ(0u, munmapCallCount);
pMemoryManager = new TestedDrmMemoryManager(false, false, false, *executionEnvironment);
pMemoryManager->munmapFunction = mockMunmap;
pMemoryManager->remainingMapBufferSize = 1;
delete pMemoryManager;
EXPECT_EQ(1u, munmapCallCount);
}
HWTEST_F(DrmMemoryManagerTest, givenMapReuseBufferRelatedDebugValuesChangedWhenMappingMemoryForSharedAllocationsThenCorrectlyUseMapReuseBuffer) {
DebugManagerStateRestore restorer;
auto mockMmap = [](void *addr, size_t len, int prot,
int flags, int fd, off_t offset) throw() {
mmapCallCount++;
return reinterpret_cast<void *>(0x1000000);
};
VariableBackup<decltype(memoryManager->mmapFunction)> mmapBackup{&memoryManager->mmapFunction, mockMmap};
DebugManager.flags.OverrideMaxAllocationSizeForMapReuseBufferInMb.set(1);
DebugManager.flags.OverrideMapReuseBufferSizeInMb.set(2);
mmapCallCount = 0;
memoryManager->mapCpuPointerOrReuse(MemoryConstants::megaByte, MemoryConstants::megaByte);
EXPECT_EQ(1u, mmapCallCount);
EXPECT_EQ(1u * MemoryConstants::megaByte, memoryManager->remainingMapBufferSize);
memoryManager->mapCpuPointerOrReuse(MemoryConstants::megaByte, MemoryConstants::megaByte);
EXPECT_EQ(1u, mmapCallCount);
EXPECT_EQ(0u * MemoryConstants::megaByte, memoryManager->remainingMapBufferSize);
memoryManager->mapCpuPointerOrReuse(MemoryConstants::megaByte, MemoryConstants::megaByte);
EXPECT_EQ(2u, mmapCallCount);
EXPECT_EQ(1u * MemoryConstants::megaByte, memoryManager->remainingMapBufferSize);
memoryManager->mapCpuPointerOrReuse(MemoryConstants::megaByte, MemoryConstants::megaByte);
EXPECT_EQ(2u, mmapCallCount);
EXPECT_EQ(0u * MemoryConstants::megaByte, memoryManager->remainingMapBufferSize);
DebugManager.flags.OverrideMaxAllocationSizeForMapReuseBufferInMb.set(3);
DebugManager.flags.OverrideMapReuseBufferSizeInMb.set(10);
mmapCallCount = 0;
memoryManager->remainingMapBufferSize = 0;
memoryManager->mapCpuPointerOrReuse(MemoryConstants::megaByte, 3 * MemoryConstants::megaByte);
EXPECT_EQ(1u, mmapCallCount);
EXPECT_EQ(7u * MemoryConstants::megaByte, memoryManager->remainingMapBufferSize);
memoryManager->mapCpuPointerOrReuse(MemoryConstants::megaByte, 3 * MemoryConstants::megaByte);
EXPECT_EQ(1u, mmapCallCount);
EXPECT_EQ(4u * MemoryConstants::megaByte, memoryManager->remainingMapBufferSize);
memoryManager->mapCpuPointerOrReuse(MemoryConstants::megaByte, 3 * MemoryConstants::megaByte);
EXPECT_EQ(1u, mmapCallCount);
EXPECT_EQ(1u * MemoryConstants::megaByte, memoryManager->remainingMapBufferSize);
memoryManager->mapCpuPointerOrReuse(MemoryConstants::megaByte, 3 * MemoryConstants::megaByte);
EXPECT_EQ(2u, mmapCallCount);
EXPECT_EQ(7u * MemoryConstants::megaByte, memoryManager->remainingMapBufferSize);
}
} // namespace NEO

View File

@ -368,4 +368,6 @@ EnableDrmCompletionFence = -1
UseDrmCompletionFenceForAllAllocations = -1
ExperimentalEnableSourceLevelDebugger = 0
Force2dImageAsArray = -1
ForceExtendedBufferSize = -1
ForceExtendedBufferSize = -1
OverrideMaxAllocationSizeForMapReuseBufferInMb = -1
OverrideMapReuseBufferSizeInMb = -1