summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2019-08-05 14:08:08 +0200
committerJonas Ã…dahl <jadahl@gmail.com>2019-08-15 20:38:28 +0000
commitf3660dc60e76b13e35f361a1ea6816f8b0af66d8 (patch)
treed161a71ec68741d94f15a6fa72e981e5e430aebc /src
parent0eb355e29d0a0644dcf30732f07c56b83ac9fd1c (diff)
downloadmutter-f3660dc60e76b13e35f361a1ea6816f8b0af66d8.tar.gz
kms: Deal with GPUs being unplugged
Add meta-kms and meta-monitor-manager-kms listener for the udev device-removed signal and on this signal update the device state / re-enumerate the monitors, so that the monitors properly get updated to disconnected state on GPU removal. We really should also have meta-backend-native remove the GPU itself from our list of GPU objects. But that is more involved, see: https://gitlab.gnome.org/GNOME/mutter/issues/710 This commit at least gets us to a point where we properly update the list of monitors when a GPU gets unplugged; and where we no longer crash the first time the user changes the monitor configuration after a GPU was unplugged. Specifically before this commit we would hit the first g_error () in meta_renderer_native_create_view () as soon as some monitor (re)configuration is done after a GPU was unplugged. https://gitlab.gnome.org/GNOME/mutter/merge_requests/713
Diffstat (limited to 'src')
-rw-r--r--src/backends/native/meta-kms.c25
-rw-r--r--src/backends/native/meta-monitor-manager-kms.c14
2 files changed, 37 insertions, 2 deletions
diff --git a/src/backends/native/meta-kms.c b/src/backends/native/meta-kms.c
index 641aaa198..13dc396d3 100644
--- a/src/backends/native/meta-kms.c
+++ b/src/backends/native/meta-kms.c
@@ -149,6 +149,7 @@ struct _MetaKms
MetaBackend *backend;
guint hotplug_handler_id;
+ guint removed_handler_id;
MetaKmsImpl *impl;
gboolean in_impl_task;
@@ -474,8 +475,7 @@ meta_kms_update_states_sync (MetaKms *kms,
}
static void
-on_udev_hotplug (MetaUdev *udev,
- MetaKms *kms)
+handle_hotplug_event (MetaKms *kms)
{
g_autoptr (GError) error = NULL;
@@ -483,6 +483,21 @@ on_udev_hotplug (MetaUdev *udev,
g_warning ("Updating KMS state failed: %s", error->message);
}
+static void
+on_udev_hotplug (MetaUdev *udev,
+ MetaKms *kms)
+{
+ handle_hotplug_event (kms);
+}
+
+static void
+on_udev_device_removed (MetaUdev *udev,
+ GUdevDevice *device,
+ MetaKms *kms)
+{
+ handle_hotplug_event (kms);
+}
+
MetaBackend *
meta_kms_get_backend (MetaKms *kms)
{
@@ -525,6 +540,9 @@ meta_kms_new (MetaBackend *backend,
kms->hotplug_handler_id =
g_signal_connect (udev, "hotplug", G_CALLBACK (on_udev_hotplug), kms);
+ kms->removed_handler_id =
+ g_signal_connect (udev, "device-removed",
+ G_CALLBACK (on_udev_device_removed), kms);
return kms;
}
@@ -548,6 +566,9 @@ meta_kms_finalize (GObject *object)
if (kms->hotplug_handler_id)
g_signal_handler_disconnect (udev, kms->hotplug_handler_id);
+ if (kms->removed_handler_id)
+ g_signal_handler_disconnect (udev, kms->removed_handler_id);
+
G_OBJECT_CLASS (meta_kms_parent_class)->finalize (object);
}
diff --git a/src/backends/native/meta-monitor-manager-kms.c b/src/backends/native/meta-monitor-manager-kms.c
index 9bac13576..26c2ddb61 100644
--- a/src/backends/native/meta-monitor-manager-kms.c
+++ b/src/backends/native/meta-monitor-manager-kms.c
@@ -76,6 +76,7 @@ struct _MetaMonitorManagerKms
MetaMonitorManager parent_instance;
guint hotplug_handler_id;
+ guint removed_handler_id;
};
struct _MetaMonitorManagerKmsClass
@@ -485,6 +486,14 @@ on_udev_hotplug (MetaUdev *udev,
}
static void
+on_udev_device_removed (MetaUdev *udev,
+ GUdevDevice *device,
+ MetaMonitorManager *manager)
+{
+ handle_hotplug_event (manager);
+}
+
+static void
meta_monitor_manager_kms_connect_hotplug_handler (MetaMonitorManagerKms *manager_kms)
{
MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_kms);
@@ -494,6 +503,9 @@ meta_monitor_manager_kms_connect_hotplug_handler (MetaMonitorManagerKms *manager
manager_kms->hotplug_handler_id =
g_signal_connect_after (udev, "hotplug",
G_CALLBACK (on_udev_hotplug), manager);
+ manager_kms->removed_handler_id =
+ g_signal_connect_after (udev, "device-removed",
+ G_CALLBACK (on_udev_device_removed), manager);
}
static void
@@ -505,6 +517,8 @@ meta_monitor_manager_kms_disconnect_hotplug_handler (MetaMonitorManagerKms *mana
g_signal_handler_disconnect (udev, manager_kms->hotplug_handler_id);
manager_kms->hotplug_handler_id = 0;
+ g_signal_handler_disconnect (udev, manager_kms->removed_handler_id);
+ manager_kms->removed_handler_id = 0;
}
void