From 14f4d5c5b9186bef476bac718f76f2e9925078ee Mon Sep 17 00:00:00 2001 From: Zbigniew Zdanowicz Date: Mon, 18 May 2020 18:48:43 +0200 Subject: [PATCH] Fix delayed first execution in diagnostic mode of direct submission Related-To: NEO-4338 Change-Id: I68cce6ac66946f1cd0af9328231ccfbc2910c3c4 Signed-off-by: Zbigniew Zdanowicz --- Jenkinsfile | 4 +-- .../direct_submission/direct_submission_hw.h | 2 ++ .../direct_submission_hw.inl | 28 +++++++++++++++---- .../direct_submission_hw_diagnostic_mode.cpp | 7 +++-- .../direct_submission_hw_diagnostic_mode.h | 16 +++++++---- .../direct_submission_tests.cpp | 15 ++++++---- .../mocks/mock_direct_submission_hw.h | 1 + 7 files changed, 51 insertions(+), 22 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 08ee7a933c..27f872bbfa 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -1,5 +1,5 @@ #!groovy dependenciesRevision='7e33b7bfa87d8f5afd1a9782119d889abdc0f476-1420' strategy='EQUAL' -allowedCD=251 -allowedF=26 +allowedCD=254 +allowedF=27 diff --git a/shared/source/direct_submission/direct_submission_hw.h b/shared/source/direct_submission/direct_submission_hw.h index dd8df0d46d..e6b8423054 100644 --- a/shared/source/direct_submission/direct_submission_hw.h +++ b/shared/source/direct_submission/direct_submission_hw.h @@ -95,6 +95,8 @@ class DirectSubmissionHw { void createDiagnostic(); void initDiagnostic(bool &submitOnInit); MOCKABLE_VIRTUAL void performDiagnosticMode(); + void dispatchDiagnosticModeSection(); + size_t getDiagnosticModeSection(); enum RingBufferUse : uint32_t { FirstBuffer, diff --git a/shared/source/direct_submission/direct_submission_hw.inl b/shared/source/direct_submission/direct_submission_hw.inl index 00e2d1a4f9..201482052a 100644 --- a/shared/source/direct_submission/direct_submission_hw.inl +++ b/shared/source/direct_submission/direct_submission_hw.inl @@ -119,6 +119,9 @@ bool DirectSubmissionHw::initialize(bool submitOnInit) { getSizeSemaphoreSection(); Dispatcher::dispatchPreemption(ringCommandStream); dispatchSemaphoreSection(currentQueueWorkCount); + if (workloadMode == 1) { + dispatchDiagnosticModeSection(); + } ringStart = submit(ringCommandStream.getGraphicsAllocation()->getGpuAddress(), startBufferSize); performDiagnosticMode(); @@ -233,7 +236,7 @@ inline size_t DirectSubmissionHw::getSizeDispatch() { if (workloadMode == 0) { size += getSizeStartSection(); } else if (workloadMode == 1) { - size += Dispatcher::getSizeStoreDwordCommand(); + size += getDiagnosticModeSection(); } //mode 2 does not dispatch any commands @@ -260,11 +263,8 @@ void *DirectSubmissionHw::dispatchWorkloadSection(BatchBu setReturnAddress(returnCmd, getCommandBufferPositionGpuAddress(returnPosition)); } else if (workloadMode == 1) { - workloadModeOneExpectedValue++; - uint64_t storeAddress = semaphoreGpuVa; - storeAddress += ptrDiff(workloadModeOneStoreAddress, semaphorePtr); DirectSubmissionDiagnostics::diagnosticModeOneDispatch(diagnostic.get()); - Dispatcher::dispatchStoreDwordCommand(ringCommandStream, storeAddress, workloadModeOneExpectedValue); + dispatchDiagnosticModeSection(); } //mode 2 does not dispatch any commands @@ -403,12 +403,15 @@ void DirectSubmissionHw::performDiagnosticMode() { if (directSubmissionDiagnosticAvailable) { if (diagnostic.get()) { diagnostic->diagnosticModeDiagnostic(); + if (workloadMode == 1) { + diagnostic->diagnosticModeOneWait(workloadModeOneStoreAddress, workloadModeOneExpectedValue); + } BatchBuffer dummyBuffer = {}; FlushStampTracker dummyTracker(true); for (uint32_t execution = 0; execution < diagnostic->getExecutionsCount(); execution++) { dispatchCommandBuffer(dummyBuffer, dummyTracker); if (workloadMode == 1) { - diagnostic->diagnosticModeOneWait(execution, workloadModeOneStoreAddress, workloadModeOneExpectedValue); + diagnostic->diagnosticModeOneWaitCollect(execution, workloadModeOneStoreAddress, workloadModeOneExpectedValue); } } workloadMode = 0; @@ -419,4 +422,17 @@ void DirectSubmissionHw::performDiagnosticMode() { } } +template +void DirectSubmissionHw::dispatchDiagnosticModeSection() { + workloadModeOneExpectedValue++; + uint64_t storeAddress = semaphoreGpuVa; + storeAddress += ptrDiff(workloadModeOneStoreAddress, semaphorePtr); + Dispatcher::dispatchStoreDwordCommand(ringCommandStream, storeAddress, workloadModeOneExpectedValue); +} + +template +size_t DirectSubmissionHw::getDiagnosticModeSection() { + return Dispatcher::getSizeStoreDwordCommand(); +} + } // namespace NEO diff --git a/shared/source/direct_submission/direct_submission_hw_diagnostic_mode.cpp b/shared/source/direct_submission/direct_submission_hw_diagnostic_mode.cpp index b7200652ac..4afff86b78 100644 --- a/shared/source/direct_submission/direct_submission_hw_diagnostic_mode.cpp +++ b/shared/source/direct_submission/direct_submission_hw_diagnostic_mode.cpp @@ -38,15 +38,16 @@ void DirectSubmissionDiagnosticsCollector::storeData() { int64_t initTimeDiff = std::chrono::duration_cast(initDelta).count(); - IoFunctions::fprintf(logFile, "From allocations ready to exit of OS submit function %lld\n", initTimeDiff); + IoFunctions::fprintf(logFile, "From allocations ready to exit of OS submit function %lld useconds\n", initTimeDiff); if (storeExecutions) { for (uint32_t execution = 0; execution < executionsCount; execution++) { DirectSubmissionSingleDelta &delta = executionList[execution]; std::stringstream value; value << std::dec << " execution: " << execution; - value << " total diff: " << delta.totalTimeDiff - << " dispatch-submit: " << delta.dispatchSubmitTimeDiff << " submit-wait: " << delta.submitWaitTimeDiff; + value << " total diff: " << delta.totalTimeDiff << " nsec" + << " dispatch-submit: " << delta.dispatchSubmitTimeDiff << " nsec" + << " submit-wait: " << delta.submitWaitTimeDiff << " nsec"; IoFunctions::fprintf(logFile, "%s\n", value.str().c_str()); } } diff --git a/shared/source/direct_submission/direct_submission_hw_diagnostic_mode.h b/shared/source/direct_submission/direct_submission_hw_diagnostic_mode.h index de5e32e2db..0ec95d518b 100644 --- a/shared/source/direct_submission/direct_submission_hw_diagnostic_mode.h +++ b/shared/source/direct_submission/direct_submission_hw_diagnostic_mode.h @@ -53,22 +53,28 @@ class DirectSubmissionDiagnosticsCollector { void diagnosticModeOneSubmit() { diagnosticModeOneSubmitTime = std::chrono::high_resolution_clock::now(); } - void diagnosticModeOneWait(uint32_t execution, - volatile void *waitLocation, + + void diagnosticModeOneWait(volatile void *waitLocation, uint32_t waitValue) { volatile uint32_t *waitAddress = static_cast(waitLocation); while (waitValue > *waitAddress) ; + } + + void diagnosticModeOneWaitCollect(uint32_t execution, + volatile void *waitLocation, + uint32_t waitValue) { + diagnosticModeOneWait(waitLocation, waitValue); diagnosticModeOneWaitTime = std::chrono::high_resolution_clock::now(); auto delta = diagnosticModeOneWaitTime - diagnosticModeOneDispatchTime; - executionList[execution].totalTimeDiff = std::chrono::duration_cast(delta).count(); + executionList[execution].totalTimeDiff = std::chrono::duration_cast(delta).count(); delta = diagnosticModeOneSubmitTime - diagnosticModeOneDispatchTime; - executionList[execution].dispatchSubmitTimeDiff = std::chrono::duration_cast(delta).count(); + executionList[execution].dispatchSubmitTimeDiff = std::chrono::duration_cast(delta).count(); delta = diagnosticModeOneWaitTime - diagnosticModeOneSubmitTime; - executionList[execution].submitWaitTimeDiff = std::chrono::duration_cast(delta).count(); + executionList[execution].submitWaitTimeDiff = std::chrono::duration_cast(delta).count(); } uint32_t getExecutionsCount() const { diff --git a/shared/test/unit_test/direct_submission/direct_submission_tests.cpp b/shared/test/unit_test/direct_submission/direct_submission_tests.cpp index d9c95088dd..245b414fba 100644 --- a/shared/test/unit_test/direct_submission/direct_submission_tests.cpp +++ b/shared/test/unit_test/direct_submission/direct_submission_tests.cpp @@ -1019,11 +1019,12 @@ HWTEST_F(DirectSubmissionTest, GTEST_SKIP(); } + uint32_t execCount = 5u; DebugManagerStateRestore restore; DebugManager.flags.DirectSubmissionEnableDebugBuffer.set(1); DebugManager.flags.DirectSubmissionDisableCacheFlush.set(true); DebugManager.flags.DirectSubmissionDisableMonitorFence.set(true); - DebugManager.flags.DirectSubmissionDiagnosticExecutionCount.set(5); + DebugManager.flags.DirectSubmissionDiagnosticExecutionCount.set(static_cast(execCount)); NEO::IoFunctions::mockFopenCalled = 0u; NEO::IoFunctions::mockVfptrinfCalled = 0u; @@ -1041,7 +1042,8 @@ HWTEST_F(DirectSubmissionTest, expectedSemaphoreValue += expectedExecCount; EXPECT_EQ(expectedExecCount, directSubmission.diagnostic->getExecutionsCount()); size_t expectedSize = Dispatcher::getSizePreemption() + - directSubmission.getSizeSemaphoreSection(); + directSubmission.getSizeSemaphoreSection() + + directSubmission.getDiagnosticModeSection(); expectedSize += expectedExecCount * directSubmission.getSizeDispatch(); bool ret = directSubmission.initialize(false); @@ -1064,11 +1066,12 @@ HWTEST_F(DirectSubmissionTest, hwParse.parseCommands(directSubmission.ringCommandStream, 0); GenCmdList storeDataCmdList = hwParse.getCommandsList(); - ASSERT_EQ(5u, storeDataCmdList.size()); + execCount += 1; + ASSERT_EQ(execCount, storeDataCmdList.size()); + uint32_t expectedData = 1u; for (auto &storeCmdData : storeDataCmdList) { MI_STORE_DATA_IMM *storeCmd = static_cast(storeCmdData); - auto storeData = storeCmd->getDataDword0(); EXPECT_EQ(expectedData, storeData); expectedData++; @@ -1178,14 +1181,14 @@ HWTEST_F(DirectSubmissionTest, EXPECT_TRUE(ret); ASSERT_NE(nullptr, directSubmission.workloadModeOneStoreAddress); - directSubmission.diagnostic->diagnosticModeOneWait(0, directSubmission.workloadModeOneStoreAddress, directSubmission.workloadModeOneExpectedValue); + directSubmission.diagnostic->diagnosticModeOneWaitCollect(0, directSubmission.workloadModeOneStoreAddress, directSubmission.workloadModeOneExpectedValue); auto mockDiagnostic = reinterpret_cast(directSubmission.diagnostic.get()); EXPECT_NE(0ll, mockDiagnostic->executionList[0].totalTimeDiff); EXPECT_NE(0ll, mockDiagnostic->executionList[0].submitWaitTimeDiff); EXPECT_EQ(0ll, mockDiagnostic->executionList[0].dispatchSubmitTimeDiff); - directSubmission.diagnostic->diagnosticModeOneWait(1, directSubmission.workloadModeOneStoreAddress, directSubmission.workloadModeOneExpectedValue); + directSubmission.diagnostic->diagnosticModeOneWaitCollect(1, directSubmission.workloadModeOneStoreAddress, directSubmission.workloadModeOneExpectedValue); EXPECT_NE(0ll, mockDiagnostic->executionList[1].totalTimeDiff); EXPECT_NE(0ll, mockDiagnostic->executionList[1].submitWaitTimeDiff); diff --git a/shared/test/unit_test/mocks/mock_direct_submission_hw.h b/shared/test/unit_test/mocks/mock_direct_submission_hw.h index 6ac9b2071c..583bc6f31a 100644 --- a/shared/test/unit_test/mocks/mock_direct_submission_hw.h +++ b/shared/test/unit_test/mocks/mock_direct_submission_hw.h @@ -34,6 +34,7 @@ struct MockDirectSubmissionHw : public DirectSubmissionHw using BaseClass::dispatchSwitchRingBufferSection; using BaseClass::dispatchWorkloadSection; using BaseClass::getCommandBufferPositionGpuAddress; + using BaseClass::getDiagnosticModeSection; using BaseClass::getSizeDispatch; using BaseClass::getSizeEnd; using BaseClass::getSizeSemaphoreSection;