diff --git a/Jenkinsfile b/Jenkinsfile index d5c8db5e3e..1f7bccfff3 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -2,4 +2,4 @@ neoDependenciesRev='716918-671' strategy='EQUAL' allowedF=49 -allowedCD=381 +allowedCD=380 diff --git a/runtime/command_queue/command_queue.cpp b/runtime/command_queue/command_queue.cpp index d95c0ecea3..bf0bb689b6 100644 --- a/runtime/command_queue/command_queue.cpp +++ b/runtime/command_queue/command_queue.cpp @@ -164,7 +164,7 @@ bool CommandQueue::isQueueBlocked() { TakeOwnershipWrapper takeOwnershipWrapper(*this); //check if we have user event and if so, if it is in blocked state. if (this->virtualEvent) { - if (this->virtualEvent->peekIsCompleted()) { + if (this->virtualEvent->peekExecutionStatus() <= CL_COMPLETE) { UNRECOVERABLE_IF(this->virtualEvent == nullptr); if (this->virtualEvent->peekIsCompletedByTermination() == false) { diff --git a/runtime/event/event.cpp b/runtime/event/event.cpp index 5590cf34a9..ef2be22092 100644 --- a/runtime/event/event.cpp +++ b/runtime/event/event.cpp @@ -534,7 +534,11 @@ inline void Event::unblockEventBy(Event &event, uint32_t taskLevel, int32_t tran } DBG_LOG(EventsDebugEnable, "Event", this, "is unblocked by", &event); - this->taskLevel = taskLevel; + if (this->taskLevel == Event::eventNotReady) { + this->taskLevel = taskLevel; + } else { + this->taskLevel = std::max(this->taskLevel.load(), taskLevel); + } int32_t statusToPropagate = CL_SUBMITTED; if (peekIsCompletedByTermination(&blockerStatus)) { diff --git a/unit_tests/command_queue/command_queue_hw_tests.cpp b/unit_tests/command_queue/command_queue_hw_tests.cpp index 7f23463269..695e6fd591 100644 --- a/unit_tests/command_queue/command_queue_hw_tests.cpp +++ b/unit_tests/command_queue/command_queue_hw_tests.cpp @@ -723,7 +723,6 @@ HWTEST_F(CommandQueueHwTest, givenBlockedInOrderCmdQueueAndAsynchronouslyComplet }; Event event(cmdQHw, CL_COMMAND_NDRANGE_KERNEL, 10, 0); - event.setStatus(CL_SUBMITTED); uint32_t virtualEventTaskLevel = 77; uint32_t virtualEventTaskCount = 80; @@ -734,16 +733,24 @@ HWTEST_F(CommandQueueHwTest, givenBlockedInOrderCmdQueueAndAsynchronouslyComplet // Put Queue in blocked state by assigning virtualEvent virtualEvent.incRefInternal(); + event.addChild(virtualEvent); cmdQHw->virtualEvent = &virtualEvent; cmdQHw->incRefInternal(); cmdQHw->taskLevel = 23; cmdQHw->enqueueKernel(mockKernel, 1, &offset, &size, &size, 1, &blockedEvent, nullptr); + //new virtual event is created on enqueue, bind it to the created virtual event + EXPECT_NE(cmdQHw->virtualEvent, &virtualEvent); + event.setStatus(CL_SUBMITTED); + + virtualEvent.Event::updateExecutionStatus(); + EXPECT_FALSE(cmdQHw->isQueueBlocked()); // +1 for next level after virtualEvent is unblocked - // +1 for dependence on eventWaitlist + // +1 as virtualEvent was a parent for event with actual command that is being submitted EXPECT_EQ(virtualEventTaskLevel + 2, cmdQHw->taskLevel); - EXPECT_EQ(virtualEventTaskLevel + 2, mockCSR->lastTaskLevelToFlushTask); + //command being submitted was dependant only on virtual event hence only +1 + EXPECT_EQ(virtualEventTaskLevel + 1, mockCSR->lastTaskLevelToFlushTask); } HWTEST_F(OOQueueHwTest, givenBlockedOutOfOrderCmdQueueAndAsynchronouslyCompletedEventWhenEnqueueCompletesVirtualEventThenUpdatedTaskLevelIsPassedToEnqueueAndFlushTask) { @@ -769,7 +776,6 @@ HWTEST_F(OOQueueHwTest, givenBlockedOutOfOrderCmdQueueAndAsynchronouslyCompleted }; Event event(cmdQHw, CL_COMMAND_NDRANGE_KERNEL, 10, 0); - event.setStatus(CL_SUBMITTED); uint32_t virtualEventTaskLevel = 77; uint32_t virtualEventTaskCount = 80; @@ -780,12 +786,22 @@ HWTEST_F(OOQueueHwTest, givenBlockedOutOfOrderCmdQueueAndAsynchronouslyCompleted // Put Queue in blocked state by assigning virtualEvent virtualEvent.incRefInternal(); + event.addChild(virtualEvent); cmdQHw->virtualEvent = &virtualEvent; cmdQHw->incRefInternal(); cmdQHw->taskLevel = 23; cmdQHw->enqueueKernel(mockKernel, 1, &offset, &size, &size, 1, &blockedEvent, nullptr); + //new virtual event is created on enqueue, bind it to the created virtual event + EXPECT_NE(cmdQHw->virtualEvent, &virtualEvent); - EXPECT_EQ(virtualEventTaskLevel, cmdQHw->taskLevel); - EXPECT_EQ(virtualEventTaskLevel, mockCSR->lastTaskLevelToFlushTask); + event.setStatus(CL_SUBMITTED); + + virtualEvent.Event::updateExecutionStatus(); + EXPECT_FALSE(cmdQHw->isQueueBlocked()); + + //+1 due to dependency between virtual event & new virtual event + //new virtual event is actually responsible for command delivery + EXPECT_EQ(virtualEventTaskLevel + 1, cmdQHw->taskLevel); + EXPECT_EQ(virtualEventTaskLevel + 1, mockCSR->lastTaskLevelToFlushTask); } diff --git a/unit_tests/event/user_events_tests.cpp b/unit_tests/event/user_events_tests.cpp index 096561f60f..7a21841249 100644 --- a/unit_tests/event/user_events_tests.cpp +++ b/unit_tests/event/user_events_tests.cpp @@ -373,6 +373,22 @@ TEST_F(EventTests, twoUserEventInjectsCountOnNDR1whichIsPropagatedToNDR2viaVirtu EXPECT_EQ(CL_SUCCESS, retVal); } +TEST_F(EventTests, givenQueueThatIsBlockedByUserEventWhenIsQueueBlockedIsCalledThenVirtualEventOnlyQueriesForExecutionStatus) { + struct mockEvent : public Event { + using Event::Event; + void updateExecutionStatus() override { + updateExecutionStatusCalled = true; + } + bool updateExecutionStatusCalled = false; + }; + mockEvent mockedVirtualEvent(pCmdQ, CL_COMMAND_NDRANGE_KERNEL, Event::eventNotReady, 0); + pCmdQ->virtualEvent = &mockedVirtualEvent; + + EXPECT_TRUE(pCmdQ->isQueueBlocked()); + EXPECT_FALSE(mockedVirtualEvent.updateExecutionStatusCalled); + pCmdQ->virtualEvent = nullptr; +} + TEST_F(EventTests, finishDoesntBlockAfterUserEventSignaling) { UserEvent uEvent(context); UserEvent uEvent2(context);