Skip to content

Commit 95505d8

Browse files
L0Debug - fix interrupt
- pass deviceIndex based on deviceBitfield - do not call ioctl again on EBUSY error Resolves: NEO-7414 Signed-off-by: Mateusz Hoppe <[email protected]>
1 parent 647321a commit 95505d8

File tree

4 files changed

+101
-6
lines changed

4 files changed

+101
-6
lines changed

level_zero/tools/source/debug/debug_session_imp.cpp

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -564,11 +564,7 @@ void DebugSessionImp::sendInterrupts() {
564564
auto deviceCount = std::max(1u, connectedDevice->getNEODevice()->getNumSubDevices());
565565

566566
if (deviceCount == 1) {
567-
uint32_t deviceIndex = 0;
568-
569-
if (connectedDevice->getNEODevice()->isSubDevice()) {
570-
deviceIndex = Math::log2(static_cast<uint32_t>(connectedDevice->getNEODevice()->getDeviceBitfield().to_ulong()));
571-
}
567+
uint32_t deviceIndex = Math::log2(static_cast<uint32_t>(connectedDevice->getNEODevice()->getDeviceBitfield().to_ulong()));
572568

573569
ze_result_t result;
574570
{

level_zero/tools/source/debug/linux/prelim/debug_session.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,21 @@ struct DebugSessionLinux : DebugSessionImp {
4747
MOCKABLE_VIRTUAL ~IoctlHandler() = default;
4848
MOCKABLE_VIRTUAL int ioctl(int fd, unsigned long request, void *arg) {
4949
int ret = 0;
50+
int error = 0;
51+
bool shouldRetryIoctl = false;
5052
do {
53+
shouldRetryIoctl = false;
5154
ret = NEO::SysCalls::ioctl(fd, request, arg);
52-
} while (ret == -1 && (errno == EINTR || errno == EAGAIN || errno == EBUSY));
55+
error = errno;
56+
57+
if (ret == -1) {
58+
shouldRetryIoctl = (error == EINTR || error == EAGAIN || error == EBUSY);
59+
60+
if (request == PRELIM_I915_DEBUG_IOCTL_EU_CONTROL) {
61+
shouldRetryIoctl = (error == EINTR || error == EAGAIN);
62+
}
63+
}
64+
} while (shouldRetryIoctl);
5365
return ret;
5466
}
5567

level_zero/tools/test/unit_tests/sources/debug/debug_session_tests.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3025,5 +3025,41 @@ TEST_F(MultiTileDebugSessionTest, givenAttachedRootDeviceWhenAttachingToTiletDev
30253025
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
30263026
}
30273027

3028+
struct AffinityMaskForSingleSubDevice : MultipleDevicesWithCustomHwInfo {
3029+
void setUp() {
3030+
DebugManager.flags.ZE_AFFINITY_MASK.set("0.1");
3031+
MultipleDevicesWithCustomHwInfo::numSubDevices = 2;
3032+
MultipleDevicesWithCustomHwInfo::setUp();
3033+
}
3034+
3035+
void tearDown() {
3036+
MultipleDevicesWithCustomHwInfo::tearDown();
3037+
}
3038+
DebugManagerStateRestore restorer;
3039+
};
3040+
3041+
using AffinityMaskForSingleSubDeviceTest = Test<AffinityMaskForSingleSubDevice>;
3042+
3043+
TEST_F(AffinityMaskForSingleSubDeviceTest, givenDeviceDebugSessionWhenSendingInterruptsThenInterruptIsSentWithCorrectDeviceIndex) {
3044+
zet_debug_config_t config = {};
3045+
config.pid = 0x1234;
3046+
3047+
L0::Device *device = driverHandle->devices[0];
3048+
L0::DeviceImp *deviceImp = static_cast<DeviceImp *>(device);
3049+
3050+
auto sessionMock = std::make_unique<MockDebugSession>(config, deviceImp);
3051+
3052+
sessionMock->interruptImpResult = ZE_RESULT_SUCCESS;
3053+
ze_device_thread_t apiThread = {0, 0, 0, 0};
3054+
3055+
auto result = sessionMock->interrupt(apiThread);
3056+
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
3057+
3058+
sessionMock->sendInterrupts();
3059+
3060+
EXPECT_TRUE(sessionMock->interruptSent);
3061+
EXPECT_EQ(1u, sessionMock->interruptedDevices[0]);
3062+
}
3063+
30283064
} // namespace ult
30293065
} // namespace L0

level_zero/tools/test/unit_tests/sources/debug/linux/test_debug_api_linux.cpp

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "shared/test/common/libult/linux/drm_query_mock.h"
2222
#include "shared/test/common/mocks/mock_sip.h"
2323
#include "shared/test/common/mocks/ult_device_factory.h"
24+
#include "shared/test/common/os_interface/linux/sys_calls_linux_ult.h"
2425
#include "shared/test/common/test_macros/test.h"
2526

2627
#include "level_zero/core/source/hw_helpers/l0_hw_helper.h"
@@ -93,6 +94,56 @@ TEST(IoctlHandler, GivenHandlerWhenMmapAndMunmapCalledThenRedirectedToSysCall) {
9394
NEO::SysCalls::munmapFuncCalled = 0;
9495
}
9596

97+
TEST(IoctlHandler, GivenHandlerWhenEuControlIoctlFailsWithEBUSYThenIoctlIsNotCalledAgain) {
98+
VariableBackup<decltype(SysCalls::sysCallsIoctl)> mockIoctl(&SysCalls::sysCallsIoctl);
99+
VariableBackup<int> mockErrno(&errno);
100+
int ioctlCount = 0;
101+
102+
SysCalls::sysCallsIoctl = [](int fileDescriptor, unsigned long int request, void *arg) -> int {
103+
auto ioctlCount = reinterpret_cast<int *>(arg);
104+
(*ioctlCount)++;
105+
if (*ioctlCount < 2) {
106+
errno = EBUSY;
107+
return -1;
108+
}
109+
errno = 0;
110+
return 0;
111+
};
112+
113+
L0::DebugSessionLinux::IoctlHandler handler;
114+
115+
auto result = handler.ioctl(0, PRELIM_I915_DEBUG_IOCTL_EU_CONTROL, &ioctlCount);
116+
EXPECT_EQ(-1, result);
117+
EXPECT_EQ(1, ioctlCount);
118+
}
119+
120+
TEST(IoctlHandler, GivenHandlerWhenEuControlIoctlFailsWithEAGAINOrEINTRThenIoctlIsCalledAgain) {
121+
VariableBackup<decltype(SysCalls::sysCallsIoctl)> mockIoctl(&SysCalls::sysCallsIoctl);
122+
VariableBackup<int> mockErrno(&errno);
123+
int ioctlCount = 0;
124+
125+
SysCalls::sysCallsIoctl = [](int fileDescriptor, unsigned long int request, void *arg) -> int {
126+
auto ioctlCount = reinterpret_cast<int *>(arg);
127+
(*ioctlCount)++;
128+
if (*ioctlCount == 1) {
129+
errno = EAGAIN;
130+
return -1;
131+
}
132+
if (*ioctlCount == 2) {
133+
errno = EINTR;
134+
return -1;
135+
}
136+
errno = 0;
137+
return 0;
138+
};
139+
140+
L0::DebugSessionLinux::IoctlHandler handler;
141+
142+
auto result = handler.ioctl(0, PRELIM_I915_DEBUG_IOCTL_EU_CONTROL, &ioctlCount);
143+
EXPECT_EQ(0, result);
144+
EXPECT_EQ(3, ioctlCount);
145+
}
146+
96147
TEST(DebugSessionLinuxTest, GivenDebugSessionWhenExtractingCpuVaFromUuidThenCorrectCpuVaReturned) {
97148
zet_debug_config_t config = {};
98149
config.pid = 0x1234;

0 commit comments

Comments
 (0)