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
This commit is contained in:
Hans de Goede 2019-08-05 14:08:08 +02:00 committed by Jonas Ådahl
parent 0eb355e29d
commit f3660dc60e
2 changed files with 37 additions and 2 deletions

View File

@ -149,6 +149,7 @@ struct _MetaKms
MetaBackend *backend; MetaBackend *backend;
guint hotplug_handler_id; guint hotplug_handler_id;
guint removed_handler_id;
MetaKmsImpl *impl; MetaKmsImpl *impl;
gboolean in_impl_task; gboolean in_impl_task;
@ -474,8 +475,7 @@ meta_kms_update_states_sync (MetaKms *kms,
} }
static void static void
on_udev_hotplug (MetaUdev *udev, handle_hotplug_event (MetaKms *kms)
MetaKms *kms)
{ {
g_autoptr (GError) error = NULL; g_autoptr (GError) error = NULL;
@ -483,6 +483,21 @@ on_udev_hotplug (MetaUdev *udev,
g_warning ("Updating KMS state failed: %s", error->message); 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 * MetaBackend *
meta_kms_get_backend (MetaKms *kms) meta_kms_get_backend (MetaKms *kms)
{ {
@ -525,6 +540,9 @@ meta_kms_new (MetaBackend *backend,
kms->hotplug_handler_id = kms->hotplug_handler_id =
g_signal_connect (udev, "hotplug", G_CALLBACK (on_udev_hotplug), kms); 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; return kms;
} }
@ -548,6 +566,9 @@ meta_kms_finalize (GObject *object)
if (kms->hotplug_handler_id) if (kms->hotplug_handler_id)
g_signal_handler_disconnect (udev, 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); G_OBJECT_CLASS (meta_kms_parent_class)->finalize (object);
} }

View File

@ -76,6 +76,7 @@ struct _MetaMonitorManagerKms
MetaMonitorManager parent_instance; MetaMonitorManager parent_instance;
guint hotplug_handler_id; guint hotplug_handler_id;
guint removed_handler_id;
}; };
struct _MetaMonitorManagerKmsClass struct _MetaMonitorManagerKmsClass
@ -484,6 +485,14 @@ on_udev_hotplug (MetaUdev *udev,
handle_hotplug_event (manager); handle_hotplug_event (manager);
} }
static void
on_udev_device_removed (MetaUdev *udev,
GUdevDevice *device,
MetaMonitorManager *manager)
{
handle_hotplug_event (manager);
}
static void static void
meta_monitor_manager_kms_connect_hotplug_handler (MetaMonitorManagerKms *manager_kms) meta_monitor_manager_kms_connect_hotplug_handler (MetaMonitorManagerKms *manager_kms)
{ {
@ -494,6 +503,9 @@ meta_monitor_manager_kms_connect_hotplug_handler (MetaMonitorManagerKms *manager
manager_kms->hotplug_handler_id = manager_kms->hotplug_handler_id =
g_signal_connect_after (udev, "hotplug", g_signal_connect_after (udev, "hotplug",
G_CALLBACK (on_udev_hotplug), manager); 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 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); g_signal_handler_disconnect (udev, manager_kms->hotplug_handler_id);
manager_kms->hotplug_handler_id = 0; manager_kms->hotplug_handler_id = 0;
g_signal_handler_disconnect (udev, manager_kms->removed_handler_id);
manager_kms->removed_handler_id = 0;
} }
void void