backends/native: Use rtkit to get realtime priority

Instead of using sched_setscheduler directly (and relying that we
somehow got CAP_SYS_NICE), use rtkit to do this for us.

Fixes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2284
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2060>
This commit is contained in:
Carlos Garnacho 2021-10-21 13:40:55 +02:00 committed by Marge Bot
parent 7c6fe21daf
commit 820aa18126
4 changed files with 79 additions and 11 deletions

View File

@ -122,9 +122,7 @@
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.
real-time scheduling. Requires a restart.
• “dma-buf-screen-sharing" — enables DMA buffered screen sharing. This
is already enabled by default when using

View File

@ -38,7 +38,6 @@
#include "backends/native/meta-backend-native-private.h"
#include "backends/native/meta-input-thread.h"
#include <sched.h>
#include <stdlib.h>
#include "backends/meta-cursor-tracker-private.h"
@ -61,6 +60,7 @@
#include "cogl/cogl.h"
#include "core/meta-border.h"
#include "meta/main.h"
#include "meta-dbus-rtkit1.h"
#ifdef HAVE_REMOTE_DESKTOP
#include "backends/meta-screen-cast.h"
@ -209,15 +209,36 @@ meta_backend_native_post_init (MetaBackend *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)
};
g_autoptr (MetaDbusRealtimeKit1) rtkit_proxy = NULL;
g_autoptr (GError) error = NULL;
retval = sched_setscheduler (0, SCHED_RR | SCHED_RESET_ON_FORK, &sp);
rtkit_proxy =
meta_dbus_realtime_kit1_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS |
G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
"org.freedesktop.RealtimeKit1",
"/org/freedesktop/RealtimeKit1",
NULL,
&error);
if (retval != 0)
g_warning ("Failed to set RT scheduler: %m");
if (rtkit_proxy)
{
uint32_t priority;
priority = sched_get_priority_min (SCHED_RR);
meta_dbus_realtime_kit1_call_make_thread_realtime_sync (rtkit_proxy,
gettid (),
priority,
NULL,
&error);
}
if (error)
{
g_dbus_error_strip_remote_error (error);
g_message ("Failed to set RT scheduler: %s", error->message);
}
}
#ifdef HAVE_REMOTE_DESKTOP

View File

@ -891,6 +891,13 @@ if have_remote_desktop
mutter_built_sources += dbus_screen_cast_built_sources
endif
dbus_rtkit_built_sources = gnome.gdbus_codegen('meta-dbus-rtkit1',
'org.freedesktop.RealtimeKit1.xml',
interface_prefix: 'org.freedesktop.',
namespace: 'MetaDbus',
)
mutter_built_sources += dbus_rtkit_built_sources
wayland_protocol_server_headers = []
wayland_protocol_client_headers = []
wayland_protocol_sources = []

View File

@ -0,0 +1,42 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
<interface name="org.freedesktop.RealtimeKit1">
<method name="MakeThreadRealtime">
<arg name="thread" type="t" direction="in"/>
<arg name="priority" type="u" direction="in"/>
</method>
<method name="MakeThreadRealtimeWithPID">
<arg name="process" type="t" direction="in"/>
<arg name="thread" type="t" direction="in"/>
<arg name="priority" type="u" direction="in"/>
</method>
<method name="MakeThreadHighPriority">
<arg name="thread" type="t" direction="in"/>
<arg name="priority" type="i" direction="in"/>
</method>
<method name="MakeThreadHighPriorityWithPID">
<arg name="process" type="t" direction="in"/>
<arg name="thread" type="t" direction="in"/>
<arg name="priority" type="i" direction="in"/>
</method>
<method name="ResetKnown"/>
<method name="ResetAll"/>
<method name="Exit"/>
<property name="RTTimeUSecMax" type="x" access="read"/>
<property name="MaxRealtimePriority" type="i" access="read"/>
<property name="MinNiceLevel" type="i" access="read"/>
</interface>
<interface name="org.freedesktop.DBus.Properties">
<method name="Get">
<arg name="interface" direction="in" type="s"/>
<arg name="property" direction="in" type="s"/>
<arg name="value" direction="out" type="v"/>
</method>
</interface>
<interface name="org.freedesktop.DBus.Introspectable">
<method name="Introspect">
<arg name="data" type="s" direction="out"/>
</method>
</interface>
</node>