From ea57fb4e2b9ffda46a61a59a528c8cd777c86b1c Mon Sep 17 00:00:00 2001 From: Maciej Plewka Date: Wed, 17 Sep 2025 11:07:28 +0000 Subject: [PATCH] refactor: add test for mutex order in enqueueBlit Signed-off-by: Maciej Plewka --- .../source/command_queue/command_queue_hw.h | 26 +++++------ .../test/unit_test/mocks/mock_command_queue.h | 6 +++ .../command_queue/enqueue_kernel_mt_tests.cpp | 44 ++++++++++++++++--- 3 files changed, 58 insertions(+), 18 deletions(-) diff --git a/opencl/source/command_queue/command_queue_hw.h b/opencl/source/command_queue/command_queue_hw.h index bd430cae1d..6c727d8c45 100644 --- a/opencl/source/command_queue/command_queue_hw.h +++ b/opencl/source/command_queue/command_queue_hw.h @@ -444,19 +444,19 @@ class CommandQueueHw : public CommandQueue { TagNodeBase *multiRootDeviceSyncNode, CsrDependencyContainer *csrDependencies); - CompletionStamp enqueueCommandWithoutKernel(Surface **surfaces, - size_t surfaceCount, - LinearStream *commandStream, - size_t commandStreamStart, - bool &blocking, - const EnqueueProperties &enqueueProperties, - TimestampPacketDependencies ×tampPacketDependencies, - EventsRequest &eventsRequest, - EventBuilder &eventBuilder, - TaskCountType taskLevel, - CsrDependencies &csrDeps, - CommandStreamReceiver *bcsCsr, - bool hasRelaxedOrderingDependencies); + MOCKABLE_VIRTUAL CompletionStamp enqueueCommandWithoutKernel(Surface **surfaces, + size_t surfaceCount, + LinearStream *commandStream, + size_t commandStreamStart, + bool &blocking, + const EnqueueProperties &enqueueProperties, + TimestampPacketDependencies ×tampPacketDependencies, + EventsRequest &eventsRequest, + EventBuilder &eventBuilder, + TaskCountType taskLevel, + CsrDependencies &csrDeps, + CommandStreamReceiver *bcsCsr, + bool hasRelaxedOrderingDependencies); void processDispatchForCacheFlush(Surface **surfaces, size_t numSurfaces, LinearStream *commandStream, diff --git a/opencl/test/unit_test/mocks/mock_command_queue.h b/opencl/test/unit_test/mocks/mock_command_queue.h index 3f8d86529a..aa8209f652 100644 --- a/opencl/test/unit_test/mocks/mock_command_queue.h +++ b/opencl/test/unit_test/mocks/mock_command_queue.h @@ -266,8 +266,10 @@ class MockCommandQueueHw : public CommandQueueHw { using BaseClass = CommandQueueHw; public: + using BaseClass::bcsAllowed; using BaseClass::bcsEngineCount; using BaseClass::bcsEngines; + using BaseClass::bcsInitialized; using BaseClass::bcsQueueEngineType; using BaseClass::bcsSplitInitialized; using BaseClass::bcsStates; @@ -531,6 +533,10 @@ class MockCommandQueueHw : public CommandQueueHw { return this->commandStream; } + ADDMETHOD(processDispatchForBlitEnqueue, BlitProperties, true, {}, (CommandStreamReceiver & blitCommandStreamReceiver, const MultiDispatchInfo &multiDispatchInfo, TimestampPacketDependencies ×tampPacketDependencies, const EventsRequest &eventsRequest, LinearStream *commandStream, uint32_t commandType, bool queueBlocked, bool profilingEnabled, TagNodeBase *multiRootDeviceEventSync), (blitCommandStreamReceiver, multiDispatchInfo, timestampPacketDependencies, eventsRequest, commandStream, commandType, queueBlocked, profilingEnabled, multiRootDeviceEventSync)); + + ADDMETHOD(enqueueCommandWithoutKernel, CompletionStamp, true, {}, (Surface * *surfaces, size_t surfaceCount, LinearStream *commandStream, size_t commandStreamStart, bool &blocking, const EnqueueProperties &enqueueProperties, TimestampPacketDependencies ×tampPacketDependencies, EventsRequest &eventsRequest, EventBuilder &eventBuilder, TaskCountType taskLevel, CsrDependencies &csrDeps, CommandStreamReceiver *bcsCsr, bool hasRelaxedOrderingDependencies), (surfaces, surfaceCount, commandStream, commandStreamStart, blocking, enqueueProperties, timestampPacketDependencies, eventsRequest, eventBuilder, taskLevel, csrDeps, bcsCsr, hasRelaxedOrderingDependencies)); + std::vector lastEnqueuedKernels; MultiDispatchInfo storedMultiDispatchInfo; BuiltinOpParams kernelParams; diff --git a/opencl/test/unit_test/mt_tests/command_queue/enqueue_kernel_mt_tests.cpp b/opencl/test/unit_test/mt_tests/command_queue/enqueue_kernel_mt_tests.cpp index 0bb042a81f..f3778a468a 100644 --- a/opencl/test/unit_test/mt_tests/command_queue/enqueue_kernel_mt_tests.cpp +++ b/opencl/test/unit_test/mt_tests/command_queue/enqueue_kernel_mt_tests.cpp @@ -12,6 +12,7 @@ #include "opencl/source/command_queue/command_queue_hw.h" #include "opencl/test/unit_test/command_queue/enqueue_fixture.h" #include "opencl/test/unit_test/fixtures/hello_world_fixture.h" +#include "opencl/test/unit_test/mocks/mock_command_queue.h" typedef HelloWorldFixture EnqueueKernelFixture; typedef Test EnqueueKernelTest; @@ -88,11 +89,6 @@ HWTEST_TEMPLATED_F(EnqueueKernelTestWithMockCsrHw2, givenCsrInBatchingModeWhenFi EXPECT_EQ(mockedSubmissionsAggregator->peekInspectionId() - 1u, mockCsr->flushCalledCount); } -template -struct MockCommandQueueHw : public CommandQueueHw { - using CommandQueue::bcsInitialized; -}; - HWTEST_F(EnqueueKernelTest, givenTwoThreadsAndBcsEnabledWhenEnqueueWriteBufferAndEnqueueNDRangeKernelInLoopThenIsNoRace) { DebugManagerStateRestore debugRestorer; debugManager.flags.ForceCsrLockInBcsEnqueueOnlyForGpgpuSubmission.set(1); @@ -594,3 +590,41 @@ HWTEST_F(EnqueueKernelTest, givenBcsEnabledAndQueuePerThreadWhenHalfQueuesEnqueu retVal = clReleaseContext(context); EXPECT_EQ(CL_SUCCESS, retVal); } + +HWTEST_F(EnqueueKernelTest, givenCommandQueueAndCsrBlockedWhenEnqueueBlitCalledThenDeadLockIsNotReached) { + using CsrType = UltCommandStreamReceiver; + HardwareInfo *hwInfo = pDevice->executionEnvironment->rootDeviceEnvironments[0]->getMutableHardwareInfo(); + hwInfo->capabilityTable.blitterOperationsSupported = true; + REQUIRE_FULL_BLITTER_OR_SKIP(*pDevice->executionEnvironment->rootDeviceEnvironments[0]); + + auto mockClDevice = std::make_unique(MockDevice::createWithExecutionEnvironment(hwInfo, pDevice->executionEnvironment, 0)); + MockContext context{mockClDevice.get()}; + + MockCommandQueueHw commandQueueHw(&context, mockClDevice.get(), nullptr); + commandQueueHw.processDispatchForBlitEnqueueCallBase = false; + commandQueueHw.enqueueCommandWithoutKernelCallBase = false; + commandQueueHw.bcsAllowed = true; + MultiDispatchInfo multiDispatchInfo = {}; + auto mockCsr = static_cast(commandQueueHw.getBcsCommandStreamReceiver(aub_stream::EngineType::ENGINE_BCS)); + std::thread th1; + std::thread th2; + { + std::atomic thread1Started = false; + std::atomic thread2Started = false; + TakeOwnershipWrapper> queueOwnership(commandQueueHw); + auto csrOwnership = mockCsr->obtainUniqueOwnership(); + th1 = std::thread([&]() { + thread1Started = true; + commandQueueHw.template enqueueBlit(multiDispatchInfo, 0, nullptr, nullptr, false, *mockCsr, nullptr); + }); + th2 = std::thread([&]() { + thread2Started = true; + TakeOwnershipWrapper> threadQueueOwnership(commandQueueHw); + auto threadCsrOwnership = mockCsr->obtainUniqueOwnership(); + }); + while (!thread1Started || !thread2Started) { + }; + } + th1.join(); + th2.join(); +}