kms/impl-device: Inhibit real-time scheduling when mode setting

Certain kernel drivers can take an unreasonably long time to
complete mode setting operations. That excessive CPU time is charged
to the process's rlimits which can lead to the process getting killed
if the thread is a real-time thread.

This commit inhibits real-time scheduling around mode setting
commits, since those commits are the ones currently presenting as
excessively slow.

Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/3037
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3324>
This commit is contained in:
Ray Strode 2023-10-10 14:48:55 -04:00
parent b1db87ae30
commit 5d3e31a499

View File

@ -1581,6 +1581,10 @@ process_mode_set_update (MetaKmsImplDevice *impl_device,
{ {
MetaKmsImplDevicePrivate *priv = MetaKmsImplDevicePrivate *priv =
meta_kms_impl_device_get_instance_private (impl_device); meta_kms_impl_device_get_instance_private (impl_device);
MetaKmsImpl *kms_impl = meta_kms_impl_device_get_impl (impl_device);
MetaThreadImpl *thread_impl = META_THREAD_IMPL (kms_impl);
MetaThread *thread = meta_thread_impl_get_thread (thread_impl);
MetaKmsFeedback *feedback;
CrtcFrame *crtc_frame; CrtcFrame *crtc_frame;
GList *l; GList *l;
GHashTableIter iter; GHashTableIter iter;
@ -1612,7 +1616,11 @@ process_mode_set_update (MetaKmsImplDevice *impl_device,
disarm_crtc_frame_deadline_timer (crtc_frame); disarm_crtc_frame_deadline_timer (crtc_frame);
} }
return do_process (impl_device, NULL, update, flags); meta_thread_inhibit_realtime_in_impl (thread);
feedback = do_process (impl_device, NULL, update, flags);
meta_thread_uninhibit_realtime_in_impl (thread);
return feedback;
} }
MetaKmsFeedback * MetaKmsFeedback *
@ -1656,13 +1664,18 @@ meta_kms_impl_device_disable (MetaKmsImplDevice *impl_device)
{ {
MetaKmsImplDevicePrivate *priv = MetaKmsImplDevicePrivate *priv =
meta_kms_impl_device_get_instance_private (impl_device); meta_kms_impl_device_get_instance_private (impl_device);
MetaKmsImpl *kms_impl = meta_kms_impl_device_get_impl (impl_device);
MetaThreadImpl *thread_impl = META_THREAD_IMPL (kms_impl);
MetaThread *thread = meta_thread_impl_get_thread (thread_impl);
MetaKmsImplDeviceClass *klass = META_KMS_IMPL_DEVICE_GET_CLASS (impl_device); MetaKmsImplDeviceClass *klass = META_KMS_IMPL_DEVICE_GET_CLASS (impl_device);
if (!priv->device_file) if (!priv->device_file)
return; return;
meta_kms_impl_device_hold_fd (impl_device); meta_kms_impl_device_hold_fd (impl_device);
meta_thread_inhibit_realtime_in_impl (thread);
klass->disable (impl_device); klass->disable (impl_device);
meta_thread_uninhibit_realtime_in_impl (thread);
g_list_foreach (priv->crtcs, g_list_foreach (priv->crtcs,
(GFunc) meta_kms_crtc_disable_in_impl, NULL); (GFunc) meta_kms_crtc_disable_in_impl, NULL);
g_list_foreach (priv->connectors, g_list_foreach (priv->connectors,