L0Debug - fix interrupt

- pass deviceIndex based on deviceBitfield
- do not call ioctl again on EBUSY error

Resolves: NEO-7414

Signed-off-by: Mateusz Hoppe <mateusz.hoppe@intel.com>
This commit is contained in:
Mateusz Hoppe
2022-10-14 10:51:14 +00:00
committed by Compute-Runtime-Automation
parent 647321af6f
commit 95505d87a5
4 changed files with 101 additions and 6 deletions

View File

@@ -564,11 +564,7 @@ void DebugSessionImp::sendInterrupts() {
auto deviceCount = std::max(1u, connectedDevice->getNEODevice()->getNumSubDevices());
if (deviceCount == 1) {
uint32_t deviceIndex = 0;
if (connectedDevice->getNEODevice()->isSubDevice()) {
deviceIndex = Math::log2(static_cast<uint32_t>(connectedDevice->getNEODevice()->getDeviceBitfield().to_ulong()));
}
uint32_t deviceIndex = Math::log2(static_cast<uint32_t>(connectedDevice->getNEODevice()->getDeviceBitfield().to_ulong()));
ze_result_t result;
{

View File

@@ -47,9 +47,21 @@ struct DebugSessionLinux : DebugSessionImp {
MOCKABLE_VIRTUAL ~IoctlHandler() = default;
MOCKABLE_VIRTUAL int ioctl(int fd, unsigned long request, void *arg) {
int ret = 0;
int error = 0;
bool shouldRetryIoctl = false;
do {
shouldRetryIoctl = false;
ret = NEO::SysCalls::ioctl(fd, request, arg);
} while (ret == -1 && (errno == EINTR || errno == EAGAIN || errno == EBUSY));
error = errno;
if (ret == -1) {
shouldRetryIoctl = (error == EINTR || error == EAGAIN || error == EBUSY);
if (request == PRELIM_I915_DEBUG_IOCTL_EU_CONTROL) {
shouldRetryIoctl = (error == EINTR || error == EAGAIN);
}
}
} while (shouldRetryIoctl);
return ret;
}

View File

@@ -3025,5 +3025,41 @@ TEST_F(MultiTileDebugSessionTest, givenAttachedRootDeviceWhenAttachingToTiletDev
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
}
struct AffinityMaskForSingleSubDevice : MultipleDevicesWithCustomHwInfo {
void setUp() {
DebugManager.flags.ZE_AFFINITY_MASK.set("0.1");
MultipleDevicesWithCustomHwInfo::numSubDevices = 2;
MultipleDevicesWithCustomHwInfo::setUp();
}
void tearDown() {
MultipleDevicesWithCustomHwInfo::tearDown();
}
DebugManagerStateRestore restorer;
};
using AffinityMaskForSingleSubDeviceTest = Test<AffinityMaskForSingleSubDevice>;
TEST_F(AffinityMaskForSingleSubDeviceTest, givenDeviceDebugSessionWhenSendingInterruptsThenInterruptIsSentWithCorrectDeviceIndex) {
zet_debug_config_t config = {};
config.pid = 0x1234;
L0::Device *device = driverHandle->devices[0];
L0::DeviceImp *deviceImp = static_cast<DeviceImp *>(device);
auto sessionMock = std::make_unique<MockDebugSession>(config, deviceImp);
sessionMock->interruptImpResult = ZE_RESULT_SUCCESS;
ze_device_thread_t apiThread = {0, 0, 0, 0};
auto result = sessionMock->interrupt(apiThread);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
sessionMock->sendInterrupts();
EXPECT_TRUE(sessionMock->interruptSent);
EXPECT_EQ(1u, sessionMock->interruptedDevices[0]);
}
} // namespace ult
} // namespace L0

View File

@@ -21,6 +21,7 @@
#include "shared/test/common/libult/linux/drm_query_mock.h"
#include "shared/test/common/mocks/mock_sip.h"
#include "shared/test/common/mocks/ult_device_factory.h"
#include "shared/test/common/os_interface/linux/sys_calls_linux_ult.h"
#include "shared/test/common/test_macros/test.h"
#include "level_zero/core/source/hw_helpers/l0_hw_helper.h"
@@ -93,6 +94,56 @@ TEST(IoctlHandler, GivenHandlerWhenMmapAndMunmapCalledThenRedirectedToSysCall) {
NEO::SysCalls::munmapFuncCalled = 0;
}
TEST(IoctlHandler, GivenHandlerWhenEuControlIoctlFailsWithEBUSYThenIoctlIsNotCalledAgain) {
VariableBackup<decltype(SysCalls::sysCallsIoctl)> mockIoctl(&SysCalls::sysCallsIoctl);
VariableBackup<int> mockErrno(&errno);
int ioctlCount = 0;
SysCalls::sysCallsIoctl = [](int fileDescriptor, unsigned long int request, void *arg) -> int {
auto ioctlCount = reinterpret_cast<int *>(arg);
(*ioctlCount)++;
if (*ioctlCount < 2) {
errno = EBUSY;
return -1;
}
errno = 0;
return 0;
};
L0::DebugSessionLinux::IoctlHandler handler;
auto result = handler.ioctl(0, PRELIM_I915_DEBUG_IOCTL_EU_CONTROL, &ioctlCount);
EXPECT_EQ(-1, result);
EXPECT_EQ(1, ioctlCount);
}
TEST(IoctlHandler, GivenHandlerWhenEuControlIoctlFailsWithEAGAINOrEINTRThenIoctlIsCalledAgain) {
VariableBackup<decltype(SysCalls::sysCallsIoctl)> mockIoctl(&SysCalls::sysCallsIoctl);
VariableBackup<int> mockErrno(&errno);
int ioctlCount = 0;
SysCalls::sysCallsIoctl = [](int fileDescriptor, unsigned long int request, void *arg) -> int {
auto ioctlCount = reinterpret_cast<int *>(arg);
(*ioctlCount)++;
if (*ioctlCount == 1) {
errno = EAGAIN;
return -1;
}
if (*ioctlCount == 2) {
errno = EINTR;
return -1;
}
errno = 0;
return 0;
};
L0::DebugSessionLinux::IoctlHandler handler;
auto result = handler.ioctl(0, PRELIM_I915_DEBUG_IOCTL_EU_CONTROL, &ioctlCount);
EXPECT_EQ(0, result);
EXPECT_EQ(3, ioctlCount);
}
TEST(DebugSessionLinuxTest, GivenDebugSessionWhenExtractingCpuVaFromUuidThenCorrectCpuVaReturned) {
zet_debug_config_t config = {};
config.pid = 0x1234;