From aa59ee94b2e5ad90b66afa61d3873ff2df195b14 Mon Sep 17 00:00:00 2001 From: Mateusz Hoppe Date: Wed, 24 Aug 2022 12:03:47 +0000 Subject: [PATCH] L0Debug - close debug fd when DebugSession is destroyed - after last tile DebugSession is detached, root DebugSession must close fd Related-To: NEO-5784 Signed-off-by: Mateusz Hoppe --- .../debug/linux/prelim/debug_session.cpp | 30 ++++++++++------- .../source/debug/linux/prelim/debug_session.h | 2 ++ .../linux/debug_session_fixtures_linux.h | 1 + .../debug/linux/test_debug_api_linux.cpp | 20 ++++++++++++ .../linux/tile_debug_session_linux_tests.cpp | 32 +++++++++++++++++++ 5 files changed, 73 insertions(+), 12 deletions(-) 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 1ac6fae2ce..464c4855f2 100644 --- a/level_zero/tools/source/debug/linux/prelim/debug_session.cpp +++ b/level_zero/tools/source/debug/linux/prelim/debug_session.cpp @@ -47,6 +47,7 @@ DebugSessionLinux::~DebugSessionLinux() { delete session.first; } tileSessions.resize(0); + closeFd(); } DebugSession *DebugSession::create(const zet_debug_config_t &config, Device *device, ze_result_t &result) { @@ -341,6 +342,21 @@ void DebugSessionLinux::closeAsyncThread() { internalEventThread.close(); } +bool DebugSessionLinux::closeFd() { + if (fd == 0) { + return false; + } + + auto res = NEO::SysCalls::close(fd); + + if (res != 0) { + PRINT_DEBUGGER_ERROR_LOG("Debug connection close() on fd: %d failed: retCode: %d\n", fd, res); + return false; + } + fd = 0; + return true; +} + std::unique_ptr DebugSessionLinux::getInternalEvent() { std::unique_ptr eventMemory; @@ -427,18 +443,8 @@ void DebugSessionLinux::readInternalEventsAsync() { bool DebugSessionLinux::closeConnection() { closeAsyncThread(); - internalEventThread.close(); - if (fd == 0) { - return false; - } - - auto res = NEO::SysCalls::close(fd); - - if (res != 0) { - PRINT_DEBUGGER_ERROR_LOG("Debug connection close() on fd: %d failed: retCode: %d\n", fd, res); - return false; - } - return true; + closeInternalEventsThread(); + return closeFd(); } void DebugSessionLinux::handleEvent(prelim_drm_i915_debug_event *event) { 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 58a1cc5748..43006eb239 100644 --- a/level_zero/tools/source/debug/linux/prelim/debug_session.h +++ b/level_zero/tools/source/debug/linux/prelim/debug_session.h @@ -211,6 +211,8 @@ struct DebugSessionLinux : DebugSessionImp { internalEventThread.close(); } + bool closeFd(); + virtual std::vector getAllMemoryHandles() { std::vector allVms; std::unique_lock memLock(asyncThreadMutex); 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 a158a19b1a..7a4f9c3a28 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 @@ -256,6 +256,7 @@ struct MockDebugSessionLinux : public L0::DebugSessionLinux { using L0::DebugSessionLinux::euControlInterruptSeqno; using L0::DebugSessionLinux::eventsToAck; using L0::DebugSessionLinux::extractVaFromUuidString; + using L0::DebugSessionLinux::fd; using L0::DebugSessionLinux::getRegisterSetProperties; using L0::DebugSessionLinux::getSbaBufferGpuVa; using L0::DebugSessionLinux::getStateSaveAreaHeader; 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 e1169dbb27..002516f71e 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 @@ -954,6 +954,8 @@ TEST_F(DebugApiLinuxTest, GivenDebugSessionWhenClosingConnectionThenSysCallClose EXPECT_NE(nullptr, session); NEO::SysCalls::closeFuncCalled = 0; + NEO::SysCalls::closeFuncArgPassed = 0; + auto ret = session->closeConnection(); EXPECT_TRUE(ret); @@ -965,6 +967,24 @@ TEST_F(DebugApiLinuxTest, GivenDebugSessionWhenClosingConnectionThenSysCallClose NEO::SysCalls::closeFuncArgPassed = 0; } +TEST_F(DebugApiLinuxTest, GivenDebugSessionWhenDestroyedThenSysCallCloseOnFdIsCalled) { + zet_debug_config_t config = {}; + config.pid = 0x1234; + + auto session = std::make_unique(config, device, 10); + EXPECT_NE(nullptr, session); + + NEO::SysCalls::closeFuncCalled = 0; + NEO::SysCalls::closeFuncArgPassed = 0; + + session.reset(nullptr); + EXPECT_EQ(1u, NEO::SysCalls::closeFuncCalled); + EXPECT_EQ(10, NEO::SysCalls::closeFuncArgPassed); + + NEO::SysCalls::closeFuncCalled = 0; + NEO::SysCalls::closeFuncArgPassed = 0; +} + TEST_F(DebugApiLinuxTest, GivenDebugSessionWithFdEqualZeroWhenClosingConnectionThenSysCallIsNotCalledAndFalseReturned) { zet_debug_config_t config = {}; config.pid = 0x1234; diff --git a/level_zero/tools/test/unit_tests/sources/debug/linux/tile_debug_session_linux_tests.cpp b/level_zero/tools/test/unit_tests/sources/debug/linux/tile_debug_session_linux_tests.cpp index 1ded55d0f5..c94eed99db 100644 --- a/level_zero/tools/test/unit_tests/sources/debug/linux/tile_debug_session_linux_tests.cpp +++ b/level_zero/tools/test/unit_tests/sources/debug/linux/tile_debug_session_linux_tests.cpp @@ -15,6 +15,15 @@ #include "level_zero/tools/test/unit_tests/sources/debug/mock_debug_session.h" #include + +namespace NEO { +namespace SysCalls { +extern uint32_t closeFuncCalled; +extern int closeFuncArgPassed; +extern int closeFuncRetVal; +} // namespace SysCalls +} // namespace NEO + namespace L0 { namespace ult { @@ -190,6 +199,29 @@ TEST_F(TileAttachTest, GivenTileAttachDisabledAndMultitileDeviceWhenCreatingTile ASSERT_EQ(0u, session->tileSessions.size()); } +TEST_F(TileAttachTest, givenTileDeviceWhenCallingDebugDetachOnLastSessionThenRootSessionIsClosed) { + zet_debug_config_t config = {}; + config.pid = 0x1234; + zet_debug_session_handle_t debugSession0 = nullptr; + + auto result = zetDebugAttach(neoDevice->getSubDevice(0)->getSpecializedDevice()->toHandle(), &config, &debugSession0); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_NE(nullptr, debugSession0); + + NEO::SysCalls::closeFuncCalled = 0; + NEO::SysCalls::closeFuncArgPassed = 0; + + auto debugFd = rootSession->fd; + result = zetDebugDetach(debugSession0); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + + EXPECT_EQ(1u, NEO::SysCalls::closeFuncCalled); + EXPECT_EQ(debugFd, NEO::SysCalls::closeFuncArgPassed); + + NEO::SysCalls::closeFuncCalled = 0; + NEO::SysCalls::closeFuncArgPassed = 0; +} + TEST_F(TileAttachTest, givenTileDeviceWhenCallingDebugAttachAndDetachThenSuccessAndValidSessionHandleAreReturned) { zet_debug_config_t config = {}; config.pid = 0x1234;