From 5961850bbc535b7b58cf7d64c38c36d467e7fc96 Mon Sep 17 00:00:00 2001 From: Lukasz Jobczyk Date: Fri, 21 Feb 2025 12:11:10 +0000 Subject: [PATCH] fix: blink ULLS light Related-To: NEO-13922 Signed-off-by: Lukasz Jobczyk --- .../linux/drm_direct_submission.h | 4 ++ .../linux/drm_direct_submission.inl | 10 ++- .../linux/drm_direct_submission_tests.cpp | 63 +++++++++++++++++++ 3 files changed, 76 insertions(+), 1 deletion(-) diff --git a/shared/source/direct_submission/linux/drm_direct_submission.h b/shared/source/direct_submission/linux/drm_direct_submission.h index 4184e5ce74..faad670123 100644 --- a/shared/source/direct_submission/linux/drm_direct_submission.h +++ b/shared/source/direct_submission/linux/drm_direct_submission.h @@ -39,6 +39,7 @@ class DrmDirectSubmission : public DirectSubmissionHw { bool isCompleted(uint32_t ringBufferIndex) override; bool isCompletionFenceSupported(); bool isGpuHangDetected(std::chrono::high_resolution_clock::time_point &lastHangCheckTime); + MOCKABLE_VIRTUAL std::chrono::steady_clock::time_point getCpuTimePoint(); MOCKABLE_VIRTUAL void wait(TaskCountType taskCountToWait); @@ -47,6 +48,9 @@ class DrmDirectSubmission : public DirectSubmissionHw { TaskCountType completionFenceValue{}; std::chrono::microseconds gpuHangCheckPeriod{CommonConstants::gpuHangCheckTimeInUS}; + constexpr static size_t ullsLightTimeout = 2'000'000; + std::chrono::steady_clock::time_point lastUllsLightExecTimestamp{}; + std::vector residency{}; std::vector execObjectsStorage{}; }; diff --git a/shared/source/direct_submission/linux/drm_direct_submission.inl b/shared/source/direct_submission/linux/drm_direct_submission.inl index 3d78870bb7..41bc916b2d 100644 --- a/shared/source/direct_submission/linux/drm_direct_submission.inl +++ b/shared/source/direct_submission/linux/drm_direct_submission.inl @@ -141,6 +141,8 @@ bool DrmDirectSubmission::submit(uint64_t gpuAddress, siz if (!allocationsForResidency) { this->handleResidency(); + } else { + this->lastUllsLightExecTimestamp = std::chrono::steady_clock::now(); } auto currentBase = this->ringCommandStream.getGraphicsAllocation()->getGpuAddress(); @@ -212,7 +214,8 @@ bool DrmDirectSubmission::handleResidency() { template void DrmDirectSubmission::handleRingRestartForUllsLightResidency(ResidencyContainer *allocationsForResidency) { if (allocationsForResidency) { - auto restartNeeded = static_cast(this->memoryOperationHandler)->obtainAndResetNewResourcesSinceLastRingSubmit(); + auto restartNeeded = (static_cast(this->memoryOperationHandler)->obtainAndResetNewResourcesSinceLastRingSubmit() || + std::chrono::duration_cast(this->getCpuTimePoint() - this->lastUllsLightExecTimestamp) > std::chrono::microseconds{ullsLightTimeout}); if (restartNeeded) { this->stopRingBuffer(false); } @@ -292,6 +295,11 @@ void DrmDirectSubmission::wait(TaskCountType taskCountToW } } +template +std::chrono::steady_clock::time_point DrmDirectSubmission::getCpuTimePoint() { + return std::chrono::steady_clock::now(); +} + template bool DrmDirectSubmission::isGpuHangDetected(std::chrono::high_resolution_clock::time_point &lastHangCheckTime) { if (!this->detectGpuHang) { diff --git a/shared/test/unit_test/direct_submission/linux/drm_direct_submission_tests.cpp b/shared/test/unit_test/direct_submission/linux/drm_direct_submission_tests.cpp index cd1daca4d9..fad52eb4c1 100644 --- a/shared/test/unit_test/direct_submission/linux/drm_direct_submission_tests.cpp +++ b/shared/test/unit_test/direct_submission/linux/drm_direct_submission_tests.cpp @@ -93,6 +93,7 @@ struct MockDrmDirectSubmission : public DrmDirectSubmissionlastUllsLightExecTimestamp = std::chrono::time_point::max(); + } + + std::chrono::steady_clock::time_point getCpuTimePoint() override { + return this->callBaseGetCpuTimePoint ? BaseClass::getCpuTimePoint() : cpuTimePointReturnValue; + } + std::chrono::steady_clock::time_point cpuTimePointReturnValue{}; + bool callBaseGetCpuTimePoint = true; }; using namespace NEO; @@ -810,6 +821,58 @@ HWTEST_F(DrmDirectSubmissionTest, givenDirectSubmissionLightWhenRegisterResource executionEnvironment.memoryManager->freeGraphicsMemory(commandBuffer); } +HWTEST_F(DrmDirectSubmissionTest, givenDirectSubmissionLightWhenExecTimeoutReachedThenRestart) { + using PIPE_CONTROL = typename FamilyType::PIPE_CONTROL; + using BATCH_BUFFER_END = typename FamilyType::MI_BATCH_BUFFER_END; + MockDrmDirectSubmission> drmDirectSubmission(*device->getDefaultEngine().commandStreamReceiver); + EXPECT_TRUE(drmDirectSubmission.initialize(false)); + + FlushStampTracker flushStamp(true); + BatchBuffer batchBuffer = {}; + GraphicsAllocation *commandBuffer = nullptr; + LinearStream stream; + + const AllocationProperties commandBufferProperties{device->getRootDeviceIndex(), 0x1000, + AllocationType::commandBuffer, device->getDeviceBitfield()}; + commandBuffer = executionEnvironment.memoryManager->allocateGraphicsMemoryWithProperties(commandBufferProperties); + + stream.replaceGraphicsAllocation(commandBuffer); + stream.replaceBuffer(commandBuffer->getUnderlyingBuffer(), commandBuffer->getUnderlyingBufferSize()); + stream.getSpace(0x20); + + memset(stream.getCpuBase(), 0, 0x20); + + batchBuffer.endCmdPtr = ptrOffset(stream.getCpuBase(), 0x20); + batchBuffer.commandBufferAllocation = commandBuffer; + batchBuffer.usedSize = 0x40; + batchBuffer.taskStartAddress = 0x881112340000; + batchBuffer.stream = &stream; + batchBuffer.hasStallingCmds = true; + + ResidencyContainer residencyContainer{}; + batchBuffer.allocationsForResidency = &residencyContainer; + drmDirectSubmission.ringStart = true; + static_cast(executionEnvironment.rootDeviceEnvironments[device->getRootDeviceIndex()]->memoryOperationsInterface.get())->obtainAndResetNewResourcesSinceLastRingSubmit(); + + drmDirectSubmission.lastUllsLightExecTimestamp = std::chrono::steady_clock::time_point{}; + drmDirectSubmission.cpuTimePointReturnValue = std::chrono::time_point::max(); + drmDirectSubmission.callBaseGetCpuTimePoint = false; + + EXPECT_TRUE(drmDirectSubmission.dispatchCommandBuffer(batchBuffer, flushStamp)); + + HardwareParse hwParse; + hwParse.parsePipeControl = true; + hwParse.parseCommands(drmDirectSubmission.ringCommandStream, 0); + hwParse.findHardwareCommands(); + auto *pipeControl = hwParse.getCommand(); + EXPECT_NE(pipeControl, nullptr); + auto *bbe = hwParse.getCommand(); + EXPECT_NE(bbe, nullptr); + + drmDirectSubmission.ringStart = false; + executionEnvironment.memoryManager->freeGraphicsMemory(commandBuffer); +} + HWTEST_F(DrmDirectSubmissionTest, givenDirectSubmissionLightWhenNoRegisteredResourcesThenNoRestart) { using PIPE_CONTROL = typename FamilyType::PIPE_CONTROL; using BATCH_BUFFER_END = typename FamilyType::MI_BATCH_BUFFER_END;