From a601a08ba7a65ebb4df46cf1f94f3fff2c0553cd Mon Sep 17 00:00:00 2001 From: Vlad Zahorodnii Date: Mon, 16 May 2022 10:31:30 +0300 Subject: [PATCH] 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. --- src/CMakeLists.txt | 3 -- src/backends/libinput/connection.cpp | 4 ++ src/config-kwin.h.cmake | 1 - src/main_wayland.cpp | 55 +--------------------------- src/utils/CMakeLists.txt | 1 + src/utils/realtime.cpp | 26 +++++++++++++ src/utils/realtime.h | 19 ++++++++++ 7 files changed, 51 insertions(+), 58 deletions(-) create mode 100644 src/utils/realtime.cpp create mode 100644 src/utils/realtime.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d56f1dd7b4..290f399a7c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -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) diff --git a/src/backends/libinput/connection.cpp b/src/backends/libinput/connection.cpp index 1471dbf953..37eb23fd90 100644 --- a/src/backends/libinput/connection.cpp +++ b/src/backends/libinput/connection.cpp @@ -24,6 +24,7 @@ #include "libinput_logging.h" #include "session.h" #include "udev.h" +#include "utils/realtime.h" #include #include @@ -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); diff --git a/src/config-kwin.h.cmake b/src/config-kwin.h.cmake index 05a85a9556..0b87ce2676 100644 --- a/src/config-kwin.h.cmake +++ b/src/config-kwin.h.cmake @@ -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 diff --git a/src/main_wayland.cpp b/src/main_wayland.cpp index 5703eb66d4..1720e14e7f 100644 --- a/src/main_wayland.cpp +++ b/src/main_wayland.cpp @@ -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 #include -#if HAVE_LIBCAP -#include -#endif - #include #include @@ -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); diff --git a/src/utils/CMakeLists.txt b/src/utils/CMakeLists.txt index e4da9f6990..80e771dbda 100644 --- a/src/utils/CMakeLists.txt +++ b/src/utils/CMakeLists.txt @@ -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 ) diff --git a/src/utils/realtime.cpp b/src/utils/realtime.cpp new file mode 100644 index 0000000000..aff3d5077f --- /dev/null +++ b/src/utils/realtime.cpp @@ -0,0 +1,26 @@ +/* + SPDX-FileCopyrightText: 2022 Vlad Zahorodnii + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +#include "realtime.h" + +#include "config-kwin.h" + +#include + +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 diff --git a/src/utils/realtime.h b/src/utils/realtime.h new file mode 100644 index 0000000000..0b05e0d63c --- /dev/null +++ b/src/utils/realtime.h @@ -0,0 +1,19 @@ +/* + SPDX-FileCopyrightText: 2022 Vlad Zahorodnii + + 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