Do not use peekIsCompleted in isQueueBlocked.
- This causes event tree update if virtual event is holding commands or callbacks - That causes race between other threads that may be updating the tree Change-Id: Ic80a8b71ed1e1c1deab8af1bc64f8ce81c21de1b
This commit is contained in:
parent
7e9ad41290
commit
3284efff86
|
@ -2,4 +2,4 @@
|
||||||
neoDependenciesRev='716918-671'
|
neoDependenciesRev='716918-671'
|
||||||
strategy='EQUAL'
|
strategy='EQUAL'
|
||||||
allowedF=49
|
allowedF=49
|
||||||
allowedCD=381
|
allowedCD=380
|
||||||
|
|
|
@ -164,7 +164,7 @@ bool CommandQueue::isQueueBlocked() {
|
||||||
TakeOwnershipWrapper<CommandQueue> takeOwnershipWrapper(*this);
|
TakeOwnershipWrapper<CommandQueue> takeOwnershipWrapper(*this);
|
||||||
//check if we have user event and if so, if it is in blocked state.
|
//check if we have user event and if so, if it is in blocked state.
|
||||||
if (this->virtualEvent) {
|
if (this->virtualEvent) {
|
||||||
if (this->virtualEvent->peekIsCompleted()) {
|
if (this->virtualEvent->peekExecutionStatus() <= CL_COMPLETE) {
|
||||||
UNRECOVERABLE_IF(this->virtualEvent == nullptr);
|
UNRECOVERABLE_IF(this->virtualEvent == nullptr);
|
||||||
|
|
||||||
if (this->virtualEvent->peekIsCompletedByTermination() == false) {
|
if (this->virtualEvent->peekIsCompletedByTermination() == false) {
|
||||||
|
|
|
@ -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);
|
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;
|
int32_t statusToPropagate = CL_SUBMITTED;
|
||||||
if (peekIsCompletedByTermination(&blockerStatus)) {
|
if (peekIsCompletedByTermination(&blockerStatus)) {
|
||||||
|
|
|
@ -723,7 +723,6 @@ HWTEST_F(CommandQueueHwTest, givenBlockedInOrderCmdQueueAndAsynchronouslyComplet
|
||||||
};
|
};
|
||||||
|
|
||||||
Event event(cmdQHw, CL_COMMAND_NDRANGE_KERNEL, 10, 0);
|
Event event(cmdQHw, CL_COMMAND_NDRANGE_KERNEL, 10, 0);
|
||||||
event.setStatus(CL_SUBMITTED);
|
|
||||||
|
|
||||||
uint32_t virtualEventTaskLevel = 77;
|
uint32_t virtualEventTaskLevel = 77;
|
||||||
uint32_t virtualEventTaskCount = 80;
|
uint32_t virtualEventTaskCount = 80;
|
||||||
|
@ -734,16 +733,24 @@ HWTEST_F(CommandQueueHwTest, givenBlockedInOrderCmdQueueAndAsynchronouslyComplet
|
||||||
|
|
||||||
// Put Queue in blocked state by assigning virtualEvent
|
// Put Queue in blocked state by assigning virtualEvent
|
||||||
virtualEvent.incRefInternal();
|
virtualEvent.incRefInternal();
|
||||||
|
event.addChild(virtualEvent);
|
||||||
cmdQHw->virtualEvent = &virtualEvent;
|
cmdQHw->virtualEvent = &virtualEvent;
|
||||||
cmdQHw->incRefInternal();
|
cmdQHw->incRefInternal();
|
||||||
|
|
||||||
cmdQHw->taskLevel = 23;
|
cmdQHw->taskLevel = 23;
|
||||||
cmdQHw->enqueueKernel(mockKernel, 1, &offset, &size, &size, 1, &blockedEvent, nullptr);
|
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 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, 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) {
|
HWTEST_F(OOQueueHwTest, givenBlockedOutOfOrderCmdQueueAndAsynchronouslyCompletedEventWhenEnqueueCompletesVirtualEventThenUpdatedTaskLevelIsPassedToEnqueueAndFlushTask) {
|
||||||
|
@ -769,7 +776,6 @@ HWTEST_F(OOQueueHwTest, givenBlockedOutOfOrderCmdQueueAndAsynchronouslyCompleted
|
||||||
};
|
};
|
||||||
|
|
||||||
Event event(cmdQHw, CL_COMMAND_NDRANGE_KERNEL, 10, 0);
|
Event event(cmdQHw, CL_COMMAND_NDRANGE_KERNEL, 10, 0);
|
||||||
event.setStatus(CL_SUBMITTED);
|
|
||||||
|
|
||||||
uint32_t virtualEventTaskLevel = 77;
|
uint32_t virtualEventTaskLevel = 77;
|
||||||
uint32_t virtualEventTaskCount = 80;
|
uint32_t virtualEventTaskCount = 80;
|
||||||
|
@ -780,12 +786,22 @@ HWTEST_F(OOQueueHwTest, givenBlockedOutOfOrderCmdQueueAndAsynchronouslyCompleted
|
||||||
|
|
||||||
// Put Queue in blocked state by assigning virtualEvent
|
// Put Queue in blocked state by assigning virtualEvent
|
||||||
virtualEvent.incRefInternal();
|
virtualEvent.incRefInternal();
|
||||||
|
event.addChild(virtualEvent);
|
||||||
cmdQHw->virtualEvent = &virtualEvent;
|
cmdQHw->virtualEvent = &virtualEvent;
|
||||||
cmdQHw->incRefInternal();
|
cmdQHw->incRefInternal();
|
||||||
|
|
||||||
cmdQHw->taskLevel = 23;
|
cmdQHw->taskLevel = 23;
|
||||||
cmdQHw->enqueueKernel(mockKernel, 1, &offset, &size, &size, 1, &blockedEvent, nullptr);
|
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);
|
event.setStatus(CL_SUBMITTED);
|
||||||
EXPECT_EQ(virtualEventTaskLevel, mockCSR->lastTaskLevelToFlushTask);
|
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -373,6 +373,22 @@ TEST_F(EventTests, twoUserEventInjectsCountOnNDR1whichIsPropagatedToNDR2viaVirtu
|
||||||
EXPECT_EQ(CL_SUCCESS, retVal);
|
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) {
|
TEST_F(EventTests, finishDoesntBlockAfterUserEventSignaling) {
|
||||||
UserEvent uEvent(context);
|
UserEvent uEvent(context);
|
||||||
UserEvent uEvent2(context);
|
UserEvent uEvent2(context);
|
||||||
|
|
Loading…
Reference in New Issue