From 7ff258fc928929ba7555e77aba76a06aa108a6a6 Mon Sep 17 00:00:00 2001 From: Mateusz Hoppe Date: Fri, 23 Sep 2022 14:56:32 +0000 Subject: [PATCH] L0Debug - Enable attaching to Root or Subdevices - enable tile attach mode by default - both root device and subdevice may be attached to Related-To: NEO-7347 Signed-off-by: Mateusz Hoppe --- level_zero/core/source/device/device.h | 2 +- level_zero/core/source/device/device_imp.cpp | 15 +- level_zero/core/source/device/device_imp.h | 2 +- .../core/test/unit_tests/mocks/mock_device.h | 2 +- .../tools/source/debug/debug_handlers.cpp | 22 ++- level_zero/tools/source/debug/debug_session.h | 11 +- .../tools/source/debug/debug_session_imp.cpp | 42 +++--- .../tools/source/debug/debug_session_imp.h | 7 +- .../source/debug/linux/debug_session.cpp | 2 +- .../debug/linux/prelim/debug_session.cpp | 11 +- .../source/debug/linux/prelim/debug_session.h | 5 +- .../source/debug/windows/debug_session.cpp | 5 +- .../source/debug/windows/debug_session.h | 4 +- .../sources/debug/debug_session_helper.cpp | 9 +- .../sources/debug/debug_session_tests.cpp | 127 +++++++++++------ .../debug/debug_session_thread_tests.cpp | 5 +- .../linux/debug_session_fixtures_linux.cpp | 4 +- .../linux/debug_session_fixtures_linux.h | 16 +++ .../debug/linux/test_debug_api_linux.cpp | 129 ++++++++++++++++-- .../sources/debug/mock_debug_session.h | 11 +- .../sources/debug/test_debug_api.cpp | 36 ++++- .../debug/windows/test_debug_api_windows.cpp | 29 +++- .../debug_settings/debug_variables_base.inl | 2 +- shared/test/common/test_files/igdrcl.config | 2 +- 24 files changed, 389 insertions(+), 111 deletions(-) diff --git a/level_zero/core/source/device/device.h b/level_zero/core/source/device/device.h index 2bf19c8da7..04ce58d193 100644 --- a/level_zero/core/source/device/device.h +++ b/level_zero/core/source/device/device.h @@ -100,7 +100,7 @@ struct Device : _ze_device_handle_t { virtual uint32_t getPlatformInfo() const = 0; virtual MetricDeviceContext &getMetricDeviceContext() = 0; virtual DebugSession *getDebugSession(const zet_debug_config_t &config) = 0; - virtual DebugSession *createDebugSession(const zet_debug_config_t &config, ze_result_t &result) = 0; + virtual DebugSession *createDebugSession(const zet_debug_config_t &config, ze_result_t &result, bool isRootAttach) = 0; virtual void removeDebugSession() = 0; virtual ze_result_t activateMetricGroupsDeferred(uint32_t count, diff --git a/level_zero/core/source/device/device_imp.cpp b/level_zero/core/source/device/device_imp.cpp index d182fd56cc..6b3551d5de 100644 --- a/level_zero/core/source/device/device_imp.cpp +++ b/level_zero/core/source/device/device_imp.cpp @@ -888,10 +888,11 @@ ze_result_t DeviceImp::getDebugProperties(zet_device_debug_properties_t *pDebugP } bool tileAttach = NEO::DebugManager.flags.ExperimentalEnableTileAttach.get(); - if (isDebugAttachAvailable && (isSubdevice == tileAttach)) { - pDebugProperties->flags = zet_device_debug_property_flag_t::ZET_DEVICE_DEBUG_PROPERTY_FLAG_ATTACH; - } else { - pDebugProperties->flags = 0; + pDebugProperties->flags = 0; + if (isDebugAttachAvailable) { + if ((isSubdevice && tileAttach) || !isSubdevice) { + pDebugProperties->flags = zet_device_debug_property_flag_t::ZET_DEVICE_DEBUG_PROPERTY_FLAG_ATTACH; + } } return ZE_RESULT_SUCCESS; } @@ -1306,10 +1307,10 @@ DebugSession *DeviceImp::getDebugSession(const zet_debug_config_t &config) { return debugSession.get(); } -DebugSession *DeviceImp::createDebugSession(const zet_debug_config_t &config, ze_result_t &result) { +DebugSession *DeviceImp::createDebugSession(const zet_debug_config_t &config, ze_result_t &result, bool isRootAttach) { if (!this->isSubdevice) { if (debugSession.get() == nullptr) { - auto session = DebugSession::create(config, this, result); + auto session = DebugSession::create(config, this, result, isRootAttach); debugSession.reset(session); } else { result = ZE_RESULT_SUCCESS; @@ -1320,7 +1321,7 @@ DebugSession *DeviceImp::createDebugSession(const zet_debug_config_t &config, ze auto session = rootL0Device->getDebugSession(config); if (!session) { - session = rootL0Device->createDebugSession(config, result); + session = rootL0Device->createDebugSession(config, result, isRootAttach); } if (result == ZE_RESULT_SUCCESS) { diff --git a/level_zero/core/source/device/device_imp.h b/level_zero/core/source/device/device_imp.h index 37c18aadbf..d7d560e987 100644 --- a/level_zero/core/source/device/device_imp.h +++ b/level_zero/core/source/device/device_imp.h @@ -75,7 +75,7 @@ struct DeviceImp : public Device { MetricDeviceContext &getMetricDeviceContext() override; DebugSession *getDebugSession(const zet_debug_config_t &config) override; void setDebugSession(DebugSession *session); - DebugSession *createDebugSession(const zet_debug_config_t &config, ze_result_t &result) override; + DebugSession *createDebugSession(const zet_debug_config_t &config, ze_result_t &result, bool isRootAttach) override; void removeDebugSession() override; uint32_t getMaxNumHwThreads() const override; diff --git a/level_zero/core/test/unit_tests/mocks/mock_device.h b/level_zero/core/test/unit_tests/mocks/mock_device.h index f1f66cbbbc..21b6d472aa 100644 --- a/level_zero/core/test/unit_tests/mocks/mock_device.h +++ b/level_zero/core/test/unit_tests/mocks/mock_device.h @@ -83,7 +83,7 @@ struct Mock : public Device { ADDMETHOD_NOBASE(obtainReusableAllocation, NEO::GraphicsAllocation *, nullptr, (size_t requiredSize, NEO::AllocationType type)) ADDMETHOD_NOBASE_VOIDRETURN(storeReusableAllocation, (NEO::GraphicsAllocation & alloc)); - DebugSession *createDebugSession(const zet_debug_config_t &config, ze_result_t &result) override { + DebugSession *createDebugSession(const zet_debug_config_t &config, ze_result_t &result, bool isRootAttach) override { result = ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; return nullptr; } diff --git a/level_zero/tools/source/debug/debug_handlers.cpp b/level_zero/tools/source/debug/debug_handlers.cpp index 43aff90154..5fe5793429 100644 --- a/level_zero/tools/source/debug/debug_handlers.cpp +++ b/level_zero/tools/source/debug/debug_handlers.cpp @@ -20,7 +20,7 @@ std::mutex debugSessionMutex; ze_result_t debugAttach(zet_device_handle_t hDevice, const zet_debug_config_t *config, zet_debug_session_handle_t *phDebug) { ze_result_t result = ZE_RESULT_SUCCESS; - if (!L0::Device::fromHandle(hDevice)->getNEODevice()->isSubDevice() && NEO::DebugManager.flags.ExperimentalEnableTileAttach.get()) { + if (L0::Device::fromHandle(hDevice)->getNEODevice()->isSubDevice() && !NEO::DebugManager.flags.ExperimentalEnableTileAttach.get()) { return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; } @@ -35,10 +35,25 @@ ze_result_t debugAttach(zet_device_handle_t hDevice, const zet_debug_config_t *c auto session = L0::Device::fromHandle(hDevice)->getDebugSession(*config); std::unique_lock lock(debugSessionMutex); - if (!session) { - session = L0::Device::fromHandle(hDevice)->createDebugSession(*config, result); + + auto rootSession = L0::Device::fromHandle(hDevice)->getNEODevice()->getRootDevice()->getSpecializedDevice()->getDebugSession(*config); + + // If root device with active TileSessions or + // subdevice with root device attached - fail + if ((!L0::Device::fromHandle(hDevice)->getNEODevice()->isSubDevice() && session && !session->areAllTileDebugSessionDetached()) || + (L0::Device::fromHandle(hDevice)->getNEODevice()->isSubDevice() && rootSession && rootSession->isAttached())) { + result = ZE_RESULT_ERROR_NOT_AVAILABLE; + *phDebug = nullptr; + return result; } + + if (!session) { + bool isRootAttach = !L0::Device::fromHandle(hDevice)->getNEODevice()->isSubDevice(); + session = L0::Device::fromHandle(hDevice)->createDebugSession(*config, result, isRootAttach); + } + if (session) { + session->setAttached(); *phDebug = session->toHandle(); } return result; @@ -58,6 +73,7 @@ ze_result_t debugDetach(zet_debug_session_handle_t hDebug) { auto rootL0Device = device->getNEODevice()->getRootDevice()->getSpecializedDevice(); zet_debug_config_t dummy = {}; auto rootSession = rootL0Device->getDebugSession(dummy); + session->setDetached(); rootSession->detachTileDebugSession(session); if (rootSession->areAllTileDebugSessionDetached()) { diff --git a/level_zero/tools/source/debug/debug_session.h b/level_zero/tools/source/debug/debug_session.h index 91e5a26b1f..8663f9b4c5 100644 --- a/level_zero/tools/source/debug/debug_session.h +++ b/level_zero/tools/source/debug/debug_session.h @@ -25,12 +25,11 @@ struct DebugSession : _zet_debug_session_handle_t { virtual ~DebugSession() = default; DebugSession() = delete; - static DebugSession *create(const zet_debug_config_t &config, Device *device, ze_result_t &result); + static DebugSession *create(const zet_debug_config_t &config, Device *device, ze_result_t &result, bool isRootAttach); static DebugSession *fromHandle(zet_debug_session_handle_t handle) { return static_cast(handle); } inline zet_debug_session_handle_t toHandle() { return this; } - void createEuThreads(); virtual bool closeConnection() = 0; virtual ze_result_t initialize() = 0; @@ -85,6 +84,11 @@ struct DebugSession : _zet_debug_session_handle_t { virtual void detachTileDebugSession(DebugSession *tileSession) = 0; virtual bool areAllTileDebugSessionDetached() = 0; + virtual void setAttachMode(bool isRootAttach) = 0; + void setAttached() { attached = true; } + void setDetached() { attached = false; } + bool isAttached() { return attached; } + struct ThreadHelper { void close() { threadActive.store(false); @@ -105,6 +109,8 @@ struct DebugSession : _zet_debug_session_handle_t { protected: DebugSession(const zet_debug_config_t &config, Device *device); + void createEuThreads(); + virtual void startAsyncThread() = 0; virtual bool isBindlessSystemRoutine(); @@ -121,6 +127,7 @@ struct DebugSession : _zet_debug_session_handle_t { Device *connectedDevice = nullptr; std::map> allThreads; + bool attached = false; }; } // namespace L0 diff --git a/level_zero/tools/source/debug/debug_session_imp.cpp b/level_zero/tools/source/debug/debug_session_imp.cpp index 070da2d045..c9d288f472 100644 --- a/level_zero/tools/source/debug/debug_session_imp.cpp +++ b/level_zero/tools/source/debug/debug_session_imp.cpp @@ -26,42 +26,38 @@ DebugSession::DebugSession(const zet_debug_config_t &config, Device *device) : c void DebugSession::createEuThreads() { if (connectedDevice) { - bool isRootDevice = !connectedDevice->getNEODevice()->isSubDevice(); bool isSubDevice = connectedDevice->getNEODevice()->isSubDevice(); - if ((isRootDevice && NEO::DebugManager.flags.ExperimentalEnableTileAttach.get() == 0) || - (isSubDevice && NEO::DebugManager.flags.ExperimentalEnableTileAttach.get() == 1)) { - auto &hwInfo = connectedDevice->getHwInfo(); - const uint32_t numSubslicesPerSlice = hwInfo.gtSystemInfo.MaxSubSlicesSupported / hwInfo.gtSystemInfo.MaxSlicesSupported; - const uint32_t numEuPerSubslice = hwInfo.gtSystemInfo.MaxEuPerSubSlice; - const uint32_t numThreadsPerEu = (hwInfo.gtSystemInfo.ThreadCount / hwInfo.gtSystemInfo.EUCount); - uint32_t subDeviceCount = std::max(1u, connectedDevice->getNEODevice()->getNumSubDevices()); + auto &hwInfo = connectedDevice->getHwInfo(); + const uint32_t numSubslicesPerSlice = hwInfo.gtSystemInfo.MaxSubSlicesSupported / hwInfo.gtSystemInfo.MaxSlicesSupported; + const uint32_t numEuPerSubslice = hwInfo.gtSystemInfo.MaxEuPerSubSlice; + const uint32_t numThreadsPerEu = (hwInfo.gtSystemInfo.ThreadCount / hwInfo.gtSystemInfo.EUCount); + uint32_t subDeviceCount = std::max(1u, connectedDevice->getNEODevice()->getNumSubDevices()); - UNRECOVERABLE_IF(isSubDevice && subDeviceCount > 1); + UNRECOVERABLE_IF(isSubDevice && subDeviceCount > 1); - for (uint32_t tileIndex = 0; tileIndex < subDeviceCount; tileIndex++) { + for (uint32_t tileIndex = 0; tileIndex < subDeviceCount; tileIndex++) { - if (isSubDevice || subDeviceCount == 1) { - tileIndex = Math::log2(static_cast(connectedDevice->getNEODevice()->getDeviceBitfield().to_ulong())); - } + if (isSubDevice || subDeviceCount == 1) { + tileIndex = Math::log2(static_cast(connectedDevice->getNEODevice()->getDeviceBitfield().to_ulong())); + } - for (uint32_t sliceID = 0; sliceID < hwInfo.gtSystemInfo.MaxSlicesSupported; sliceID++) { - for (uint32_t subsliceID = 0; subsliceID < numSubslicesPerSlice; subsliceID++) { - for (uint32_t euID = 0; euID < numEuPerSubslice; euID++) { + for (uint32_t sliceID = 0; sliceID < hwInfo.gtSystemInfo.MaxSlicesSupported; sliceID++) { + for (uint32_t subsliceID = 0; subsliceID < numSubslicesPerSlice; subsliceID++) { + for (uint32_t euID = 0; euID < numEuPerSubslice; euID++) { - for (uint32_t threadID = 0; threadID < numThreadsPerEu; threadID++) { + for (uint32_t threadID = 0; threadID < numThreadsPerEu; threadID++) { - EuThread::ThreadId thread = {tileIndex, sliceID, subsliceID, euID, threadID}; + EuThread::ThreadId thread = {tileIndex, sliceID, subsliceID, euID, threadID}; - allThreads[uint64_t(thread)] = std::make_unique(thread); - } + allThreads[uint64_t(thread)] = std::make_unique(thread); } } } + } - if (isSubDevice || subDeviceCount == 1) { - break; - } + if (isSubDevice || subDeviceCount == 1) { + break; } } } diff --git a/level_zero/tools/source/debug/debug_session_imp.h b/level_zero/tools/source/debug/debug_session_imp.h index 907eb3a752..ae283653af 100644 --- a/level_zero/tools/source/debug/debug_session_imp.h +++ b/level_zero/tools/source/debug/debug_session_imp.h @@ -34,7 +34,6 @@ struct DebugSessionImp : DebugSession { DebugSessionImp(const zet_debug_config_t &config, Device *device) : DebugSession(config, device) { tileAttachEnabled = NEO::DebugManager.flags.ExperimentalEnableTileAttach.get(); - createEuThreads(); } ze_result_t interrupt(ze_device_thread_t thread) override; @@ -48,6 +47,12 @@ struct DebugSessionImp : DebugSession { void detachTileDebugSession(DebugSession *tileSession) override; bool areAllTileDebugSessionDetached() override; + void setAttachMode(bool isRootAttach) override { + if (isRootAttach) { + tileAttachEnabled = false; + } + } + virtual void attachTile() = 0; virtual void detachTile() = 0; virtual void cleanRootSessionAfterDetach(uint32_t deviceIndex) = 0; diff --git a/level_zero/tools/source/debug/linux/debug_session.cpp b/level_zero/tools/source/debug/linux/debug_session.cpp index 1b61258f46..b385363abf 100644 --- a/level_zero/tools/source/debug/linux/debug_session.cpp +++ b/level_zero/tools/source/debug/linux/debug_session.cpp @@ -11,7 +11,7 @@ namespace L0 { -DebugSession *DebugSession::create(const zet_debug_config_t &config, Device *device, ze_result_t &result) { +DebugSession *DebugSession::create(const zet_debug_config_t &config, Device *device, ze_result_t &result, bool isRootAttach) { result = ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; return nullptr; } diff --git a/level_zero/tools/source/debug/linux/prelim/debug_session.cpp b/level_zero/tools/source/debug/linux/prelim/debug_session.cpp index 8228cb6f60..347775ac80 100644 --- a/level_zero/tools/source/debug/linux/prelim/debug_session.cpp +++ b/level_zero/tools/source/debug/linux/prelim/debug_session.cpp @@ -50,7 +50,7 @@ DebugSessionLinux::~DebugSessionLinux() { closeFd(); } -DebugSession *DebugSession::create(const zet_debug_config_t &config, Device *device, ze_result_t &result) { +DebugSession *DebugSession::create(const zet_debug_config_t &config, Device *device, ze_result_t &result, bool isRootAttach) { if (device->getOsInterface().isDebugAttachAvailable()) { struct prelim_drm_i915_debugger_open_param open = {}; open.pid = config.pid; @@ -62,6 +62,7 @@ DebugSession *DebugSession::create(const zet_debug_config_t &config, Device *dev open.pid, open.events, debugFd); auto debugSession = createDebugSessionHelper(config, device, debugFd); + debugSession->setAttachMode(isRootAttach); result = debugSession->initialize(); if (result != ZE_RESULT_SUCCESS) { @@ -245,6 +246,10 @@ ze_result_t DebugSessionLinux::initialize() { return ZE_RESULT_NOT_READY; } + bool isRootDevice = !connectedDevice->getNEODevice()->isSubDevice(); + if (isRootDevice && !tileAttachEnabled) { + createEuThreads(); + } createTileSessionsIfEnabled(); startInternalEventsThread(); @@ -292,7 +297,9 @@ void DebugSessionLinux::createTileSessionsIfEnabled() { } TileDebugSessionLinux *DebugSessionLinux::createTileSession(const zet_debug_config_t &config, Device *device, DebugSessionImp *rootDebugSession) { - return new TileDebugSessionLinux(config, device, rootDebugSession); + auto tileSession = new TileDebugSessionLinux(config, device, rootDebugSession); + tileSession->initialize(); + return tileSession; } void *DebugSessionLinux::asyncThreadFunction(void *arg) { diff --git a/level_zero/tools/source/debug/linux/prelim/debug_session.h b/level_zero/tools/source/debug/linux/prelim/debug_session.h index 632ee162f8..f0a1a1f4c5 100644 --- a/level_zero/tools/source/debug/linux/prelim/debug_session.h +++ b/level_zero/tools/source/debug/linux/prelim/debug_session.h @@ -328,7 +328,10 @@ struct TileDebugSessionLinux : DebugSessionLinux { ~TileDebugSessionLinux() override = default; bool closeConnection() override { return true; } - ze_result_t initialize() override { return ZE_RESULT_SUCCESS; } + ze_result_t initialize() override { + createEuThreads(); + return ZE_RESULT_SUCCESS; + } bool insertModule(zet_debug_event_info_module_t module); bool removeModule(zet_debug_event_info_module_t module); diff --git a/level_zero/tools/source/debug/windows/debug_session.cpp b/level_zero/tools/source/debug/windows/debug_session.cpp index 2f64652468..129951cec0 100644 --- a/level_zero/tools/source/debug/windows/debug_session.cpp +++ b/level_zero/tools/source/debug/windows/debug_session.cpp @@ -23,13 +23,14 @@ DebugSessionWindows::~DebugSessionWindows() { closeAsyncThread(); } -DebugSession *DebugSession::create(const zet_debug_config_t &config, Device *device, ze_result_t &result) { - if (!device->getOsInterface().isDebugAttachAvailable()) { +DebugSession *DebugSession::create(const zet_debug_config_t &config, Device *device, ze_result_t &result, bool isRootAttach) { + if (!device->getOsInterface().isDebugAttachAvailable() || !isRootAttach) { result = ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; return nullptr; } auto debugSession = createDebugSessionHelper(config, device, 0); + debugSession->setAttachMode(isRootAttach); result = debugSession->initialize(); if (result != ZE_RESULT_SUCCESS) { debugSession->closeConnection(); diff --git a/level_zero/tools/source/debug/windows/debug_session.h b/level_zero/tools/source/debug/windows/debug_session.h index 19ad4b038d..6e8273b116 100644 --- a/level_zero/tools/source/debug/windows/debug_session.h +++ b/level_zero/tools/source/debug/windows/debug_session.h @@ -22,7 +22,9 @@ namespace L0 { struct DebugSessionWindows : DebugSessionImp { - DebugSessionWindows(const zet_debug_config_t &config, Device *device) : DebugSessionImp(config, device), processId(config.pid) {} + DebugSessionWindows(const zet_debug_config_t &config, Device *device) : DebugSessionImp(config, device), processId(config.pid) { + createEuThreads(); + } ~DebugSessionWindows() override; ze_result_t initialize() override; diff --git a/level_zero/tools/test/unit_tests/sources/debug/debug_session_helper.cpp b/level_zero/tools/test/unit_tests/sources/debug/debug_session_helper.cpp index 192640dbf2..3d73e9af5f 100644 --- a/level_zero/tools/test/unit_tests/sources/debug/debug_session_helper.cpp +++ b/level_zero/tools/test/unit_tests/sources/debug/debug_session_helper.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021 Intel Corporation + * Copyright (C) 2021-2022 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -7,9 +7,16 @@ #include "level_zero/tools/test/unit_tests/sources/debug/mock_debug_session.h" #include + namespace L0 { +namespace ult { +CreateDebugSessionHelperFunc createDebugSessionFunc = nullptr; +} DebugSession *createDebugSessionHelper(const zet_debug_config_t &config, Device *device, int debugFd) { + if (L0::ult::createDebugSessionFunc) { + return L0::ult::createDebugSessionFunc(config, device, debugFd); + } return new L0::ult::DebugSessionMock(config, device); } diff --git a/level_zero/tools/test/unit_tests/sources/debug/debug_session_tests.cpp b/level_zero/tools/test/unit_tests/sources/debug/debug_session_tests.cpp index 4b250bef4e..1aa8e1d251 100644 --- a/level_zero/tools/test/unit_tests/sources/debug/debug_session_tests.cpp +++ b/level_zero/tools/test/unit_tests/sources/debug/debug_session_tests.cpp @@ -63,7 +63,13 @@ struct MockDebugSession : public L0::DebugSessionImp { using L0::DebugSessionImp::tileAttachEnabled; using L0::DebugSessionImp::tileSessions; - MockDebugSession(const zet_debug_config_t &config, L0::Device *device) : DebugSessionImp(config, device) { + MockDebugSession(const zet_debug_config_t &config, L0::Device *device) : MockDebugSession(config, device, true) {} + + MockDebugSession(const zet_debug_config_t &config, L0::Device *device, bool rootAttach) : DebugSessionImp(config, device) { + setAttachMode(rootAttach); + if (rootAttach) { + createEuThreads(); + } } ~MockDebugSession() override { @@ -2346,43 +2352,12 @@ TEST(DebugSessionTest, GivenRootDeviceAndTileAttachWhenDebugSessionIsCreatedThen NEO::MockDevice *neoDevice(NEO::MockDevice::createWithNewExecutionEnvironment(&hwInfo, 0)); Mock deviceImp(neoDevice, neoDevice->getExecutionEnvironment()); - auto sessionMock = std::make_unique(config, &deviceImp); + auto sessionMock = std::make_unique(config, &deviceImp, false); ASSERT_NE(nullptr, sessionMock); EXPECT_EQ(0u, sessionMock->allThreads.size()); } -TEST(DebugSessionTest, GivenSubDeviceAndTileAttachWhenDebugSessionIsCreatedThenThreadsAreCreated) { - DebugManagerStateRestore restorer; - NEO::DebugManager.flags.ExperimentalEnableTileAttach.set(1); - - zet_debug_config_t config = {}; - config.pid = 0x1234; - auto hwInfo = *NEO::defaultHwInfo.get(); - - NEO::MockDevice *neoDevice(NEO::MockDevice::createWithNewExecutionEnvironment(&hwInfo, 0)); - neoDevice->incRefInternal(); - - auto subDevice = NEO::Device::create(neoDevice->getExecutionEnvironment(), 0, *neoDevice); - subDevice->incRefInternal(); - { - auto deviceImp = std::make_unique>(subDevice, subDevice->getExecutionEnvironment()); - - auto sessionMock = std::make_unique(config, deviceImp.get()); - ASSERT_NE(nullptr, sessionMock); - - const uint32_t numSubslicesPerSlice = hwInfo.gtSystemInfo.MaxSubSlicesSupported / hwInfo.gtSystemInfo.MaxSlicesSupported; - const uint32_t numEuPerSubslice = hwInfo.gtSystemInfo.MaxEuPerSubSlice; - const uint32_t numThreadsPerEu = (hwInfo.gtSystemInfo.ThreadCount / hwInfo.gtSystemInfo.EUCount); - - auto total = hwInfo.gtSystemInfo.MaxSlicesSupported * numSubslicesPerSlice * numEuPerSubslice * numThreadsPerEu; - - EXPECT_EQ(total, sessionMock->allThreads.size()); - } - delete subDevice; - delete neoDevice; -} - TEST_F(MultiTileDebugSessionTest, GivenSubDeviceAndTileAttachWhenRootDeviceDebugSessionCreateFailsThenTileAttachFails) { DebugManagerStateRestore restorer; NEO::DebugManager.flags.ExperimentalEnableTileAttach.set(1); @@ -2409,7 +2384,7 @@ TEST_F(MultiTileDebugSessionTest, GivenSubDeviceAndTileAttachWhenRootDeviceDebug EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, retVal); } -TEST_F(MultiTileDebugSessionTest, givenTileAttachEnabledWhenGettingDebugPropertiesThenDebugAttachIsSetForSubdevices) { +TEST_F(MultiTileDebugSessionTest, givenTileAttachEnabledWhenGettingDebugPropertiesThenDebugAttachIsSetForRootAndSubdevices) { DebugManagerStateRestore restorer; NEO::DebugManager.flags.ExperimentalEnableTileAttach.set(1); @@ -2434,7 +2409,7 @@ TEST_F(MultiTileDebugSessionTest, givenTileAttachEnabledWhenGettingDebugProperti auto result = zetDeviceGetDebugProperties(device->toHandle(), &debugProperties); EXPECT_EQ(ZE_RESULT_SUCCESS, result); - EXPECT_EQ(0u, debugProperties.flags); + EXPECT_EQ(zet_device_debug_property_flag_t::ZET_DEVICE_DEBUG_PROPERTY_FLAG_ATTACH, debugProperties.flags); result = zetDeviceGetDebugProperties(subDevice0->toHandle(), &debugProperties); @@ -2447,7 +2422,7 @@ TEST_F(MultiTileDebugSessionTest, givenTileAttachEnabledWhenGettingDebugProperti EXPECT_EQ(zet_device_debug_property_flag_t::ZET_DEVICE_DEBUG_PROPERTY_FLAG_ATTACH, debugProperties.flags); } -TEST_F(MultiTileDebugSessionTest, givenTileAttachEnabledWhenAttachingToRootDeviceThenErrorIsReturned) { +TEST_F(MultiTileDebugSessionTest, givenTileAttachEnabledWhenAttachingToRootDeviceThenTileAttachIsDisabledAndSuccessIsReturned) { DebugManagerStateRestore restorer; NEO::DebugManager.flags.ExperimentalEnableTileAttach.set(1); @@ -2456,11 +2431,18 @@ TEST_F(MultiTileDebugSessionTest, givenTileAttachEnabledWhenAttachingToRootDevic zet_debug_session_handle_t debugSession = nullptr; L0::Device *device = driverHandle->devices[0]; + auto deviceImp = static_cast(device); device->getNEODevice()->getExecutionEnvironment()->rootDeviceEnvironments[0]->osInterface.reset(new OsInterfaceWithDebugAttach); + auto sessionMock = new MockDebugSession(config, device, true); + sessionMock->initialize(); + deviceImp->setDebugSession(sessionMock); auto result = zetDebugAttach(device->toHandle(), &config, &debugSession); - EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, result); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + ASSERT_NE(nullptr, debugSession); + EXPECT_TRUE(sessionMock->isAttached()); + EXPECT_FALSE(sessionMock->tileAttachEnabled); } TEST_F(MultiTileDebugSessionTest, givenTileAttachEnabledWhenAttachingToTileDevicesThenDebugSessionForRootIsCreatedAndTileSessionsAreReturned) { @@ -2476,7 +2458,7 @@ TEST_F(MultiTileDebugSessionTest, givenTileAttachEnabledWhenAttachingToTileDevic auto deviceImp = static_cast(device); neoDevice->getExecutionEnvironment()->rootDeviceEnvironments[0]->osInterface.reset(new OsInterfaceWithDebugAttach); - auto sessionMock = new MockDebugSession(config, device); + auto sessionMock = new MockDebugSession(config, device, false); sessionMock->initialize(); deviceImp->setDebugSession(sessionMock); @@ -2491,6 +2473,7 @@ TEST_F(MultiTileDebugSessionTest, givenTileAttachEnabledWhenAttachingToTileDevic EXPECT_TRUE(sessionMock->tileSessions[0].second); EXPECT_EQ(sessionMock->tileSessions[0].first, L0::DebugSession::fromHandle(debugSession0)); + EXPECT_TRUE(sessionMock->tileSessions[0].first->isAttached()); EXPECT_NE(nullptr, deviceImp->getDebugSession(config)); @@ -2502,6 +2485,8 @@ TEST_F(MultiTileDebugSessionTest, givenTileAttachEnabledWhenAttachingToTileDevic EXPECT_TRUE(sessionMock->tileSessions[1].second); EXPECT_EQ(sessionMock->tileSessions[1].first, L0::DebugSession::fromHandle(debugSession1)); + EXPECT_TRUE(sessionMock->tileSessions[1].first->isAttached()); + EXPECT_TRUE(tileSession1->attachTileCalled); EXPECT_FALSE(tileSession1->detachTileCalled); @@ -2510,6 +2495,7 @@ TEST_F(MultiTileDebugSessionTest, givenTileAttachEnabledWhenAttachingToTileDevic EXPECT_EQ(ZE_RESULT_SUCCESS, result); EXPECT_NE(nullptr, deviceImp->getDebugSession(config)); EXPECT_FALSE(sessionMock->tileSessions[1].second); + EXPECT_FALSE(sessionMock->tileSessions[1].first->isAttached()); EXPECT_TRUE(tileSession1->detachTileCalled); ASSERT_EQ(1u, sessionMock->cleanRootSessionDeviceIndices.size()); @@ -2533,7 +2519,7 @@ TEST_F(MultiTileDebugSessionTest, givenTileAttachEnabledWhenTileAttachFailsDurin auto deviceImp = static_cast(device); neoDevice->getExecutionEnvironment()->rootDeviceEnvironments[0]->osInterface.reset(new OsInterfaceWithDebugAttach); - auto sessionMock = new MockDebugSession(config, device); + auto sessionMock = new MockDebugSession(config, device, false); sessionMock->initialize(); deviceImp->setDebugSession(sessionMock); @@ -2542,9 +2528,70 @@ TEST_F(MultiTileDebugSessionTest, givenTileAttachEnabledWhenTileAttachFailsDurin auto subDevice0 = neoDevice->getSubDevice(0)->getSpecializedDevice(); ze_result_t result = ZE_RESULT_SUCCESS; - auto debugSession = subDevice0->createDebugSession(config, result); + auto debugSession = subDevice0->createDebugSession(config, result, false); EXPECT_EQ(ZE_RESULT_ERROR_NOT_AVAILABLE, result); EXPECT_EQ(nullptr, debugSession); } + +TEST_F(MultiTileDebugSessionTest, givenAttachedTileDeviceWhenAttachingToRootDeviceThenErrorIsReturned) { + DebugManagerStateRestore restorer; + NEO::DebugManager.flags.ExperimentalEnableTileAttach.set(1); + + zet_debug_config_t config = {}; + config.pid = 0x1234; + zet_debug_session_handle_t debugSession0 = nullptr, debugSession1 = nullptr; + + L0::Device *device = driverHandle->devices[0]; + auto neoDevice = device->getNEODevice(); + auto deviceImp = static_cast(device); + neoDevice->getExecutionEnvironment()->rootDeviceEnvironments[0]->osInterface.reset(new OsInterfaceWithDebugAttach); + + auto sessionMock = new MockDebugSession(config, device, false); + sessionMock->initialize(); + deviceImp->setDebugSession(sessionMock); + + auto subDevice0 = neoDevice->getSubDevice(0)->getSpecializedDevice(); + auto result = zetDebugAttach(subDevice0->toHandle(), &config, &debugSession0); + + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_NE(nullptr, debugSession0); + + result = zetDebugAttach(deviceImp->toHandle(), &config, &debugSession1); + EXPECT_EQ(ZE_RESULT_ERROR_NOT_AVAILABLE, result); + + result = zetDebugDetach(debugSession0); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); +} + +TEST_F(MultiTileDebugSessionTest, givenAttachedRootDeviceWhenAttachingToTiletDeviceThenErrorIsReturned) { + DebugManagerStateRestore restorer; + NEO::DebugManager.flags.ExperimentalEnableTileAttach.set(1); + + zet_debug_config_t config = {}; + config.pid = 0x1234; + zet_debug_session_handle_t debugSession0 = nullptr, debugSessionRoot = nullptr; + + L0::Device *device = driverHandle->devices[0]; + auto neoDevice = device->getNEODevice(); + auto deviceImp = static_cast(device); + neoDevice->getExecutionEnvironment()->rootDeviceEnvironments[0]->osInterface.reset(new OsInterfaceWithDebugAttach); + + auto sessionMock = new MockDebugSession(config, device, true); + sessionMock->initialize(); + deviceImp->setDebugSession(sessionMock); + + auto subDevice0 = neoDevice->getSubDevice(0)->getSpecializedDevice(); + + auto result = zetDebugAttach(deviceImp->toHandle(), &config, &debugSessionRoot); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + + result = zetDebugAttach(subDevice0->toHandle(), &config, &debugSession0); + EXPECT_EQ(ZE_RESULT_ERROR_NOT_AVAILABLE, result); + EXPECT_EQ(nullptr, debugSession0); + + result = zetDebugDetach(debugSessionRoot); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); +} + } // namespace ult } // namespace L0 diff --git a/level_zero/tools/test/unit_tests/sources/debug/debug_session_thread_tests.cpp b/level_zero/tools/test/unit_tests/sources/debug/debug_session_thread_tests.cpp index 89fb1fefd8..315943f1bd 100644 --- a/level_zero/tools/test/unit_tests/sources/debug/debug_session_thread_tests.cpp +++ b/level_zero/tools/test/unit_tests/sources/debug/debug_session_thread_tests.cpp @@ -358,7 +358,7 @@ TEST(DebugSession, givenAllStoppedThreadsWhenAreRequestedThreadsStoppedCalledThe Mock deviceImp(neoDevice, neoDevice->getExecutionEnvironment()); auto sessionMock = std::make_unique(config, &deviceImp); - + sessionMock->initialize(); for (uint32_t i = 0; i < hwInfo.gtSystemInfo.ThreadCount / hwInfo.gtSystemInfo.EUCount; i++) { EuThread::ThreadId thread(0, 0, 0, 0, i); sessionMock->allThreads[thread]->stopThread(1u); @@ -377,7 +377,7 @@ TEST(DebugSession, givenSomeStoppedThreadsWhenAreRequestedThreadsStoppedCalledTh Mock deviceImp(neoDevice, neoDevice->getExecutionEnvironment()); auto sessionMock = std::make_unique(config, &deviceImp); - + sessionMock->initialize(); for (uint32_t i = 0; i < hwInfo.gtSystemInfo.ThreadCount / hwInfo.gtSystemInfo.EUCount; i++) { EuThread::ThreadId thread(0, 0, 0, 0, i); if (i % 2) { @@ -412,6 +412,7 @@ TEST(DebugSession, givenDifferentCombinationsOfThreadsAndMemoryTypeCheckExpected Mock deviceImp(neoDevice, neoDevice->getExecutionEnvironment()); auto sessionMock = std::make_unique(config, &deviceImp); + sessionMock->initialize(); ze_device_thread_t thread = {UINT32_MAX, UINT32_MAX, UINT32_MAX, UINT32_MAX}; zet_debug_memory_space_desc_t desc; desc.address = 0x1000; diff --git a/level_zero/tools/test/unit_tests/sources/debug/linux/debug_session_fixtures_linux.cpp b/level_zero/tools/test/unit_tests/sources/debug/linux/debug_session_fixtures_linux.cpp index 586e573fbb..a03e349f59 100644 --- a/level_zero/tools/test/unit_tests/sources/debug/linux/debug_session_fixtures_linux.cpp +++ b/level_zero/tools/test/unit_tests/sources/debug/linux/debug_session_fixtures_linux.cpp @@ -62,7 +62,9 @@ void DebugApiLinuxMultiDeviceFixture::setUp() { } TileDebugSessionLinux *MockDebugSessionLinux::createTileSession(const zet_debug_config_t &config, L0::Device *device, L0::DebugSessionImp *rootDebugSession) { - return new MockTileDebugSessionLinux(config, device, rootDebugSession); + auto tileSession = new MockTileDebugSessionLinux(config, device, rootDebugSession); + tileSession->initialize(); + return tileSession; } } // namespace ult } // namespace L0 diff --git a/level_zero/tools/test/unit_tests/sources/debug/linux/debug_session_fixtures_linux.h b/level_zero/tools/test/unit_tests/sources/debug/linux/debug_session_fixtures_linux.h index 828839f5a9..d71a49a772 100644 --- a/level_zero/tools/test/unit_tests/sources/debug/linux/debug_session_fixtures_linux.h +++ b/level_zero/tools/test/unit_tests/sources/debug/linux/debug_session_fixtures_linux.h @@ -294,6 +294,21 @@ struct MockDebugSessionLinux : public L0::DebugSessionLinux { MockDebugSessionLinux(const zet_debug_config_t &config, L0::Device *device, int debugFd) : DebugSessionLinux(config, device, debugFd) { clientHandleToConnection[mockClientHandle].reset(new ClientConnection); clientHandle = mockClientHandle; + createEuThreads(); + } + + ze_result_t initialize() override { + if (initializeRetVal != ZE_RESULT_FORCE_UINT32) { + bool isRootDevice = !connectedDevice->getNEODevice()->isSubDevice(); + if (isRootDevice && !tileAttachEnabled) { + createEuThreads(); + } + createTileSessionsIfEnabled(); + + clientHandle = mockClientHandle; + return initializeRetVal; + } + return DebugSessionLinux::initialize(); } std::unordered_map> &getClassHandleToIndex() { @@ -392,6 +407,7 @@ struct MockDebugSessionLinux : public L0::DebugSessionLinux { TileDebugSessionLinux *createTileSession(const zet_debug_config_t &config, L0::Device *device, L0::DebugSessionImp *rootDebugSession) override; + ze_result_t initializeRetVal = ZE_RESULT_FORCE_UINT32; bool allThreadsStopped = false; int64_t returnTimeDiff = -1; static constexpr uint64_t mockClientHandle = 1; diff --git a/level_zero/tools/test/unit_tests/sources/debug/linux/test_debug_api_linux.cpp b/level_zero/tools/test/unit_tests/sources/debug/linux/test_debug_api_linux.cpp index 3811c5aa10..acc4b36b5a 100644 --- a/level_zero/tools/test/unit_tests/sources/debug/linux/test_debug_api_linux.cpp +++ b/level_zero/tools/test/unit_tests/sources/debug/linux/test_debug_api_linux.cpp @@ -16,6 +16,7 @@ #include "shared/source/os_interface/os_interface.h" #include "shared/test/common/helpers/debug_manager_state_restore.h" #include "shared/test/common/helpers/gtest_helpers.h" +#include "shared/test/common/helpers/variable_backup.h" #include "shared/test/common/libult/linux/drm_mock_helper.h" #include "shared/test/common/libult/linux/drm_query_mock.h" #include "shared/test/common/mocks/mock_sip.h" @@ -53,6 +54,8 @@ extern uint32_t munmapFuncCalled; namespace L0 { namespace ult { +extern CreateDebugSessionHelperFunc createDebugSessionFunc; + TEST(IoctlHandler, GivenHandlerWhenPreadCalledThenSysCallIsCalled) { L0::DebugSessionLinux::IoctlHandler handler; NEO::SysCalls::preadFuncCalled = 0; @@ -549,7 +552,7 @@ TEST_F(DebugApiLinuxTest, GivenSuccessfulInitializationWhenCreatingDebugSessionT mockDrm->baseErrno = false; mockDrm->errnoRetVal = 0; - auto session = std::unique_ptr(DebugSession::create(config, device, result)); + auto session = std::unique_ptr(DebugSession::create(config, device, result, !device->getNEODevice()->isSubDevice())); EXPECT_NE(nullptr, session); EXPECT_EQ(ZE_RESULT_SUCCESS, result); @@ -563,12 +566,12 @@ TEST_F(DebugApiLinuxTest, GivenRootDeviceWhenDebugSessionIsCreatedForTheSecondTi config.pid = 0x1234; ze_result_t result = ZE_RESULT_SUCCESS; - auto sessionMock = device->createDebugSession(config, result); + auto sessionMock = device->createDebugSession(config, result, true); ASSERT_NE(nullptr, sessionMock); EXPECT_EQ(ZE_RESULT_SUCCESS, result); - auto sessionMock2 = device->createDebugSession(config, result); + auto sessionMock2 = device->createDebugSession(config, result, true); EXPECT_EQ(sessionMock, sessionMock2); EXPECT_EQ(ZE_RESULT_SUCCESS, result); } @@ -899,7 +902,7 @@ TEST_F(DebugApiLinuxTest, GivenDebuggerLogsWhenOpenDebuggerFailsThenCorrectMessa mockDrm->errnoRetVal = 22; ::testing::internal::CaptureStderr(); - auto session = DebugSession::create(config, device, result); + auto session = DebugSession::create(config, device, result, !device->getNEODevice()->isSubDevice()); EXPECT_EQ(nullptr, session); EXPECT_EQ(ZE_RESULT_ERROR_UNKNOWN, result); @@ -916,25 +919,25 @@ TEST_F(DebugApiLinuxTest, WhenOpenDebuggerFailsThenCorrectErrorIsReturned) { mockDrm->context.debuggerOpenRetval = -1; mockDrm->baseErrno = false; mockDrm->errnoRetVal = EBUSY; - auto session = DebugSession::create(config, device, result); + auto session = DebugSession::create(config, device, result, !device->getNEODevice()->isSubDevice()); EXPECT_EQ(nullptr, session); EXPECT_EQ(ZE_RESULT_ERROR_NOT_AVAILABLE, result); mockDrm->errnoRetVal = ENODEV; - session = DebugSession::create(config, device, result); + session = DebugSession::create(config, device, result, !device->getNEODevice()->isSubDevice()); EXPECT_EQ(nullptr, session); EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, result); mockDrm->errnoRetVal = EACCES; - session = DebugSession::create(config, device, result); + session = DebugSession::create(config, device, result, !device->getNEODevice()->isSubDevice()); EXPECT_EQ(nullptr, session); EXPECT_EQ(ZE_RESULT_ERROR_INSUFFICIENT_PERMISSIONS, result); mockDrm->errnoRetVal = ESRCH; - session = DebugSession::create(config, device, result); + session = DebugSession::create(config, device, result, !device->getNEODevice()->isSubDevice()); EXPECT_EQ(nullptr, session); EXPECT_EQ(ZE_RESULT_ERROR_UNKNOWN, result); @@ -954,7 +957,7 @@ TEST_F(DebugApiLinuxTest, GivenDebuggerLogsWhenOpenDebuggerSucceedsThenCorrectMe mockDrm->errnoRetVal = 0; ::testing::internal::CaptureStdout(); - auto session = std::unique_ptr(DebugSession::create(config, device, result)); + auto session = std::unique_ptr(DebugSession::create(config, device, result, !device->getNEODevice()->isSubDevice())); EXPECT_NE(nullptr, session); EXPECT_EQ(ZE_RESULT_SUCCESS, result); @@ -2147,7 +2150,7 @@ TEST_F(DebugApiLinuxTest, givenErrorReturnedFromInitializeWhenDebugSessionIsCrea config.pid = 0; ze_result_t result = ZE_RESULT_SUCCESS; - auto session = DebugSession::create(config, device, result); + auto session = DebugSession::create(config, device, result, !device->getNEODevice()->isSubDevice()); EXPECT_EQ(nullptr, session); EXPECT_EQ(ZE_RESULT_ERROR_UNKNOWN, result); } @@ -6212,6 +6215,112 @@ TEST_F(DebugApiRegistersAccessTest, givenWriteSbaRegistersCalledThenErrorInvalid using DebugApiLinuxMultitileTest = Test; +TEST_F(DebugApiLinuxMultitileTest, GivenRootDeviceAndTileAttachDisabledWhenDebugSessionInitializedThenEuThreadsAreCreated) { + DebugManagerStateRestore restorer; + NEO::DebugManager.flags.ExperimentalEnableTileAttach.set(0); + + zet_debug_config_t config = {}; + + auto session = std::make_unique(config, deviceImp, 1); + auto handler = new MockIoctlHandler; + handler->pollRetVal = 1; + session->ioctlHandler.reset(handler); + session->allThreads.clear(); + + prelim_drm_i915_debug_event_client client = {}; + + client.base.type = PRELIM_DRM_I915_DEBUG_EVENT_CLIENT; + client.base.flags = PRELIM_DRM_I915_DEBUG_EVENT_CREATE; + client.base.size = sizeof(prelim_drm_i915_debug_event_client); + client.handle = 1; + handler->eventQueue.push({reinterpret_cast(&client), static_cast(client.base.size)}); + + session->initialize(); + + EXPECT_NE(0u, session->allThreads.size()); + EXPECT_FALSE(session->tileAttachEnabled); + EXPECT_FALSE(session->tileSessionsEnabled); +} + +TEST_F(DebugApiLinuxMultitileTest, GivenRootDeviceAndRootAttachModeWhenDebugSessionInitializedThenEuThreadsAreCreated) { + zet_debug_config_t config = {}; + + auto session = std::make_unique(config, deviceImp, 1); + auto handler = new MockIoctlHandler; + handler->pollRetVal = 1; + session->ioctlHandler.reset(handler); + session->allThreads.clear(); + session->setAttachMode(true); + + prelim_drm_i915_debug_event_client client = {}; + + client.base.type = PRELIM_DRM_I915_DEBUG_EVENT_CLIENT; + client.base.flags = PRELIM_DRM_I915_DEBUG_EVENT_CREATE; + client.base.size = sizeof(prelim_drm_i915_debug_event_client); + client.handle = 1; + handler->eventQueue.push({reinterpret_cast(&client), static_cast(client.base.size)}); + + session->initialize(); + + EXPECT_NE(0u, session->allThreads.size()); + EXPECT_FALSE(session->tileAttachEnabled); + EXPECT_FALSE(session->tileSessionsEnabled); +} + +TEST_F(DebugApiLinuxMultitileTest, GivenRootDeviceWhenDebugAttachCalledThenRootSessionIsCreatedAndTileAttachDisabled) { + zet_debug_config_t config = {}; + config.pid = 0x1234; + zet_debug_session_handle_t debugSession = nullptr; + + VariableBackup mockCreateDebugSessionBackup(&L0::ult::createDebugSessionFunc, [](const zet_debug_config_t &config, L0::Device *device, int debugFd) -> DebugSession * { + auto session = new MockDebugSessionLinux(config, device, debugFd); + session->initializeRetVal = ZE_RESULT_SUCCESS; + return session; + }); + + auto result = zetDebugAttach(deviceImp->toHandle(), &config, &debugSession); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_NE(nullptr, debugSession); + + EXPECT_TRUE(deviceImp->getDebugSession(config)->isAttached()); + + auto session = static_cast(deviceImp->getDebugSession(config)); + EXPECT_FALSE(session->tileAttachEnabled); + + result = zetDebugAttach(deviceImp->subDevices[0]->toHandle(), &config, &debugSession); + EXPECT_EQ(ZE_RESULT_ERROR_NOT_AVAILABLE, result); + + zetDebugDetach(debugSession); +} + +TEST_F(DebugApiLinuxMultitileTest, GivenSubDeviceWhenDebugAttachCalledThenTileSessionsAreCreatedAndRootCannotBeAttached) { + zet_debug_config_t config = {}; + config.pid = 0x1234; + zet_debug_session_handle_t debugSession = nullptr; + zet_debug_session_handle_t debugSessionRoot = nullptr; + + VariableBackup mockCreateDebugSessionBackup(&L0::ult::createDebugSessionFunc, [](const zet_debug_config_t &config, L0::Device *device, int debugFd) -> DebugSession * { + auto session = new MockDebugSessionLinux(config, device, debugFd); + session->initializeRetVal = ZE_RESULT_SUCCESS; + return session; + }); + + auto result = zetDebugAttach(deviceImp->subDevices[0]->toHandle(), &config, &debugSession); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_NE(nullptr, debugSession); + + EXPECT_FALSE(deviceImp->getDebugSession(config)->isAttached()); + + auto session = static_cast(deviceImp->getDebugSession(config)); + EXPECT_TRUE(session->tileAttachEnabled); + + result = zetDebugAttach(deviceImp->toHandle(), &config, &debugSessionRoot); + EXPECT_EQ(ZE_RESULT_ERROR_NOT_AVAILABLE, result); + EXPECT_EQ(nullptr, debugSessionRoot); + + zetDebugDetach(debugSession); +} + TEST_F(DebugApiLinuxMultitileTest, GivenMultitileDeviceWhenCallingResumeThenThreadsFromBothTilesAreResumed) { zet_debug_config_t config = {}; config.pid = 0x1234; diff --git a/level_zero/tools/test/unit_tests/sources/debug/mock_debug_session.h b/level_zero/tools/test/unit_tests/sources/debug/mock_debug_session.h index 24f177f10f..40a88d23ca 100644 --- a/level_zero/tools/test/unit_tests/sources/debug/mock_debug_session.h +++ b/level_zero/tools/test/unit_tests/sources/debug/mock_debug_session.h @@ -11,8 +11,12 @@ #include "level_zero/tools/source/debug/debug_session.h" namespace L0 { +DebugSession *createDebugSessionHelper(const zet_debug_config_t &config, Device *device, int debugFd); + namespace ult { +using CreateDebugSessionHelperFunc = decltype(&L0::createDebugSessionHelper); + class OsInterfaceWithDebugAttach : public NEO::OSInterface { public: OsInterfaceWithDebugAttach() : OSInterface() {} @@ -31,14 +35,13 @@ struct DebugSessionMock : public L0::DebugSession { using L0::DebugSession::getSingleThreadsForDevice; using L0::DebugSession::isBindlessSystemRoutine; - DebugSessionMock(const zet_debug_config_t &config, L0::Device *device) : DebugSession(config, device), config(config) { - createEuThreads(); - }; + DebugSessionMock(const zet_debug_config_t &config, L0::Device *device) : DebugSession(config, device), config(config){}; bool closeConnection() override { return true; } ze_result_t initialize() override { if (config.pid == 0) { return ZE_RESULT_ERROR_UNKNOWN; } + createEuThreads(); return ZE_RESULT_SUCCESS; } ze_result_t readEvent(uint64_t timeout, zet_debug_event_t *event) override { @@ -83,6 +86,8 @@ struct DebugSessionMock : public L0::DebugSession { return nullptr; } + void setAttachMode(bool isRootAttach) override {} + zet_debug_config_t config; bool asyncThreadStarted = false; }; diff --git a/level_zero/tools/test/unit_tests/sources/debug/test_debug_api.cpp b/level_zero/tools/test/unit_tests/sources/debug/test_debug_api.cpp index c3286d469c..e531a1e17c 100644 --- a/level_zero/tools/test/unit_tests/sources/debug/test_debug_api.cpp +++ b/level_zero/tools/test/unit_tests/sources/debug/test_debug_api.cpp @@ -113,7 +113,10 @@ TEST_F(DebugApiTest, givenStateSaveAreaHeaderUnavailableWhenGettingDebugProperti EXPECT_EQ(0u, debugProperties.flags); } -TEST_F(DebugApiTest, givenSubDeviceWhenDebugAttachIsAvaialbleThenGetPropertiesReturnsNoFlag) { +TEST_F(DebugApiTest, givenTileAttachedDisabledAndSubDeviceWhenDebugAttachIsAvaialbleThenGetPropertiesReturnsNoFlag) { + DebugManagerStateRestore restorer; + NEO::DebugManager.flags.ExperimentalEnableTileAttach.set(0); + zet_device_debug_properties_t debugProperties = {}; debugProperties.flags = ZET_DEVICE_DEBUG_PROPERTY_FLAG_FORCE_UINT32; @@ -316,7 +319,10 @@ TEST(DebugSessionTest, givenDeviceWithDebugSessionWhenRemoveCalledThenSessionIsN EXPECT_EQ(nullptr, deviceImp.debugSession.get()); } -TEST(DebugSessionTest, givenSubDeviceWhenCreatingSessionThenNullptrReturned) { +TEST(DebugSessionTest, givenTileAttachDisabledAndSubDeviceWhenCreatingSessionThenNullptrReturned) { + DebugManagerStateRestore restorer; + NEO::DebugManager.flags.ExperimentalEnableTileAttach.set(0); + zet_debug_config_t config = {}; config.pid = 0x1234; @@ -325,12 +331,34 @@ TEST(DebugSessionTest, givenSubDeviceWhenCreatingSessionThenNullptrReturned) { deviceImp.isSubdevice = true; ze_result_t result = ZE_RESULT_ERROR_DEVICE_LOST; - auto session = deviceImp.createDebugSession(config, result); + auto session = deviceImp.createDebugSession(config, result, false); EXPECT_EQ(nullptr, session); EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, result); } +TEST(DebugSessionTest, givenTileAttachDisabledAndSubDeviceWhenDebugAttachCalledThenErrorReturned) { + DebugManagerStateRestore restorer; + NEO::DebugManager.flags.ExperimentalEnableTileAttach.set(0); + + zet_debug_config_t config = {}; + config.pid = 0x1234; + + auto neoDevice = std::unique_ptr(NEO::MockDevice::createWithNewExecutionEnvironment(NEO::defaultHwInfo.get(), 0)); + neoDevice->incRefInternal(); + auto neoSubdevice = std::unique_ptr(neoDevice->createSubDevice(0)); + + auto deviceImp = std::make_unique>(neoSubdevice.get(), neoSubdevice->getExecutionEnvironment()); + deviceImp->isSubdevice = true; + + ze_result_t result = ZE_RESULT_ERROR_DEVICE_LOST; + zet_debug_session_handle_t debugSession = nullptr; + result = zetDebugAttach(deviceImp->toHandle(), &config, &debugSession); + + EXPECT_EQ(nullptr, debugSession); + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, result); +} + TEST(DebugSessionTest, givenRootDeviceWhenCreatingSessionThenResultReturnedIsCorrect) { zet_debug_config_t config = {}; config.pid = 0x1234; @@ -345,7 +373,7 @@ TEST(DebugSessionTest, givenRootDeviceWhenCreatingSessionThenResultReturnedIsCor deviceImp.isSubdevice = false; ze_result_t result = ZE_RESULT_ERROR_DEVICE_LOST; - auto session = deviceImp.createDebugSession(config, result); + auto session = deviceImp.createDebugSession(config, result, true); EXPECT_EQ(nullptr, session); EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, result); diff --git a/level_zero/tools/test/unit_tests/sources/debug/windows/test_debug_api_windows.cpp b/level_zero/tools/test/unit_tests/sources/debug/windows/test_debug_api_windows.cpp index 165b40a938..6a87dc2370 100644 --- a/level_zero/tools/test/unit_tests/sources/debug/windows/test_debug_api_windows.cpp +++ b/level_zero/tools/test/unit_tests/sources/debug/windows/test_debug_api_windows.cpp @@ -461,17 +461,42 @@ TEST_F(DebugApiWindowsTest, givenDebugAttachIsNotAvailableWhenGetDebugProperties EXPECT_EQ(0u, debugProperties.flags); } +TEST_F(DebugApiWindowsTest, givenSubDeviceWhenDebugAttachCalledThenUnsupportedErrorIsReturned) { + zet_debug_config_t config = {}; + config.pid = 0x1234; + + NEO::Device *neoDevice(NEO::MockDevice::createWithNewExecutionEnvironment(NEO::defaultHwInfo.get(), 0)); + Mock deviceImp(neoDevice, neoDevice->getExecutionEnvironment()); + deviceImp.isSubdevice = true; + + auto mockWddm = new WddmEuDebugInterfaceMock(*neoDevice->getExecutionEnvironment()->rootDeviceEnvironments[0]); + mockWddm->debugAttachAvailable = false; + neoDevice->getExecutionEnvironment()->rootDeviceEnvironments[0]->osInterface.reset(new NEO::OSInterface); + neoDevice->getExecutionEnvironment()->rootDeviceEnvironments[0]->osInterface->setDriverModel(std::unique_ptr(mockWddm)); + + ze_result_t result = ZE_RESULT_SUCCESS; + auto session = DebugSession::create(config, &deviceImp, result, false); + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, result); + EXPECT_EQ(nullptr, session); + + result = ZE_RESULT_SUCCESS; + mockWddm->debugAttachAvailable = true; + session = DebugSession::create(config, &deviceImp, result, false); + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, result); + EXPECT_EQ(nullptr, session); +} + TEST_F(DebugApiWindowsTest, GivenRootDeviceWhenDebugSessionIsCreatedForTheSecondTimeThenSuccessIsReturned) { zet_debug_config_t config = {}; config.pid = 0x1234; ze_result_t result = ZE_RESULT_SUCCESS; - auto sessionMock = device->createDebugSession(config, result); + auto sessionMock = device->createDebugSession(config, result, true); ASSERT_NE(nullptr, sessionMock); EXPECT_EQ(ZE_RESULT_SUCCESS, result); - auto sessionMock2 = device->createDebugSession(config, result); + auto sessionMock2 = device->createDebugSession(config, result, true); EXPECT_EQ(sessionMock, sessionMock2); EXPECT_EQ(ZE_RESULT_SUCCESS, result); } diff --git a/shared/source/debug_settings/debug_variables_base.inl b/shared/source/debug_settings/debug_variables_base.inl index 7106ddd225..710d8cca64 100644 --- a/shared/source/debug_settings/debug_variables_base.inl +++ b/shared/source/debug_settings/debug_variables_base.inl @@ -428,7 +428,7 @@ DECLARE_DEBUG_VARIABLE(int32_t, ExperimentalH2DCpuCopyThreshold, -1, "Override d DECLARE_DEBUG_VARIABLE(int32_t, ExperimentalD2HCpuCopyThreshold, -1, "Override default treshold (in bytes) for D2H CPU copy.") DECLARE_DEBUG_VARIABLE(bool, ExperimentalEnableSourceLevelDebugger, false, "Experimentally enable source level debugger.") DECLARE_DEBUG_VARIABLE(bool, ExperimentalEnableL0DebuggerForOpenCL, false, "Experimentally enable debugging OCL with L0 Debug API.") -DECLARE_DEBUG_VARIABLE(bool, ExperimentalEnableTileAttach, false, "Experimentally enable attaching to tiles (subdevices).") +DECLARE_DEBUG_VARIABLE(bool, ExperimentalEnableTileAttach, true, "Experimentally enable attaching to tiles (subdevices).") DECLARE_DEBUG_VARIABLE(bool, ExperimentalCopyThroughLock, false, "Experimentally copy memory through locked ptr.") /*DRIVER TOGGLES*/ diff --git a/shared/test/common/test_files/igdrcl.config b/shared/test/common/test_files/igdrcl.config index 7fde1d9067..a47f29ede5 100644 --- a/shared/test/common/test_files/igdrcl.config +++ b/shared/test/common/test_files/igdrcl.config @@ -455,7 +455,7 @@ DebuggerDisableSingleAddressSbaTracking = 0 ForceImagesSupport = -1 RemoveUserFenceInCmdlistResetAndDestroy = -1 ForceCsrLockInBcsEnqueueOnlyForGpgpuSubmission = -1 -ExperimentalEnableTileAttach = 0 +ExperimentalEnableTileAttach = 1 DirectSubmissionDisablePrefetcher = -1 ForceDefaultGrfCompilationMode = 0 ForceLargeGrfCompilationMode = 0