From 436579ca8ca87f63c257a40c1baae077647bca35 Mon Sep 17 00:00:00 2001 From: Lukasz Jobczyk Date: Wed, 27 Mar 2024 10:32:50 +0000 Subject: [PATCH] fix: Disable async release of buffers with external host ptr Related-To: NEO-10036 Signed-off-by: Lukasz Jobczyk --- opencl/source/mem_obj/mem_obj.cpp | 3 +- .../mem_obj/mem_obj_destruction_tests.cpp | 49 ++++++++++++++++++- 2 files changed, 49 insertions(+), 3 deletions(-) diff --git a/opencl/source/mem_obj/mem_obj.cpp b/opencl/source/mem_obj/mem_obj.cpp index 4d9105f6e7..74427537b7 100644 --- a/opencl/source/mem_obj/mem_obj.cpp +++ b/opencl/source/mem_obj/mem_obj.cpp @@ -82,7 +82,8 @@ MemObj::~MemObj() { needWait |= multiGraphicsAllocation.getGraphicsAllocations().size() > 1u; for (auto graphicsAllocation : multiGraphicsAllocation.getGraphicsAllocations()) { auto rootDeviceIndex = graphicsAllocation ? graphicsAllocation->getRootDeviceIndex() : 0; - bool doAsyncDestructions = debugManager.flags.EnableAsyncDestroyAllocations.get(); + + bool doAsyncDestructions = debugManager.flags.EnableAsyncDestroyAllocations.get() && !this->memoryProperties.flags.useHostPtr; if (graphicsAllocation && !associatedMemObject && !isHostPtrSVM && graphicsAllocation->peekReuseCount() == 0) { memoryManager->removeAllocationFromHostPtrManager(graphicsAllocation); if (!doAsyncDestructions) { diff --git a/opencl/test/unit_test/mem_obj/mem_obj_destruction_tests.cpp b/opencl/test/unit_test/mem_obj/mem_obj_destruction_tests.cpp index 5287604f4c..909c66f710 100644 --- a/opencl/test/unit_test/mem_obj/mem_obj_destruction_tests.cpp +++ b/opencl/test/unit_test/mem_obj/mem_obj_destruction_tests.cpp @@ -55,7 +55,7 @@ class MyCsr : public UltCommandStreamReceiver { void CL_CALLBACK emptyDestructorCallback(cl_mem memObj, void *userData) { } -template +template class MemObjDestructionTest : public ::testing::TestWithParam { public: void SetUp() override { @@ -65,7 +65,12 @@ class MemObjDestructionTest : public ::testing::TestWithParam { device = std::make_unique(MockDevice::create(executionEnvironment, 0)); context.reset(new MockContext(device.get())); allocation = memoryManager->allocateGraphicsMemoryWithProperties(MockAllocationProperties{device->getRootDeviceIndex(), size}); - if constexpr (useMultiGraphicsAllocation) { + if constexpr (useHostPtr) { + memObj = new MemObj(context.get(), CL_MEM_OBJECT_BUFFER, + ClMemoryPropertiesHelper::createMemoryProperties(CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR, 0, 0, &device->getDevice()), + CL_MEM_READ_WRITE, 0, size, + nullptr, nullptr, GraphicsAllocationHelper::toMultiGraphicsAllocation(allocation), true, false, false); + } else if constexpr (useMultiGraphicsAllocation) { MultiGraphicsAllocation multiAllocation(1u); multiAllocation.addAllocation(allocation); memObj = new MemObj(context.get(), CL_MEM_OBJECT_BUFFER, @@ -137,6 +142,18 @@ class MemObjMulitAllocationAsyncDestructionTest : public MemObjDestructionTest { + public: + void SetUp() override { + debugManager.flags.EnableAsyncDestroyAllocations.set(true); + MemObjDestructionTest::SetUp(); + } + void TearDown() override { + MemObjDestructionTest::TearDown(); + } + DebugManagerStateRestore restorer; +}; + class MemObjSyncDestructionTest : public MemObjDestructionTest<> { public: void SetUp() override { @@ -199,6 +216,34 @@ HWTEST_F(MemObjMulitAllocationAsyncDestructionTest, givenUsedMemObjWithAsyncDest EXPECT_EQ(expectedTaskCount1, mockCsr1->waitForCompletionWithTimeoutParamsPassed[0].taskCountToWait); } +HWTEST_F(MemObjUseHostPtrAsyncDestructionTest, givenUsedMemObjWithAsyncDestructionsEnabledThatUsesExternalHostPtrWhenItIsDestroyedThenDestructorWaitsOnTaskCount) { + auto rootDeviceIndex = device->getRootDeviceIndex(); + auto mockCsr0 = new MyCsr(*device->executionEnvironment, device->getDeviceBitfield()); + auto mockCsr1 = new MyCsr(*device->executionEnvironment, device->getDeviceBitfield()); + device->resetCommandStreamReceiver(mockCsr0, 0); + device->resetCommandStreamReceiver(mockCsr1, 1); + *mockCsr0->getTagAddress() = 0; + *mockCsr1->getTagAddress() = 0; + mockCsr0->getTagAddressValue = taskCountReady; + mockCsr1->getTagAddressValue = taskCountReady; + auto osContextId0 = mockCsr0->getOsContext().getContextId(); + auto osContextId1 = mockCsr1->getOsContext().getContextId(); + memObj->getGraphicsAllocation(rootDeviceIndex)->updateTaskCount(taskCountReady, osContextId0); + memObj->getGraphicsAllocation(rootDeviceIndex)->updateTaskCount(taskCountReady, osContextId1); + auto expectedTaskCount0 = allocation->getTaskCount(osContextId0); + auto expectedTaskCount1 = allocation->getTaskCount(osContextId1); + + delete memObj; + + EXPECT_EQ(1u, mockCsr0->waitForCompletionWithTimeoutCalled); + EXPECT_EQ(TimeoutControls::maxTimeout, mockCsr0->waitForCompletionWithTimeoutParamsPassed[0].timeoutMs); + EXPECT_EQ(expectedTaskCount0, mockCsr0->waitForCompletionWithTimeoutParamsPassed[0].taskCountToWait); + + EXPECT_EQ(1u, mockCsr1->waitForCompletionWithTimeoutCalled); + EXPECT_EQ(TimeoutControls::maxTimeout, mockCsr1->waitForCompletionWithTimeoutParamsPassed[0].timeoutMs); + EXPECT_EQ(expectedTaskCount1, mockCsr1->waitForCompletionWithTimeoutParamsPassed[0].taskCountToWait); +} + HWTEST_P(MemObjAsyncDestructionTest, givenUsedMemObjWithAsyncDestructionsEnabledThatHasDestructorCallbacksWhenItIsDestroyedThenDestructorWaitsOnTaskCount) { bool hasCallbacks = GetParam();