diff --git a/level_zero/core/source/gfx_core_helpers/l0_gfx_core_helper.h b/level_zero/core/source/gfx_core_helpers/l0_gfx_core_helper.h index 2cee21978c..08a2124b2f 100644 --- a/level_zero/core/source/gfx_core_helpers/l0_gfx_core_helper.h +++ b/level_zero/core/source/gfx_core_helpers/l0_gfx_core_helper.h @@ -87,6 +87,7 @@ class L0GfxCoreHelper : public NEO::ApiGfxCoreHelper { virtual void getAttentionBitmaskForSingleThreads(const std::vector &threads, const NEO::HardwareInfo &hwInfo, std::unique_ptr &bitmask, size_t &bitmaskSize) const = 0; virtual std::vector getThreadsFromAttentionBitmask(const NEO::HardwareInfo &hwInfo, uint32_t tile, const uint8_t *bitmask, const size_t bitmaskSize) const = 0; + virtual bool threadResumeRequiresUnlock() const = 0; virtual bool alwaysAllocateEventInLocalMem() const = 0; virtual bool platformSupportsCmdListHeapSharing() const = 0; virtual bool platformSupportsStateComputeModeTracking() const = 0; @@ -137,6 +138,7 @@ class L0GfxCoreHelperHw : public L0GfxCoreHelper { bool forceDefaultUsmCompressionSupport() const override; void getAttentionBitmaskForSingleThreads(const std::vector &threads, const NEO::HardwareInfo &hwInfo, std::unique_ptr &bitmask, size_t &bitmaskSize) const override; std::vector getThreadsFromAttentionBitmask(const NEO::HardwareInfo &hwInfo, uint32_t tile, const uint8_t *bitmask, const size_t bitmaskSize) const override; + bool threadResumeRequiresUnlock() const override; bool alwaysAllocateEventInLocalMem() const override; bool platformSupportsCmdListHeapSharing() const override; bool platformSupportsStateComputeModeTracking() const override; diff --git a/level_zero/core/source/gfx_core_helpers/l0_gfx_core_helper_base.inl b/level_zero/core/source/gfx_core_helpers/l0_gfx_core_helper_base.inl index d694949f6a..4b1d0d70fb 100644 --- a/level_zero/core/source/gfx_core_helpers/l0_gfx_core_helper_base.inl +++ b/level_zero/core/source/gfx_core_helpers/l0_gfx_core_helper_base.inl @@ -79,4 +79,9 @@ std::unique_ptr L0GfxCoreHelperHw::getInOrderTime return std::make_unique>(rootDeviceIndices, memoryManager, initialTagCount, tagAlignment, size, false, false, deviceBitfield); } +template +bool L0GfxCoreHelperHw::threadResumeRequiresUnlock() const { + return false; +} + } // namespace L0 diff --git a/level_zero/core/test/unit_tests/xe2_hpg_core/test_l0_gfx_core_helper_xe2_hpg_core.cpp b/level_zero/core/test/unit_tests/xe2_hpg_core/test_l0_gfx_core_helper_xe2_hpg_core.cpp index cba1626e2f..b72a514982 100644 --- a/level_zero/core/test/unit_tests/xe2_hpg_core/test_l0_gfx_core_helper_xe2_hpg_core.cpp +++ b/level_zero/core/test/unit_tests/xe2_hpg_core/test_l0_gfx_core_helper_xe2_hpg_core.cpp @@ -122,6 +122,11 @@ XE2_HPG_CORETEST_F(L0GfxCoreHelperTestXe2Hpg, GivenXe2HpgWhenGettingCmdlistUpdat EXPECT_EQ(63u, l0GfxCoreHelper.getPlatformCmdListUpdateCapabilities()); } +XE2_HPG_CORETEST_F(L0GfxCoreHelperTestXe2Hpg, GivenXe2HpgWhenCallingThreadResumeRequiresUnlockThenReturnFalse) { + const auto &l0GfxCoreHelper = getHelper(); + EXPECT_FALSE(l0GfxCoreHelper.threadResumeRequiresUnlock()); +} + XE2_HPG_CORETEST_F(L0GfxCoreHelperTestXe2Hpg, GivenXe2HpgWhenCheckingL0HelperForDeletingIpSamplingEntryWithNullValuesThenMapRemainstheSameSize) { auto &l0GfxCoreHelper = getHelper(); std::map stallSumIpDataMap; diff --git a/level_zero/tools/source/debug/linux/xe/debug_session.cpp b/level_zero/tools/source/debug/linux/xe/debug_session.cpp index 5d27f26f9b..285f47c9ca 100644 --- a/level_zero/tools/source/debug/linux/xe/debug_session.cpp +++ b/level_zero/tools/source/debug/linux/xe/debug_session.cpp @@ -718,7 +718,6 @@ int DebugSessionLinuxXe::threadControlResume(const std::vector bitmask; size_t bitmaskSize = 0; @@ -733,15 +732,23 @@ int DebugSessionLinuxXe::threadControlResume(const std::vector(euControl.cmd), static_cast(euControl.exec_queue_handle), - static_cast(euControl.lrc_handle)); - } else { - PRINT_DEBUGGER_INFO_LOG("DRM_XE_EUDEBUG_IOCTL_EU_CONTROL: seqno = %llu command = %u\n", static_cast(euControl.seqno), static_cast(euControl.cmd)); + auto invokeIoctl = [&](int cmd) { + euControl.cmd = cmd; + euControlRetVal = ioctl(DRM_XE_EUDEBUG_IOCTL_EU_CONTROL, &euControl); + if (euControlRetVal != 0) { + PRINT_DEBUGGER_ERROR_LOG("DRM_XE_EUDEBUG_IOCTL_EU_CONTROL failed: retCode: %d errno = %d command = %d, execQueueHandle = %llu lrcHandle = %llu\n", + euControlRetVal, errno, static_cast(euControl.cmd), static_cast(euControl.exec_queue_handle), + static_cast(euControl.lrc_handle)); + } else { + PRINT_DEBUGGER_INFO_LOG("DRM_XE_EUDEBUG_IOCTL_EU_CONTROL: seqno = %llu command = %u\n", static_cast(euControl.seqno), static_cast(euControl.cmd)); + } + }; + + if (l0GfxCoreHelper.threadResumeRequiresUnlock()) { + invokeIoctl(getEuControlCmdUnlock()); } + invokeIoctl(DRM_XE_EUDEBUG_EU_CONTROL_CMD_RESUME); return euControlRetVal; } diff --git a/level_zero/tools/source/debug/linux/xe/debug_session.h b/level_zero/tools/source/debug/linux/xe/debug_session.h index 054f949c17..e74f2f2a5a 100644 --- a/level_zero/tools/source/debug/linux/xe/debug_session.h +++ b/level_zero/tools/source/debug/linux/xe/debug_session.h @@ -71,6 +71,7 @@ struct DebugSessionLinuxXe : DebugSessionLinux { bool handleMetadataOpEvent(drm_xe_eudebug_event_vm_bind_op_metadata *vmBindOpMetadata); void updateContextAndLrcHandlesForThreadsWithAttention(EuThread::ThreadId threadId, AttentionEventFields &attention) override; int eventAckIoctl(EventToAck &event) override; + MOCKABLE_VIRTUAL int getEuControlCmdUnlock() const; Module &getModule(uint64_t moduleHandle) override { auto connection = clientHandleToConnection[clientHandle].get(); DEBUG_BREAK_IF(connection->metaDataToModule.find(moduleHandle) == connection->metaDataToModule.end()); diff --git a/level_zero/tools/source/debug/linux/xe/handle_event_helper.cpp b/level_zero/tools/source/debug/linux/xe/handle_event_helper.cpp index 7693b7e800..093bb82ca7 100644 --- a/level_zero/tools/source/debug/linux/xe/handle_event_helper.cpp +++ b/level_zero/tools/source/debug/linux/xe/handle_event_helper.cpp @@ -19,4 +19,8 @@ bool DebugSessionLinuxXe::eventTypeIsAttention(uint16_t eventType) { return (eventType == DRM_XE_EUDEBUG_EVENT_EU_ATTENTION); } +int DebugSessionLinuxXe::getEuControlCmdUnlock() const { + return -1; +} + } // namespace L0 \ No newline at end of file diff --git a/level_zero/tools/test/unit_tests/sources/debug/linux/xe/debug_session_fixtures_linux_xe.h b/level_zero/tools/test/unit_tests/sources/debug/linux/xe/debug_session_fixtures_linux_xe.h index 33e482aacc..e91e8229ca 100644 --- a/level_zero/tools/test/unit_tests/sources/debug/linux/xe/debug_session_fixtures_linux_xe.h +++ b/level_zero/tools/test/unit_tests/sources/debug/linux/xe/debug_session_fixtures_linux_xe.h @@ -166,6 +166,7 @@ struct MockDebugSessionLinuxXe : public L0::DebugSessionLinuxXe { using L0::DebugSessionLinuxXe::debugArea; using L0::DebugSessionLinuxXe::euControlInterruptSeqno; using L0::DebugSessionLinuxXe::eventTypeIsAttention; + using L0::DebugSessionLinuxXe::getEuControlCmdUnlock; using L0::DebugSessionLinuxXe::getThreadStateMutexForTileSession; using L0::DebugSessionLinuxXe::getVmHandleFromClientAndlrcHandle; using L0::DebugSessionLinuxXe::handleEvent; diff --git a/level_zero/tools/test/unit_tests/sources/debug/linux/xe/test_debug_api_linux_xe.cpp b/level_zero/tools/test/unit_tests/sources/debug/linux/xe/test_debug_api_linux_xe.cpp index 15160eb9f7..c76b619e50 100644 --- a/level_zero/tools/test/unit_tests/sources/debug/linux/xe/test_debug_api_linux_xe.cpp +++ b/level_zero/tools/test/unit_tests/sources/debug/linux/xe/test_debug_api_linux_xe.cpp @@ -1787,13 +1787,23 @@ TEST_F(DebugApiLinuxTestXe, GivenErrorFromIoctlWhenCallingThreadControlThenThrea EXPECT_EQ(4, handler->ioctlCalled); + auto &l0GfxCoreHelper = neoDevice->getRootDeviceEnvironment().getHelper(); + result = sessionMock->threadControl(threads, 0, MockDebugSessionLinuxXe::ThreadControlCmd::resume, bitmaskOut, bitmaskSizeOut); EXPECT_NE(0, result); - EXPECT_EQ(5, handler->ioctlCalled); + if (l0GfxCoreHelper.threadResumeRequiresUnlock()) { + EXPECT_EQ(6, handler->ioctlCalled); + } else { + EXPECT_EQ(5, handler->ioctlCalled); + } result = sessionMock->threadControl(threads, 0, MockDebugSessionLinuxXe::ThreadControlCmd::stopped, bitmaskOut, bitmaskSizeOut); EXPECT_NE(0, result); - EXPECT_EQ(9, handler->ioctlCalled); + if (l0GfxCoreHelper.threadResumeRequiresUnlock()) { + EXPECT_EQ(10, handler->ioctlCalled); + } else { + EXPECT_EQ(9, handler->ioctlCalled); + } } TEST_F(DebugApiLinuxTestXe, GivenSuccessFromIoctlWhenCallingThreadControlForInterruptAllThenSequenceNumbersProperlyUpdates) { @@ -1863,8 +1873,15 @@ TEST_F(DebugApiLinuxTestXe, WhenCallingThreadControlForResumeThenProperIoctlsIsC auto result = sessionMock->threadControl(threads, 0, MockDebugSessionLinuxXe::ThreadControlCmd::resume, bitmaskOut, bitmaskSizeOut); EXPECT_EQ(result, ZE_RESULT_SUCCESS); - EXPECT_EQ(1, handler->ioctlCalled); - EXPECT_EQ(uint32_t(DRM_XE_EUDEBUG_EU_CONTROL_CMD_RESUME), handler->euControlArgs[0].euControl.cmd); + auto &l0GfxCoreHelper = neoDevice->getRootDeviceEnvironment().getHelper(); + if (l0GfxCoreHelper.threadResumeRequiresUnlock()) { + EXPECT_EQ(2, handler->ioctlCalled); + EXPECT_EQ(uint32_t(sessionMock->getEuControlCmdUnlock()), handler->euControlArgs[0].euControl.cmd); + EXPECT_EQ(uint32_t(DRM_XE_EUDEBUG_EU_CONTROL_CMD_RESUME), handler->euControlArgs[1].euControl.cmd); + } else { + EXPECT_EQ(1, handler->ioctlCalled); + EXPECT_EQ(uint32_t(DRM_XE_EUDEBUG_EU_CONTROL_CMD_RESUME), handler->euControlArgs[0].euControl.cmd); + } EXPECT_NE(0u, handler->euControlArgs[0].euControl.bitmask_size); auto bitMaskPtrToCheck = handler->euControlArgs[0].euControl.bitmask_ptr; EXPECT_NE(0u, bitMaskPtrToCheck);