diff --git a/runtime/memory_manager/memory_manager.h b/runtime/memory_manager/memory_manager.h index d96d6a9f8e..1fe4dc5575 100644 --- a/runtime/memory_manager/memory_manager.h +++ b/runtime/memory_manager/memory_manager.h @@ -264,7 +264,7 @@ class MemoryManager { ::alignedFree(ptr); } - void registerOsContext(OsContext *contextToRegister); + virtual void registerOsContext(OsContext *contextToRegister); size_t getOsContextCount() { return registeredOsContexts.size(); } protected: diff --git a/runtime/os_interface/windows/wddm_memory_manager.cpp b/runtime/os_interface/windows/wddm_memory_manager.cpp index 23181db672..bf1435e91b 100644 --- a/runtime/os_interface/windows/wddm_memory_manager.cpp +++ b/runtime/os_interface/windows/wddm_memory_manager.cpp @@ -416,6 +416,11 @@ void WddmMemoryManager::cleanOsHandles(OsHandleStorage &handleStorage) { } } +void WddmMemoryManager::registerOsContext(OsContext *contextToRegister) { + MemoryManager::registerOsContext(contextToRegister); + this->lastPeriodicTrimFenceValues.resize(this->registeredOsContexts.size()); +} + void WddmMemoryManager::obtainGpuAddresFromFragments(WddmAllocation *allocation, OsHandleStorage &handleStorage) { if (this->force32bitAllocations && (handleStorage.fragmentCount > 0)) { auto hostPtr = allocation->getUnderlyingBuffer(); @@ -652,10 +657,10 @@ void WddmMemoryManager::trimResidency(D3DDDI_TRIMRESIDENCYSET_FLAGS flags, uint6 WddmAllocation *wddmAllocation = nullptr; while ((wddmAllocation = getTrimCandidateHead()) != nullptr) { - DBG_LOG(ResidencyDebugEnable, "Residency:", __FUNCTION__, "lastPeriodicTrimFenceValue = ", lastPeriodicTrimFenceValue); + DBG_LOG(ResidencyDebugEnable, "Residency:", __FUNCTION__, "lastPeriodicTrimFenceValue = ", lastPeriodicTrimFenceValues[0]); // allocation was not used from last periodic trim - if (wddmAllocation->getResidencyData().getFenceValueForContextId(0) <= lastPeriodicTrimFenceValue) { + if (wddmAllocation->getResidencyData().getFenceValueForContextId(0) <= lastPeriodicTrimFenceValues[0]) { DBG_LOG(ResidencyDebugEnable, "Residency:", __FUNCTION__, "allocation: handle =", wddmAllocation->handle, "lastFence =", (wddmAllocation)->getResidencyData().getFenceValueForContextId(0)); @@ -667,7 +672,7 @@ void WddmMemoryManager::trimResidency(D3DDDI_TRIMRESIDENCYSET_FLAGS flags, uint6 } for (uint32_t allocationId = 0; allocationId < wddmAllocation->fragmentsStorage.fragmentCount; allocationId++) { - if (wddmAllocation->fragmentsStorage.fragmentStorageData[allocationId].residency->getFenceValueForContextId(0) <= lastPeriodicTrimFenceValue) { + if (wddmAllocation->fragmentsStorage.fragmentStorageData[allocationId].residency->getFenceValueForContextId(0) <= lastPeriodicTrimFenceValues[0]) { DBG_LOG(ResidencyDebugEnable, "Residency:", __FUNCTION__, "Evict fragment: handle =", wddmAllocation->fragmentsStorage.fragmentStorageData[allocationId].osHandleStorage->handle, "lastFence =", wddmAllocation->fragmentsStorage.fragmentStorageData[allocationId].residency->getFenceValueForContextId(0)); @@ -709,8 +714,8 @@ void WddmMemoryManager::trimResidency(D3DDDI_TRIMRESIDENCYSET_FLAGS flags, uint6 if (!osContext) { osContext = platform()->getDevice(0)->getOsContext(); } - lastPeriodicTrimFenceValue = *osContext->get()->getMonitoredFence().cpuAddress; - DBG_LOG(ResidencyDebugEnable, "Residency:", __FUNCTION__, "updated lastPeriodicTrimFenceValue =", lastPeriodicTrimFenceValue); + lastPeriodicTrimFenceValues[0] = *osContext->get()->getMonitoredFence().cpuAddress; + DBG_LOG(ResidencyDebugEnable, "Residency:", __FUNCTION__, "updated lastPeriodicTrimFenceValue =", lastPeriodicTrimFenceValues[0]); } } diff --git a/runtime/os_interface/windows/wddm_memory_manager.h b/runtime/os_interface/windows/wddm_memory_manager.h index 3839d5f7fd..bec3abf89f 100644 --- a/runtime/os_interface/windows/wddm_memory_manager.h +++ b/runtime/os_interface/windows/wddm_memory_manager.h @@ -55,6 +55,8 @@ class WddmMemoryManager : public MemoryManager { AllocationStatus populateOsHandles(OsHandleStorage &handleStorage) override; void cleanOsHandles(OsHandleStorage &handleStorage) override; + void registerOsContext(OsContext *contextToRegister) override; + void obtainGpuAddresFromFragments(WddmAllocation *allocation, OsHandleStorage &handleStorage); GraphicsAllocation *createGraphicsAllocation(OsHandleStorage &handleStorage, size_t hostPtrSize, const void *hostPtr) override; @@ -112,7 +114,7 @@ class WddmMemoryManager : public MemoryManager { ResidencyContainer trimCandidateList; std::mutex trimCandidateListMutex; std::atomic residencyLock; - uint64_t lastPeriodicTrimFenceValue = 0; + std::vector lastPeriodicTrimFenceValues; uint32_t trimCandidatesCount = 0; bool memoryBudgetExhausted = false; AlignedMallocRestrictions mallocRestrictions; diff --git a/unit_tests/os_interface/windows/mock_wddm_memory_manager.h b/unit_tests/os_interface/windows/mock_wddm_memory_manager.h index 5fd4b95364..4883147ae9 100644 --- a/unit_tests/os_interface/windows/mock_wddm_memory_manager.h +++ b/unit_tests/os_interface/windows/mock_wddm_memory_manager.h @@ -18,7 +18,7 @@ class MockWddmMemoryManager : public WddmMemoryManager { using BaseClass::checkTrimCandidateListCompaction; using BaseClass::compactTrimCandidateList; using BaseClass::createWddmAllocation; - using BaseClass::lastPeriodicTrimFenceValue; + using BaseClass::lastPeriodicTrimFenceValues; using BaseClass::removeFromTrimCandidateList; using BaseClass::trimCandidateList; using BaseClass::trimCandidatesCount; diff --git a/unit_tests/os_interface/windows/wddm_memory_manager_tests.cpp b/unit_tests/os_interface/windows/wddm_memory_manager_tests.cpp index b67a3712e9..935d5da5f8 100644 --- a/unit_tests/os_interface/windows/wddm_memory_manager_tests.cpp +++ b/unit_tests/os_interface/windows/wddm_memory_manager_tests.cpp @@ -25,22 +25,21 @@ using namespace ::testing; void WddmMemoryManagerFixture::SetUp() { GmmEnvironmentFixture::SetUp(); GdiDllFixture::SetUp(); - wddm.reset(static_cast(Wddm::createWddm())); - ASSERT_NE(nullptr, wddm); + + wddm = static_cast(Wddm::createWddm()); if (platformDevices[0]->capabilityTable.ftrRenderCompressedBuffers || platformDevices[0]->capabilityTable.ftrRenderCompressedImages) { GMM_DEVICE_CALLBACKS_INT dummyDeviceCallbacks = {}; GMM_TRANSLATIONTABLE_CALLBACKS dummyTTCallbacks = {}; wddm->resetPageTableManager(GmmPageTableMngr::create(&dummyDeviceCallbacks, 0, &dummyTTCallbacks)); } EXPECT_TRUE(wddm->init()); - uint64_t heap32Base = (uint64_t)(0x800000000000); - if (sizeof(uintptr_t) == 4) { - heap32Base = 0x1000; - } + constexpr uint64_t heap32Base = (is32bit) ? 0x1000 : 0x800000000000; wddm->setHeap32(heap32Base, 1000 * MemoryConstants::pageSize - 1); - memoryManager.reset(new (std::nothrow) MockWddmMemoryManager(wddm.get())); - //assert we have memory manager - ASSERT_NE(nullptr, memoryManager); + + osInterface = std::make_unique(); + osInterface->get()->setWddm(wddm); + + memoryManager = std::make_unique(wddm); } TEST(WddmMemoryManager, NonCopyable) { @@ -53,6 +52,24 @@ TEST(WddmMemoryManager, NonAssignable) { EXPECT_FALSE(std::is_copy_assignable::value); } +TEST_F(WddmMemoryManagerTest, givenWddmMemoryManagerWhenRegisteringOsContextThenLastPeriodicTrimFenceValuesIsResizedAccordinglyToContextId) { + memoryManager->registerOsContext(new OsContext(osInterface.get(), 0u)); + EXPECT_EQ(1, memoryManager->lastPeriodicTrimFenceValues.size()); + EXPECT_EQ(0, memoryManager->lastPeriodicTrimFenceValues[0]); + + memoryManager->registerOsContext(new OsContext(osInterface.get(), 2u)); + EXPECT_EQ(3, memoryManager->lastPeriodicTrimFenceValues.size()); + EXPECT_EQ(0, memoryManager->lastPeriodicTrimFenceValues[0]); + EXPECT_EQ(0, memoryManager->lastPeriodicTrimFenceValues[1]); + EXPECT_EQ(0, memoryManager->lastPeriodicTrimFenceValues[2]); + + memoryManager->registerOsContext(new OsContext(osInterface.get(), 1u)); + EXPECT_EQ(3, memoryManager->lastPeriodicTrimFenceValues.size()); + EXPECT_EQ(0, memoryManager->lastPeriodicTrimFenceValues[0]); + EXPECT_EQ(0, memoryManager->lastPeriodicTrimFenceValues[1]); + EXPECT_EQ(0, memoryManager->lastPeriodicTrimFenceValues[2]); +} + TEST(WddmMemoryManagerAllocator32BitTest, allocator32BitIsCreatedWithCorrectBase) { std::unique_ptr wddm(static_cast(Wddm::createWddm())); uint64_t base = 0x56000; @@ -206,7 +223,6 @@ TEST_F(WddmMemoryManagerTest, givenDefaultWddmMemoryManagerWhenAskedForVirtualPa } TEST_F(WddmMemoryManagerTest, GivenGraphicsAllocationWhenAddAndRemoveAllocationToHostPtrManagerThenfragmentHasCorrectValues) { - memoryManager.reset(new (std::nothrow) MockWddmMemoryManager(wddm.get())); void *cpuPtr = (void *)0x30000; size_t size = 0x1000; @@ -1115,7 +1131,7 @@ TEST_F(WddmMemoryManagerResidencyTest, givenNotUsedAllocationsFromPreviousPeriod allocation2.getResidencyData().resident = true; // Set last periodic fence value - memoryManager->lastPeriodicTrimFenceValue = 10; + memoryManager->lastPeriodicTrimFenceValues[0] = 10; // Set current fence value to greater value osContext->get()->getMonitoredFence().currentFenceValue = 20; @@ -1151,7 +1167,7 @@ TEST_F(WddmMemoryManagerResidencyTest, givenOneUsedAllocationFromPreviousPeriodi allocation2.getResidencyData().resident = true; // Set last periodic fence value - memoryManager->lastPeriodicTrimFenceValue = 10; + memoryManager->lastPeriodicTrimFenceValues[0] = 10; // Set current fence value to greater value osContext->get()->getMonitoredFence().currentFenceValue = 20; @@ -1197,7 +1213,7 @@ TEST_F(WddmMemoryManagerResidencyTest, givenTripleAllocationWithUsedAndUnusedFra allocationTriple->fragmentsStorage.fragmentStorageData[2].residency->resident = true; // Set last periodic fence value - memoryManager->lastPeriodicTrimFenceValue = 10; + memoryManager->lastPeriodicTrimFenceValues[0] = 10; // Set current fence value to greater value osContext->get()->getMonitoredFence().currentFenceValue = 20; @@ -1226,14 +1242,14 @@ TEST_F(WddmMemoryManagerResidencyTest, givenPeriodicTrimWhenTrimCallbackCalledTh trimNotification.NumBytesToTrim = 0; // Set last periodic fence value - memoryManager->lastPeriodicTrimFenceValue = 10; + memoryManager->lastPeriodicTrimFenceValues[0] = 10; // Set current fence value to greater value *osContext->get()->getMonitoredFence().cpuAddress = 20; memoryManager->trimCandidateList.resize(0); memoryManager->trimResidency(trimNotification.Flags, trimNotification.NumBytesToTrim); - EXPECT_EQ(20u, memoryManager->lastPeriodicTrimFenceValue); + EXPECT_EQ(20u, memoryManager->lastPeriodicTrimFenceValues[0]); } TEST_F(WddmMemoryManagerResidencyTest, givenRestartPeriodicTrimWhenTrimCallbackCalledThenLastPeriodicTrimFenceIsSetToCurrentFenceValue) { @@ -1244,14 +1260,14 @@ TEST_F(WddmMemoryManagerResidencyTest, givenRestartPeriodicTrimWhenTrimCallbackC trimNotification.NumBytesToTrim = 0; // Set last periodic fence value - memoryManager->lastPeriodicTrimFenceValue = 10; + memoryManager->lastPeriodicTrimFenceValues[0] = 10; // Set current fence value to greater value *osContext->get()->getMonitoredFence().cpuAddress = 20; memoryManager->trimCandidateList.resize(0); memoryManager->trimResidency(trimNotification.Flags, trimNotification.NumBytesToTrim); - EXPECT_EQ(20u, memoryManager->lastPeriodicTrimFenceValue); + EXPECT_EQ(20u, memoryManager->lastPeriodicTrimFenceValues[0]); } TEST_F(WddmMemoryManagerResidencyTest, trimToBudgetWithZeroSizeReturnsTrue) { diff --git a/unit_tests/os_interface/windows/wddm_memory_manager_tests.h b/unit_tests/os_interface/windows/wddm_memory_manager_tests.h index e3862df01f..9af8f2da1b 100644 --- a/unit_tests/os_interface/windows/wddm_memory_manager_tests.h +++ b/unit_tests/os_interface/windows/wddm_memory_manager_tests.h @@ -32,9 +32,9 @@ class WddmMemoryManagerFixture : public GmmEnvironmentFixture, public GdiDllFixt GdiDllFixture::TearDown(); GmmEnvironmentFixture::TearDown(); } - + std::unique_ptr osInterface; std::unique_ptr memoryManager; - std::unique_ptr wddm; + WddmMock *wddm; }; typedef ::Test WddmMemoryManagerTest; @@ -43,32 +43,34 @@ class MockWddmMemoryManagerFixture : public GmmEnvironmentFixture { public: void SetUp() { GmmEnvironmentFixture::SetUp(); - wddm = (static_cast(Wddm::createWddm())); + + gdi = new MockGdi(); + + wddm = static_cast(Wddm::createWddm()); + wddm->gdi.reset(gdi); + constexpr uint64_t heap32Base = (is32bit) ? 0x1000 : 0x800000000000; + wddm->setHeap32(heap32Base, 1000 * MemoryConstants::pageSize - 1); + EXPECT_TRUE(wddm->init()); + osInterface = std::make_unique(); osInterface->get()->setWddm(wddm); - gdi = new MockGdi(); - wddm->gdi.reset(gdi); - EXPECT_TRUE(wddm->init()); + osContext = new OsContext(osInterface.get(), 0u); osContext->incRefInternal(); - uint64_t heap32Base = (uint64_t)(0x800000000000); - if (sizeof(uintptr_t) == 4) { - heap32Base = 0x1000; - } - wddm->setHeap32(heap32Base, 1000 * MemoryConstants::pageSize - 1); - memoryManager.reset(new (std::nothrow) MockWddmMemoryManager(wddm)); - //assert we have memory manager - ASSERT_NE(nullptr, memoryManager); + + memoryManager = std::make_unique(wddm); + memoryManager->registerOsContext(osContext); } void TearDown() { osContext->decRefInternal(); GmmEnvironmentFixture::TearDown(); } + + std::unique_ptr osInterface; std::unique_ptr memoryManager; WddmMock *wddm = nullptr; - std::unique_ptr osInterface; - OsContext *osContext; + OsContext *osContext = nullptr; MockGdi *gdi = nullptr; }; @@ -145,15 +147,6 @@ class BufferWithWddmMemory : public ::testing::Test, void SetUp() { WddmMemoryManagerFixture::SetUp(); tmp = context.getMemoryManager(); - EXPECT_TRUE(wddm->init()); - uint64_t heap32Base = (uint64_t)(0x800000000000); - if (sizeof(uintptr_t) == 4) { - heap32Base = 0x1000; - } - wddm->setHeap32(heap32Base, 1000 * MemoryConstants::pageSize - 1); - memoryManager.reset(new (std::nothrow) MockWddmMemoryManager(wddm.get())); - //assert we have memory manager - ASSERT_NE(nullptr, memoryManager); context.setMemoryManager(memoryManager.get()); flags = 0; }