From 0589a70dc72c986fd4a6397f3c824d89d1e3ad3a Mon Sep 17 00:00:00 2001 From: Mateusz Hoppe Date: Thu, 12 Dec 2024 12:38:40 +0000 Subject: [PATCH] feature(sysman): reinitialize gfxPartition on reset Related-To: NEO-13203 Signed-off-by: Mateusz Hoppe --- .../source/sysman/linux/os_sysman_imp.cpp | 1 + .../linux/test_zes_sysman_diagnostics.cpp | 15 ++++++- shared/source/memory_manager/memory_manager.h | 3 ++ shared/source/os_interface/device_factory.cpp | 1 + .../os_interface/linux/drm_memory_manager.cpp | 19 ++++++++ .../os_interface/linux/drm_memory_manager.h | 2 + .../test/common/mocks/mock_memory_manager.cpp | 20 +++++++++ .../test/common/mocks/mock_memory_manager.h | 3 ++ .../linux/drm_memory_manager_tests.cpp | 43 +++++++++++++++++++ 9 files changed, 106 insertions(+), 1 deletion(-) diff --git a/level_zero/tools/source/sysman/linux/os_sysman_imp.cpp b/level_zero/tools/source/sysman/linux/os_sysman_imp.cpp index 3dcc9720b85a1..c1ee3840a06bb 100644 --- a/level_zero/tools/source/sysman/linux/os_sysman_imp.cpp +++ b/level_zero/tools/source/sysman/linux/os_sysman_imp.cpp @@ -341,6 +341,7 @@ void LinuxSysmanImp::releaseDeviceResources() { executionEnvironment->memoryManager->releaseDeviceSpecificMemResources(rootDeviceIndex); executionEnvironment->releaseRootDeviceEnvironmentResources(executionEnvironment->rootDeviceEnvironments[rootDeviceIndex].get()); executionEnvironment->rootDeviceEnvironments[rootDeviceIndex].reset(); + executionEnvironment->memoryManager->releaseDeviceSpecificGfxPartition(rootDeviceIndex); } void LinuxSysmanImp::reInitSysmanDeviceResources() { diff --git a/level_zero/tools/test/unit_tests/sources/sysman/diagnostics/linux/test_zes_sysman_diagnostics.cpp b/level_zero/tools/test/unit_tests/sources/sysman/diagnostics/linux/test_zes_sysman_diagnostics.cpp index 6f354263b1d7a..c4b2830c42440 100644 --- a/level_zero/tools/test/unit_tests/sources/sysman/diagnostics/linux/test_zes_sysman_diagnostics.cpp +++ b/level_zero/tools/test/unit_tests/sources/sysman/diagnostics/linux/test_zes_sysman_diagnostics.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020-2023 Intel Corporation + * Copyright (C) 2020-2024 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -764,6 +764,19 @@ TEST_F(ZesDiagnosticsFixture, GivenValidSysmanImpPointerWhenCallingReleaseResour EXPECT_EQ(ZE_RESULT_SUCCESS, pLinuxSysmanImp->initDevice()); } +TEST_F(ZesDiagnosticsFixture, GivenSysmanImpPointerWhenCallingReleaseResourcesThenGfxPartitionIsRemovedForRootDevice) { + pLinuxSysmanImp->diagnosticsReset = true; + auto devicePtr = static_cast(pLinuxSysmanImp->pDevice); + auto executionEnvironment = devicePtr->getNEODevice()->getExecutionEnvironment(); + auto rootIndex = devicePtr->getNEODevice()->getRootDeviceIndex(); + + pLinuxSysmanImp->releaseDeviceResources(); + + EXPECT_EQ(nullptr, executionEnvironment->memoryManager->getGfxPartition(rootIndex)); + EXPECT_EQ(ZE_RESULT_SUCCESS, pLinuxSysmanImp->initDevice()); + EXPECT_NE(nullptr, executionEnvironment->memoryManager->getGfxPartition(rootIndex)); +} + HWTEST2_F(ZesDiagnosticsFixture, GivenValidDiagnosticsHandleAndHandleCountZeroWhenCallingReInitThenValidCountIsReturnedAndVerifyzesDeviceEnumDiagnosticTestSuitesSucceeds, IsPVC) { uint32_t count = 0; ze_result_t result = zesDeviceEnumDiagnosticTestSuites(device->toHandle(), &count, nullptr); diff --git a/shared/source/memory_manager/memory_manager.h b/shared/source/memory_manager/memory_manager.h index ac7bdb0a0546b..288baac898de3 100644 --- a/shared/source/memory_manager/memory_manager.h +++ b/shared/source/memory_manager/memory_manager.h @@ -286,6 +286,9 @@ class MemoryManager { virtual void releaseDeviceSpecificMemResources(uint32_t rootDeviceIndex){}; virtual void createDeviceSpecificMemResources(uint32_t rootDeviceIndex){}; + virtual void releaseDeviceSpecificGfxPartition(uint32_t rootDeviceIndex){}; + virtual bool reInitDeviceSpecificGfxPartition(uint32_t rootDeviceIndex) { return true; }; + void reInitLatestContextId() { latestContextId = std::numeric_limits::max(); } diff --git a/shared/source/os_interface/device_factory.cpp b/shared/source/os_interface/device_factory.cpp index cbf390ba749e2..777eee7429d75 100644 --- a/shared/source/os_interface/device_factory.cpp +++ b/shared/source/os_interface/device_factory.cpp @@ -249,6 +249,7 @@ std::unique_ptr DeviceFactory::createDevice(ExecutionEnvironment &execut return device; } + executionEnvironment.memoryManager->reInitDeviceSpecificGfxPartition(rootDeviceIndex); executionEnvironment.memoryManager->createDeviceSpecificMemResources(rootDeviceIndex); executionEnvironment.memoryManager->reInitLatestContextId(); device = createRootDeviceFunc(executionEnvironment, rootDeviceIndex); diff --git a/shared/source/os_interface/linux/drm_memory_manager.cpp b/shared/source/os_interface/linux/drm_memory_manager.cpp index 0fe8dc1c65b8d..61b83029df750 100644 --- a/shared/source/os_interface/linux/drm_memory_manager.cpp +++ b/shared/source/os_interface/linux/drm_memory_manager.cpp @@ -2948,4 +2948,23 @@ void DrmMemoryManager::getExtraDeviceProperties(uint32_t rootDeviceIndex, uint32 getDrm(rootDeviceIndex).getIoctlHelper()->queryDeviceParams(moduleId, serverType); } +bool DrmMemoryManager::reInitDeviceSpecificGfxPartition(uint32_t rootDeviceIndex) { + if (gfxPartitions.at(rootDeviceIndex) == nullptr) { + auto gpuAddressSpace = executionEnvironment.rootDeviceEnvironments[rootDeviceIndex]->getHardwareInfo()->capabilityTable.gpuAddressSpace; + + gfxPartitions.at(rootDeviceIndex) = std::make_unique(reservedCpuAddressRange); + + uint64_t gfxTop{}; + getDrm(rootDeviceIndex).queryGttSize(gfxTop, false); + + if (getGfxPartition(rootDeviceIndex)->init(gpuAddressSpace, getSizeToReserve(), rootDeviceIndex, gfxPartitions.size(), heapAssigners[rootDeviceIndex]->apiAllowExternalHeapForSshAndDsh, DrmMemoryManager::getSystemSharedMemory(rootDeviceIndex), gfxTop)) { + return true; + } + } + return false; +} + +void DrmMemoryManager::releaseDeviceSpecificGfxPartition(uint32_t rootDeviceIndex) { + gfxPartitions.at(rootDeviceIndex).reset(); +} } // namespace NEO diff --git a/shared/source/os_interface/linux/drm_memory_manager.h b/shared/source/os_interface/linux/drm_memory_manager.h index 1ad1c4d75c33b..e28af2eb34a1c 100644 --- a/shared/source/os_interface/linux/drm_memory_manager.h +++ b/shared/source/os_interface/linux/drm_memory_manager.h @@ -100,6 +100,8 @@ class DrmMemoryManager : public MemoryManager { DrmAllocation *createUSMHostAllocationFromSharedHandle(osHandle handle, const AllocationProperties &properties, void *mappedPtr, bool reuseSharedAllocation); void releaseDeviceSpecificMemResources(uint32_t rootDeviceIndex) override; void createDeviceSpecificMemResources(uint32_t rootDeviceIndex) override; + void releaseDeviceSpecificGfxPartition(uint32_t rootDeviceIndex) override; + bool reInitDeviceSpecificGfxPartition(uint32_t rootDeviceIndex) override; bool allowIndirectAllocationsAsPack(uint32_t rootDeviceIndex) override; Drm &getDrm(uint32_t rootDeviceIndex) const; size_t getSizeOfChunk(size_t allocSize); diff --git a/shared/test/common/mocks/mock_memory_manager.cpp b/shared/test/common/mocks/mock_memory_manager.cpp index dfd038b4a7755..7859493976251 100644 --- a/shared/test/common/mocks/mock_memory_manager.cpp +++ b/shared/test/common/mocks/mock_memory_manager.cpp @@ -10,6 +10,7 @@ #include "shared/source/command_stream/command_stream_receiver.h" #include "shared/source/gmm_helper/gmm.h" #include "shared/source/helpers/aligned_memory.h" +#include "shared/source/helpers/hw_info.h" #include "shared/source/helpers/surface_format_info.h" #include "shared/source/memory_manager/deferred_deleter.h" #include "shared/source/memory_manager/gfx_partition.h" @@ -248,6 +249,25 @@ bool MockMemoryManager::copyMemoryToAllocationBanks(GraphicsAllocation *graphics return OsAgnosticMemoryManager::copyMemoryToAllocationBanks(graphicsAllocation, destinationOffset, memoryToCopy, sizeToCopy, handleMask); }; +bool MockMemoryManager::reInitDeviceSpecificGfxPartition(uint32_t rootDeviceIndex) { + if (gfxPartitions.at(rootDeviceIndex) == nullptr) { + // 4 x sizeof(Heap32) + 2 x sizeof(Standard/Standard64k) + size_t reservedCpuAddressRangeSize = static_cast((4 * 4 + 2 * 4)) * static_cast(MemoryConstants::gigaByte); + gfxPartitions.at(rootDeviceIndex) = std::make_unique(reservedCpuAddressRange); + + auto gpuAddressSpace = executionEnvironment.rootDeviceEnvironments[rootDeviceIndex]->getHardwareInfo()->capabilityTable.gpuAddressSpace; + auto gfxTop = gpuAddressSpace + 1; + if (getGfxPartition(rootDeviceIndex)->init(gpuAddressSpace, reservedCpuAddressRangeSize, rootDeviceIndex, gfxPartitions.size(), heapAssigners[rootDeviceIndex]->apiAllowExternalHeapForSshAndDsh, OsAgnosticMemoryManager::getSystemSharedMemory(rootDeviceIndex), gfxTop)) { + return true; + } + } + return false; +} + +void MockMemoryManager::releaseDeviceSpecificGfxPartition(uint32_t rootDeviceIndex) { + gfxPartitions.at(rootDeviceIndex).reset(); +} + void *MockAllocSysMemAgnosticMemoryManager::allocateSystemMemory(size_t size, size_t alignment) { constexpr size_t minAlignment = 16; alignment = std::max(alignment, minAlignment); diff --git a/shared/test/common/mocks/mock_memory_manager.h b/shared/test/common/mocks/mock_memory_manager.h index ba5e9bee90358..4792355ac697d 100644 --- a/shared/test/common/mocks/mock_memory_manager.h +++ b/shared/test/common/mocks/mock_memory_manager.h @@ -287,6 +287,9 @@ class MockMemoryManager : public MemoryManagerCreate { *serverType = MockMemoryManager::serverType; } + bool reInitDeviceSpecificGfxPartition(uint32_t rootDeviceIndex) override; + void releaseDeviceSpecificGfxPartition(uint32_t rootDeviceIndex) override; + MockGraphicsAllocation *mockGa; size_t ipcAllocationSize = 4096u; uint32_t copyMemoryToAllocationBanksCalled = 0u; 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 72ef3c775c096..cadadc8d5448e 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 @@ -8476,3 +8476,46 @@ TEST_F(DrmMemoryManagerTest, givenVmAdviseAtomicAttributeNotPresentWhenCreateSha memoryManager->freeGraphicsMemory(sharedUSM); } + +TEST_F(DrmMemoryManagerTest, givenGfxPartitionWhenReleasedAndReinitializedThenNewGfxPartitionIsCorrect) { + + auto gfxPartition = memoryManager->getGfxPartition(0); + + auto heapExternal = gfxPartition->getHeapBase(HeapIndex::heapExternal); + auto heapStandard = gfxPartition->getHeapBase(HeapIndex::heapStandard); + auto heapStandard64KB = gfxPartition->getHeapBase(HeapIndex::heapStandard64KB); + auto heapSvm = gfxPartition->getHeapBase(HeapIndex::heapSvm); + auto heapExtended = gfxPartition->getHeapBase(HeapIndex::heapExtended); + auto heapExternalFrontWindow = gfxPartition->getHeapBase(HeapIndex::heapExternalFrontWindow); + auto heapExternalDeviceFrontWindow = gfxPartition->getHeapBase(HeapIndex::heapExternalDeviceFrontWindow); + auto heapInternalFrontWindow = gfxPartition->getHeapBase(HeapIndex::heapInternalFrontWindow); + auto heapInternalDeviceFrontWindow = gfxPartition->getHeapBase(HeapIndex::heapInternalDeviceFrontWindow); + + memoryManager->releaseDeviceSpecificGfxPartition(0); + EXPECT_EQ(nullptr, memoryManager->getGfxPartition(0)); + memoryManager->reInitDeviceSpecificGfxPartition(0); + + EXPECT_NE(nullptr, memoryManager->getGfxPartition(0)); + + gfxPartition = memoryManager->getGfxPartition(0); + + auto heapExternal2 = gfxPartition->getHeapBase(HeapIndex::heapExternal); + auto heapStandard2 = gfxPartition->getHeapBase(HeapIndex::heapStandard); + auto heapStandard64KB2 = gfxPartition->getHeapBase(HeapIndex::heapStandard64KB); + auto heapSvm2 = gfxPartition->getHeapBase(HeapIndex::heapSvm); + auto heapExtended2 = gfxPartition->getHeapBase(HeapIndex::heapExtended); + auto heapExternalFrontWindow2 = gfxPartition->getHeapBase(HeapIndex::heapExternalFrontWindow); + auto heapExternalDeviceFrontWindow2 = gfxPartition->getHeapBase(HeapIndex::heapExternalDeviceFrontWindow); + auto heapInternalFrontWindow2 = gfxPartition->getHeapBase(HeapIndex::heapInternalFrontWindow); + auto heapInternalDeviceFrontWindow2 = gfxPartition->getHeapBase(HeapIndex::heapInternalDeviceFrontWindow); + + EXPECT_EQ(heapExternal, heapExternal2); + EXPECT_EQ(heapStandard, heapStandard2); + EXPECT_EQ(heapStandard64KB, heapStandard64KB2); + EXPECT_EQ(heapSvm, heapSvm2); + EXPECT_EQ(heapExtended, heapExtended2); + EXPECT_EQ(heapExternalFrontWindow, heapExternalFrontWindow2); + EXPECT_EQ(heapExternalDeviceFrontWindow, heapExternalDeviceFrontWindow2); + EXPECT_EQ(heapInternalFrontWindow, heapInternalFrontWindow2); + EXPECT_EQ(heapInternalDeviceFrontWindow, heapInternalDeviceFrontWindow2); +} \ No newline at end of file