From ad18099ed81da5173d25bc4dc717328adaa81e96 Mon Sep 17 00:00:00 2001 From: Zbigniew Zdanowicz Date: Tue, 15 Jun 2021 11:31:12 +0000 Subject: [PATCH] Enable KMD fallback for User Fence wait call Related-To: NEO-5845 Signed-off-by: Zbigniew Zdanowicz --- .../os_interface/linux/drm_command_stream.h | 4 +- .../os_interface/linux/drm_command_stream.inl | 19 ++-- .../linux/drm_command_stream_bdw_plus.inl | 2 +- .../unit_test/helpers/kmd_notify_tests.cpp | 22 ++-- .../linux/device_command_stream_fixture.h | 23 +++- .../linux/drm_command_stream_tests.cpp | 101 +++++++++++++++--- .../command_stream_receiver_hw.h | 2 +- .../command_stream_receiver_hw_base.inl | 2 +- .../debug_settings/debug_variables_base.inl | 2 +- .../source/helpers/kmd_notify_properties.cpp | 4 +- shared/source/helpers/kmd_notify_properties.h | 2 +- .../os_interface/linux/drm_buffer_object.cpp | 10 +- shared/source/os_interface/linux/drm_neo.cpp | 12 ++- shared/source/os_interface/linux/drm_neo.h | 4 +- .../source/os_interface/linux/drm_query.cpp | 2 +- .../os_interface/linux/drm_query_dg1.cpp | 2 +- 16 files changed, 154 insertions(+), 59 deletions(-) diff --git a/opencl/source/os_interface/linux/drm_command_stream.h b/opencl/source/os_interface/linux/drm_command_stream.h index 6c3b807b6c..b54386a689 100644 --- a/opencl/source/os_interface/linux/drm_command_stream.h +++ b/opencl/source/os_interface/linux/drm_command_stream.h @@ -45,7 +45,7 @@ class DrmCommandStreamReceiver : public DeviceCommandStreamReceiver { MOCKABLE_VIRTUAL void processResidency(const ResidencyContainer &allocationsForResidency, uint32_t handleId) override; void makeNonResident(GraphicsAllocation &gfxAllocation) override; bool waitForFlushStamp(FlushStamp &flushStampToWait) override; - bool isNewResidencyModelActive() override; + bool isKmdWaitModeActive() override; DrmMemoryManager *getMemoryManager() const; GmmPageTableMngr *createPageTableManager() override; @@ -71,6 +71,6 @@ class DrmCommandStreamReceiver : public DeviceCommandStreamReceiver { gemCloseWorkerMode gemCloseWorkerOperationMode; bool useUserFenceWait = false; - bool useContextForUserFenceWait = false; + bool useContextForUserFenceWait = true; }; } // namespace NEO diff --git a/opencl/source/os_interface/linux/drm_command_stream.inl b/opencl/source/os_interface/linux/drm_command_stream.inl index 793d51dc33..0c4bc2ad43 100644 --- a/opencl/source/os_interface/linux/drm_command_stream.inl +++ b/opencl/source/os_interface/linux/drm_command_stream.inl @@ -52,11 +52,13 @@ DrmCommandStreamReceiver::DrmCommandStreamReceiver(ExecutionEnvironme if (DebugManager.flags.CsrDispatchMode.get()) { this->dispatchMode = static_cast(DebugManager.flags.CsrDispatchMode.get()); } - if (DebugManager.flags.EnableUserFenceForCompletionWait.get() == 1) { - useUserFenceWait = true; + int overrideUserFenceForCompletionWait = DebugManager.flags.EnableUserFenceForCompletionWait.get(); + if (overrideUserFenceForCompletionWait != -1) { + useUserFenceWait = !!(overrideUserFenceForCompletionWait); } - if (DebugManager.flags.EnableUserFenceUseCtxId.get() == 1) { - useContextForUserFenceWait = true; + int overrideUserFenceUseCtxId = DebugManager.flags.EnableUserFenceUseCtxId.get(); + if (overrideUserFenceUseCtxId != -1) { + useContextForUserFenceWait = !!(overrideUserFenceUseCtxId); } } @@ -207,15 +209,18 @@ bool DrmCommandStreamReceiver::waitForFlushStamp(FlushStamp &flushSta if (useUserFenceWait) { waitUserFence(waitValue); } else { - this->drm->waitHandle(waitValue); + this->drm->waitHandle(waitValue, -1); } return true; } template -bool DrmCommandStreamReceiver::isNewResidencyModelActive() { - return this->drm->isVmBindAvailable(); +bool DrmCommandStreamReceiver::isKmdWaitModeActive() { + if (this->drm->isVmBindAvailable()) { + return useUserFenceWait && useContextForUserFenceWait; + } + return true; } } // namespace NEO diff --git a/opencl/source/os_interface/linux/drm_command_stream_bdw_plus.inl b/opencl/source/os_interface/linux/drm_command_stream_bdw_plus.inl index ae28c23ddd..6568f5accb 100644 --- a/opencl/source/os_interface/linux/drm_command_stream_bdw_plus.inl +++ b/opencl/source/os_interface/linux/drm_command_stream_bdw_plus.inl @@ -23,7 +23,7 @@ int DrmCommandStreamReceiver::waitUserFence(uint32_t waitValue) { if (useContextForUserFenceWait) { ctxId = static_cast(osContext)->getDrmContextIds()[0]; } - return this->drm->waitUserFence(ctxId, getTagAllocation()->getGpuAddress(), waitValue, Drm::ValueWidth::U32); + return this->drm->waitUserFence(ctxId, getTagAllocation()->getGpuAddress(), waitValue, Drm::ValueWidth::U32, -1); } } // namespace NEO diff --git a/opencl/test/unit_test/helpers/kmd_notify_tests.cpp b/opencl/test/unit_test/helpers/kmd_notify_tests.cpp index 548437b218..6a7f8218d1 100644 --- a/opencl/test/unit_test/helpers/kmd_notify_tests.cpp +++ b/opencl/test/unit_test/helpers/kmd_notify_tests.cpp @@ -298,7 +298,7 @@ TEST_F(KmdNotifyTests, givenTaskCountDiffLowerThanMinimumToCheckAcLineWhenObtain EXPECT_EQ(10u, KmdNotifyConstants::minimumTaskCountDiffToCheckAcLine); int64_t timeout = 0; - helper.obtainTimeoutParams(timeout, false, hwTag, taskCountToWait, 1, false, false); + helper.obtainTimeoutParams(timeout, false, hwTag, taskCountToWait, 1, false, true); EXPECT_EQ(0u, helper.updateAcLineStatusCalled); } @@ -313,16 +313,16 @@ TEST_F(KmdNotifyTests, givenTaskCountDiffGreaterThanMinimumToCheckAcLineAndDisab EXPECT_EQ(10u, KmdNotifyConstants::minimumTaskCountDiffToCheckAcLine); int64_t timeout = 0; - helper.obtainTimeoutParams(timeout, false, hwTag, taskCountToWait, 1, false, false); + helper.obtainTimeoutParams(timeout, false, hwTag, taskCountToWait, 1, false, true); EXPECT_EQ(1u, helper.updateAcLineStatusCalled); } -TEST_F(KmdNotifyTests, givenNewResidencyModelAvailableWhenObtainTimeoutParamsThenFalseIsReturned) { +TEST_F(KmdNotifyTests, givenKmdWaitModeNotActiveWhenObtainTimeoutParamsThenFalseIsReturned) { MockKmdNotifyHelper helper(&(hwInfo->capabilityTable.kmdNotifyProperties)); int64_t timeout = 0; - auto enableTimeout = helper.obtainTimeoutParams(timeout, false, 1, 1, 1, false, true); + auto enableTimeout = helper.obtainTimeoutParams(timeout, false, 1, 1, 1, false, false); EXPECT_FALSE(enableTimeout); EXPECT_FALSE(timeout); @@ -338,7 +338,7 @@ TEST_F(KmdNotifyTests, givenTaskCountDiffGreaterThanMinimumToCheckAcLineAndEnabl EXPECT_EQ(10u, KmdNotifyConstants::minimumTaskCountDiffToCheckAcLine); int64_t timeout = 0; - helper.obtainTimeoutParams(timeout, false, hwTag, taskCountToWait, 1, false, false); + helper.obtainTimeoutParams(timeout, false, hwTag, taskCountToWait, 1, false, true); EXPECT_EQ(0u, helper.updateAcLineStatusCalled); } @@ -349,7 +349,7 @@ TEST_F(KmdNotifyTests, givenDisabledKmdNotifyMechanismWhenAcLineIsDisconnectedTh helper.acLineConnected = false; int64_t timeout = 0; - bool timeoutEnabled = helper.obtainTimeoutParams(timeout, false, 1, 2, 2, false, false); + bool timeoutEnabled = helper.obtainTimeoutParams(timeout, false, 1, 2, 2, false, true); EXPECT_TRUE(timeoutEnabled); EXPECT_EQ(KmdNotifyConstants::timeoutInMicrosecondsForDisconnectedAcLine, timeout); @@ -363,7 +363,7 @@ TEST_F(KmdNotifyTests, givenEnabledKmdNotifyMechanismWhenAcLineIsDisconnectedThe helper.acLineConnected = false; int64_t timeout = 0; - bool timeoutEnabled = helper.obtainTimeoutParams(timeout, false, 1, 2, 2, false, false); + bool timeoutEnabled = helper.obtainTimeoutParams(timeout, false, 1, 2, 2, false, true); EXPECT_TRUE(timeoutEnabled); EXPECT_EQ(hwInfo->capabilityTable.kmdNotifyProperties.delayKmdNotifyMicroseconds, timeout); @@ -376,7 +376,7 @@ TEST_F(KmdNotifyTests, givenDisabledKmdNotifyMechanismAndFlushStampIsZeroWhenAcL int64_t timeout = 0; FlushStamp flushStampToWait = 0; - bool timeoutEnabled = helper.obtainTimeoutParams(timeout, false, 1, 2, flushStampToWait, false, false); + bool timeoutEnabled = helper.obtainTimeoutParams(timeout, false, 1, 2, flushStampToWait, false, true); EXPECT_FALSE(timeoutEnabled); } @@ -390,7 +390,7 @@ TEST_F(KmdNotifyTests, givenDisabledKmdNotifyMechanismWhenPowerSavingModeIsSetTh int64_t timeout = 0; FlushStamp flushStampToWait = 1; - bool timeoutEnabled = helper.obtainTimeoutParams(timeout, false, 1, 2, flushStampToWait, false, false); + bool timeoutEnabled = helper.obtainTimeoutParams(timeout, false, 1, 2, flushStampToWait, false, true); EXPECT_TRUE(timeoutEnabled); EXPECT_EQ(1, timeout); } @@ -401,7 +401,7 @@ TEST_F(KmdNotifyTests, givenDisabledKmdNotifyMechanismWhenPowerSavingModeIsReque int64_t timeout = 0; FlushStamp flushStampToWait = 1; - bool timeoutEnabled = helper.obtainTimeoutParams(timeout, false, 1, 2, flushStampToWait, true, false); + bool timeoutEnabled = helper.obtainTimeoutParams(timeout, false, 1, 2, flushStampToWait, true, true); EXPECT_TRUE(timeoutEnabled); EXPECT_EQ(1, timeout); } @@ -415,7 +415,7 @@ TEST_F(KmdNotifyTests, givenEnabledKmdNotifyMechanismWhenPowerSavingModeIsSetAnd int64_t timeout = 0; FlushStamp flushStampToWait = 0; - bool timeoutEnabled = helper.obtainTimeoutParams(timeout, false, 1, 2, flushStampToWait, false, false); + bool timeoutEnabled = helper.obtainTimeoutParams(timeout, false, 1, 2, flushStampToWait, false, true); EXPECT_FALSE(timeoutEnabled); EXPECT_EQ(0, timeout); } diff --git a/opencl/test/unit_test/os_interface/linux/device_command_stream_fixture.h b/opencl/test/unit_test/os_interface/linux/device_command_stream_fixture.h index c27a54ec18..475c651690 100644 --- a/opencl/test/unit_test/os_interface/linux/device_command_stream_fixture.h +++ b/opencl/test/unit_test/os_interface/linux/device_command_stream_fixture.h @@ -356,18 +356,37 @@ class DrmMockCustom : public Drm { uint64_t value = 0u; uint32_t ctxId = 0u; ValueWidth dataWidth = ValueWidth::U8; + int64_t timeout = 0; uint32_t called = 0u; }; WaitUserFenceCall waitUserFenceCall{}; - int waitUserFence(uint32_t ctxId, uint64_t address, uint64_t value, ValueWidth dataWidth) override { + int waitUserFence(uint32_t ctxId, uint64_t address, uint64_t value, ValueWidth dataWidth, int64_t timeout) override { waitUserFenceCall.called++; waitUserFenceCall.ctxId = ctxId; waitUserFenceCall.address = address; waitUserFenceCall.dataWidth = dataWidth; waitUserFenceCall.value = value; - return Drm::waitUserFence(ctxId, address, value, dataWidth); + waitUserFenceCall.timeout = timeout; + return Drm::waitUserFence(ctxId, address, value, dataWidth, timeout); + } + + struct IsVmBindAvailableCall { + bool callParent = true; + bool returnValue = true; + uint32_t called = 0u; + }; + + IsVmBindAvailableCall isVmBindAvailableCall{}; + + bool isVmBindAvailable() override { + isVmBindAvailableCall.called++; + if (isVmBindAvailableCall.callParent) { + return Drm::isVmBindAvailable(); + } else { + return isVmBindAvailableCall.returnValue; + } } }; diff --git a/opencl/test/unit_test/os_interface/linux/drm_command_stream_tests.cpp b/opencl/test/unit_test/os_interface/linux/drm_command_stream_tests.cpp index 11648f1c2f..f588874322 100644 --- a/opencl/test/unit_test/os_interface/linux/drm_command_stream_tests.cpp +++ b/opencl/test/unit_test/os_interface/linux/drm_command_stream_tests.cpp @@ -1691,32 +1691,26 @@ HWTEST_TEMPLATED_F(DrmCommandStreamEnhancedTest, givenWaitUserFenceFlagSetWhenDr mm->freeGraphicsMemory(commandBuffer); } -HWTEST_TEMPLATED_F(DrmCommandStreamEnhancedTest, givenWaitUserFenceFlagSetWhenDrmCsrThenExpectUseDrmWaitUserFenceCallWithZeroContext) { - DebugManagerStateRestore restorer; - DebugManager.flags.EnableUserFenceForCompletionWait.set(1); - +HWTEST_TEMPLATED_F(DrmCommandStreamEnhancedTest, givenWaitUserFenceFlagNotSetWhenDrmCsrWaitsForFlushStampThenExpectUseDrmGemWaitCall) { TestedDrmCommandStreamReceiver *testedCsr = new TestedDrmCommandStreamReceiver(gemCloseWorkerMode::gemCloseWorkerInactive, *this->executionEnvironment, 1); - EXPECT_TRUE(testedCsr->useUserFenceWait); - EXPECT_FALSE(testedCsr->useContextForUserFenceWait); + EXPECT_FALSE(testedCsr->useUserFenceWait); + EXPECT_TRUE(testedCsr->useContextForUserFenceWait); device->resetCommandStreamReceiver(testedCsr); + mock->ioctl_cnt.gemWait = 0; FlushStamp handleToWait = 123; testedCsr->waitForFlushStamp(handleToWait); - EXPECT_EQ(1u, testedCsr->waitUserFenceResult.called); - EXPECT_EQ(123u, testedCsr->waitUserFenceResult.waitValue); - EXPECT_EQ(0u, mock->waitUserFenceCall.ctxId); - EXPECT_EQ(1u, mock->waitUserFenceCall.called); - EXPECT_EQ(Drm::ValueWidth::U32, mock->waitUserFenceCall.dataWidth); + EXPECT_EQ(1, mock->ioctl_cnt.gemWait); + EXPECT_EQ(0u, testedCsr->waitUserFenceResult.called); } -HWTEST_TEMPLATED_F(DrmCommandStreamEnhancedTest, givenWaitUserFenceAndUseCtxFlagsSetWhenDrmCsrThenExpectUseDrmWaitUserFenceCallWithNonZeroContext) { +HWTEST_TEMPLATED_F(DrmCommandStreamEnhancedTest, givenWaitUserFenceFlagSetWhenDrmCsrWaitsForFlushStampThenExpectUseDrmWaitUserFenceCallWithNonZeroContext) { DebugManagerStateRestore restorer; DebugManager.flags.EnableUserFenceForCompletionWait.set(1); - DebugManager.flags.EnableUserFenceUseCtxId.set(1); TestedDrmCommandStreamReceiver *testedCsr = new TestedDrmCommandStreamReceiver(gemCloseWorkerMode::gemCloseWorkerInactive, @@ -1725,6 +1719,7 @@ HWTEST_TEMPLATED_F(DrmCommandStreamEnhancedTest, givenWaitUserFenceAndUseCtxFlag EXPECT_TRUE(testedCsr->useUserFenceWait); EXPECT_TRUE(testedCsr->useContextForUserFenceWait); device->resetCommandStreamReceiver(testedCsr); + mock->ioctl_cnt.gemWait = 0; auto osContextLinux = static_cast(device->getDefaultEngine().osContext); std::vector &drmCtxIds = const_cast &>(osContextLinux->getDrmContextIds()); @@ -1736,9 +1731,87 @@ HWTEST_TEMPLATED_F(DrmCommandStreamEnhancedTest, givenWaitUserFenceAndUseCtxFlag FlushStamp handleToWait = 123; testedCsr->waitForFlushStamp(handleToWait); + EXPECT_EQ(0, mock->ioctl_cnt.gemWait); EXPECT_EQ(1u, testedCsr->waitUserFenceResult.called); EXPECT_EQ(123u, testedCsr->waitUserFenceResult.waitValue); - EXPECT_NE(0u, mock->waitUserFenceCall.ctxId); + EXPECT_EQ(1u, mock->waitUserFenceCall.called); + + EXPECT_NE(0u, mock->waitUserFenceCall.ctxId); + EXPECT_EQ(-1, mock->waitUserFenceCall.timeout); EXPECT_EQ(Drm::ValueWidth::U32, mock->waitUserFenceCall.dataWidth); } + +HWTEST_TEMPLATED_F(DrmCommandStreamEnhancedTest, givenWaitUserFenceSetAndUseCtxFlagsNotSetWhenDrmCsrWaitsForFlushStampThenExpectUseDrmWaitUserFenceCallWithZeroContext) { + DebugManagerStateRestore restorer; + DebugManager.flags.EnableUserFenceForCompletionWait.set(1); + DebugManager.flags.EnableUserFenceUseCtxId.set(0); + + TestedDrmCommandStreamReceiver *testedCsr = + new TestedDrmCommandStreamReceiver(gemCloseWorkerMode::gemCloseWorkerInactive, + *this->executionEnvironment, + 1); + EXPECT_TRUE(testedCsr->useUserFenceWait); + EXPECT_FALSE(testedCsr->useContextForUserFenceWait); + device->resetCommandStreamReceiver(testedCsr); + mock->ioctl_cnt.gemWait = 0; + + FlushStamp handleToWait = 123; + testedCsr->waitForFlushStamp(handleToWait); + + EXPECT_EQ(0, mock->ioctl_cnt.gemWait); + EXPECT_EQ(1u, testedCsr->waitUserFenceResult.called); + EXPECT_EQ(123u, testedCsr->waitUserFenceResult.waitValue); + + EXPECT_EQ(1u, mock->waitUserFenceCall.called); + + EXPECT_EQ(0u, mock->waitUserFenceCall.ctxId); + EXPECT_EQ(-1, mock->waitUserFenceCall.timeout); + EXPECT_EQ(Drm::ValueWidth::U32, mock->waitUserFenceCall.dataWidth); +} + +HWTEST_TEMPLATED_F(DrmCommandStreamEnhancedTest, givenVmBindNotAvailableWhenCheckingForKmdWaitModeActiveThenReturnTrue) { + auto testDrmCsr = static_cast *>(csr); + mock->isVmBindAvailableCall.called = 0u; + mock->isVmBindAvailableCall.callParent = false; + mock->isVmBindAvailableCall.returnValue = false; + + EXPECT_TRUE(testDrmCsr->isKmdWaitModeActive()); + EXPECT_EQ(1u, mock->isVmBindAvailableCall.called); +} + +HWTEST_TEMPLATED_F(DrmCommandStreamEnhancedTest, givenVmBindAvailableUseWaitCallAndUseContextIdTrueWhenCheckingForKmdWaitModeActiveThenReturnTrue) { + auto testDrmCsr = static_cast *>(csr); + mock->isVmBindAvailableCall.called = 0u; + mock->isVmBindAvailableCall.callParent = false; + mock->isVmBindAvailableCall.returnValue = true; + testDrmCsr->useUserFenceWait = true; + testDrmCsr->useContextForUserFenceWait = true; + + EXPECT_TRUE(testDrmCsr->isKmdWaitModeActive()); + EXPECT_EQ(1u, mock->isVmBindAvailableCall.called); +} + +HWTEST_TEMPLATED_F(DrmCommandStreamEnhancedTest, givenVmBindAvailableUseWaitCallFalseAndUseContextIdTrueWhenCheckingForKmdWaitModeActiveThenReturnFalse) { + auto testDrmCsr = static_cast *>(csr); + mock->isVmBindAvailableCall.called = 0u; + mock->isVmBindAvailableCall.callParent = false; + mock->isVmBindAvailableCall.returnValue = true; + testDrmCsr->useUserFenceWait = false; + testDrmCsr->useContextForUserFenceWait = true; + + EXPECT_FALSE(testDrmCsr->isKmdWaitModeActive()); + EXPECT_EQ(1u, mock->isVmBindAvailableCall.called); +} + +HWTEST_TEMPLATED_F(DrmCommandStreamEnhancedTest, givenVmBindAvailableUseWaitCallTrueAndUseContextIdFalseWhenCheckingForKmdWaitModeActiveThenReturnFalse) { + auto testDrmCsr = static_cast *>(csr); + mock->isVmBindAvailableCall.called = 0u; + mock->isVmBindAvailableCall.callParent = false; + mock->isVmBindAvailableCall.returnValue = true; + testDrmCsr->useUserFenceWait = true; + testDrmCsr->useContextForUserFenceWait = false; + + EXPECT_FALSE(testDrmCsr->isKmdWaitModeActive()); + EXPECT_EQ(1u, mock->isVmBindAvailableCall.called); +} diff --git a/shared/source/command_stream/command_stream_receiver_hw.h b/shared/source/command_stream/command_stream_receiver_hw.h index 21e01d7f86..bd062a296c 100644 --- a/shared/source/command_stream/command_stream_receiver_hw.h +++ b/shared/source/command_stream/command_stream_receiver_hw.h @@ -118,7 +118,7 @@ class CommandStreamReceiverHw : public CommandStreamReceiver { return blitterDirectSubmission.get() != nullptr; } - virtual bool isNewResidencyModelActive() { return false; } + virtual bool isKmdWaitModeActive() { return true; } bool initDirectSubmission(Device &device, OsContext &osContext) override; GraphicsAllocation *getClearColorAllocation() override; diff --git a/shared/source/command_stream/command_stream_receiver_hw_base.inl b/shared/source/command_stream/command_stream_receiver_hw_base.inl index e2b1d00772..399164f57e 100644 --- a/shared/source/command_stream/command_stream_receiver_hw_base.inl +++ b/shared/source/command_stream/command_stream_receiver_hw_base.inl @@ -843,7 +843,7 @@ inline void CommandStreamReceiverHw::waitForTaskCountWithKmdNotifyFal int64_t waitTimeout = 0; bool enableTimeout = false; - enableTimeout = kmdNotifyHelper->obtainTimeoutParams(waitTimeout, useQuickKmdSleep, *getTagAddress(), taskCountToWait, flushStampToWait, forcePowerSavingMode, this->isNewResidencyModelActive()); + enableTimeout = kmdNotifyHelper->obtainTimeoutParams(waitTimeout, useQuickKmdSleep, *getTagAddress(), taskCountToWait, flushStampToWait, forcePowerSavingMode, this->isKmdWaitModeActive()); PRINT_DEBUG_STRING(DebugManager.flags.LogWaitingForCompletion.get(), stdout, "\nWaiting for task count %u at location %p. Current value: %u\n", diff --git a/shared/source/debug_settings/debug_variables_base.inl b/shared/source/debug_settings/debug_variables_base.inl index 954079bbf3..568a7e4edc 100644 --- a/shared/source/debug_settings/debug_variables_base.inl +++ b/shared/source/debug_settings/debug_variables_base.inl @@ -232,7 +232,7 @@ DECLARE_DEBUG_VARIABLE(int32_t, WaitLoopCount, -1, "-1: use default, >=0: number DECLARE_DEBUG_VARIABLE(int32_t, GTPinAllocateBufferInSharedMemory, -1, "Force GTPin to allocate buffer in shared memory") DECLARE_DEBUG_VARIABLE(int32_t, AlignLocalMemoryVaTo2MB, -1, "Allow 2MB pages for allocations with size>=2MB. On Linux it means aligned VA, on Windows it means aligned size. -1: default, 0: disabled, 1: enabled") DECLARE_DEBUG_VARIABLE(int32_t, EnableUserFenceForCompletionWait, -1, "-1: default (disabled), 0: disable, 1: enable : Use Wait User Fence instead Gem Wait") -DECLARE_DEBUG_VARIABLE(int32_t, EnableUserFenceUseCtxId, -1, "-1: default (disabled), 0: disable, 1: enable : Use Context Id in Wait User Fence when waiting for completion tag") +DECLARE_DEBUG_VARIABLE(int32_t, EnableUserFenceUseCtxId, -1, "-1: default (enabled), 0: disable, 1: enable : Use Context Id in Wait User Fence when waiting for completion tag") /*EXPERIMENTAL TOGGLES*/ DECLARE_DEBUG_VARIABLE(int32_t, ExperimentalEnableCustomLocalMemoryAlignment, 0, "Align local memory allocations to a given value. Works only with allocations at least as big as the value. 0: no effect, 2097152: 2 megabytes, 1073741824: 1 gigabyte") diff --git a/shared/source/helpers/kmd_notify_properties.cpp b/shared/source/helpers/kmd_notify_properties.cpp index a4791bb55d..373c70777f 100644 --- a/shared/source/helpers/kmd_notify_properties.cpp +++ b/shared/source/helpers/kmd_notify_properties.cpp @@ -19,12 +19,12 @@ bool KmdNotifyHelper::obtainTimeoutParams(int64_t &timeoutValueOutput, uint32_t taskCountToWait, FlushStamp flushStampToWait, bool forcePowerSavingMode, - bool newResidencyModelActive) { + bool kmdWaitModeActive) { if (flushStampToWait == 0) { return false; } - if (newResidencyModelActive) { + if (!kmdWaitModeActive) { return false; } diff --git a/shared/source/helpers/kmd_notify_properties.h b/shared/source/helpers/kmd_notify_properties.h index 9d3e636bc6..7e8c55a09d 100644 --- a/shared/source/helpers/kmd_notify_properties.h +++ b/shared/source/helpers/kmd_notify_properties.h @@ -42,7 +42,7 @@ class KmdNotifyHelper { uint32_t taskCountToWait, FlushStamp flushStampToWait, bool forcePowerSavingMode, - bool newResidencyModelActive); + bool kmdWaitModeActive); bool quickKmdSleepForSporadicWaitsEnabled() const { return properties->enableQuickKmdSleepForSporadicWaits; } MOCKABLE_VIRTUAL void updateLastWaitForCompletionTimestamp(); diff --git a/shared/source/os_interface/linux/drm_buffer_object.cpp b/shared/source/os_interface/linux/drm_buffer_object.cpp index 6fdc939b1e..5ee9df7cd7 100644 --- a/shared/source/os_interface/linux/drm_buffer_object.cpp +++ b/shared/source/os_interface/linux/drm_buffer_object.cpp @@ -76,15 +76,7 @@ int BufferObject::wait(int64_t timeoutNs) { return 0; } - drm_i915_gem_wait wait = {}; - wait.bo_handle = this->handle; - wait.timeout_ns = -1; - - int ret = this->drm->ioctl(DRM_IOCTL_I915_GEM_WAIT, &wait); - if (ret != 0) { - int err = errno; - PRINT_DEBUG_STRING(DebugManager.flags.PrintDebugMessages.get(), stderr, "ioctl(I915_GEM_WAIT) failed with %d. errno=%d(%s)\n", ret, err, strerror(err)); - } + int ret = this->drm->waitHandle(this->handle, -1); UNRECOVERABLE_IF(ret != 0); return ret; diff --git a/shared/source/os_interface/linux/drm_neo.cpp b/shared/source/os_interface/linux/drm_neo.cpp index 961785e9f8..ff11ea9aa9 100644 --- a/shared/source/os_interface/linux/drm_neo.cpp +++ b/shared/source/os_interface/linux/drm_neo.cpp @@ -743,12 +743,18 @@ const std::vector &Drm::getSliceMappings(uint32_t deviceIndex) { return topologyMap[deviceIndex].sliceIndices; } -int Drm::waitHandle(uint32_t waitHandle) { +int Drm::waitHandle(uint32_t waitHandle, int64_t timeout) { drm_i915_gem_wait wait = {}; wait.bo_handle = waitHandle; - wait.timeout_ns = -1; + wait.timeout_ns = timeout; - return ioctl(DRM_IOCTL_I915_GEM_WAIT, &wait); + int ret = ioctl(DRM_IOCTL_I915_GEM_WAIT, &wait); + if (ret != 0) { + int err = errno; + PRINT_DEBUG_STRING(DebugManager.flags.PrintDebugMessages.get(), stderr, "ioctl(I915_GEM_WAIT) failed with %d. errno=%d(%s)\n", ret, err, strerror(err)); + } + + return ret; } } // namespace NEO diff --git a/shared/source/os_interface/linux/drm_neo.h b/shared/source/os_interface/linux/drm_neo.h index 5dc49e3b8c..ce7b6fd903 100644 --- a/shared/source/os_interface/linux/drm_neo.h +++ b/shared/source/os_interface/linux/drm_neo.h @@ -204,14 +204,14 @@ class Drm : public DriverModel { uint64_t getNextFenceVal(uint32_t vmHandleId) { return ++fenceVal[vmHandleId]; } uint64_t *getFenceAddr(uint32_t vmHandleId) { return &pagingFence[vmHandleId]; } - int waitHandle(uint32_t waitHandle); + int waitHandle(uint32_t waitHandle, int64_t timeout); enum class ValueWidth : uint32_t { U8, U16, U32, U64 }; - MOCKABLE_VIRTUAL int waitUserFence(uint32_t ctxId, uint64_t address, uint64_t value, ValueWidth dataWidth); + MOCKABLE_VIRTUAL int waitUserFence(uint32_t ctxId, uint64_t address, uint64_t value, ValueWidth dataWidth, int64_t timeout); void setNewResourceBound(bool value) { this->newResourceBound = value; }; bool getNewResourceBound() { return this->newResourceBound; }; diff --git a/shared/source/os_interface/linux/drm_query.cpp b/shared/source/os_interface/linux/drm_query.cpp index 0bb11f98bd..14f72495f1 100644 --- a/shared/source/os_interface/linux/drm_query.cpp +++ b/shared/source/os_interface/linux/drm_query.cpp @@ -75,7 +75,7 @@ int Drm::unbindBufferObject(OsContext *osContext, uint32_t vmHandleId, BufferObj void Drm::waitForBind(uint32_t vmHandleId) { } -int Drm::waitUserFence(uint32_t ctx, uint64_t address, uint64_t value, ValueWidth dataWidth) { +int Drm::waitUserFence(uint32_t ctx, uint64_t address, uint64_t value, ValueWidth dataWidth, int64_t timeout) { return 0; } diff --git a/shared/source/os_interface/linux/drm_query_dg1.cpp b/shared/source/os_interface/linux/drm_query_dg1.cpp index 06455a8b4f..f580b64c81 100644 --- a/shared/source/os_interface/linux/drm_query_dg1.cpp +++ b/shared/source/os_interface/linux/drm_query_dg1.cpp @@ -84,7 +84,7 @@ int Drm::unbindBufferObject(OsContext *osContext, uint32_t vmHandleId, BufferObj void Drm::waitForBind(uint32_t vmHandleId) { } -int Drm::waitUserFence(uint32_t ctx, uint64_t address, uint64_t value, ValueWidth dataWidth) { +int Drm::waitUserFence(uint32_t ctx, uint64_t address, uint64_t value, ValueWidth dataWidth, int64_t timeout) { return 0; }