wayland: Make setting realtime scheduler more fine grained

With this only the main and the libinput threads will use realtime
scheduling, so it will be harder to leak realtime scheduling to somebody
else.

The only caveat is that kwin would need to keep CAP_SYS_NICE around,
however on the other hand, it's needed to ensure that kwin_wayland is
able to get high priority EGL contexts with some drivers, e.g. intel.
This commit is contained in:
Vlad Zahorodnii 2022-05-16 10:31:30 +03:00
parent 1878ba0e10
commit a601a08ba7
7 changed files with 51 additions and 58 deletions

View file

@ -302,9 +302,6 @@ target_link_libraries(kwin_wayland
KWinXwaylandServerModule
)
kcoreaddons_target_static_plugins(kwin_wayland "kwin/effects/plugins")
if (HAVE_LIBCAP)
target_link_libraries(kwin_wayland ${Libcap_LIBRARIES})
endif()
install(TARGETS kwin_wayland ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})
if (HAVE_LIBCAP)

View file

@ -24,6 +24,7 @@
#include "libinput_logging.h"
#include "session.h"
#include "udev.h"
#include "utils/realtime.h"
#include <QDBusConnection>
#include <QMutexLocker>
@ -150,6 +151,9 @@ void Connection::setup()
void Connection::doSetup()
{
Q_ASSERT(!m_notifier);
gainRealTime();
m_notifier = new QSocketNotifier(m_input->fileDescriptor(), QSocketNotifier::Read, this);
connect(m_notifier, &QSocketNotifier::activated, this, &Connection::handleEvent);

View file

@ -17,7 +17,6 @@
#cmakedefine01 HAVE_GBM_BO_GET_FD_FOR_PLANE
#cmakedefine01 HAVE_WAYLAND_EGL
#cmakedefine01 HAVE_BREEZE_DECO
#cmakedefine01 HAVE_LIBCAP
#cmakedefine01 HAVE_SCHED_RESET_ON_FORK
#cmakedefine01 HAVE_ACCESSIBILITY
#if HAVE_BREEZE_DECO

View file

@ -15,6 +15,7 @@
#include "inputmethod.h"
#include "platform.h"
#include "tabletmodemanager.h"
#include "utils/realtime.h"
#include "wayland/display.h"
#include "wayland/seat_interface.h"
#include "wayland_server.h"
@ -38,10 +39,6 @@
#include <QWindow>
#include <qplatformdefs.h>
#if HAVE_LIBCAP
#include <sys/capability.h>
#endif
#include <sched.h>
#include <sys/resource.h>
@ -102,30 +99,6 @@ void disableDrKonqi()
// that would enable drkonqi
Q_CONSTRUCTOR_FUNCTION(disableDrKonqi)
enum class RealTimeFlags {
DontReset,
ResetOnFork
};
namespace
{
void gainRealTime(RealTimeFlags flags = RealTimeFlags::DontReset)
{
#if HAVE_SCHED_RESET_ON_FORK
const int minPriority = sched_get_priority_min(SCHED_RR);
struct sched_param sp;
sp.sched_priority = minPriority;
int policy = SCHED_RR;
if (flags == RealTimeFlags::ResetOnFork) {
policy |= SCHED_RESET_ON_FORK;
}
sched_setscheduler(0, policy, &sp);
#else
Q_UNUSED(flags);
#endif
}
}
//************************************
// ApplicationWayland
//************************************
@ -170,11 +143,7 @@ void ApplicationWayland::performStartup()
waylandServer()->initPlatform();
createColorManager();
// try creating the Wayland Backend
createInput();
// now libinput thread has been created, adjust scheduler to not leak into other processes
gainRealTime(RealTimeFlags::ResetOnFork);
createInputMethod();
TabletModeManager::create(this);
createPlugins();
@ -312,27 +281,6 @@ static QString automaticBackendSelection()
return s_drmPlugin;
}
void dropNiceCapability()
{
#if HAVE_LIBCAP
cap_t caps = cap_get_proc();
if (!caps) {
return;
}
cap_value_t capList[] = {CAP_SYS_NICE};
if (cap_set_flag(caps, CAP_PERMITTED, 1, capList, CAP_CLEAR) == -1) {
cap_free(caps);
return;
}
if (cap_set_flag(caps, CAP_EFFECTIVE, 1, capList, CAP_CLEAR) == -1) {
cap_free(caps);
return;
}
cap_set_proc(caps);
cap_free(caps);
#endif
}
} // namespace
int main(int argc, char *argv[])
@ -340,7 +288,6 @@ int main(int argc, char *argv[])
KWin::Application::setupMalloc();
KWin::Application::setupLocalizedString();
KWin::gainRealTime();
KWin::dropNiceCapability();
if (signal(SIGTERM, KWin::sighandler) == SIG_IGN) {
signal(SIGTERM, SIG_IGN);

View file

@ -2,6 +2,7 @@ target_sources(kwin PRIVATE
abstract_opengl_context_attribute_builder.cpp
common.cpp
egl_context_attribute_builder.cpp
realtime.cpp
subsurfacemonitor.cpp
xcbutils.cpp
)

26
src/utils/realtime.cpp Normal file
View file

@ -0,0 +1,26 @@
/*
SPDX-FileCopyrightText: 2022 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "realtime.h"
#include "config-kwin.h"
#include <sched.h>
namespace KWin
{
void gainRealTime()
{
#if HAVE_SCHED_RESET_ON_FORK
const int minPriority = sched_get_priority_min(SCHED_RR);
sched_param sp;
sp.sched_priority = minPriority;
sched_setscheduler(0, SCHED_RR | SCHED_RESET_ON_FORK, &sp);
#endif
}
} // namespace KWin

19
src/utils/realtime.h Normal file
View file

@ -0,0 +1,19 @@
/*
SPDX-FileCopyrightText: 2022 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#pragma once
#include "kwin_export.h"
namespace KWin
{
/**
* Makes the calling thread to use realtime scheduling.
*/
KWIN_EXPORT void gainRealTime();
} // namespace KWin