184 lines
6.1 KiB
Diff
184 lines
6.1 KiB
Diff
|
From 99be4ed7c3be19969930ce826f48c444e5e9da41 Mon Sep 17 00:00:00 2001
|
||
|
From: Ray Strode <rstrode@redhat.com>
|
||
|
Date: Tue, 10 Oct 2023 14:48:55 -0400
|
||
|
Subject: [PATCH 4/4] 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
|
||
|
---
|
||
|
src/backends/native/meta-kms-impl-device.c | 15 ++++++++++++++-
|
||
|
1 file changed, 14 insertions(+), 1 deletion(-)
|
||
|
|
||
|
diff --git a/src/backends/native/meta-kms-impl-device.c b/src/backends/native/meta-kms-impl-device.c
|
||
|
index da372383d..d53552704 100644
|
||
|
--- a/src/backends/native/meta-kms-impl-device.c
|
||
|
+++ b/src/backends/native/meta-kms-impl-device.c
|
||
|
@@ -1554,141 +1554,154 @@ meta_kms_impl_device_schedule_process (MetaKmsImplDevice *impl_device,
|
||
|
|
||
|
if (crtc_frame->await_flush)
|
||
|
return;
|
||
|
|
||
|
if (!is_using_deadline_timer (impl_device))
|
||
|
goto needs_flush;
|
||
|
|
||
|
if (crtc_frame->pending_page_flip)
|
||
|
return;
|
||
|
|
||
|
if (ensure_deadline_timer_armed (impl_device, crtc_frame, &error))
|
||
|
return;
|
||
|
|
||
|
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
|
||
|
g_warning ("Failed to determine deadline: %s", error->message);
|
||
|
|
||
|
priv = meta_kms_impl_device_get_instance_private (impl_device);
|
||
|
priv->deadline_timer_inhibited = TRUE;
|
||
|
|
||
|
needs_flush:
|
||
|
meta_kms_device_set_needs_flush (meta_kms_crtc_get_device (crtc), crtc);
|
||
|
}
|
||
|
|
||
|
static MetaKmsFeedback *
|
||
|
process_mode_set_update (MetaKmsImplDevice *impl_device,
|
||
|
MetaKmsUpdate *update,
|
||
|
MetaKmsUpdateFlag flags)
|
||
|
{
|
||
|
MetaKmsImplDevicePrivate *priv =
|
||
|
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;
|
||
|
GList *l;
|
||
|
GHashTableIter iter;
|
||
|
|
||
|
for (l = meta_kms_update_get_mode_sets (update); l; l = l->next)
|
||
|
{
|
||
|
MetaKmsModeSet *mode_set = l->data;
|
||
|
MetaKmsCrtc *crtc = mode_set->crtc;
|
||
|
|
||
|
crtc_frame = get_crtc_frame (impl_device, crtc);
|
||
|
if (!crtc_frame)
|
||
|
continue;
|
||
|
|
||
|
if (!crtc_frame->pending_update)
|
||
|
continue;
|
||
|
|
||
|
meta_kms_update_merge_from (update, crtc_frame->pending_update);
|
||
|
g_clear_pointer (&crtc_frame->pending_update, meta_kms_update_free);
|
||
|
}
|
||
|
|
||
|
g_hash_table_iter_init (&iter, priv->crtc_frames);
|
||
|
while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &crtc_frame))
|
||
|
{
|
||
|
crtc_frame->deadline.is_deadline_page_flip = FALSE;
|
||
|
crtc_frame->await_flush = FALSE;
|
||
|
crtc_frame->pending_page_flip = FALSE;
|
||
|
g_clear_pointer (&crtc_frame->pending_update, meta_kms_update_free);
|
||
|
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 *
|
||
|
meta_kms_impl_device_process_update (MetaKmsImplDevice *impl_device,
|
||
|
MetaKmsUpdate *update,
|
||
|
MetaKmsUpdateFlag flags)
|
||
|
{
|
||
|
g_autoptr (GError) error = NULL;
|
||
|
|
||
|
if (!ensure_device_file (impl_device, &error))
|
||
|
{
|
||
|
MetaKmsFeedback *feedback = NULL;
|
||
|
|
||
|
feedback = meta_kms_feedback_new_failed (NULL, g_steal_pointer (&error));
|
||
|
queue_result_feedback (impl_device, update, feedback);
|
||
|
|
||
|
meta_kms_update_free (update);
|
||
|
return feedback;
|
||
|
}
|
||
|
|
||
|
meta_kms_update_realize (update, impl_device);
|
||
|
|
||
|
if (flags & META_KMS_UPDATE_FLAG_TEST_ONLY)
|
||
|
{
|
||
|
return do_process (impl_device,
|
||
|
meta_kms_update_get_latch_crtc (update),
|
||
|
update, flags);
|
||
|
}
|
||
|
else if (flags & META_KMS_UPDATE_FLAG_MODE_SET)
|
||
|
{
|
||
|
return process_mode_set_update (impl_device, update, flags);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
g_assert_not_reached ();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void
|
||
|
meta_kms_impl_device_disable (MetaKmsImplDevice *impl_device)
|
||
|
{
|
||
|
MetaKmsImplDevicePrivate *priv =
|
||
|
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);
|
||
|
|
||
|
if (!priv->device_file)
|
||
|
return;
|
||
|
|
||
|
meta_kms_impl_device_hold_fd (impl_device);
|
||
|
+ meta_thread_inhibit_realtime_in_impl (thread);
|
||
|
klass->disable (impl_device);
|
||
|
+ meta_thread_uninhibit_realtime_in_impl (thread);
|
||
|
g_list_foreach (priv->crtcs,
|
||
|
(GFunc) meta_kms_crtc_disable_in_impl, NULL);
|
||
|
g_list_foreach (priv->connectors,
|
||
|
(GFunc) meta_kms_connector_disable_in_impl, NULL);
|
||
|
meta_kms_impl_device_unhold_fd (impl_device);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
meta_kms_impl_device_handle_page_flip_callback (MetaKmsImplDevice *impl_device,
|
||
|
MetaKmsPageFlipData *page_flip_data)
|
||
|
{
|
||
|
MetaKmsImplDeviceClass *klass = META_KMS_IMPL_DEVICE_GET_CLASS (impl_device);
|
||
|
|
||
|
klass->handle_page_flip_callback (impl_device, page_flip_data);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
meta_kms_impl_device_discard_pending_page_flips (MetaKmsImplDevice *impl_device)
|
||
|
{
|
||
|
MetaKmsImplDeviceClass *klass = META_KMS_IMPL_DEVICE_GET_CLASS (impl_device);
|
||
|
|
||
|
klass->discard_pending_page_flips (impl_device);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
meta_kms_impl_device_hold_fd (MetaKmsImplDevice *impl_device)
|
||
|
{
|
||
|
MetaKmsImplDevicePrivate *priv =
|
||
|
meta_kms_impl_device_get_instance_private (impl_device);
|
||
|
MetaKms *kms = meta_kms_device_get_kms (priv->device);
|
||
|
--
|
||
|
2.41.0
|
||
|
|