backends/native: Add rt-scheduler experimental key to set RT scheduling

This is similar to a change in kwin:
https://blog.martin-graesslin.com/blog/2017/09/kwinwayland-goes-real-time/

If the experimental features key has "rt-scheduler", make it claim the lowest
of RT scheduler priorities, this will be both educated to other RT processes
and improves responsiveness wrt all other processes.

This can only work if mutter/gnome-shell process receives CAP_SYS_NICE
somehow, e.g.: "setcap CAP_SYS_NICE=+ep `which gnome-shell`"

Closes: https://gitlab.gnome.org/GNOME/gnome-shell/issues/921
https://gitlab.gnome.org/GNOME/mutter/merge_requests/460
This commit is contained in:
Carlos Garnacho 2019-02-27 19:02:25 +01:00 committed by Georges Basile Stavracas Neto
parent 01d0316fd7
commit dae2c1d420
4 changed files with 24 additions and 0 deletions

View File

@ -120,6 +120,10 @@
framebuffers instead of window content, framebuffers instead of window content,
to manage HiDPI monitors. Does not to manage HiDPI monitors. Does not
require a restart. require a restart.
• “rt-scheduler” — makes mutter request a low priority
real-time scheduling. The executable
or user must have CAP_SYS_NICE.
Requires a restart.
</description> </description>
</key> </key>

View File

@ -33,6 +33,7 @@ typedef enum _MetaExperimentalFeature
META_EXPERIMENTAL_FEATURE_NONE = 0, META_EXPERIMENTAL_FEATURE_NONE = 0,
META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER = (1 << 0), META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER = (1 << 0),
META_EXPERIMENTAL_FEATURE_KMS_MODIFIERS = (1 << 1), META_EXPERIMENTAL_FEATURE_KMS_MODIFIERS = (1 << 1),
META_EXPERIMENTAL_FEATURE_RT_SCHEDULER = (1 << 2),
} MetaExperimentalFeature; } MetaExperimentalFeature;
#define META_TYPE_SETTINGS (meta_settings_get_type ()) #define META_TYPE_SETTINGS (meta_settings_get_type ())

View File

@ -264,6 +264,8 @@ experimental_features_handler (GVariant *features_variant,
features |= META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER; features |= META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER;
else if (g_str_equal (feature, "kms-modifiers")) else if (g_str_equal (feature, "kms-modifiers"))
features |= META_EXPERIMENTAL_FEATURE_KMS_MODIFIERS; features |= META_EXPERIMENTAL_FEATURE_KMS_MODIFIERS;
else if (g_str_equal (feature, "rt-scheduler"))
features |= META_EXPERIMENTAL_FEATURE_RT_SCHEDULER;
else else
g_info ("Unknown experimental feature '%s'\n", feature); g_info ("Unknown experimental feature '%s'\n", feature);
} }

View File

@ -37,6 +37,7 @@
#include "backends/native/meta-backend-native.h" #include "backends/native/meta-backend-native.h"
#include "backends/native/meta-backend-native-private.h" #include "backends/native/meta-backend-native-private.h"
#include <sched.h>
#include <stdlib.h> #include <stdlib.h>
#include "backends/meta-cursor-tracker-private.h" #include "backends/meta-cursor-tracker-private.h"
@ -44,6 +45,7 @@
#include "backends/meta-logical-monitor.h" #include "backends/meta-logical-monitor.h"
#include "backends/meta-monitor-manager-private.h" #include "backends/meta-monitor-manager-private.h"
#include "backends/meta-pointer-constraint.h" #include "backends/meta-pointer-constraint.h"
#include "backends/meta-settings-private.h"
#include "backends/meta-stage-private.h" #include "backends/meta-stage-private.h"
#include "backends/native/meta-barrier-native.h" #include "backends/native/meta-barrier-native.h"
#include "backends/native/meta-clutter-backend-native.h" #include "backends/native/meta-clutter-backend-native.h"
@ -331,6 +333,7 @@ static void
meta_backend_native_post_init (MetaBackend *backend) meta_backend_native_post_init (MetaBackend *backend)
{ {
ClutterDeviceManager *manager = clutter_device_manager_get_default (); ClutterDeviceManager *manager = clutter_device_manager_get_default ();
MetaSettings *settings = meta_backend_get_settings (backend);
META_BACKEND_CLASS (meta_backend_native_parent_class)->post_init (backend); META_BACKEND_CLASS (meta_backend_native_parent_class)->post_init (backend);
@ -338,6 +341,20 @@ meta_backend_native_post_init (MetaBackend *backend)
NULL, NULL); NULL, NULL);
clutter_evdev_set_relative_motion_filter (manager, relative_motion_filter, clutter_evdev_set_relative_motion_filter (manager, relative_motion_filter,
meta_backend_get_monitor_manager (backend)); meta_backend_get_monitor_manager (backend));
if (meta_settings_is_experimental_feature_enabled (settings,
META_EXPERIMENTAL_FEATURE_RT_SCHEDULER))
{
int retval;
struct sched_param sp = {
.sched_priority = sched_get_priority_min (SCHED_RR)
};
retval = sched_setscheduler (0, SCHED_RR | SCHED_RESET_ON_FORK, &sp);
if (retval != 0)
g_warning ("Failed to set RT scheduler: %m");
}
} }
static MetaMonitorManager * static MetaMonitorManager *