[PATCH igt] lib/kms: Disallow hotplugs during testing by default

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



After a hotplug, it is mandatory for userspace to reprobe (and maybe
retrain the links). Currently igt doesn't do this and so we may cause
spurious test failures (likely to be EINVAL when trying to apply a
mode). Detect the hotplug uevent and die loudly so that the actual failure
is logged.

Signed-off-by: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx>
---
 lib/igt_kms.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 lib/igt_kms.h |  3 +++
 2 files changed, 79 insertions(+)

diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index 5312f8d8..3c16547e 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -1512,6 +1512,8 @@ void igt_display_init(igt_display_t *display, int drm_fd)
 	drmModeFreePlaneResources(plane_resources);
 	drmModeFreeResources(resources);
 
+	igt_kms_disallow_hotplug(drm_fd);
+
 	LOG_UNINDENT(display);
 }
 
@@ -2777,3 +2779,77 @@ uint32_t kmstest_get_vbl_flag(uint32_t pipe_id)
 		return pipe_flag;
 	}
 }
+
+#if HAVE_UDEV
+#include <sys/poll.h>
+#include <libudev.h>
+#include <signal.h>
+
+static struct igt_helper_process hpd_helper;
+static void __attribute__((noreturn))
+hpd_process(pid_t pid, dev_t rdev)
+{
+	struct udev_monitor *mon =
+		udev_monitor_new_from_netlink(udev_new(), "kernel");
+	struct pollfd pfd;
+
+	udev_monitor_filter_add_match_subsystem_devtype(mon, "drm", NULL);
+	udev_monitor_enable_receiving(mon);
+
+	pfd.fd = udev_monitor_get_fd(mon);
+	pfd.events = POLLIN;
+
+	while (poll(&pfd, 1, -1) > 0) {
+		struct udev_device *dev = udev_monitor_receive_device(mon);
+		dev_t devnum;
+
+		if (dev == NULL)
+			continue;
+
+		devnum = udev_device_get_devnum(dev);
+		if (memcmp(&rdev, &devnum, sizeof(dev_t)) == 0) {
+			const char *str;
+
+			str = udev_device_get_property_value(dev, "HOTPLUG");
+			if (str && atoi(str) == 1)
+				kill(pid, SIGIO);
+		}
+
+		udev_device_unref(dev);
+		if (kill(pid, 0)) /* Parent has died, so must we. */
+			break;
+	}
+
+	exit(0);
+}
+
+static void sig_abort(int sig)
+{
+	errno = 0; /* inside a signal, last errno reporting is confusing */
+	igt_assert(!"Hotplug detected");
+}
+
+void igt_kms_disallow_hotplug(int fd)
+{
+	struct stat st;
+
+	igt_assert(fstat(fd, &st) == 0);
+
+	signal(SIGIO, sig_abort);
+	igt_fork_helper(&hpd_helper)
+		hpd_process(getppid(), st.st_rdev);
+}
+
+void igt_kms_allow_hotplug(void)
+{
+	igt_stop_helper(&hpd_helper);
+}
+#else
+void igt_kms_disallow_hotplug(int fd)
+{
+}
+
+void igt_kms_allow_hotplug(void)
+{
+}
+#endif
diff --git a/lib/igt_kms.h b/lib/igt_kms.h
index 5234f6c1..788b7457 100644
--- a/lib/igt_kms.h
+++ b/lib/igt_kms.h
@@ -473,6 +473,9 @@ static inline bool igt_output_is_connected(igt_output_t *output)
 void igt_enable_connectors(void);
 void igt_reset_connectors(void);
 
+void igt_kms_disallow_hotplug(int fd);
+void igt_kms_allow_hotplug(void);
+
 uint32_t kmstest_get_vbl_flag(uint32_t pipe_id);
 
 #define EDID_LENGTH 128
-- 
2.11.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@xxxxxxxxxxxxxxxxxxxxx
https://lists.freedesktop.org/mailman/listinfo/intel-gfx




[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]
  Powered by Linux