mirror of
https://github.com/intel/compute-runtime.git
synced 2026-01-03 14:55:24 +08:00
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:
committed by
Compute-Runtime-Automation
parent
647321af6f
commit
95505d87a5
@@ -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;
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user