[PATCH] udev: Do not attempt to remove GPUs for connector updates

Chris Wilson chris at chris-wilson.co.uk
Tue Aug 5 01:27:04 PDT 2014


With the advent of MST we now receive notifications through uevents of
not just the comings and goings of the GPUs themselves, but of the
individual connectors. Differentiate between these events and filter out
the calls to add/remove the actual GPU if we only have topology updates.

Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
Cc: Dave Airlie <airlied at redhat.com>
---
 config/udev.c | 82 ++++++++++++++++++++++++++++++++++++-----------------------
 1 file changed, 50 insertions(+), 32 deletions(-)

diff --git a/config/udev.c b/config/udev.c
index 1e4a9d7..dbe32c4 100644
--- a/config/udev.c
+++ b/config/udev.c
@@ -69,6 +69,23 @@ static const char *itoa(int i)
     return itoa_buf;
 }
 
+static enum { NO, OTHER, GPU } is_drm_device(struct udev_device *device)
+{
+    const char *sysname;
+
+    if (strcmp(udev_device_get_subsystem(device), "drm"))
+	return NO;
+
+    sysname = udev_device_get_sysname(device);
+    if (strncmp(sysname, "card", 4))
+	return OTHER;
+
+    if (strchr(sysname, '-'))
+	return OTHER;
+
+    return GPU;
+}
+
 static void
 device_added(struct udev_device *udev_device)
 {
@@ -87,7 +104,6 @@ device_added(struct udev_device *udev_device)
     dev_t devnum;
 
     path = udev_device_get_devnode(udev_device);
-
     syspath = udev_device_get_syspath(udev_device);
 
     if (!path || !syspath)
@@ -106,21 +122,18 @@ device_added(struct udev_device *udev_device)
     devnum = udev_device_get_devnum(udev_device);
 
 #ifdef CONFIG_UDEV_KMS
-    if (!strcmp(udev_device_get_subsystem(udev_device), "drm")) {
-        const char *sysname = udev_device_get_sysname(udev_device);
-
-        if (strncmp(sysname, "card", 4) != 0)
-            return;
-
-        /* Check for devices already added through xf86platformProbe() */
-        if (xf86_find_platform_device_by_devnum(major(devnum), minor(devnum)))
-            return;
-
-        LogMessage(X_INFO, "config/udev: Adding drm device (%s)\n", path);
-
-        config_udev_odev_setup_attribs(path, syspath, major(devnum),
-                                       minor(devnum), NewGPUDeviceRequest);
-        return;
+    switch (is_drm_device(udev_device)) {
+    case NO:
+	break;
+    case GPU:
+	/* Check for devices already added through xf86platformProbe() */
+	if (!xf86_find_platform_device_by_devnum(major(devnum), minor(devnum))) {
+	    LogMessage(X_INFO, "config/udev: Adding drm device (%s)\n", path);
+	    config_udev_odev_setup_attribs(path, syspath, major(devnum),
+					   minor(devnum), NewGPUDeviceRequest);
+	}
+    case OTHER:
+	return;
     }
 #endif
 
@@ -291,25 +304,30 @@ device_added(struct udev_device *udev_device)
 static void
 device_removed(struct udev_device *device)
 {
-    char *value;
+    dev_t devnum = udev_device_get_devnum(device);
     const char *syspath = udev_device_get_syspath(device);
+    char *value;
 
-#ifdef CONFIG_UDEV_KMS
-    if (!strcmp(udev_device_get_subsystem(device), "drm")) {
-        const char *sysname = udev_device_get_sysname(device);
-        const char *path = udev_device_get_devnode(device);
-        dev_t devnum = udev_device_get_devnum(device);
-
-        if (strncmp(sysname,"card", 4) != 0)
-            return;
-        ErrorF("removing GPU device %s %s\n", syspath, path);
-        if (!path)
-            return;
+    if (syspath == NULL)
+	return;
 
-        config_udev_odev_setup_attribs(path, syspath, major(devnum),
-                                       minor(devnum), DeleteGPUDeviceRequest);
-        /* Retry vtenter after a drm node removal */
-        systemd_logind_vtenter();
+#ifdef CONFIG_UDEV_KMS
+    switch (is_drm_device(device)) {
+    case NO:
+	break;
+    case GPU:
+	if (xf86_find_platform_device_by_devnum(major(devnum), minor(devnum))) {
+	    const char *path = udev_device_get_devnode(device);
+	    if (path) {
+		LogMessage(X_INFO, "config/udev: Removing drm device (%s)\n", path);
+		config_udev_odev_setup_attribs(path, syspath,
+					       major(devnum), minor(devnum),
+					       DeleteGPUDeviceRequest);
+		/* Retry vtenter after a drm node removal */
+		systemd_logind_vtenter();
+	    }
+	}
+    case OTHER:
         return;
     }
 #endif
-- 
2.0.1



More information about the xorg-devel mailing list