diff --git a/shared/source/direct_submission/linux/drm_direct_submission.inl b/shared/source/direct_submission/linux/drm_direct_submission.inl index fd462550a5..3d4bb603cc 100644 --- a/shared/source/direct_submission/linux/drm_direct_submission.inl +++ b/shared/source/direct_submission/linux/drm_direct_submission.inl @@ -150,7 +150,7 @@ bool DrmDirectSubmission::handleResidency() { template bool DrmDirectSubmission::isNewResourceHandleNeeded() { auto osContextLinux = static_cast(&this->osContext); - auto newResourcesBound = osContextLinux->getNewResourceBound(); + auto newResourcesBound = osContextLinux->isTlbFlushRequired(); if (DebugManager.flags.DirectSubmissionNewResourceTlbFlush.get() != -1) { newResourcesBound = DebugManager.flags.DirectSubmissionNewResourceTlbFlush.get(); @@ -162,22 +162,18 @@ bool DrmDirectSubmission::isNewResourceHandleNeeded() { template void DrmDirectSubmission::handleNewResourcesSubmission() { if (isNewResourceHandleNeeded()) { - Dispatcher::dispatchTlbFlush(this->ringCommandStream, this->gpuVaForMiFlush, *this->hwInfo); - } + auto osContextLinux = static_cast(&this->osContext); + auto tlbFlushCounter = osContextLinux->peekTlbFlushCounter(); - auto osContextLinux = static_cast(&this->osContext); - osContextLinux->setNewResourceBound(false); + Dispatcher::dispatchTlbFlush(this->ringCommandStream, this->gpuVaForMiFlush, *this->hwInfo); + osContextLinux->setTlbFlushed(tlbFlushCounter); + } } template size_t DrmDirectSubmission::getSizeNewResourceHandler() { - size_t size = 0u; - - if (isNewResourceHandleNeeded()) { - size += Dispatcher::getSizeTlbFlush(); - } - - return size; + // Overestimate to avoid race + return Dispatcher::getSizeTlbFlush(); } template diff --git a/shared/source/os_interface/linux/drm_neo.cpp b/shared/source/os_interface/linux/drm_neo.cpp index 85876cf1e3..5ffdffcab5 100644 --- a/shared/source/os_interface/linux/drm_neo.cpp +++ b/shared/source/os_interface/linux/drm_neo.cpp @@ -636,7 +636,7 @@ void Drm::setNewResourceBoundToVM(uint32_t vmHandleId) { auto osContextLinux = static_cast(engine.osContext); if (&osContextLinux->getDrm() == this) { - osContextLinux->setNewResourceBound(true); + osContextLinux->setNewResourceBound(); } } } diff --git a/shared/source/os_interface/linux/drm_neo.h b/shared/source/os_interface/linux/drm_neo.h index 526c336ad9..73d0906074 100644 --- a/shared/source/os_interface/linux/drm_neo.h +++ b/shared/source/os_interface/linux/drm_neo.h @@ -25,6 +25,7 @@ #include "igfxfmid.h" #include +#include #include #include #include diff --git a/shared/source/os_interface/linux/os_context_linux.h b/shared/source/os_interface/linux/os_context_linux.h index 125087b7bb..486a296568 100644 --- a/shared/source/os_interface/linux/os_context_linux.h +++ b/shared/source/os_interface/linux/os_context_linux.h @@ -7,8 +7,10 @@ #pragma once +#include "shared/source/helpers/interlocked_max.h" #include "shared/source/os_interface/os_context.h" +#include #include namespace NEO { @@ -24,8 +26,18 @@ class OsContextLinux : public OsContext { void setEngineFlag(unsigned int engineFlag) { this->engineFlag = engineFlag; } const std::vector &getDrmContextIds() const { return drmContextIds; } const std::vector &getDrmVmIds() const { return drmVmIds; } - void setNewResourceBound(bool value) { this->newResourceBound = value; }; - bool getNewResourceBound() { return this->newResourceBound; }; + void setNewResourceBound() { + tlbFlushCounter++; + }; + + uint32_t peekTlbFlushCounter() const { return tlbFlushCounter.load(); } + + void setTlbFlushed(uint32_t newCounter) { + interlockedMax(lastFlushedTlbFlushCounter, newCounter); + }; + bool isTlbFlushRequired() const { + return (tlbFlushCounter.load() > lastFlushedTlbFlushCounter.load()); + }; bool isDirectSubmissionSupported(const HardwareInfo &hwInfo) const override; Drm &getDrm() const; void waitForPagingFence(); @@ -35,8 +47,9 @@ class OsContextLinux : public OsContext { protected: void initializeContext() override; + std::atomic tlbFlushCounter{0}; + std::atomic lastFlushedTlbFlushCounter{0}; unsigned int engineFlag = 0; - bool newResourceBound = false; std::vector drmContextIds; std::vector drmVmIds; Drm &drm; 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 248a31226a..5f8191764d 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 @@ -542,7 +542,7 @@ HWTEST_F(DrmDirectSubmissionTest, givenDirectSubmissionNewResourceTlbFlushWhenDi EXPECT_EQ(directSubmission.getSizeNewResourceHandler(), sizeof(PIPE_CONTROL)); } -HWTEST_F(DrmDirectSubmissionTest, givenNewResourceBoundhWhenDispatchCommandBufferThenTlbIsFlushed) { +HWTEST_F(DrmDirectSubmissionTest, givenNewResourceBoundWhenDispatchCommandBufferThenTlbIsFlushed) { using PIPE_CONTROL = typename FamilyType::PIPE_CONTROL; using Dispatcher = RenderDispatcher; @@ -554,9 +554,10 @@ HWTEST_F(DrmDirectSubmissionTest, givenNewResourceBoundhWhenDispatchCommandBuffe bool ret = directSubmission.allocateResources(); EXPECT_TRUE(ret); - osContext->setNewResourceBound(true); + osContext->setNewResourceBound(); EXPECT_EQ(directSubmission.getSizeNewResourceHandler(), sizeof(PIPE_CONTROL)); + EXPECT_TRUE(osContext->isTlbFlushRequired()); directSubmission.handleNewResourcesSubmission(); @@ -567,12 +568,12 @@ HWTEST_F(DrmDirectSubmissionTest, givenNewResourceBoundhWhenDispatchCommandBuffe auto *pipeControl = hwParse.getCommand(); EXPECT_TRUE(pipeControl->getTlbInvalidate()); EXPECT_TRUE(pipeControl->getTextureCacheInvalidationEnable()); - EXPECT_FALSE(osContext->getNewResourceBound()); + EXPECT_FALSE(osContext->isTlbFlushRequired()); - EXPECT_EQ(directSubmission.getSizeNewResourceHandler(), 0u); + EXPECT_EQ(directSubmission.getSizeNewResourceHandler(), sizeof(PIPE_CONTROL)); } -HWTEST_F(DrmDirectSubmissionTest, givenNoNewResourceBoundhWhenDispatchCommandBufferThenTlbIsNotFlushed) { +HWTEST_F(DrmDirectSubmissionTest, givenNoNewResourceBoundWhenDispatchCommandBufferThenTlbIsNotFlushed) { using PIPE_CONTROL = typename FamilyType::PIPE_CONTROL; using Dispatcher = RenderDispatcher; @@ -584,9 +585,7 @@ HWTEST_F(DrmDirectSubmissionTest, givenNoNewResourceBoundhWhenDispatchCommandBuf bool ret = directSubmission.allocateResources(); EXPECT_TRUE(ret); - osContext->setNewResourceBound(false); - - EXPECT_EQ(directSubmission.getSizeNewResourceHandler(), 0u); + EXPECT_EQ(directSubmission.getSizeNewResourceHandler(), sizeof(PIPE_CONTROL)); directSubmission.handleNewResourcesSubmission(); @@ -596,12 +595,12 @@ HWTEST_F(DrmDirectSubmissionTest, givenNoNewResourceBoundhWhenDispatchCommandBuf hwParse.findHardwareCommands(); auto *pipeControl = hwParse.getCommand(); EXPECT_EQ(pipeControl, nullptr); - EXPECT_FALSE(osContext->getNewResourceBound()); + EXPECT_FALSE(osContext->isTlbFlushRequired()); - EXPECT_EQ(directSubmission.getSizeNewResourceHandler(), 0u); + EXPECT_EQ(directSubmission.getSizeNewResourceHandler(), sizeof(PIPE_CONTROL)); } -HWTEST_F(DrmDirectSubmissionTest, givenDirectSubmissionNewResourceTlbFlusZeroAndNewResourceBoundhWhenDispatchCommandBufferThenTlbIsNotFlushed) { +HWTEST_F(DrmDirectSubmissionTest, givenDirectSubmissionNewResourceTlbFlushZeroAndNewResourceBoundWhenDispatchCommandBufferThenTlbIsNotFlushed) { using PIPE_CONTROL = typename FamilyType::PIPE_CONTROL; using Dispatcher = RenderDispatcher; @@ -613,9 +612,7 @@ HWTEST_F(DrmDirectSubmissionTest, givenDirectSubmissionNewResourceTlbFlusZeroAnd bool ret = directSubmission.allocateResources(); EXPECT_TRUE(ret); - osContext->setNewResourceBound(true); - - EXPECT_EQ(directSubmission.getSizeNewResourceHandler(), 0u); + EXPECT_EQ(directSubmission.getSizeNewResourceHandler(), sizeof(PIPE_CONTROL)); directSubmission.handleNewResourcesSubmission(); @@ -625,9 +622,9 @@ HWTEST_F(DrmDirectSubmissionTest, givenDirectSubmissionNewResourceTlbFlusZeroAnd hwParse.findHardwareCommands(); auto *pipeControl = hwParse.getCommand(); EXPECT_EQ(pipeControl, nullptr); - EXPECT_FALSE(osContext->getNewResourceBound()); + EXPECT_FALSE(osContext->isTlbFlushRequired()); - EXPECT_EQ(directSubmission.getSizeNewResourceHandler(), 0u); + EXPECT_EQ(directSubmission.getSizeNewResourceHandler(), sizeof(PIPE_CONTROL)); } HWCMDTEST_F(IGFX_XE_HP_CORE, DrmDirectSubmissionTest, givenMultipleActiveTilesWhenWaitingForTagUpdateThenQueryAllActiveTiles) { diff --git a/shared/test/unit_test/os_interface/linux/drm_residency_handler_prelim_tests.cpp b/shared/test/unit_test/os_interface/linux/drm_residency_handler_prelim_tests.cpp index 7ad1ed18f5..3901e6326f 100644 --- a/shared/test/unit_test/os_interface/linux/drm_residency_handler_prelim_tests.cpp +++ b/shared/test/unit_test/os_interface/linux/drm_residency_handler_prelim_tests.cpp @@ -105,21 +105,25 @@ struct DrmMemoryOperationsHandlerBindFixture : public ::testing::Test { using DrmMemoryOperationsHandlerBindMultiRootDeviceTest = DrmMemoryOperationsHandlerBindFixture<2u>; TEST_F(DrmMemoryOperationsHandlerBindMultiRootDeviceTest, whenSetNewResourceBoundToVMThenAllContextsUsingThatVMHasSetNewResourceBound) { + struct MockOsContextLinux : OsContextLinux { + using OsContextLinux::lastFlushedTlbFlushCounter; + }; + mock->setNewResourceBoundToVM(1u); for (const auto &engine : device->getAllEngines()) { - auto osContexLinux = static_cast(engine.osContext); + auto osContexLinux = static_cast(engine.osContext); if (osContexLinux->getDeviceBitfield().test(1u)) { - EXPECT_TRUE(osContexLinux->getNewResourceBound()); + EXPECT_TRUE(osContexLinux->isTlbFlushRequired()); } else { - EXPECT_FALSE(osContexLinux->getNewResourceBound()); + EXPECT_FALSE(osContexLinux->isTlbFlushRequired()); } - osContexLinux->setNewResourceBound(false); + osContexLinux->lastFlushedTlbFlushCounter.store(osContexLinux->peekTlbFlushCounter()); } for (const auto &engine : devices[1]->getAllEngines()) { auto osContexLinux = static_cast(engine.osContext); - EXPECT_FALSE(osContexLinux->getNewResourceBound()); + EXPECT_FALSE(osContexLinux->isTlbFlushRequired()); } auto mock2 = executionEnvironment->rootDeviceEnvironments[1u]->osInterface->getDriverModel()->as(); @@ -128,14 +132,14 @@ TEST_F(DrmMemoryOperationsHandlerBindMultiRootDeviceTest, whenSetNewResourceBoun for (const auto &engine : devices[1]->getAllEngines()) { auto osContexLinux = static_cast(engine.osContext); if (osContexLinux->getDeviceBitfield().test(0u)) { - EXPECT_TRUE(osContexLinux->getNewResourceBound()); + EXPECT_TRUE(osContexLinux->isTlbFlushRequired()); } else { - EXPECT_FALSE(osContexLinux->getNewResourceBound()); + EXPECT_FALSE(osContexLinux->isTlbFlushRequired()); } } for (const auto &engine : device->getAllEngines()) { auto osContexLinux = static_cast(engine.osContext); - EXPECT_FALSE(osContexLinux->getNewResourceBound()); + EXPECT_FALSE(osContexLinux->isTlbFlushRequired()); } }