diff --git a/shared/source/os_interface/linux/drm_memory_manager.cpp b/shared/source/os_interface/linux/drm_memory_manager.cpp index fd9b2989ed..87b485a5cf 100644 --- a/shared/source/os_interface/linux/drm_memory_manager.cpp +++ b/shared/source/os_interface/linux/drm_memory_manager.cpp @@ -355,6 +355,7 @@ SubmissionStatus DrmMemoryManager::emitPinningRequestForBoContainer(BufferObject } StorageInfo DrmMemoryManager::createStorageInfoFromProperties(const AllocationProperties &properties) { + auto storageInfo{MemoryManager::createStorageInfoFromProperties(properties)}; auto *memoryInfo = getDrm(properties.rootDeviceIndex).getMemoryInfo(); @@ -366,9 +367,17 @@ StorageInfo DrmMemoryManager::createStorageInfoFromProperties(const AllocationPr DEBUG_BREAK_IF(localMemoryRegions.empty()); DeviceBitfield allMemoryBanks{0b0}; - for (auto i = 0u; i < localMemoryRegions.size(); ++i) { - if ((properties.subDevicesBitfield & localMemoryRegions[i].tilesMask).any()) { - allMemoryBanks.set(i); + if (storageInfo.tileInstanced) { + const auto deviceCount = GfxCoreHelper::getSubDevicesCount(executionEnvironment.rootDeviceEnvironments[properties.rootDeviceIndex]->getHardwareInfo()); + const auto subDevicesMask = executionEnvironment.rootDeviceEnvironments[properties.rootDeviceIndex]->deviceAffinityMask.getGenericSubDevicesMask().to_ulong(); + const DeviceBitfield allTilesValue(properties.subDevicesBitfield.count() == 1 ? maxNBitValue(deviceCount) & subDevicesMask : properties.subDevicesBitfield); + + allMemoryBanks = allTilesValue; + } else { + for (auto i = 0u; i < localMemoryRegions.size(); ++i) { + if ((properties.subDevicesBitfield & localMemoryRegions[i].tilesMask).any()) { + allMemoryBanks.set(i); + } } } if (allMemoryBanks.none()) { @@ -1780,7 +1789,8 @@ void DrmMemoryManager::unlockBufferObject(BufferObject *bo) { bo->setLockedAddress(nullptr); } -void createColouredGmms(GmmHelper *gmmHelper, DrmAllocation &allocation, const StorageInfo &storageInfo, bool compression) { +void createColouredGmms(GmmHelper *gmmHelper, DrmAllocation &allocation, bool compression) { + const StorageInfo &storageInfo = allocation.storageInfo; DEBUG_BREAK_IF(storageInfo.colouringPolicy == ColouringPolicy::deviceCountBased && storageInfo.colouringGranularity != MemoryConstants::pageSize64k); auto remainingSize = alignUp(allocation.getUnderlyingBufferSize(), storageInfo.colouringGranularity); @@ -1824,12 +1834,14 @@ void createColouredGmms(GmmHelper *gmmHelper, DrmAllocation &allocation, const S } } -void fillGmmsInAllocation(GmmHelper *gmmHelper, DrmAllocation *allocation, const StorageInfo &storageInfo) { +void fillGmmsInAllocation(GmmHelper *gmmHelper, DrmAllocation *allocation) { auto alignedSize = alignUp(allocation->getUnderlyingBufferSize(), MemoryConstants::pageSize64k); auto &productHelper = gmmHelper->getRootDeviceEnvironment().getHelper(); GmmRequirements gmmRequirements{}; gmmRequirements.allowLargePages = true; gmmRequirements.preferCompressed = false; + + const StorageInfo &storageInfo = allocation->storageInfo; for (auto handleId = 0u; handleId < storageInfo.getNumBanks(); handleId++) { StorageInfo limitedStorageInfo = storageInfo; limitedStorageInfo.memoryBanks &= 1u << handleId; @@ -1945,18 +1957,16 @@ inline std::unique_ptr DrmMemoryManager::makeDrmAllocation(const auto allocation = std::make_unique(allocationData.rootDeviceIndex, allocationData.storageInfo.getNumBanks(), allocationData.type, nullptr, nullptr, gmmHelper->canonize(gpuAddress), sizeAligned, MemoryPool::localMemory); + allocation->storageInfo = allocationData.storageInfo; if (createSingleHandle) { allocation->setDefaultGmm(gmm.release()); } else if (allocationData.storageInfo.multiStorage) { - createColouredGmms(gmmHelper, - *allocation, - allocationData.storageInfo, - allocationData.flags.preferCompressed); + createColouredGmms(gmmHelper, *allocation, allocationData.flags.preferCompressed); } else { - fillGmmsInAllocation(gmmHelper, allocation.get(), allocationData.storageInfo); + fillGmmsInAllocation(gmmHelper, allocation.get()); } - allocation->storageInfo = allocationData.storageInfo; + allocation->setFlushL3Required(allocationData.flags.flushL3); allocation->setUncacheable(allocationData.flags.uncacheable); if (debugManager.flags.EnableHostAllocationMemPolicy.get()) { @@ -2255,7 +2265,6 @@ bool DrmMemoryManager::createDrmAllocation(Drm *drm, DrmAllocation *allocation, auto useKmdMigrationForBuffers = (AllocationType::buffer == allocation->getAllocationType() && (debugManager.flags.UseKmdMigrationForBuffers.get() > 0)); auto handles = storageInfo.getNumBanks(); - bool useChunking = false; size_t boTotalChunkSize = 0; if (checkAllocationForChunking(allocation->getUnderlyingBufferSize(), drm->getMinimalSizeForChunking(), @@ -2265,9 +2274,12 @@ bool DrmMemoryManager::createDrmAllocation(Drm *drm, DrmAllocation *allocation, handles = 1; allocation->resizeBufferObjects(handles); bos.resize(handles); - useChunking = true; boTotalChunkSize = allocation->getUnderlyingBufferSize(); - } else if (storageInfo.colouringPolicy == ColouringPolicy::chunkSizeBased) { + allocation->setNumHandles(handles); + return createDrmChunkedAllocation(drm, allocation, gpuAddress, boTotalChunkSize, maxOsContextCount); + } + + if (storageInfo.colouringPolicy == ColouringPolicy::chunkSizeBased) { handles = allocation->getNumGmms(); allocation->resizeBufferObjects(handles); bos.resize(handles); @@ -2275,11 +2287,6 @@ bool DrmMemoryManager::createDrmAllocation(Drm *drm, DrmAllocation *allocation, allocation->setNumHandles(handles); int32_t pairHandle = -1; - - if (useChunking) { - return createDrmChunkedAllocation(drm, allocation, gpuAddress, boTotalChunkSize, maxOsContextCount); - } - for (auto handleId = 0u; handleId < handles; handleId++, currentBank++) { if (currentBank == banksCnt) { currentBank = 0; 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 40f2405eba..ecc81e26f5 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 @@ -5512,7 +5512,7 @@ TEST_F(DrmMemoryManagerWithLocalMemoryTest, givenSingleLocalMemoryWhenParticular EXPECT_EQ(memoryManager->computeStorageInfoMemoryBanksCalled, 2UL); } -TEST_F(DrmMemoryManagerWithLocalMemoryTest, givenSingleLocalMemoryWhenAllSubdevicesIndicatedThenCorrectBankIsSelected) { +TEST_F(DrmMemoryManagerWithLocalMemoryTest, givenSingleLocalMemoryAndNonTileInstancedAllocationWhenAllTilesIndicatedThenCorrectBankIsSelected) { auto *memoryInfo = static_cast(mock->memoryInfo.get()); auto &localMemoryRegions = memoryInfo->localMemoryRegions; localMemoryRegions.resize(1U); @@ -5529,6 +5529,72 @@ TEST_F(DrmMemoryManagerWithLocalMemoryTest, givenSingleLocalMemoryWhenAllSubdevi EXPECT_EQ(memoryManager->computeStorageInfoMemoryBanksCalled, 2UL); } +TEST_F(DrmMemoryManagerWithLocalMemoryTest, givenSingleLocalMemoryWhenTileInstancedAllocationCreatedThenMemoryBanksSetToAllTilesRegardlessOfSubDevicesIndicatedInProperties) { + auto *memoryInfo = static_cast(mock->memoryInfo.get()); + auto &localMemoryRegions = memoryInfo->localMemoryRegions; + debugManager.flags.CreateMultipleSubDevices.set(2); + localMemoryRegions.resize(1U); + localMemoryRegions[0].tilesMask = 0b11; + + const auto expectedMemoryBanks = 0b11; + for (auto subDevicesMask = 1U; subDevicesMask < 4; ++subDevicesMask) { + AllocationProperties properties{1, 4096, AllocationType::workPartitionSurface, subDevicesMask}; + + memoryManager->computeStorageInfoMemoryBanksCalled = 0U; + auto storageInfo = memoryManager->createStorageInfoFromProperties(properties); + + EXPECT_TRUE(storageInfo.tileInstanced); + EXPECT_EQ(storageInfo.memoryBanks, expectedMemoryBanks); + EXPECT_EQ(memoryManager->computeStorageInfoMemoryBanksCalled, 2UL); + } +} + +TEST_F(DrmMemoryManagerWithLocalMemoryTest, givenSingleLocalMemoryAndTileInstancedAllocationTypeEvenWhenSubsetOfTilesIndicatedThenCorrectBankIsSelected) { + auto *memoryInfo = static_cast(mock->memoryInfo.get()); + auto &localMemoryRegions = memoryInfo->localMemoryRegions; + debugManager.flags.CreateMultipleSubDevices.set(2); + + localMemoryRegions.resize(1U); + localMemoryRegions[0].tilesMask = 0b11; + + AllocationProperties properties{1, true, 4096, AllocationType::workPartitionSurface, false, 0b10}; + const auto expectedMemoryBanks = 0b11; + + memoryManager->computeStorageInfoMemoryBanksCalled = 0U; + auto storageInfo = memoryManager->createStorageInfoFromProperties(properties); + + EXPECT_EQ(storageInfo.memoryBanks, expectedMemoryBanks); + EXPECT_EQ(memoryManager->computeStorageInfoMemoryBanksCalled, 2UL); +} + +TEST_F(DrmMemoryManagerWithLocalMemoryAndExplicitExpectationsTest, givenSingleLocalMemoryWhenTileInstancedAllocationCreatedThenItHasCorrectBOs) { + auto *memoryInfo = static_cast(mock->memoryInfo.get()); + auto &localMemoryRegions = memoryInfo->localMemoryRegions; + localMemoryRegions.resize(1U); + localMemoryRegions[0].tilesMask = 0b11; + + const DeviceBitfield subDeviceBitfield{0b11}; + const auto expectedNumHandles{subDeviceBitfield.count()}; + EXPECT_NE(expectedNumHandles, 0UL); + + AllocationProperties properties{1, 4096, AllocationType::workPartitionSurface, subDeviceBitfield}; + auto *allocation{memoryManager->allocateGraphicsMemoryInPreferredPool(properties, nullptr)}; + EXPECT_EQ(allocation->getNumHandles(), expectedNumHandles); + + const auto &bos{static_cast(allocation)->getBOs()}; + const auto commonBoAddress{bos[0U]->peekAddress()}; + auto numberOfValidBos{0U}; + for (const auto bo : bos) { + if (bo == nullptr) { + continue; + } + ++numberOfValidBos; + EXPECT_EQ(bo->peekAddress(), commonBoAddress); + } + EXPECT_EQ(numberOfValidBos, expectedNumHandles); + memoryManager->freeGraphicsMemory(allocation); +} + TEST_F(DrmMemoryManagerWithLocalMemoryTest, givenMultipleLocalMemoryRegionsWhenParticularSubdeviceIndicatedThenItIsSelected) { auto *memoryInfo = static_cast(mock->memoryInfo.get()); auto &localMemoryRegions = memoryInfo->localMemoryRegions;