diff --git a/opencl/test/unit_test/mt_tests/memory_manager/deferred_deleter_clear_queue_mt_tests.cpp b/opencl/test/unit_test/mt_tests/memory_manager/deferred_deleter_clear_queue_mt_tests.cpp index 123b7f31b2..6dfe645383 100644 --- a/opencl/test/unit_test/mt_tests/memory_manager/deferred_deleter_clear_queue_mt_tests.cpp +++ b/opencl/test/unit_test/mt_tests/memory_manager/deferred_deleter_clear_queue_mt_tests.cpp @@ -30,7 +30,7 @@ struct ClearQueueTest : public ::testing::Test, static void threadMethod(MockDeferredDeleter *deleter) { while (!startClear) ; - deleter->clearQueue(false); + deleter->clearQueue(); threadStopped++; } MockDeferrableDeletion *createDeletion() { diff --git a/opencl/test/unit_test/mt_tests/memory_manager/deferred_deleter_mt_tests.cpp b/opencl/test/unit_test/mt_tests/memory_manager/deferred_deleter_mt_tests.cpp index e064c57087..537acb5e3c 100644 --- a/opencl/test/unit_test/mt_tests/memory_manager/deferred_deleter_mt_tests.cpp +++ b/opencl/test/unit_test/mt_tests/memory_manager/deferred_deleter_mt_tests.cpp @@ -213,13 +213,13 @@ TEST_F(DeferredDeleterTest, WhenSettingDoWorkInBackgroundThenThreadShouldStopIsS } TEST_F(DeferredDeleterTest, givenDeferredDeleterWhenBlockingDrainIsCalledThenArElementsReleasedIsCalled) { - deleter->drain(true, false); + deleter->drain(true); EXPECT_NE(0, deleter->areElementsReleasedCalled); EXPECT_EQ(1, deleter->drainCalled); } TEST_F(DeferredDeleterTest, givenDeferredDeleterWhenNonBlockingDrainIsCalledThenArElementsReleasedIsNotCalled) { - deleter->drain(false, false); + deleter->drain(false); EXPECT_EQ(0, deleter->areElementsReleasedCalled); EXPECT_EQ(1, deleter->drainCalled); } diff --git a/shared/source/memory_manager/deferrable_deletion.h b/shared/source/memory_manager/deferrable_deletion.h index 41467d2d13..d241975c40 100644 --- a/shared/source/memory_manager/deferrable_deletion.h +++ b/shared/source/memory_manager/deferrable_deletion.h @@ -14,8 +14,5 @@ class DeferrableDeletion : public IDNode { template static DeferrableDeletion *create(Args... args); virtual bool apply() = 0; - - bool isExternalHostptr() const { return externalHostptr; } - bool externalHostptr = false; }; } // namespace NEO diff --git a/shared/source/memory_manager/deferred_deleter.cpp b/shared/source/memory_manager/deferred_deleter.cpp index 6eecc0a4db..bd623779c5 100644 --- a/shared/source/memory_manager/deferred_deleter.cpp +++ b/shared/source/memory_manager/deferred_deleter.cpp @@ -11,7 +11,10 @@ #include "shared/source/os_interface/os_thread.h" namespace NEO { -DeferredDeleter::DeferredDeleter() = default; +DeferredDeleter::DeferredDeleter() { + doWorkInBackground = false; + elementsToRelease = 0; +} void DeferredDeleter::stop() { // Called with threadMutex acquired @@ -32,7 +35,7 @@ void DeferredDeleter::stop() { // Delete working thread worker.reset(); } - drain(false, false); + drain(false); } void DeferredDeleter::safeStop() { @@ -46,14 +49,8 @@ DeferredDeleter::~DeferredDeleter() { void DeferredDeleter::deferDeletion(DeferrableDeletion *deletion) { std::unique_lock lock(queueMutex); - - this->elementsToRelease++; - if (deletion->isExternalHostptr()) { - this->hostptrsToRelease++; - } - + elementsToRelease++; queue.pushTailOne(*deletion); - lock.unlock(); condition.notify_one(); } @@ -79,8 +76,8 @@ void DeferredDeleter::ensureThread() { worker = Thread::createFunc(run, reinterpret_cast(this)); } -bool DeferredDeleter::areElementsReleased(bool hostptrsOnly) { - return hostptrsOnly ? this->hostptrsToRelease == 0 : this->elementsToRelease == 0; +bool DeferredDeleter::areElementsReleased() { + return elementsToRelease == 0; } bool DeferredDeleter::shouldStop() { @@ -99,7 +96,7 @@ void *DeferredDeleter::run(void *arg) { } lock.unlock(); // Delete items placed into deferred delete queue - self->clearQueue(false); + self->clearQueue(); lock.lock(); // Check whether working thread should be stopped } while (!self->shouldStop()); @@ -107,24 +104,20 @@ void *DeferredDeleter::run(void *arg) { return nullptr; } -void DeferredDeleter::drain(bool blocking, bool hostptrsOnly) { - clearQueue(hostptrsOnly); +void DeferredDeleter::drain(bool blocking) { + clearQueue(); if (blocking) { - while (!areElementsReleased(hostptrsOnly)) + while (!areElementsReleased()) ; } } -void DeferredDeleter::clearQueue(bool hostptrsOnly) { +void DeferredDeleter::clearQueue() { do { auto deletion = queue.removeFrontOne(); if (deletion) { - bool isDeletionHostptr = deletion->isExternalHostptr(); - if ((!hostptrsOnly || isDeletionHostptr) && deletion->apply()) { - this->elementsToRelease--; - if (isDeletionHostptr) { - this->hostptrsToRelease--; - } + if (deletion->apply()) { + elementsToRelease--; } else { queue.pushTailOne(*deletion.release()); } diff --git a/shared/source/memory_manager/deferred_deleter.h b/shared/source/memory_manager/deferred_deleter.h index d0c65f84a7..27d67d57ac 100644 --- a/shared/source/memory_manager/deferred_deleter.h +++ b/shared/source/memory_manager/deferred_deleter.h @@ -29,21 +29,20 @@ class DeferredDeleter { MOCKABLE_VIRTUAL void removeClient(); - MOCKABLE_VIRTUAL void drain(bool blocking, bool hostptrsOnly); + MOCKABLE_VIRTUAL void drain(bool blocking); protected: void stop(); void safeStop(); void ensureThread(); - MOCKABLE_VIRTUAL void clearQueue(bool hostptrsOnly); - MOCKABLE_VIRTUAL bool areElementsReleased(bool hostptrsOnly); + MOCKABLE_VIRTUAL void clearQueue(); + MOCKABLE_VIRTUAL bool areElementsReleased(); MOCKABLE_VIRTUAL bool shouldStop(); static void *run(void *); - std::atomic doWorkInBackground = false; - std::atomic elementsToRelease = 0; - std::atomic hostptrsToRelease = 0; + std::atomic doWorkInBackground; + std::atomic elementsToRelease; std::unique_ptr worker; int32_t numClients = 0; IDList queue; diff --git a/shared/source/memory_manager/memory_manager.cpp b/shared/source/memory_manager/memory_manager.cpp index 1ab0ce2213..17a5733616 100644 --- a/shared/source/memory_manager/memory_manager.cpp +++ b/shared/source/memory_manager/memory_manager.cpp @@ -198,7 +198,7 @@ void *MemoryManager::allocateSystemMemory(size_t size, size_t alignment) { GraphicsAllocation *MemoryManager::allocateGraphicsMemoryWithHostPtr(const AllocationData &allocationData) { if (deferredDeleter) { - deferredDeleter->drain(true, false); + deferredDeleter->drain(true); } GraphicsAllocation *graphicsAllocation = nullptr; auto osStorage = hostPtrManager->prepareOsStorageForAllocation(*this, allocationData.size, allocationData.hostPtr, allocationData.rootDeviceIndex); @@ -315,7 +315,7 @@ void MemoryManager::checkGpuUsageAndDestroyGraphicsAllocations(GraphicsAllocatio if (gfxAllocation->isUsed()) { if (gfxAllocation->isUsedByManyOsContexts()) { multiContextResourceDestructor->deferDeletion(new DeferrableAllocationDeletion{*this, *gfxAllocation}); - multiContextResourceDestructor->drain(false, false); + multiContextResourceDestructor->drain(false); return; } for (auto &engine : getRegisteredEngines(gfxAllocation->getRootDeviceIndex())) { @@ -345,7 +345,7 @@ bool MemoryManager::isLimitedRange(uint32_t rootDeviceIndex) { void MemoryManager::waitForDeletions() { if (deferredDeleter) { - deferredDeleter->drain(false, false); + deferredDeleter->drain(false); } deferredDeleter.reset(nullptr); } @@ -737,12 +737,6 @@ bool MemoryManager::mapAuxGpuVA(GraphicsAllocation *graphicsAllocation) { } GraphicsAllocation *MemoryManager::allocateGraphicsMemory(const AllocationData &allocationData) { - if (allocationData.type == AllocationType::externalHostPtr && - allocationData.hostPtr && - this->getDeferredDeleter()) { - this->getDeferredDeleter()->drain(true, true); - } - if (allocationData.type == AllocationType::image || allocationData.type == AllocationType::sharedResourceCopy) { UNRECOVERABLE_IF(allocationData.imgInfo == nullptr); return allocateGraphicsMemoryForImage(allocationData); diff --git a/shared/source/os_interface/windows/deferrable_deletion_win.cpp b/shared/source/os_interface/windows/deferrable_deletion_win.cpp index bd620896d5..9d1fd91fc9 100644 --- a/shared/source/os_interface/windows/deferrable_deletion_win.cpp +++ b/shared/source/os_interface/windows/deferrable_deletion_win.cpp @@ -7,7 +7,6 @@ #include "shared/source/os_interface/windows/deferrable_deletion_win.h" -#include "shared/source/memory_manager/allocation_type.h" #include "shared/source/os_interface/windows/wddm/wddm.h" namespace NEO { @@ -16,10 +15,9 @@ template DeferrableDeletion *DeferrableDeletion::create(Args... args) { return new DeferrableDeletionImpl(std::forward(args)...); } +template DeferrableDeletion *DeferrableDeletion::create(Wddm *wddm, const D3DKMT_HANDLE *handles, uint32_t allocationCount, D3DKMT_HANDLE resourceHandle); -template DeferrableDeletion *DeferrableDeletion::create(Wddm *wddm, const D3DKMT_HANDLE *handles, uint32_t allocationCount, D3DKMT_HANDLE resourceHandle, AllocationType type); - -DeferrableDeletionImpl::DeferrableDeletionImpl(Wddm *wddm, const D3DKMT_HANDLE *handles, uint32_t allocationCount, D3DKMT_HANDLE resourceHandle, AllocationType type) +DeferrableDeletionImpl::DeferrableDeletionImpl(Wddm *wddm, const D3DKMT_HANDLE *handles, uint32_t allocationCount, D3DKMT_HANDLE resourceHandle) : wddm(wddm), allocationCount(allocationCount), resourceHandle(resourceHandle) { if (handles) { this->handles = new D3DKMT_HANDLE[allocationCount]; @@ -27,15 +25,12 @@ DeferrableDeletionImpl::DeferrableDeletionImpl(Wddm *wddm, const D3DKMT_HANDLE * this->handles[i] = handles[i]; } } - this->externalHostptr = type == AllocationType::externalHostPtr; } - bool DeferrableDeletionImpl::apply() { [[maybe_unused]] bool destroyStatus = wddm->destroyAllocations(handles, allocationCount, resourceHandle); DEBUG_BREAK_IF(!destroyStatus); return true; } - DeferrableDeletionImpl::~DeferrableDeletionImpl() { if (handles) { delete[] handles; diff --git a/shared/source/os_interface/windows/deferrable_deletion_win.h b/shared/source/os_interface/windows/deferrable_deletion_win.h index 9ccff56754..8b60b10d3f 100644 --- a/shared/source/os_interface/windows/deferrable_deletion_win.h +++ b/shared/source/os_interface/windows/deferrable_deletion_win.h @@ -15,11 +15,10 @@ namespace NEO { class OsContextWin; class Wddm; -enum class AllocationType; class DeferrableDeletionImpl : public DeferrableDeletion { public: - DeferrableDeletionImpl(Wddm *wddm, const D3DKMT_HANDLE *handles, uint32_t allocationCount, D3DKMT_HANDLE resourceHandle, AllocationType type); + DeferrableDeletionImpl(Wddm *wddm, const D3DKMT_HANDLE *handles, uint32_t allocationCount, D3DKMT_HANDLE resourceHandle); bool apply() override; ~DeferrableDeletionImpl() override; diff --git a/shared/source/os_interface/windows/wddm_memory_manager.cpp b/shared/source/os_interface/windows/wddm_memory_manager.cpp index fb0e9393f8..de5ef4ccd2 100644 --- a/shared/source/os_interface/windows/wddm_memory_manager.cpp +++ b/shared/source/os_interface/windows/wddm_memory_manager.cpp @@ -811,8 +811,8 @@ void WddmMemoryManager::handleFenceCompletion(GraphicsAllocation *allocation) { bool WddmMemoryManager::tryDeferDeletions(const D3DKMT_HANDLE *handles, uint32_t allocationCount, D3DKMT_HANDLE resourceHandle, uint32_t rootDeviceIndex, AllocationType type) { bool status = true; - if (deferredDeleter) { - deferredDeleter->deferDeletion(DeferrableDeletion::create(&getWddm(rootDeviceIndex), handles, allocationCount, resourceHandle, type)); + if (deferredDeleter && type != AllocationType::externalHostPtr) { + deferredDeleter->deferDeletion(DeferrableDeletion::create(&getWddm(rootDeviceIndex), handles, allocationCount, resourceHandle)); } else { status = getWddm(rootDeviceIndex).destroyAllocations(handles, allocationCount, resourceHandle); } @@ -1044,7 +1044,7 @@ bool WddmMemoryManager::mapGpuVaForOneHandleAllocation(WddmAllocation *allocatio auto status = getWddm(allocation->getRootDeviceIndex()).mapGpuVirtualAddress(allocation->getDefaultGmm(), allocation->getDefaultHandle(), minimumAddress, maximumAddress, addressToMap, allocation->getGpuAddressToModify(), allocation->getAllocationType()); if (!status && deferredDeleter) { - deferredDeleter->drain(true, false); + deferredDeleter->drain(true); status = getWddm(allocation->getRootDeviceIndex()).mapGpuVirtualAddress(allocation->getDefaultGmm(), allocation->getDefaultHandle(), minimumAddress, maximumAddress, addressToMap, allocation->getGpuAddressToModify(), allocation->getAllocationType()); } if (!status) { @@ -1090,7 +1090,7 @@ bool WddmMemoryManager::mapMultiHandleAllocationWithRetry(WddmAllocation *alloca gfxPartition->getHeapMinimalAddress(heapIndex), gfxPartition->getHeapLimit(heapIndex), addressToMap, gpuAddress, allocation->getAllocationType()); if (!status && deferredDeleter) { - deferredDeleter->drain(true, false); + deferredDeleter->drain(true); status = wddm.mapGpuVirtualAddress(allocation->getGmm(currentHandle), allocation->getHandles()[currentHandle], gfxPartition->getHeapMinimalAddress(heapIndex), gfxPartition->getHeapLimit(heapIndex), addressToMap, gpuAddress, allocation->getAllocationType()); } @@ -1113,7 +1113,7 @@ bool WddmMemoryManager::createGpuAllocationsWithRetry(WddmAllocation *allocation auto gmm = allocation->getGmm(handleId); auto status = getWddm(allocation->getRootDeviceIndex()).createAllocation(gmm->gmmResourceInfo->getSystemMemPointer(), gmm, allocation->getHandleToModify(handleId), allocation->getResourceHandleToModify(), allocation->getSharedHandleToModify()); if (status == STATUS_GRAPHICS_NO_VIDEO_MEMORY && deferredDeleter) { - deferredDeleter->drain(true, false); + deferredDeleter->drain(true); status = getWddm(allocation->getRootDeviceIndex()).createAllocation(gmm->gmmResourceInfo->getSystemMemPointer(), gmm, allocation->getHandleToModify(handleId), allocation->getResourceHandleToModify(), allocation->getSharedHandleToModify()); } if (status != STATUS_SUCCESS) { diff --git a/shared/test/common/mocks/mock_deferred_deleter.cpp b/shared/test/common/mocks/mock_deferred_deleter.cpp index f38ac7b6d8..5719ca382e 100644 --- a/shared/test/common/mocks/mock_deferred_deleter.cpp +++ b/shared/test/common/mocks/mock_deferred_deleter.cpp @@ -34,20 +34,19 @@ void MockDeferredDeleter::removeClient() { --numClients; } -void MockDeferredDeleter::drain(bool blocking, bool hostptrsOnly) { +void MockDeferredDeleter::drain(bool blocking) { if (expectDrainCalled) { EXPECT_EQ(expectedDrainValue, blocking); } - DeferredDeleter::drain(blocking, hostptrsOnly); + DeferredDeleter::drain(blocking); drainCalled++; } void MockDeferredDeleter::drain() { - return drain(true, false); + return drain(true); } -bool MockDeferredDeleter::areElementsReleased(bool hostptrsOnly) { - this->areElementsReleasedCalledForHostptrs = hostptrsOnly; +bool MockDeferredDeleter::areElementsReleased() { areElementsReleasedCalled++; return areElementsReleasedCalled != 1; } @@ -66,8 +65,8 @@ bool MockDeferredDeleter::shouldStop() { return shouldStopCalled > 1; } -void MockDeferredDeleter::clearQueue(bool hostptrsOnly) { - DeferredDeleter::clearQueue(hostptrsOnly); +void MockDeferredDeleter::clearQueue() { + DeferredDeleter::clearQueue(); clearCalled++; } @@ -101,7 +100,7 @@ void MockDeferredDeleter::setDoWorkInBackgroundValue(bool value) { } bool MockDeferredDeleter::baseAreElementsReleased() { - return DeferredDeleter::areElementsReleased(false); + return DeferredDeleter::areElementsReleased(); } bool MockDeferredDeleter::baseShouldStop() { diff --git a/shared/test/common/mocks/mock_deferred_deleter.h b/shared/test/common/mocks/mock_deferred_deleter.h index 3b9b7c00d9..fd09ddf2a0 100644 --- a/shared/test/common/mocks/mock_deferred_deleter.h +++ b/shared/test/common/mocks/mock_deferred_deleter.h @@ -22,9 +22,9 @@ class MockDeferredDeleter : public DeferredDeleter { void removeClient() override; - void drain(bool blocking, bool hostptrsOnly) override; + void drain(bool blocking) override; - bool areElementsReleased(bool hostptrsOnly) override; + bool areElementsReleased() override; bool shouldStop() override; @@ -56,8 +56,6 @@ class MockDeferredDeleter : public DeferredDeleter { int areElementsReleasedCalled = 0; - bool areElementsReleasedCalledForHostptrs = false; - std::atomic shouldStopCalled; std::atomic clearCalled; @@ -75,6 +73,6 @@ class MockDeferredDeleter : public DeferredDeleter { bool expectDrainCalled = false; - void clearQueue(bool hostptrsOnly) override; + void clearQueue() override; }; } // namespace NEO diff --git a/shared/test/unit_test/memory_manager/deferred_deleter_tests.cpp b/shared/test/unit_test/memory_manager/deferred_deleter_tests.cpp index cef5ccc517..226435061c 100644 --- a/shared/test/unit_test/memory_manager/deferred_deleter_tests.cpp +++ b/shared/test/unit_test/memory_manager/deferred_deleter_tests.cpp @@ -23,23 +23,14 @@ TEST(DeferredDeleter, WhenDeferredDeleterIsCreatedThenItIsNotAssignable) { TEST(DeferredDeleter, givenDeferredDeleterWhenBlockingDrainIsCalledThenArElementsReleasedIsCalled) { auto deleter = std::make_unique(); - deleter->drain(true, false); + deleter->drain(true); EXPECT_NE(0, deleter->areElementsReleasedCalled); - EXPECT_FALSE(deleter->areElementsReleasedCalledForHostptrs); - EXPECT_EQ(1, deleter->drainCalled); -} - -TEST(DeferredDeleter, givenDeferredDeleterWhenBlockingDrainOnlyForHostptrsIsCalledThenArElementsReleasedIsCalledWithHostptrsOnly) { - auto deleter = std::make_unique(); - deleter->drain(true, true); - EXPECT_NE(0, deleter->areElementsReleasedCalled); - EXPECT_TRUE(deleter->areElementsReleasedCalledForHostptrs); EXPECT_EQ(1, deleter->drainCalled); } TEST(DeferredDeleter, givenDeferredDeleterWhenNonBlockingDrainIsCalledThenArElementsReleasedIsNotCalled) { auto deleter = std::make_unique(); - deleter->drain(false, false); + deleter->drain(false); EXPECT_EQ(0, deleter->areElementsReleasedCalled); EXPECT_EQ(1, deleter->drainCalled); } diff --git a/shared/test/unit_test/os_interface/windows/deferrable_deletion_win_tests.cpp b/shared/test/unit_test/os_interface/windows/deferrable_deletion_win_tests.cpp index 2e354b4238..d20d3b5791 100644 --- a/shared/test/unit_test/os_interface/windows/deferrable_deletion_win_tests.cpp +++ b/shared/test/unit_test/os_interface/windows/deferrable_deletion_win_tests.cpp @@ -51,21 +51,18 @@ class DeferrableDeletionTest : public ::testing::Test { }; TEST_F(DeferrableDeletionTest, givenDeferrableDeletionWhenIsCreatedThenObjectMembersAreSetProperly) { - MockDeferrableDeletion deletion(wddm.get(), &handle, allocationCount, resourceHandle, AllocationType::buffer); + MockDeferrableDeletion deletion(wddm.get(), &handle, allocationCount, resourceHandle); EXPECT_EQ(wddm.get(), deletion.wddm); EXPECT_NE(nullptr, deletion.handles); EXPECT_EQ(handle, *deletion.handles); EXPECT_NE(&handle, deletion.handles); EXPECT_EQ(allocationCount, deletion.allocationCount); EXPECT_EQ(resourceHandle, deletion.resourceHandle); - EXPECT_FALSE(deletion.isExternalHostptr()); - MockDeferrableDeletion deletion2(wddm.get(), &handle, allocationCount, resourceHandle, AllocationType::externalHostPtr); - EXPECT_TRUE(deletion2.isExternalHostptr()); } TEST_F(DeferrableDeletionTest, givenDeferrableDeletionWhenApplyIsCalledThenDeletionIsApplied) { wddm->callBaseDestroyAllocations = false; - std::unique_ptr deletion(DeferrableDeletion::create((Wddm *)wddm.get(), &handle, allocationCount, resourceHandle, AllocationType::buffer)); + std::unique_ptr deletion(DeferrableDeletion::create((Wddm *)wddm.get(), &handle, allocationCount, resourceHandle)); EXPECT_EQ(0u, wddm->destroyAllocationResult.called); deletion->apply(); EXPECT_EQ(1u, wddm->destroyAllocationResult.called); diff --git a/shared/test/unit_test/os_interface/windows/wddm_memory_manager_tests.cpp b/shared/test/unit_test/os_interface/windows/wddm_memory_manager_tests.cpp index 1bd2db0378..0da98c306c 100644 --- a/shared/test/unit_test/os_interface/windows/wddm_memory_manager_tests.cpp +++ b/shared/test/unit_test/os_interface/windows/wddm_memory_manager_tests.cpp @@ -4037,6 +4037,13 @@ struct WddmMemoryManagerWithAsyncDeleterTest : public ::testing::Test { WddmMock *wddm; }; +TEST_F(WddmMemoryManagerWithAsyncDeleterTest, givenWddmWhenAsyncDeleterIsEnabledThenDoNotDeferExternalHostptrDeletions) { + EXPECT_EQ(0, deleter->deferDeletionCalled); + memoryManager->tryDeferDeletions(nullptr, 0, 0, 0, AllocationType::externalHostPtr); + EXPECT_EQ(0, deleter->deferDeletionCalled); + EXPECT_EQ(1u, wddm->destroyAllocationResult.called); +} + TEST_F(WddmMemoryManagerWithAsyncDeleterTest, givenWddmWhenAsyncDeleterIsEnabledThenCanDeferDeletions) { EXPECT_EQ(0, deleter->deferDeletionCalled); memoryManager->tryDeferDeletions(nullptr, 0, 0, 0, AllocationType::unknown);