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) {
|
int Drm::ioctl(DrmIoctl request, void *arg) {
|
||||||
auto requestValue = getIoctlRequestValue(request, ioctlHelper.get());
|
auto requestValue = getIoctlRequestValue(request, ioctlHelper.get());
|
||||||
int ret;
|
int ret;
|
||||||
int returnedErrno;
|
int returnedErrno = 0;
|
||||||
SYSTEM_ENTER();
|
SYSTEM_ENTER();
|
||||||
do {
|
do {
|
||||||
auto measureTime = DebugManager.flags.PrintIoctlTimes.get();
|
auto measureTime = DebugManager.flags.PrintIoctlTimes.get();
|
||||||
@ -78,7 +78,9 @@ int Drm::ioctl(DrmIoctl request, void *arg) {
|
|||||||
}
|
}
|
||||||
ret = SysCalls::ioctl(getFileDescriptor(), requestValue, arg);
|
ret = SysCalls::ioctl(getFileDescriptor(), requestValue, arg);
|
||||||
|
|
||||||
returnedErrno = errno;
|
if (ret != 0) {
|
||||||
|
returnedErrno = getErrno();
|
||||||
|
}
|
||||||
|
|
||||||
if (measureTime) {
|
if (measureTime) {
|
||||||
end = std::chrono::steady_clock::now();
|
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);
|
SYSTEM_LEAVE(request);
|
||||||
return ret;
|
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) {
|
int getDrmParamValue(DrmParam drmParam, IoctlHelper *ioctlHelper) {
|
||||||
if (ioctlHelper) {
|
if (ioctlHelper) {
|
||||||
return ioctlHelper->getDrmParamValue(drmParam);
|
return ioctlHelper->getDrmParamValue(drmParam);
|
||||||
|
@ -207,6 +207,14 @@ struct DrmVersion {
|
|||||||
char *desc;
|
char *desc;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct DrmDebuggerOpen {
|
||||||
|
uint64_t pid;
|
||||||
|
uint32_t flags;
|
||||||
|
uint32_t version;
|
||||||
|
uint64_t events;
|
||||||
|
uint64_t extensions;
|
||||||
|
};
|
||||||
|
|
||||||
enum class DrmIoctl {
|
enum class DrmIoctl {
|
||||||
GemExecbuffer2,
|
GemExecbuffer2,
|
||||||
GemWait,
|
GemWait,
|
||||||
@ -299,5 +307,6 @@ unsigned int getIoctlRequestValue(DrmIoctl ioctlRequest, IoctlHelper *ioctlHelpe
|
|||||||
int getDrmParamValue(DrmParam drmParam, IoctlHelper *ioctlHelper);
|
int getDrmParamValue(DrmParam drmParam, IoctlHelper *ioctlHelper);
|
||||||
std::string getDrmParamString(DrmParam param, IoctlHelper *ioctlHelper);
|
std::string getDrmParamString(DrmParam param, IoctlHelper *ioctlHelper);
|
||||||
std::string getIoctlString(DrmIoctl ioctlRequest, IoctlHelper *ioctlHelper);
|
std::string getIoctlString(DrmIoctl ioctlRequest, IoctlHelper *ioctlHelper);
|
||||||
|
bool checkIfIoctlReinvokeRequired(int error, DrmIoctl ioctlRequest, IoctlHelper *ioctlHelper);
|
||||||
|
|
||||||
} // namespace NEO
|
} // namespace NEO
|
||||||
|
@ -369,4 +369,7 @@ std::string IoctlHelper::getFileForMaxMemoryFrequencyOfSubDevice(int subDeviceId
|
|||||||
return "/gt/gt" + std::to_string(subDeviceId) + "/mem_RP0_freq_mhz";
|
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
|
} // namespace NEO
|
||||||
|
@ -114,6 +114,7 @@ class IoctlHelper {
|
|||||||
virtual std::string getDrmParamString(DrmParam param) const = 0;
|
virtual std::string getDrmParamString(DrmParam param) const = 0;
|
||||||
virtual std::string getIoctlString(DrmIoctl ioctlRequest) 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 std::vector<MemoryRegion> translateToMemoryRegions(const std::vector<uint8_t> ®ionInfo);
|
||||||
|
|
||||||
virtual uint32_t createDrmContext(Drm &drm, OsContextLinux &osContext, uint32_t drmVmId, uint32_t deviceIndex);
|
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;
|
int getDrmParamValue(DrmParam drmParam) const override;
|
||||||
std::string getDrmParamString(DrmParam param) const override;
|
std::string getDrmParamString(DrmParam param) const override;
|
||||||
std::string getIoctlString(DrmIoctl ioctlRequest) const override;
|
std::string getIoctlString(DrmIoctl ioctlRequest) const override;
|
||||||
|
bool checkIfIoctlReinvokeRequired(int error, DrmIoctl ioctlRequest) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace NEO
|
} // 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(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, 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));
|
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());
|
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 {
|
struct BufferObjectMock : public BufferObject {
|
||||||
using BufferObject::BufferObject;
|
using BufferObject::BufferObject;
|
||||||
using BufferObject::fillExecObject;
|
using BufferObject::fillExecObject;
|
||||||
|
@ -1404,6 +1404,36 @@ TEST(DrmWrapperTest, WhenGettingDrmParamValueStringThenProperStringIsReturned) {
|
|||||||
EXPECT_THROW(getDrmParamString(DrmParam::EngineClassRender, &ioctlHelper), std::runtime_error);
|
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) {
|
TEST(IoctlHelperTest, whenGettingDrmParamValueThenProperValueIsReturned) {
|
||||||
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
|
auto executionEnvironment = std::make_unique<MockExecutionEnvironment>();
|
||||||
DrmMock drm{*executionEnvironment->rootDeviceEnvironments[0]};
|
DrmMock drm{*executionEnvironment->rootDeviceEnvironments[0]};
|
||||||
|
Reference in New Issue
Block a user