From eb3ff3f44ac4daf06279c6e566e4fcb99ff1988d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Fri, 10 Mar 2017 16:55:53 +0800 Subject: [PATCH] monitor-manager-kms: Don't try to wait for EDID on hot plug The mitigation to avoid missing EDID blob was incorrect; the reason it sometimes failed to read was a race between different applications all trying to read the EDID at the same time. E.g. gnome-shell as GDM would at the same time as the session gnome-shell try to read the EDID of the same connector at the same time, triggering a race in the kernel, making the blob reading ioctl occationally fail with ENOENT. Remove this mitigation, as it didn't really mitigate anything; the race could just as well happen when doing the actual read later. https://bugzilla.gnome.org/show_bug.cgi?id=779837 --- .../native/meta-monitor-manager-kms.c | 130 ------------------ 1 file changed, 130 deletions(-) diff --git a/src/backends/native/meta-monitor-manager-kms.c b/src/backends/native/meta-monitor-manager-kms.c index 5256b4775..202567600 100644 --- a/src/backends/native/meta-monitor-manager-kms.c +++ b/src/backends/native/meta-monitor-manager-kms.c @@ -52,10 +52,6 @@ #define ALL_TRANSFORMS_MASK ((1 << ALL_TRANSFORMS) - 1) #define SYNC_TOLERANCE 0.01 /* 1 percent */ -/* Try each 50 milleseconds up to half a second to get a proper EDID read */ -#define EDID_RETRY_TIMEOUT_MS 50 -#define EDID_MAX_NUM_RETRIES 10 - typedef struct { drmModeConnector *connector; @@ -117,9 +113,6 @@ struct _MetaMonitorManagerKms GSettings *desktop_settings; gboolean page_flips_not_supported; - - guint handle_hotplug_timeout; - int read_edid_tries; }; struct _MetaMonitorManagerKmsClass @@ -1595,76 +1588,6 @@ meta_monitor_manager_kms_set_crtc_gamma (MetaMonitorManager *manager, drmModeCrtcSetGamma (manager_kms->fd, crtc->crtc_id, size, red, green, blue); } -static gboolean -has_pending_edid_blob (MetaMonitorManagerKms *manager_kms) -{ - drmModeRes *resources; - int n_connectors; - int i, j; - gboolean edid_blob_pending; - - resources = drmModeGetResources (manager_kms->fd); - n_connectors = resources->count_connectors; - - edid_blob_pending = FALSE; - for (i = 0; i < n_connectors; i++) - { - drmModeConnector *drm_connector; - uint32_t edid_blob_id; - - drm_connector = drmModeGetConnector (manager_kms->fd, - resources->connectors[i]); - - edid_blob_id = 0; - for (j = 0; j < drm_connector->count_props; j++) - { - drmModePropertyPtr prop; - - prop = drmModeGetProperty (manager_kms->fd, drm_connector->props[j]); - - if (prop->flags & DRM_MODE_PROP_BLOB && - g_str_equal (prop->name, "EDID")) - edid_blob_id = drm_connector->prop_values[j]; - - drmModeFreeProperty (prop); - - if (edid_blob_id) - break; - } - - drmModeFreeConnector (drm_connector); - - if (edid_blob_id) - { - GError *error = NULL; - drmModePropertyBlobPtr edid_blob; - - edid_blob = read_edid_blob (manager_kms, edid_blob_id, &error); - if (!edid_blob && - g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) - { - edid_blob_pending = TRUE; - g_error_free (error); - } - else if (!edid_blob) - { - g_error_free (error); - } - else - { - drmModeFreePropertyBlob (edid_blob); - } - } - - if (edid_blob_pending) - break; - } - - drmModeFreeResources (resources); - - return edid_blob_pending; -} - static void handle_hotplug_event (MetaMonitorManager *manager) { @@ -1672,37 +1595,6 @@ handle_hotplug_event (MetaMonitorManager *manager) meta_monitor_manager_on_hotplug (manager); } -static gboolean -handle_hotplug_event_timeout (gpointer user_data) -{ - MetaMonitorManager *manager = user_data; - MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (user_data); - - if (!has_pending_edid_blob (manager_kms)) - { - handle_hotplug_event (manager); - - manager_kms->handle_hotplug_timeout = 0; - return G_SOURCE_REMOVE; - } - - manager_kms->read_edid_tries++; - - if (manager_kms->read_edid_tries > EDID_MAX_NUM_RETRIES) - { - g_warning ("Tried to read the EDID %d times, " - "but one or more are still missing, continuing without", - manager_kms->read_edid_tries); - - handle_hotplug_event (manager); - - manager_kms->handle_hotplug_timeout = 0; - return G_SOURCE_REMOVE; - } - - return G_SOURCE_CONTINUE; -} - static void on_uevent (GUdevClient *client, const char *action, @@ -1715,28 +1607,6 @@ on_uevent (GUdevClient *client, if (!g_udev_device_get_property_as_boolean (device, "HOTPLUG")) return; - if (manager_kms->handle_hotplug_timeout) - { - g_source_remove (manager_kms->handle_hotplug_timeout); - manager_kms->handle_hotplug_timeout = 0; - } - - /* - * On a hot-plug event, the EDID of one or more connectors might not yet be - * ready at this point, resulting in invalid configuration potentially being - * applied. Avoid this by first checking whether the EDID is ready at this - * point, or otherwise wait a bit and try again. - */ - manager_kms->read_edid_tries = 0; - if (has_pending_edid_blob (manager_kms)) - { - manager_kms->handle_hotplug_timeout = - g_timeout_add (EDID_RETRY_TIMEOUT_MS, - handle_hotplug_event_timeout, - manager); - return; - } - handle_hotplug_event (manager); }