Skip to content

Commit 3007159

Browse files
Create buffer object with multiple lmem regions for kmd-migrated buffers
This commit enables cross-tile kmd migration for buffers in local memory Related-To: NEO-6977 Signed-off-by: Milczarek, Slawomir <[email protected]>
1 parent f2bbd63 commit 3007159

File tree

6 files changed

+107
-8
lines changed

6 files changed

+107
-8
lines changed

shared/source/os_interface/linux/drm_memory_manager.cpp

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1483,7 +1483,14 @@ BufferObject *DrmMemoryManager::createBufferObjectInMemoryRegion(Drm *drm, Gmm *
14831483
}
14841484

14851485
uint32_t handle = 0;
1486-
auto ret = memoryInfo->createGemExtWithSingleRegion(drm, memoryBanks, size, handle);
1486+
uint32_t ret = 0;
1487+
1488+
auto banks = std::bitset<32>(memoryBanks);
1489+
if (banks.count() > 1) {
1490+
ret = memoryInfo->createGemExtWithMultipleRegions(drm, memoryBanks, size, handle);
1491+
} else {
1492+
ret = memoryInfo->createGemExtWithSingleRegion(drm, memoryBanks, size, handle);
1493+
}
14871494

14881495
if (ret != 0) {
14891496
return nullptr;
@@ -1508,6 +1515,7 @@ bool DrmMemoryManager::createDrmAllocation(Drm *drm, DrmAllocation *allocation,
15081515
auto currentBank = 0u;
15091516
auto iterationOffset = 0u;
15101517
auto banksCnt = storageInfo.getTotalBanksCnt();
1518+
auto useKmdMigrationForBuffers = (AllocationType::BUFFER == allocation->getAllocationType() && (DebugManager.flags.UseKmdMigrationForBuffers.get() > 0));
15111519

15121520
auto handles = storageInfo.getNumBanks();
15131521
if (storageInfo.colouringPolicy == ColouringPolicy::ChunkSizeBased) {
@@ -1522,14 +1530,16 @@ bool DrmMemoryManager::createDrmAllocation(Drm *drm, DrmAllocation *allocation,
15221530
currentBank = 0;
15231531
iterationOffset += banksCnt;
15241532
}
1525-
uint32_t memoryBanks = static_cast<uint32_t>(storageInfo.memoryBanks.to_ulong());
1526-
if (storageInfo.getNumBanks() > 1) {
1527-
// check if we have this bank, if not move to next one
1528-
// we may have holes in memoryBanks that we need to skip i.e. memoryBanks 1101 and 3 handle allocation
1529-
while (!(memoryBanks & (1u << currentBank))) {
1530-
currentBank++;
1533+
auto memoryBanks = static_cast<uint32_t>(storageInfo.memoryBanks.to_ulong());
1534+
if (!useKmdMigrationForBuffers) {
1535+
if (storageInfo.getNumBanks() > 1) {
1536+
// check if we have this bank, if not move to next one
1537+
// we may have holes in memoryBanks that we need to skip i.e. memoryBanks 1101 and 3 handle allocation
1538+
while (!(memoryBanks & (1u << currentBank))) {
1539+
currentBank++;
1540+
}
1541+
memoryBanks &= 1u << currentBank;
15311542
}
1532-
memoryBanks &= 1u << currentBank;
15331543
}
15341544
auto gmm = allocation->getGmm(handleId);
15351545
auto boSize = alignUp(gmm->gmmResourceInfo->getSizeAllocation(), MemoryConstants::pageSize64k);

shared/source/os_interface/linux/memory_info.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,4 +122,22 @@ uint32_t MemoryInfo::createGemExtWithSingleRegion(Drm *drm, uint32_t memoryBanks
122122
return ret;
123123
}
124124

125+
uint32_t MemoryInfo::createGemExtWithMultipleRegions(Drm *drm, uint32_t memoryBanks, size_t allocSize, uint32_t &handle) {
126+
auto pHwInfo = drm->getRootDeviceEnvironment().getHardwareInfo();
127+
auto banks = std::bitset<32>(memoryBanks);
128+
MemRegionsVec memRegions{};
129+
size_t currentBank = 0;
130+
size_t i = 0;
131+
while (i < banks.count()) {
132+
if (banks.test(currentBank)) {
133+
auto regionClassAndInstance = getMemoryRegionClassAndInstance(1u << currentBank, *pHwInfo);
134+
memRegions.push_back(regionClassAndInstance);
135+
i++;
136+
}
137+
currentBank++;
138+
}
139+
auto ret = createGemExt(drm, memRegions, allocSize, handle, {});
140+
return ret;
141+
}
142+
125143
} // namespace NEO

shared/source/os_interface/linux/memory_info.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ class MemoryInfo {
3737
uint32_t getTileIndex(uint32_t memoryBank, const HardwareInfo &hwInfo);
3838

3939
MOCKABLE_VIRTUAL uint32_t createGemExtWithSingleRegion(Drm *drm, uint32_t memoryBanks, size_t allocSize, uint32_t &handle);
40+
MOCKABLE_VIRTUAL uint32_t createGemExtWithMultipleRegions(Drm *drm, uint32_t memoryBanks, size_t allocSize, uint32_t &handle);
4041

4142
const RegionContainer &getDrmRegionInfos() const { return drmQueryRegions; }
4243

shared/test/common/os_interface/linux/drm_memory_manager_fixture.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,15 @@ struct MockedMemoryInfo : public NEO::MemoryInfo {
8383
handle = 1u;
8484
return 0u;
8585
}
86+
uint32_t createGemExtWithMultipleRegions(Drm *drm, uint32_t memoryBanks, size_t allocSize, uint32_t &handle) override {
87+
if (allocSize == 0) {
88+
return EINVAL;
89+
}
90+
handle = 1u;
91+
banks = memoryBanks;
92+
return 0u;
93+
}
94+
uint32_t banks = 0;
8695
};
8796

8897
class DrmMemoryManagerFixtureWithoutQuietIoctlExpectation {

shared/test/unit_test/os_interface/linux/drm_memory_info_prelim_tests.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -505,3 +505,44 @@ TEST(MemoryInfo, givenMemoryInfoWithRegionsAndPrivateBOSupportedAndIsPerContextV
505505
ASSERT_TRUE(createExt);
506506
EXPECT_EQ(std::nullopt, createExt->vmPrivateExt.vmId);
507507
}
508+
509+
TEST(MemoryInfo, givenMemoryInfoWithRegionsWhenCreatingGemExtWithMultipleRegionsThenReturnCorrectValues) {
510+
DebugManagerStateRestore restorer;
511+
DebugManager.flags.EnableLocalMemory.set(1);
512+
513+
std::vector<MemoryRegion> regionInfo(5);
514+
regionInfo[0].region = {I915_MEMORY_CLASS_SYSTEM, 0};
515+
regionInfo[0].probedSize = 8 * GB;
516+
regionInfo[1].region = {I915_MEMORY_CLASS_DEVICE, 0};
517+
regionInfo[1].probedSize = 16 * GB;
518+
regionInfo[2].region = {I915_MEMORY_CLASS_DEVICE, 1};
519+
regionInfo[2].probedSize = 16 * GB;
520+
regionInfo[3].region = {I915_MEMORY_CLASS_DEVICE, 2};
521+
regionInfo[3].probedSize = 16 * GB;
522+
regionInfo[4].region = {I915_MEMORY_CLASS_DEVICE, 3};
523+
regionInfo[4].probedSize = 16 * GB;
524+
525+
auto memoryInfo = std::make_unique<MemoryInfo>(regionInfo);
526+
ASSERT_NE(nullptr, memoryInfo);
527+
528+
auto executionEnvironment = std::make_unique<ExecutionEnvironment>();
529+
executionEnvironment->prepareRootDeviceEnvironments(1);
530+
auto drm = std::make_unique<DrmQueryMock>(*executionEnvironment->rootDeviceEnvironments[0]);
531+
uint32_t handle = 0;
532+
uint32_t memoryRegions = 0b1011;
533+
auto ret = memoryInfo->createGemExtWithMultipleRegions(drm.get(), memoryRegions, 1024, handle);
534+
EXPECT_EQ(1u, handle);
535+
EXPECT_EQ(0u, ret);
536+
EXPECT_EQ(1u, drm->ioctlCallsCount);
537+
538+
const auto &createExt = drm->context.receivedCreateGemExt;
539+
ASSERT_TRUE(createExt);
540+
ASSERT_EQ(3u, createExt->memoryRegions.size());
541+
EXPECT_EQ(I915_MEMORY_CLASS_DEVICE, createExt->memoryRegions[0].memoryClass);
542+
EXPECT_EQ(0u, createExt->memoryRegions[0].memoryInstance);
543+
EXPECT_EQ(I915_MEMORY_CLASS_DEVICE, createExt->memoryRegions[1].memoryClass);
544+
EXPECT_EQ(1u, createExt->memoryRegions[1].memoryInstance);
545+
EXPECT_EQ(I915_MEMORY_CLASS_DEVICE, createExt->memoryRegions[2].memoryClass);
546+
EXPECT_EQ(3u, createExt->memoryRegions[2].memoryInstance);
547+
EXPECT_EQ(1024u, drm->context.receivedCreateGemExt->size);
548+
}

shared/test/unit_test/os_interface/linux/drm_memory_manager_tests.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4140,6 +4140,26 @@ TEST_F(DrmMemoryManagerWithLocalMemoryAndExplicitExpectationsTest, givenDrmMemor
41404140
EXPECT_EQ(nullptr, bo);
41414141
}
41424142

4143+
TEST_F(DrmMemoryManagerWithLocalMemoryAndExplicitExpectationsTest, givenUseKmdMigrationForBuffersWhenGraphicsAllocationInDevicePoolIsAllocatedForBufferWithSeveralMemoryBanksThenCreateGemObjectWithMultipleRegions) {
4144+
DebugManager.flags.UseKmdMigrationForBuffers.set(1);
4145+
4146+
MemoryManager::AllocationStatus status = MemoryManager::AllocationStatus::Success;
4147+
AllocationData allocData;
4148+
allocData.allFlags = 0;
4149+
allocData.size = MemoryConstants::pageSize;
4150+
allocData.type = AllocationType::BUFFER;
4151+
allocData.rootDeviceIndex = rootDeviceIndex;
4152+
allocData.storageInfo.memoryBanks = 0b11;
4153+
4154+
auto allocation = memoryManager->allocateGraphicsMemoryInDevicePool(allocData, status);
4155+
EXPECT_NE(nullptr, allocation);
4156+
EXPECT_EQ(MemoryManager::AllocationStatus::Success, status);
4157+
4158+
EXPECT_EQ(allocData.storageInfo.memoryBanks, static_cast<MockedMemoryInfo *>(mock->getMemoryInfo())->banks);
4159+
4160+
memoryManager->freeGraphicsMemory(allocation);
4161+
}
4162+
41434163
TEST_F(DrmMemoryManagerWithLocalMemoryAndExplicitExpectationsTest, givenUseSystemMemoryFlagWhenGraphicsAllocationInDevicePoolIsAllocatedThenNullptrIsReturned) {
41444164
MemoryManager::AllocationStatus status = MemoryManager::AllocationStatus::Success;
41454165
AllocationData allocData;

0 commit comments

Comments
 (0)