diff --git a/runtime/dll/linux/drm_neo_create.cpp b/runtime/dll/linux/drm_neo_create.cpp index 753dc2209c..d697ec4999 100644 --- a/runtime/dll/linux/drm_neo_create.cpp +++ b/runtime/dll/linux/drm_neo_create.cpp @@ -23,6 +23,8 @@ namespace NEO { +bool (*Drm::pIsi915Version)(int fd) = Drm::isi915Version; +int (*Drm::pClose)(int fd) = ::close; const DeviceDescriptor deviceDescriptorTable[] = { #define DEVICE(devId, gt, gtType) {devId, >::hwInfo, >::setupHardwareInfo, gtType}, #include "devices.inl" @@ -71,26 +73,38 @@ int Drm::getDeviceFd(const int devType) { const char *pathPrefix; unsigned int startNum; const unsigned int maxDrmDevices = 64; - - switch (devType) { - case 0: - startNum = 128; - pathPrefix = "/dev/dri/renderD"; - break; - default: - startNum = 0; - pathPrefix = "/dev/dri/card"; - break; - } - - for (unsigned int i = 0; i < maxDrmDevices; i++) { - snprintf(fullPath, PATH_MAX, "%s%u", pathPrefix, i + startNum); - int fd = ::open(fullPath, O_RDWR); - if (fd >= 0) { - if (isi915Version(fd)) { - return fd; + if (DebugManager.flags.ForceDeviceId.get() == "unk") { + switch (devType) { + case 0: + startNum = 128; + pathPrefix = "/dev/dri/renderD"; + break; + default: + startNum = 0; + pathPrefix = "/dev/dri/card"; + break; + } + for (unsigned int i = 0; i < maxDrmDevices; i++) { + snprintf(fullPath, PATH_MAX, "%s%u", pathPrefix, i + startNum); + int fd = ::open(fullPath, O_RDWR); + if (fd >= 0) { + if (isi915Version(fd)) { + return fd; + } + ::close(fd); + } + } + } else { + const char *cardType[] = {"-render", "-card"}; + for (auto param : cardType) { + snprintf(fullPath, PATH_MAX, "/dev/dri/by-path/pci-0000:%s%s", DebugManager.flags.ForceDeviceId.get().c_str(), param); + int fd = ::open(fullPath, O_RDWR); + if (fd >= 0) { + if (pIsi915Version(fd)) { + return fd; + } + pClose(fd); } - ::close(fd); } } diff --git a/runtime/os_interface/linux/drm_neo.h b/runtime/os_interface/linux/drm_neo.h index 8e27b2d422..eba02e603b 100644 --- a/runtime/os_interface/linux/drm_neo.h +++ b/runtime/os_interface/linux/drm_neo.h @@ -83,6 +83,9 @@ class Drm { MemoryInfo *getMemoryInfo() const { return memoryInfo.get(); } + static bool (*pIsi915Version)(int fd); + static bool isi915Version(int fd); + static int (*pClose)(int fd); protected: int getQueueSliceCount(drm_i915_gem_context_param_sseu *sseu); @@ -97,7 +100,6 @@ class Drm { std::unique_ptr engineInfo; std::unique_ptr memoryInfo; - static bool isi915Version(int fd); static int getDeviceFd(const int devType); static int openDevice(); static Drm *create(int32_t deviceOrdinal); diff --git a/unit_tests/linux/main_linux_dll.cpp b/unit_tests/linux/main_linux_dll.cpp index 79c3d254d0..9511f4e544 100644 --- a/unit_tests/linux/main_linux_dll.cpp +++ b/unit_tests/linux/main_linux_dll.cpp @@ -48,6 +48,55 @@ void initializeTestedDevice() { } } +int openRetVal = 0; +int testOpen(const char *fullPath, int, ...) { + return openRetVal; +}; + +TEST(DrmTest, GivenSelectedNotExistingDeviceWhenGetDeviceFdThenFail) { + DebugManagerStateRestore stateRestore; + DebugManager.flags.ForceDeviceId.set("1234"); + struct DrmTest : public NEO::Drm { + using NEO::Drm::getDeviceFd; + }; + VariableBackup backupOpenFull(&openFull); + openFull = testOpen; + openRetVal = -1; + int fd = DrmTest::getDeviceFd(0); + EXPECT_EQ(fd, -1); +} + +TEST(DrmTest, GivenSelectedExistingDeviceWhenGetDeviceFdThenReturnFd) { + DebugManagerStateRestore stateRestore; + DebugManager.flags.ForceDeviceId.set("1234"); + struct DrmTest : public NEO::Drm { + using NEO::Drm::getDeviceFd; + }; + VariableBackup backupOpenFull(&openFull); + openRetVal = 1023; // fakeFd + openFull = testOpen; + int fd = DrmTest::getDeviceFd(0); + EXPECT_NE(fd, -1); +} + +TEST(DrmTest, GivenSelectedIncorectDeviceWhenGetDeviceFdThenFail) { + DebugManagerStateRestore stateRestore; + DebugManager.flags.ForceDeviceId.set("1234"); + struct DrmTest : public NEO::Drm { + using NEO::Drm::getDeviceFd; + }; + VariableBackup backupOpenFull(&openFull); + VariableBackup backupIsi915Version(&Drm::pIsi915Version); + VariableBackup backupClose(&Drm::pClose); + openFull = testOpen; + openRetVal = 1023; + Drm::pIsi915Version = [](int x) -> bool { return false; }; + Drm::pClose = [](int x) -> int { return 0; }; + + int fd = DrmTest::getDeviceFd(0); + EXPECT_EQ(fd, -1); +} + TEST_F(DrmTests, getReturnsNull) { auto drm = Drm::get(0); EXPECT_EQ(drm, nullptr); diff --git a/unit_tests/linux/mock_os_layer.cpp b/unit_tests/linux/mock_os_layer.cpp index c75b4a529d..fd7c6b545c 100644 --- a/unit_tests/linux/mock_os_layer.cpp +++ b/unit_tests/linux/mock_os_layer.cpp @@ -11,6 +11,7 @@ #include int (*c_open)(const char *pathname, int flags, ...) = nullptr; +int (*openFull)(const char *pathname, int flags, ...) = nullptr; int (*c_ioctl)(int fd, unsigned long int request, ...) = nullptr; int fakeFd = 1023; @@ -36,6 +37,9 @@ int ioctlSeq[8] = {0, 0, 0, 0, 0, 0, 0, 0}; size_t ioctlCnt = 0; int open(const char *pathname, int flags, ...) { + if (openFull != nullptr) { + return openFull(pathname, flags); + } if (c_open == nullptr) { c_open = (int (*)(const char *, int, ...))dlsym(RTLD_NEXT, "open"); } diff --git a/unit_tests/linux/mock_os_layer.h b/unit_tests/linux/mock_os_layer.h index 0d33ab67de..b560d4095c 100644 --- a/unit_tests/linux/mock_os_layer.h +++ b/unit_tests/linux/mock_os_layer.h @@ -24,6 +24,7 @@ int ioctl(int fd, unsigned long int request, ...) throw(); } extern int (*c_open)(const char *pathname, int flags, ...); +extern int (*openFull)(const char *pathname, int flags, ...); extern int (*c_ioctl)(int __fd, unsigned long int __request, ...); extern int fakeFd;