mirror of
https://github.com/intel/compute-runtime.git
synced 2025-09-15 13:01:45 +08:00
Do not call DebuggerOpen ioctl again on EBUSY
Resolves: NEO-7429 Signed-off-by: Mateusz Hoppe <mateusz.hoppe@intel.com>
This commit is contained in:

committed by
Compute-Runtime-Automation

parent
abe4e0cb91
commit
5bd4b9eb48
@ -60,7 +60,7 @@ void Drm::queryAndSetVmBindPatIndexProgrammingSupport() {
|
||||
int Drm::ioctl(DrmIoctl request, void *arg) {
|
||||
auto requestValue = getIoctlRequestValue(request, ioctlHelper.get());
|
||||
int ret;
|
||||
int returnedErrno;
|
||||
int returnedErrno = 0;
|
||||
SYSTEM_ENTER();
|
||||
do {
|
||||
auto measureTime = DebugManager.flags.PrintIoctlTimes.get();
|
||||
@ -78,7 +78,9 @@ int Drm::ioctl(DrmIoctl request, void *arg) {
|
||||
}
|
||||
ret = SysCalls::ioctl(getFileDescriptor(), requestValue, arg);
|
||||
|
||||
returnedErrno = errno;
|
||||
if (ret != 0) {
|
||||
returnedErrno = getErrno();
|
||||
}
|
||||
|
||||
if (measureTime) {
|
||||
end = std::chrono::steady_clock::now();
|
||||
@ -108,7 +110,7 @@ int Drm::ioctl(DrmIoctl request, void *arg) {
|
||||
}
|
||||
}
|
||||
|
||||
} while (ret == -1 && (returnedErrno == EINTR || returnedErrno == EAGAIN || returnedErrno == EBUSY || returnedErrno == -EBUSY));
|
||||
} while (ret == -1 && checkIfIoctlReinvokeRequired(returnedErrno, request, ioctlHelper.get()));
|
||||
SYSTEM_LEAVE(request);
|
||||
return ret;
|
||||
}
|
||||
|
@ -29,6 +29,13 @@ unsigned int getIoctlRequestValue(DrmIoctl ioctlRequest, IoctlHelper *ioctlHelpe
|
||||
}
|
||||
}
|
||||
|
||||
bool checkIfIoctlReinvokeRequired(int error, DrmIoctl ioctlRequest, IoctlHelper *ioctlHelper) {
|
||||
if (ioctlHelper) {
|
||||
return ioctlHelper->checkIfIoctlReinvokeRequired(error, ioctlRequest);
|
||||
}
|
||||
return (error == EINTR || error == EAGAIN || error == EBUSY || error == -EBUSY);
|
||||
}
|
||||
|
||||
int getDrmParamValue(DrmParam drmParam, IoctlHelper *ioctlHelper) {
|
||||
if (ioctlHelper) {
|
||||
return ioctlHelper->getDrmParamValue(drmParam);
|
||||
|
@ -207,6 +207,14 @@ struct DrmVersion {
|
||||
char *desc;
|
||||
};
|
||||
|
||||
struct DrmDebuggerOpen {
|
||||
uint64_t pid;
|
||||
uint32_t flags;
|
||||
uint32_t version;
|
||||
uint64_t events;
|
||||
uint64_t extensions;
|
||||
};
|
||||
|
||||
enum class DrmIoctl {
|
||||
GemExecbuffer2,
|
||||
GemWait,
|
||||
@ -299,5 +307,6 @@ unsigned int getIoctlRequestValue(DrmIoctl ioctlRequest, IoctlHelper *ioctlHelpe
|
||||
int getDrmParamValue(DrmParam drmParam, IoctlHelper *ioctlHelper);
|
||||
std::string getDrmParamString(DrmParam param, IoctlHelper *ioctlHelper);
|
||||
std::string getIoctlString(DrmIoctl ioctlRequest, IoctlHelper *ioctlHelper);
|
||||
bool checkIfIoctlReinvokeRequired(int error, DrmIoctl ioctlRequest, IoctlHelper *ioctlHelper);
|
||||
|
||||
} // namespace NEO
|
||||
|
@ -369,4 +369,7 @@ std::string IoctlHelper::getFileForMaxMemoryFrequencyOfSubDevice(int subDeviceId
|
||||
return "/gt/gt" + std::to_string(subDeviceId) + "/mem_RP0_freq_mhz";
|
||||
}
|
||||
|
||||
bool IoctlHelper::checkIfIoctlReinvokeRequired(int error, DrmIoctl ioctlRequest) const {
|
||||
return (error == EINTR || error == EAGAIN || error == EBUSY || error == -EBUSY);
|
||||
}
|
||||
} // namespace NEO
|
||||
|
@ -114,6 +114,7 @@ class IoctlHelper {
|
||||
virtual std::string getDrmParamString(DrmParam param) const = 0;
|
||||
virtual std::string getIoctlString(DrmIoctl ioctlRequest) const = 0;
|
||||
|
||||
virtual bool checkIfIoctlReinvokeRequired(int error, DrmIoctl ioctlRequest) const;
|
||||
virtual std::vector<MemoryRegion> translateToMemoryRegions(const std::vector<uint8_t> ®ionInfo);
|
||||
|
||||
virtual uint32_t createDrmContext(Drm &drm, OsContextLinux &osContext, uint32_t drmVmId, uint32_t deviceIndex);
|
||||
@ -254,6 +255,7 @@ class IoctlHelperPrelim20 : public IoctlHelper {
|
||||
int getDrmParamValue(DrmParam drmParam) const override;
|
||||
std::string getDrmParamString(DrmParam param) const override;
|
||||
std::string getIoctlString(DrmIoctl ioctlRequest) const override;
|
||||
bool checkIfIoctlReinvokeRequired(int error, DrmIoctl ioctlRequest) const override;
|
||||
};
|
||||
|
||||
} // namespace NEO
|
||||
|
@ -645,6 +645,16 @@ std::string IoctlHelperPrelim20::getIoctlString(DrmIoctl ioctlRequest) const {
|
||||
}
|
||||
}
|
||||
|
||||
bool IoctlHelperPrelim20::checkIfIoctlReinvokeRequired(int error, DrmIoctl ioctlRequest) const {
|
||||
switch (ioctlRequest) {
|
||||
case DrmIoctl::DebuggerOpen:
|
||||
return (error == EINTR || error == EAGAIN);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return IoctlHelper::checkIfIoctlReinvokeRequired(error, ioctlRequest);
|
||||
}
|
||||
|
||||
static_assert(sizeof(MemoryClassInstance) == sizeof(prelim_drm_i915_gem_memory_class_instance));
|
||||
static_assert(offsetof(MemoryClassInstance, memoryClass) == offsetof(prelim_drm_i915_gem_memory_class_instance, memory_class));
|
||||
static_assert(offsetof(MemoryClassInstance, memoryInstance) == offsetof(prelim_drm_i915_gem_memory_class_instance, memory_instance));
|
||||
|
@ -206,6 +206,68 @@ TEST(DrmQueryTest, WhenCallingIsDebugAttachAvailableThenReturnValueIsTrue) {
|
||||
EXPECT_TRUE(drm.isDebugAttachAvailable());
|
||||
}
|
||||
|
||||
TEST(DrmPrelimTest, GivenDebuggerOpenIoctlWhenErrorEbusyReturnedThenErrorIsReturnedWithoutReinvokingIoctl) {
|
||||
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
|
||||
DrmQueryMock drm{*executionEnvironment->rootDeviceEnvironments[0]};
|
||||
drm.allowDebugAttachCallBase = true;
|
||||
|
||||
VariableBackup<decltype(SysCalls::sysCallsIoctl)> mockIoctl(&SysCalls::sysCallsIoctl, [](int fileDescriptor, unsigned long int request, void *arg) -> int {
|
||||
return -1;
|
||||
});
|
||||
DrmDebuggerOpen open = {};
|
||||
open.pid = 1;
|
||||
open.events = 0;
|
||||
drm.context.debuggerOpenRetval = -1;
|
||||
drm.errnoRetVal = EBUSY;
|
||||
|
||||
auto ret = drm.Drm::ioctl(DrmIoctl::DebuggerOpen, &open);
|
||||
EXPECT_EQ(-1, ret);
|
||||
}
|
||||
|
||||
TEST(DrmPrelimTest, GivenDebuggerOpenIoctlWhenErrorEAgainOrEIntrReturnedThenIoctlIsCalledAgain) {
|
||||
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
|
||||
DrmQueryMock drm{*executionEnvironment->rootDeviceEnvironments[0]};
|
||||
drm.allowDebugAttachCallBase = true;
|
||||
drm.baseErrno = false;
|
||||
|
||||
DrmDebuggerOpen open = {};
|
||||
open.pid = 1;
|
||||
open.events = 0;
|
||||
|
||||
{
|
||||
VariableBackup<decltype(SysCalls::sysCallsIoctl)> mockIoctl(&SysCalls::sysCallsIoctl, [](int fileDescriptor, unsigned long int request, void *arg) -> int {
|
||||
static int callCount = 3;
|
||||
if (callCount > 0) {
|
||||
callCount--;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
|
||||
drm.errnoRetVal = EAGAIN;
|
||||
|
||||
auto ret = drm.Drm::ioctl(DrmIoctl::DebuggerOpen, &open);
|
||||
EXPECT_EQ(0, ret);
|
||||
}
|
||||
|
||||
{
|
||||
VariableBackup<decltype(SysCalls::sysCallsIoctl)> mockIoctl(&SysCalls::sysCallsIoctl, [](int fileDescriptor, unsigned long int request, void *arg) -> int {
|
||||
static int callCount = 3;
|
||||
if (callCount > 0) {
|
||||
callCount--;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
|
||||
drm.ioctlCallsCount = 0;
|
||||
drm.errnoRetVal = EINTR;
|
||||
|
||||
auto ret = drm.Drm::ioctl(DrmIoctl::DebuggerOpen, &open);
|
||||
EXPECT_EQ(0, ret);
|
||||
}
|
||||
}
|
||||
|
||||
struct BufferObjectMock : public BufferObject {
|
||||
using BufferObject::BufferObject;
|
||||
using BufferObject::fillExecObject;
|
||||
|
@ -1404,6 +1404,36 @@ TEST(DrmWrapperTest, WhenGettingDrmParamValueStringThenProperStringIsReturned) {
|
||||
EXPECT_THROW(getDrmParamString(DrmParam::EngineClassRender, &ioctlHelper), std::runtime_error);
|
||||
}
|
||||
|
||||
TEST(DrmWrapperTest, givenEAgainOrEIntrOrEBusyWhenCheckingIfReinvokeRequiredThenTrueIsReturned) {
|
||||
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
|
||||
DrmMock drm{*executionEnvironment->rootDeviceEnvironments[0]};
|
||||
|
||||
MockIoctlHelper ioctlHelper{drm};
|
||||
EXPECT_TRUE(checkIfIoctlReinvokeRequired(EAGAIN, DrmIoctl::Getparam, &ioctlHelper));
|
||||
EXPECT_TRUE(checkIfIoctlReinvokeRequired(EINTR, DrmIoctl::Getparam, &ioctlHelper));
|
||||
EXPECT_TRUE(checkIfIoctlReinvokeRequired(EBUSY, DrmIoctl::Getparam, &ioctlHelper));
|
||||
EXPECT_TRUE(checkIfIoctlReinvokeRequired(-EBUSY, DrmIoctl::Getparam, &ioctlHelper));
|
||||
}
|
||||
|
||||
TEST(DrmWrapperTest, givenNoIoctlHelperAndEAgainOrEIntrOrEBusyWhenCheckingIfReinvokeRequiredThenTrueIsReturned) {
|
||||
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
|
||||
DrmMock drm{*executionEnvironment->rootDeviceEnvironments[0]};
|
||||
|
||||
EXPECT_TRUE(checkIfIoctlReinvokeRequired(EAGAIN, DrmIoctl::Getparam, nullptr));
|
||||
EXPECT_TRUE(checkIfIoctlReinvokeRequired(EINTR, DrmIoctl::Getparam, nullptr));
|
||||
EXPECT_TRUE(checkIfIoctlReinvokeRequired(EBUSY, DrmIoctl::Getparam, nullptr));
|
||||
EXPECT_TRUE(checkIfIoctlReinvokeRequired(-EBUSY, DrmIoctl::Getparam, nullptr));
|
||||
}
|
||||
|
||||
TEST(DrmWrapperTest, givenErrorWhenCheckingIfReinvokeRequiredThenFalseIsReturned) {
|
||||
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
|
||||
DrmMock drm{*executionEnvironment->rootDeviceEnvironments[0]};
|
||||
|
||||
MockIoctlHelper ioctlHelper{drm};
|
||||
EXPECT_FALSE(checkIfIoctlReinvokeRequired(ENOENT, DrmIoctl::Getparam, &ioctlHelper));
|
||||
EXPECT_FALSE(checkIfIoctlReinvokeRequired(ENOENT, DrmIoctl::Getparam, nullptr));
|
||||
}
|
||||
|
||||
TEST(IoctlHelperTest, whenGettingDrmParamValueThenProperValueIsReturned) {
|
||||
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
|
||||
DrmMock drm{*executionEnvironment->rootDeviceEnvironments[0]};
|
||||
|
Reference in New Issue
Block a user