diff --git a/level_zero/core/source/cmdlist/cmdlist.cpp b/level_zero/core/source/cmdlist/cmdlist.cpp index ea21863581..b95c69298b 100644 --- a/level_zero/core/source/cmdlist/cmdlist.cpp +++ b/level_zero/core/source/cmdlist/cmdlist.cpp @@ -251,6 +251,9 @@ ze_result_t CommandList::setKernelState(Kernel *kernel, const ze_group_size_t gr if (args.size() > 0 && !arguments) { return ZE_RESULT_ERROR_INVALID_NULL_POINTER; } + + auto lock = static_cast(kernel)->getParentModule().getDevice()->getDriverHandle()->getSvmAllocsManager()->obtainReadContainerLock(); + for (auto i = 0u; i < args.size(); i++) { auto &arg = args[i]; diff --git a/opencl/test/unit_test/memory_manager/unified_memory_manager_tests.cpp b/opencl/test/unit_test/memory_manager/unified_memory_manager_tests.cpp index 7cd95683fe..9baae81cb1 100644 --- a/opencl/test/unit_test/memory_manager/unified_memory_manager_tests.cpp +++ b/opencl/test/unit_test/memory_manager/unified_memory_manager_tests.cpp @@ -46,6 +46,15 @@ TEST_F(SVMMemoryAllocatorTest, whenRequestSVMAllocsThenReturnNonNullptr) { EXPECT_NE(svmAllocs, nullptr); } +TEST_F(SVMMemoryAllocatorTest, whenObtainReadContainerLockThenContainerMarkedAsLocked) { + EXPECT_EQ(svmManager->containerLockedById, std::thread::id{}); + { + auto lock = svmManager->obtainReadContainerLock(); + EXPECT_EQ(svmManager->containerLockedById, std::this_thread::get_id()); + } + EXPECT_EQ(svmManager->containerLockedById, std::thread::id{}); +} + using MultiDeviceSVMMemoryAllocatorTest = MultiRootDeviceWithSubDevicesFixture; TEST_F(MultiDeviceSVMMemoryAllocatorTest, givenMultipleDevicesWhenCreatingSVMAllocThenCreateOneGraphicsAllocationPerRootDeviceIndex) { diff --git a/shared/source/memory_manager/unified_memory_manager.cpp b/shared/source/memory_manager/unified_memory_manager.cpp index 0c1875e995..9126b501cd 100644 --- a/shared/source/memory_manager/unified_memory_manager.cpp +++ b/shared/source/memory_manager/unified_memory_manager.cpp @@ -1196,6 +1196,10 @@ std::unique_lock SVMAllocsManager::obtainOwnership() { return std::unique_lock(mtxForIndirectAccess); } +SVMAllocsManager::ContainerReadLockTypeRAIIHelper SVMAllocsManager::obtainReadContainerLock() { + return ContainerReadLockTypeRAIIHelper(*this); +} + void SVMAllocsManager::insertSVMAlloc(void *svmPtr, const SvmAllocationData &allocData) { ContainerReadWriteLockType lock(mtx); this->svmAllocs.insert(svmPtr, allocData); diff --git a/shared/source/memory_manager/unified_memory_manager.h b/shared/source/memory_manager/unified_memory_manager.h index cd46434b21..2a51f8ab9c 100644 --- a/shared/source/memory_manager/unified_memory_manager.h +++ b/shared/source/memory_manager/unified_memory_manager.h @@ -26,6 +26,7 @@ #include #include #include +#include #include namespace NEO { @@ -101,6 +102,17 @@ class SVMAllocsManager { using ContainerReadLockType = std::shared_lock; using ContainerReadWriteLockType = std::unique_lock; + struct ContainerReadLockTypeRAIIHelper : public NonCopyableAndNonMovableClass { + ContainerReadLockTypeRAIIHelper(SVMAllocsManager &svmAllocsManager) : svmAllocsManager(svmAllocsManager), lock(svmAllocsManager.mtx) { + svmAllocsManager.containerLockedById = std::this_thread::get_id(); + } + ~ContainerReadLockTypeRAIIHelper() { + svmAllocsManager.containerLockedById = std::thread::id(); + } + SVMAllocsManager &svmAllocsManager; + ContainerReadLockType lock{}; + }; + class MapBasedAllocationTracker { friend class SVMAllocsManager; @@ -251,7 +263,12 @@ class SVMAllocsManager { template || std::is_same_v, int> = 0> SvmAllocationData *getSVMAlloc(T *ptr) { - ContainerReadLockType lock(mtx); + ContainerReadLockType lock{}; + + if (this->containerLockedById != std::this_thread::get_id()) { + lock = ContainerReadLockType(mtx); + } + return svmAllocs.get(ptr); } @@ -290,6 +307,7 @@ class SVMAllocsManager { void sharedSystemAtomicAccess(Device &device, AtomicAccessMode mode, const void *ptr, const size_t size); MOCKABLE_VIRTUAL AtomicAccessMode getSharedSystemAtomicAccess(Device &device, const void *ptr, const size_t size); std::unique_lock obtainOwnership(); + ContainerReadLockTypeRAIIHelper obtainReadContainerLock(); std::map indirectAllocationsResidency; @@ -325,5 +343,7 @@ class SVMAllocsManager { std::unique_ptr usmDeviceAllocationsCache; std::unique_ptr usmHostAllocationsCache; std::multimap internalAllocationsMap; + + std::thread::id containerLockedById{}; }; } // namespace NEO diff --git a/shared/test/common/mocks/mock_svm_manager.h b/shared/test/common/mocks/mock_svm_manager.h index d6da31808f..1dd78b825e 100644 --- a/shared/test/common/mocks/mock_svm_manager.h +++ b/shared/test/common/mocks/mock_svm_manager.h @@ -15,6 +15,7 @@ namespace NEO { struct MockSVMAllocsManager : public SVMAllocsManager { public: + using SVMAllocsManager::containerLockedById; using SVMAllocsManager::insertSVMAlloc; using SVMAllocsManager::internalAllocationsMap; using SVMAllocsManager::memoryManager;