Ensure that submissions are flushed prior to csr destruction.

Change-Id: Ie04de561d3d295f40f55a19f01274d873d259abd
This commit is contained in:
Mrozek, Michal 2018-03-09 14:48:42 +01:00
parent 3d139c204e
commit 8254d6a081
10 changed files with 78 additions and 18 deletions

View File

@ -454,8 +454,9 @@ inline void CommandStreamReceiverHw<GfxFamily>::flushBatchedSubmissions() {
}
//make sure we flush DC
((PIPE_CONTROL *)epiloguePipeControlLocation)->setDcFlushEnable(true);
if (epiloguePipeControlLocation) {
((PIPE_CONTROL *)epiloguePipeControlLocation)->setDcFlushEnable(true);
}
auto flushStamp = this->flush(primaryCmdBuffer->batchBuffer, engineType, &surfacesForSubmit);
//after flush task level is closed

View File

@ -92,8 +92,12 @@ Device::~Device() {
if (performanceCounters) {
performanceCounters->shutdown();
}
delete commandStreamReceiver;
commandStreamReceiver = nullptr;
if (commandStreamReceiver) {
commandStreamReceiver->flushBatchedSubmissions();
delete commandStreamReceiver;
commandStreamReceiver = nullptr;
}
if (memoryManager) {
if (preemptionAllocation) {
memoryManager->freeGraphicsMemory(preemptionAllocation);

View File

@ -278,6 +278,8 @@ void WddmMemoryManager::freeGraphicsMemoryImpl(GraphicsAllocation *gfxAllocation
releaseResidencyLock();
UNRECOVERABLE_IF(gfxAllocation->taskCount != ObjectNotUsed && this->device && this->device->peekCommandStreamReceiver() && gfxAllocation->taskCount > *this->device->getCommandStreamReceiver().getTagAddress());
if (input->gmm) {
if (input->gmm->isRenderCompressed) {
auto status = wddm->updateAuxTable(input->gpuPtr, input->gmm, false);

View File

@ -105,6 +105,8 @@ HWTEST_F(AUBHelloWorld, simple) {
ASSERT_EQ(CL_SUCCESS, retVal);
pCmdQ->flush();
parseCommands<FamilyType>(*pCmdQ);
auto *pWalker = reinterpret_cast<GPGPU_WALKER *>(cmdWalker);
@ -242,6 +244,8 @@ HWTEST_F(AUBSimpleArg, simple) {
parseCommands<FamilyType>(*pCmdQ);
pCmdQ->flush();
auto *pWalker = reinterpret_cast<GPGPU_WALKER *>(cmdWalker);
ASSERT_NE(nullptr, pWalker);
auto alignmentIDSA = 32 * sizeof(uint8_t);
@ -293,6 +297,7 @@ HWTEST_F(AUBSimpleArg, givenAubCommandStreamerReceiverWhenBatchBufferFlateningIs
event);
ASSERT_EQ(CL_SUCCESS, retVal);
pCmdQ->flush();
}
struct AUBSimpleArgIntegrateTest : public SimpleArgFixture<AUBSimpleArgFixtureFactory>,
@ -352,9 +357,4 @@ INSTANTIATE_TEST_CASE_P(
::testing::Combine(
::testing::ValuesIn(TestSimdTable),
::testing::ValuesIn(TestParamTable)));
typedef TwoWalkerTest<AUBHelloWorldFixtureFactory> AUBTwoWalker;
TEST_F(AUBTwoWalker, simple) {
}
} // namespace ULT

View File

@ -93,6 +93,9 @@ struct TwoOOQsTwoDependentWalkers : public HelloWorldTest<OOQFixtureFactory>,
ASSERT_EQ(CL_SUCCESS, retVal);
HardwareParse::parseCommands<FamilyType>(*pCmdQ2);
pCmdQ->flush();
pCmdQ2->flush();
Event *E1 = castToObject<Event>(event1);
ASSERT_NE(nullptr, E1);
Event *E2 = castToObject<Event>(event2);

View File

@ -344,6 +344,7 @@ HWTEST_F(EnqueueWriteBufferTypeTest, givenOOQWithEnabledSupportCpuCopiesAndDstPt
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(pCmdOOQ->taskLevel, 0u);
pCmdOOQ->flush();
}
HWTEST_F(EnqueueWriteBufferTypeTest, givenOOQWithDisabledSupportCpuCopiesAndDstPtrEqualSrcPtrZeroCopyBufferWhenWriteBufferIsExecutedThenTaskLevelNotIncreased) {
DebugManagerStateRestore dbgRestore;
@ -363,6 +364,7 @@ HWTEST_F(EnqueueWriteBufferTypeTest, givenOOQWithDisabledSupportCpuCopiesAndDstP
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(pCmdOOQ->taskLevel, 0u);
pCmdOOQ->flush();
}
HWTEST_F(EnqueueWriteBufferTypeTest, givenInOrderQueueAndEnabledSupportCpuCopiesAndDstPtrZeroCopyBufferEqualSrcPtrWhenWriteBufferIsExecutedThenTaskLevelShouldNotBeIncreased) {
DebugManagerStateRestore dbgRestore;

View File

@ -36,36 +36,66 @@ struct OOQTaskTypedTests : public HelloWorldTest<OOQFixtureFactory> {
TYPED_TEST_CASE_P(OOQTaskTypedTests);
TYPED_TEST_P(OOQTaskTypedTests, doesntChangeTaskLevel) {
bool isBlockingCall(unsigned int cmdType) {
if (cmdType == CL_COMMAND_WRITE_BUFFER ||
cmdType == CL_COMMAND_READ_BUFFER ||
cmdType == CL_COMMAND_WRITE_IMAGE ||
cmdType == CL_COMMAND_READ_IMAGE) {
return true;
} else {
return false;
}
}
TYPED_TEST_P(OOQTaskTypedTests, givenNonBlockingCallWhenDoneOnOutOfOrderQueueThenTaskLevelDoesntChange) {
auto &commandStreamReceiver = this->pDevice->getCommandStreamReceiver();
auto tagAddress = commandStreamReceiver.getTagAddress();
auto blockingCall = isBlockingCall(TypeParam::Traits::cmdType);
auto taskLevelClosed = blockingCall ? 1u : 0u; // for blocking commands task level will be closed
//for non blocking calls make sure that resources are added to defer free list instaed of being destructed in place
if (!blockingCall) {
*tagAddress = 0;
}
auto previousTaskLevel = this->pCmdQ->taskLevel;
auto taskLevelClosed = 0u; // for blocking commands task level will be closed
if (TypeParam::Traits::cmdType == CL_COMMAND_WRITE_BUFFER || TypeParam::Traits::cmdType == CL_COMMAND_READ_BUFFER) {
auto buffer = std::unique_ptr<Buffer>(BufferHelper<>::create());
buffer->forceDisallowCPUCopy = true; // no task level logic when cpu copy
TypeParam::enqueue(this->pCmdQ, buffer.get());
taskLevelClosed = 1u;
this->pCmdQ->flush();
} else {
TypeParam::enqueue(this->pCmdQ, nullptr);
}
if (TypeParam::Traits::cmdType == CL_COMMAND_WRITE_IMAGE || TypeParam::Traits::cmdType == CL_COMMAND_READ_IMAGE) {
taskLevelClosed = 1u;
}
EXPECT_EQ(previousTaskLevel + taskLevelClosed, this->pCmdQ->taskLevel);
*tagAddress = initialHardwareTag;
}
TYPED_TEST_P(OOQTaskTypedTests, changesTaskCount) {
TYPED_TEST_P(OOQTaskTypedTests, givenTaskWhenEnqueuedOnOutOfOrderQueueThenTaskCountIsUpdated) {
auto &commandStreamReceiver = this->pDevice->getCommandStreamReceiver();
auto previousTaskCount = commandStreamReceiver.peekTaskCount();
auto tagAddress = commandStreamReceiver.getTagAddress();
auto blockingCall = isBlockingCall(TypeParam::Traits::cmdType);
//for non blocking calls make sure that resources are added to defer free list instaed of being destructed in place
if (!blockingCall) {
*tagAddress = 0;
}
if (TypeParam::Traits::cmdType == CL_COMMAND_WRITE_BUFFER || TypeParam::Traits::cmdType == CL_COMMAND_READ_BUFFER) {
auto buffer = std::unique_ptr<Buffer>(BufferHelper<>::create());
buffer->forceDisallowCPUCopy = true; // no task level logic when cpu copy
TypeParam::enqueue(this->pCmdQ, buffer.get());
this->pCmdQ->flush();
} else {
TypeParam::enqueue(this->pCmdQ, nullptr);
}
EXPECT_LT(previousTaskCount, commandStreamReceiver.peekTaskCount());
EXPECT_LE(this->pCmdQ->taskCount, commandStreamReceiver.peekTaskCount());
*tagAddress = initialHardwareTag;
}
typedef ::testing::Types<
@ -80,8 +110,8 @@ typedef ::testing::Types<
EnqueueParams;
REGISTER_TYPED_TEST_CASE_P(OOQTaskTypedTests,
doesntChangeTaskLevel,
changesTaskCount);
givenNonBlockingCallWhenDoneOnOutOfOrderQueueThenTaskLevelDoesntChange,
givenTaskWhenEnqueuedOnOutOfOrderQueueThenTaskCountIsUpdated);
// Instantiate all of these parameterized tests
INSTANTIATE_TYPED_TEST_CASE_P(OOQ, OOQTaskTypedTests, EnqueueParams);
@ -248,6 +278,7 @@ TEST_F(OOQTaskTests, enqueueReadBuffer_blockingAndNonBlockedOnUserEvent) {
retVal = clReleaseEvent(userEvent);
EXPECT_EQ(CL_SUCCESS, retVal);
pCmdQ->flush();
alignedFree(alignedReadPtr);
}

View File

@ -107,6 +107,7 @@ struct UltCommandStreamReceiverTest
}
void TearDown() override {
pDevice->getCommandStreamReceiver().flushBatchedSubmissions();
delete dsh.getGraphicsAllocation();
delete ih.getGraphicsAllocation();
delete ioh.getGraphicsAllocation();

View File

@ -27,6 +27,7 @@
#include "unit_tests/fixtures/device_fixture.h"
#include "unit_tests/fixtures/memory_management_fixture.h"
#include "unit_tests/mocks/mock_context.h"
#include "unit_tests/mocks/mock_csr.h"
#include "unit_tests/libult/create_command_stream.h"
#include "test.h"
#include <memory>
@ -144,3 +145,14 @@ TEST(DeviceCreation, givenDeviceWithUsedTagAllocationWhenItIsDestroyedThenThereA
auto tagAllocation = device->peekTagAllocation();
tagAllocation->taskCount = 1;
}
TEST(DeviceCleanup, givenDeviceWhenItIsDestroyedThenFlushBatchedSubmissionsIsCalled) {
auto mockDevice = std::unique_ptr<MockDevice>(MockDevice::create<MockDevice>(nullptr));
MockCommandStreamReceiver *csr = new MockCommandStreamReceiver;
mockDevice->resetCommandStreamReceiver(csr);
int flushedBatchedSubmissionsCalledCount = 0;
csr->flushBatchedSubmissionsCallCounter = &flushedBatchedSubmissionsCalledCount;
mockDevice.reset(nullptr);
EXPECT_EQ(1, flushedBatchedSubmissionsCalledCount);
}

View File

@ -200,6 +200,7 @@ class MockCommandStreamReceiver : public CommandStreamReceiver {
using CommandStreamReceiver::latestSentTaskCount;
using CommandStreamReceiver::tagAddress;
std::vector<char> instructionHeapReserveredData;
int *flushBatchedSubmissionsCallCounter = nullptr;
~MockCommandStreamReceiver() {
}
@ -217,6 +218,9 @@ class MockCommandStreamReceiver : public CommandStreamReceiver {
DispatchFlags &dispatchFlags) override;
void flushBatchedSubmissions() override {
if (flushBatchedSubmissionsCallCounter) {
(*flushBatchedSubmissionsCallCounter)++;
}
}
void waitForTaskCountWithKmdNotifyFallback(uint32_t taskCountToWait, FlushStamp flushStampToWait) override {