|
|
ddca0b |
From 8bf8409c6e08f5aef35d1976e172b3f61b651c8d Mon Sep 17 00:00:00 2001
|
|
|
ddca0b |
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
|
|
ddca0b |
Date: Fri, 24 May 2019 08:35:51 +0200
|
|
|
ddca0b |
Subject: [PATCH] pid1: parse CPUAffinity= in incremental fashion
|
|
|
ddca0b |
|
|
|
ddca0b |
This makes the handling of this option match what we do in unit files. I think
|
|
|
ddca0b |
consistency is important here. (As it happens, it is the only option in
|
|
|
ddca0b |
system.conf that is "non-atomic", i.e. where there's a list of things which can
|
|
|
ddca0b |
be split over multiple assignments. All other options are single-valued, so
|
|
|
ddca0b |
there's no issue of how to handle multiple assignments.)
|
|
|
ddca0b |
|
|
|
ddca0b |
(cherry picked from commit 61fbbac1d517a0b3498a689c736c6ca918497904)
|
|
|
ddca0b |
|
|
|
ddca0b |
Related: #1734787
|
|
|
ddca0b |
---
|
|
|
ddca0b |
man/systemd-system.conf.xml | 13 ++++++++-----
|
|
|
ddca0b |
man/systemd.exec.xml | 2 +-
|
|
|
ddca0b |
src/core/main.c | 36 ++++++++++++++++++++++++++----------
|
|
|
ddca0b |
3 files changed, 35 insertions(+), 16 deletions(-)
|
|
|
ddca0b |
|
|
|
ddca0b |
diff --git a/man/systemd-system.conf.xml b/man/systemd-system.conf.xml
|
|
|
ddca0b |
index 085086200a..ab23779ec0 100644
|
|
|
ddca0b |
--- a/man/systemd-system.conf.xml
|
|
|
ddca0b |
+++ b/man/systemd-system.conf.xml
|
|
|
ddca0b |
@@ -99,11 +99,14 @@
|
|
|
ddca0b |
<varlistentry>
|
|
|
ddca0b |
<term><varname>CPUAffinity=</varname></term>
|
|
|
ddca0b |
|
|
|
ddca0b |
- <listitem><para>Configures the initial CPU affinity for the
|
|
|
ddca0b |
- init process. Takes a list of CPU indices or ranges separated
|
|
|
ddca0b |
- by either whitespace or commas. CPU ranges are specified by
|
|
|
ddca0b |
- the lower and upper CPU indices separated by a
|
|
|
ddca0b |
- dash.</para></listitem>
|
|
|
ddca0b |
+ <listitem><para>Configures the CPU affinity for the service manager as well as the default CPU
|
|
|
ddca0b |
+ affinity for all forked off processes. Takes a list of CPU indices or ranges separated by either
|
|
|
ddca0b |
+ whitespace or commas. CPU ranges are specified by the lower and upper CPU indices separated by a
|
|
|
ddca0b |
+ dash. This option may be specified more than once, in which case the specified CPU affinity masks are
|
|
|
ddca0b |
+ merged. If the empty string is assigned, the mask is reset, all assignments prior to this will have
|
|
|
ddca0b |
+ no effect. Individual services may override the CPU affinity for their processes with the
|
|
|
ddca0b |
+ <varname>CPUAffinity=</varname> setting in unit files, see
|
|
|
ddca0b |
+ <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para></listitem>
|
|
|
ddca0b |
</varlistentry>
|
|
|
ddca0b |
|
|
|
ddca0b |
<varlistentry>
|
|
|
ddca0b |
diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml
|
|
|
ddca0b |
index 737c52bcc4..342b8385bc 100644
|
|
|
ddca0b |
--- a/man/systemd.exec.xml
|
|
|
ddca0b |
+++ b/man/systemd.exec.xml
|
|
|
ddca0b |
@@ -703,7 +703,7 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
|
|
|
ddca0b |
|
|
|
ddca0b |
<listitem><para>Controls the CPU affinity of the executed processes. Takes a list of CPU indices or ranges
|
|
|
ddca0b |
separated by either whitespace or commas. CPU ranges are specified by the lower and upper CPU indices separated
|
|
|
ddca0b |
- by a dash. This option may be specified more than once, in which case the specified CPU affinity masks are
|
|
|
ddca0b |
+ by a dash. This option may be specified more than once, in which case the specified CPU affinity masks are
|
|
|
ddca0b |
merged. If the empty string is assigned, the mask is reset, all assignments prior to this will have no
|
|
|
ddca0b |
effect. See
|
|
|
ddca0b |
<citerefentry><refentrytitle>sched_setaffinity</refentrytitle><manvolnum>2</manvolnum></citerefentry> for
|
|
|
ddca0b |
diff --git a/src/core/main.c b/src/core/main.c
|
|
|
ddca0b |
index e62b2756ee..bc1db2af7b 100644
|
|
|
ddca0b |
--- a/src/core/main.c
|
|
|
ddca0b |
+++ b/src/core/main.c
|
|
|
ddca0b |
@@ -127,6 +127,7 @@ static bool arg_default_tasks_accounting = true;
|
|
|
ddca0b |
static uint64_t arg_default_tasks_max = UINT64_MAX;
|
|
|
ddca0b |
static sd_id128_t arg_machine_id = {};
|
|
|
ddca0b |
static EmergencyAction arg_cad_burst_action = EMERGENCY_ACTION_REBOOT_FORCE;
|
|
|
ddca0b |
+static CPUSet arg_cpu_affinity = {};
|
|
|
ddca0b |
|
|
|
ddca0b |
_noreturn_ static void freeze_or_reboot(void) {
|
|
|
ddca0b |
|
|
|
ddca0b |
@@ -537,17 +538,11 @@ static int config_parse_cpu_affinity2(
|
|
|
ddca0b |
void *data,
|
|
|
ddca0b |
void *userdata) {
|
|
|
ddca0b |
|
|
|
ddca0b |
- _cleanup_(cpu_set_reset) CPUSet c = {};
|
|
|
ddca0b |
- int r;
|
|
|
ddca0b |
-
|
|
|
ddca0b |
- r = parse_cpu_set_full(rvalue, &c, true, unit, filename, line, lvalue);
|
|
|
ddca0b |
- if (r < 0)
|
|
|
ddca0b |
- return r;
|
|
|
ddca0b |
+ CPUSet *affinity = data;
|
|
|
ddca0b |
|
|
|
ddca0b |
- if (sched_setaffinity(0, c.allocated, c.set) < 0)
|
|
|
ddca0b |
- log_warning_errno(errno, "Failed to set CPU affinity: %m");
|
|
|
ddca0b |
+ assert(affinity);
|
|
|
ddca0b |
|
|
|
ddca0b |
- // FIXME: parsing and execution should be seperated.
|
|
|
ddca0b |
+ (void) parse_cpu_set_extend(rvalue, affinity, true, unit, filename, line, lvalue);
|
|
|
ddca0b |
|
|
|
ddca0b |
return 0;
|
|
|
ddca0b |
}
|
|
|
ddca0b |
@@ -655,7 +650,7 @@ static int parse_config_file(void) {
|
|
|
ddca0b |
{ "Manager", "CrashShell", config_parse_bool, 0, &arg_crash_shell },
|
|
|
ddca0b |
{ "Manager", "CrashReboot", config_parse_bool, 0, &arg_crash_reboot },
|
|
|
ddca0b |
{ "Manager", "ShowStatus", config_parse_show_status, 0, &arg_show_status },
|
|
|
ddca0b |
- { "Manager", "CPUAffinity", config_parse_cpu_affinity2, 0, NULL },
|
|
|
ddca0b |
+ { "Manager", "CPUAffinity", config_parse_cpu_affinity2, 0, &arg_cpu_affinity },
|
|
|
ddca0b |
{ "Manager", "JoinControllers", config_parse_join_controllers, 0, &arg_join_controllers },
|
|
|
ddca0b |
{ "Manager", "RuntimeWatchdogSec", config_parse_sec, 0, &arg_runtime_watchdog },
|
|
|
ddca0b |
{ "Manager", "ShutdownWatchdogSec", config_parse_sec, 0, &arg_shutdown_watchdog },
|
|
|
ddca0b |
@@ -1483,6 +1478,21 @@ static void initialize_coredump(bool skip_setup) {
|
|
|
ddca0b |
#endif
|
|
|
ddca0b |
}
|
|
|
ddca0b |
|
|
|
ddca0b |
+static void update_cpu_affinity(bool skip_setup) {
|
|
|
ddca0b |
+ _cleanup_free_ char *mask = NULL;
|
|
|
ddca0b |
+
|
|
|
ddca0b |
+ if (skip_setup || !arg_cpu_affinity.set)
|
|
|
ddca0b |
+ return;
|
|
|
ddca0b |
+
|
|
|
ddca0b |
+ assert(arg_cpu_affinity.allocated > 0);
|
|
|
ddca0b |
+
|
|
|
ddca0b |
+ mask = cpu_set_to_string(&arg_cpu_affinity);
|
|
|
ddca0b |
+ log_debug("Setting CPU affinity to %s.", strnull(mask));
|
|
|
ddca0b |
+
|
|
|
ddca0b |
+ if (sched_setaffinity(0, arg_cpu_affinity.allocated, arg_cpu_affinity.set) < 0)
|
|
|
ddca0b |
+ log_warning_errno(errno, "Failed to set CPU affinity: %m");
|
|
|
ddca0b |
+}
|
|
|
ddca0b |
+
|
|
|
ddca0b |
static void do_reexecute(
|
|
|
ddca0b |
int argc,
|
|
|
ddca0b |
char *argv[],
|
|
|
ddca0b |
@@ -1655,6 +1665,8 @@ static int invoke_main_loop(
|
|
|
ddca0b |
|
|
|
ddca0b |
set_manager_defaults(m);
|
|
|
ddca0b |
|
|
|
ddca0b |
+ update_cpu_affinity(false);
|
|
|
ddca0b |
+
|
|
|
ddca0b |
if (saved_log_level >= 0)
|
|
|
ddca0b |
manager_override_log_level(m, saved_log_level);
|
|
|
ddca0b |
if (saved_log_target >= 0)
|
|
|
ddca0b |
@@ -1813,6 +1825,8 @@ static int initialize_runtime(
|
|
|
ddca0b |
if (arg_action != ACTION_RUN)
|
|
|
ddca0b |
return 0;
|
|
|
ddca0b |
|
|
|
ddca0b |
+ update_cpu_affinity(skip_setup);
|
|
|
ddca0b |
+
|
|
|
ddca0b |
if (arg_system) {
|
|
|
ddca0b |
/* Make sure we leave a core dump without panicing the kernel. */
|
|
|
ddca0b |
install_crash_handler();
|
|
|
ddca0b |
@@ -1947,6 +1961,8 @@ static void free_arguments(void) {
|
|
|
ddca0b |
arg_join_controllers = strv_free_free(arg_join_controllers);
|
|
|
ddca0b |
arg_default_environment = strv_free(arg_default_environment);
|
|
|
ddca0b |
arg_syscall_archs = set_free(arg_syscall_archs);
|
|
|
ddca0b |
+
|
|
|
ddca0b |
+ cpu_set_reset(&arg_cpu_affinity);
|
|
|
ddca0b |
}
|
|
|
ddca0b |
|
|
|
ddca0b |
static int load_configuration(int argc, char **argv, const char **ret_error_message) {
|