Use real-time scheduling policy for kwin_wayland
Summary: The base idea behind this change is to keep the system responsive no matter what other processes do. All input and rendering needs to go through the windowing system, so keeping it responsive is important. Currently KWin competes with all other processes for resources and this can render the system unusable. Consider some processes running amok. In this case the user might not be able to easily close the applications as KWin does not get the cpu time to perform the input tasks requested by the user. Or in the case of playing a demanding game it is important that KWin gets scheduled to forward the pointer input events. The user doesn't want that the game (or another process) wins against the windowing sytem. The disadvantage is that KWin always wins against other processes with real time scheduling. This could result in KWin running amok stalling the system. On the other hand this is no change to the current situation as if KWin runs amok the sytem is unusable. The change uses libcap to set CAP_SYS_NICE on kwin_wayland executable. KWin_wayland on start sets the scheduling policy to SCHED_RR with the lowest possible priority. Thus any other SCHED_RR process will win against KWin. So real time processes are not affected by this change! After adjusting the scheduling (which requires CAP_SYS_NICE) KWin drops this capability again. Test Plan: Verified that KWin adjusts the scheduler, that it is not passed to child processes, that the capability gets dropped and not passed to child processes. Reviewers: #kwin, #plasma Subscribers: plasma-devel, kwin Tags: #kwin Differential Revision: https://phabricator.kde.org/D7757
This commit is contained in:
parent
2a34fdde4c
commit
7c8003f7f6
4 changed files with 124 additions and 0 deletions
|
@ -279,6 +279,13 @@ set_package_properties(Xwayland PROPERTIES
|
|||
PURPOSE "Needed for running kwin_wayland"
|
||||
)
|
||||
|
||||
find_package(Libcap)
|
||||
set_package_properties(Libcap PROPERTIES
|
||||
TYPE OPTIONAL
|
||||
PURPOSE "Needed for running kwin_wayland with real-time scheduling policy"
|
||||
)
|
||||
set(HAVE_LIBCAP ${Libcap_FOUND})
|
||||
|
||||
########### configure tests ###############
|
||||
include(CMakeDependentOption)
|
||||
|
||||
|
@ -339,6 +346,11 @@ add_feature_info("linux/fb.h"
|
|||
HAVE_LINUX_FB_H
|
||||
"Required for the fbdev backend")
|
||||
|
||||
check_symbol_exists(SCHED_RESET_ON_FORK "sched.h" HAVE_SCHED_RESET_ON_FORK)
|
||||
add_feature_info("SCHED_RESET_ON_FORK"
|
||||
HAVE_SCHED_RESET_ON_FORK
|
||||
"Required for running kwin_wayland with real-time scheduling")
|
||||
|
||||
########### global ###############
|
||||
set(kwin_effects_dbus_xml ${CMAKE_CURRENT_SOURCE_DIR}/org.kde.kwin.Effects.xml)
|
||||
|
||||
|
@ -624,8 +636,20 @@ install(TARGETS kwin_x11 ${INSTALL_TARGETS_DEFAULT_ARGS} )
|
|||
|
||||
add_executable(kwin_wayland main_wayland.cpp)
|
||||
target_link_libraries(kwin_wayland kwin)
|
||||
if (HAVE_LIBCAP)
|
||||
target_link_libraries(kwin_wayland ${Libcap_LIBRARIES})
|
||||
endif()
|
||||
|
||||
install(TARGETS kwin_wayland ${INSTALL_TARGETS_DEFAULT_ARGS} )
|
||||
if (HAVE_LIBCAP)
|
||||
install(
|
||||
CODE "execute_process(
|
||||
COMMAND
|
||||
${SETCAP_EXECUTABLE}
|
||||
CAP_SYS_NICE=+ep
|
||||
${CMAKE_INSTALL_FULL_BINDIR}/kwin_wayland)"
|
||||
)
|
||||
endif()
|
||||
|
||||
add_subdirectory(platformsupport)
|
||||
add_subdirectory(plugins)
|
||||
|
|
59
cmake/modules/FindLibcap.cmake
Normal file
59
cmake/modules/FindLibcap.cmake
Normal file
|
@ -0,0 +1,59 @@
|
|||
# Try to find the setcap binary and cap libraries
|
||||
#
|
||||
# This will define:
|
||||
#
|
||||
# Libcap_FOUND - system has the cap library and setcap binary
|
||||
# Libcap_LIBRARIES - cap libraries to link against
|
||||
# SETCAP_EXECUTABLE - path of the setcap binary
|
||||
# In addition, the following targets are defined:
|
||||
#
|
||||
# Libcap::SetCapabilities
|
||||
#
|
||||
|
||||
|
||||
# Copyright (c) 2014, Hrvoje Senjan, <hrvoje.senjan@gmail.com>
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# 3. The name of the author may not be used to endorse or promote products
|
||||
# derived from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
find_program(SETCAP_EXECUTABLE NAMES setcap DOC "The setcap executable")
|
||||
|
||||
find_library(Libcap_LIBRARIES NAMES cap DOC "The cap (capabilities) library")
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(Libcap FOUND_VAR Libcap_FOUND
|
||||
REQUIRED_VARS SETCAP_EXECUTABLE Libcap_LIBRARIES)
|
||||
|
||||
if(Libcap_FOUND AND NOT TARGET Libcap::SetCapabilities)
|
||||
add_executable(Libcap::SetCapabilities IMPORTED)
|
||||
set_target_properties(Libcap::SetCapabilities PROPERTIES
|
||||
IMPORTED_LOCATION "${SETCAP_EXECUTABLE}"
|
||||
)
|
||||
endif()
|
||||
|
||||
mark_as_advanced(SETCAP_EXECUTABLE Libcap_LIBRARIES)
|
||||
|
||||
include(FeatureSummary)
|
||||
set_package_properties(Libcap PROPERTIES
|
||||
URL https://sites.google.com/site/fullycapable/
|
||||
DESCRIPTION "Capabilities are a measure to limit the omnipotence of the superuser.")
|
|
@ -24,6 +24,8 @@
|
|||
#cmakedefine01 HAVE_SYS_SYSMACROS_H
|
||||
#cmakedefine01 HAVE_BREEZE_DECO
|
||||
#cmakedefine01 HAVE_UDEV
|
||||
#cmakedefine01 HAVE_LIBCAP
|
||||
#cmakedefine01 HAVE_SCHED_RESET_ON_FORK
|
||||
#if HAVE_BREEZE_DECO
|
||||
#define BREEZE_KDECORATION_PLUGIN_ID "${BREEZE_KDECORATION_PLUGIN_ID}"
|
||||
#endif
|
||||
|
|
|
@ -63,6 +63,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include <sys/procctl.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_LIBCAP
|
||||
#include <sys/capability.h>
|
||||
#endif
|
||||
|
||||
#include <sched.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
|
||||
|
@ -438,6 +444,37 @@ static void unsetDumpable(int sig)
|
|||
return;
|
||||
}
|
||||
|
||||
void gainRealTime()
|
||||
{
|
||||
#if HAVE_SCHED_RESET_ON_FORK
|
||||
const int minPriority = sched_get_priority_min(SCHED_RR);
|
||||
struct sched_param sp;
|
||||
sp.sched_priority = minPriority;
|
||||
sched_setscheduler(0, SCHED_RR | SCHED_RESET_ON_FORK, &sp);
|
||||
#endif
|
||||
}
|
||||
|
||||
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[])
|
||||
|
@ -445,6 +482,8 @@ int main(int argc, char * argv[])
|
|||
KWin::disablePtrace();
|
||||
KWin::Application::setupMalloc();
|
||||
KWin::Application::setupLocalizedString();
|
||||
KWin::gainRealTime();
|
||||
KWin::dropNiceCapability();
|
||||
|
||||
if (signal(SIGTERM, KWin::sighandler) == SIG_IGN)
|
||||
signal(SIGTERM, SIG_IGN);
|
||||
|
|
Loading…
Reference in a new issue