Merge pull request #20768 from pdmorrow/shutdown_cgroup_ctrl

cgroups: apply StartupAllowedCPUs= and StartupAllowedMemoryNodes= during shutdown
This commit is contained in:
Lennart Poettering 2021-09-27 13:44:54 +02:00 committed by GitHub
commit 49e9218ae3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 62 additions and 47 deletions

View file

@ -189,10 +189,10 @@
Scheduler</ulink>. The available CPU time is split up among all units within one slice relative to
their CPU time weight. A higher weight means more CPU time, a lower weight means less.</para>
<para>While <varname>StartupCPUWeight=</varname> only applies to the startup phase of the system,
<para>While <varname>StartupCPUWeight=</varname> applies to the startup and shutdown phases of the system,
<varname>CPUWeight=</varname> applies to normal runtime of the system, and if the former is not set also to
the startup phase. Using <varname>StartupCPUWeight=</varname> allows prioritizing specific services at
boot-up differently than during normal runtime.</para>
the startup and shutdown phases. Using <varname>StartupCPUWeight=</varname> allows prioritizing specific services at
boot-up and shutdown differently than during normal runtime.</para>
<para>These settings replace <varname>CPUShares=</varname> and <varname>StartupCPUShares=</varname>.</para>
</listitem>
@ -247,10 +247,10 @@
of the CPUs will be used by the processes as it may be limited by parent units. The effective configuration is
reported as <varname>EffectiveCPUs=</varname>.</para>
<para>While <varname>StartupAllowedCPUs=</varname> only applies to the startup phase of the system,
<para>While <varname>StartupAllowedCPUs=</varname> applies to the startup and shutdown phases of the system,
<varname>AllowedCPUs=</varname> applies to normal runtime of the system, and if the former is not set also to
the startup phase. Using <varname>StartupAllowedCPUs=</varname> allows prioritizing specific services at
boot-up differently than during normal runtime.</para>
the startup and shutdown phases. Using <varname>StartupAllowedCPUs=</varname> allows prioritizing specific services at
boot-up and shutdown differently than during normal runtime.</para>
<para>This setting is supported only with the unified control group hierarchy.</para>
</listitem>
@ -269,10 +269,10 @@
guarantee that all of the memory NUMA nodes will be used by the processes as it may be limited by parent units.
The effective configuration is reported as <varname>EffectiveMemoryNodes=</varname>.</para>
<para>While <varname>StartupAllowedMemoryNodes=</varname> only applies to the startup phase of the system,
<para>While <varname>StartupAllowedMemoryNodes=</varname> applies to the startup and shutdown phases of the system,
<varname>AllowedMemoryNodes=</varname> applies to normal runtime of the system, and if the former is not set also to
the startup phase. Using <varname>StartupAllowedMemoryNodes=</varname> allows prioritizing specific services at
boot-up differently than during normal runtime.</para>
the startup and shutdown phases. Using <varname>StartupAllowedMemoryNodes=</varname> allows prioritizing specific services at
boot-up and shutdown differently than during normal runtime.</para>
<para>This setting is supported only with the unified control group hierarchy.</para>
</listitem>
@ -458,12 +458,12 @@
relative to their block I/O weight. A higher weight means more I/O bandwidth, a lower weight means
less.</para>
<para>While <varname>StartupIOWeight=</varname> only applies
to the startup phase of the system,
<para>While <varname>StartupIOWeight=</varname> applies
to the startup and shutdown phases of the system,
<varname>IOWeight=</varname> applies to the later runtime of
the system, and if the former is not set also to the startup
phase. This allows prioritizing specific services at boot-up
differently than during runtime.</para>
and shutdown phases. This allows prioritizing specific services at boot-up
and shutdown differently than during runtime.</para>
<para>These settings replace <varname>BlockIOWeight=</varname> and <varname>StartupBlockIOWeight=</varname>
and disable settings prefixed with <varname>BlockIO</varname> or <varname>StartupBlockIO</varname>.</para>
@ -1194,10 +1194,10 @@ DeviceAllow=/dev/loop-control
The available CPU time is split up among all units within one slice relative to their CPU time share
weight.</para>
<para>While <varname>StartupCPUShares=</varname> only applies to the startup phase of the system,
<para>While <varname>StartupCPUShares=</varname> applies to the startup and shutdown phases of the system,
<varname>CPUShares=</varname> applies to normal runtime of the system, and if the former is not set also to
the startup phase. Using <varname>StartupCPUShares=</varname> allows prioritizing specific services at
boot-up differently than during normal runtime.</para>
the startup and shutdown phases. Using <varname>StartupCPUShares=</varname> allows prioritizing specific services at
boot-up and shutdown differently than during normal runtime.</para>
<para>Implies <literal>CPUAccounting=yes</literal>.</para>
@ -1254,11 +1254,11 @@ DeviceAllow=/dev/loop-control
weight.</para>
<para>While <varname>StartupBlockIOWeight=</varname> only
applies to the startup phase of the system,
applies to the startup and shutdown phases of the system,
<varname>BlockIOWeight=</varname> applies to the later runtime
of the system, and if the former is not set also to the
startup phase. This allows prioritizing specific services at
boot-up differently than during runtime.</para>
startup and shutdown phases. This allows prioritizing specific services at
boot-up and shutdown differently than during runtime.</para>
<para>Implies
<literal>BlockIOAccounting=yes</literal>.</para>

View file

@ -68,6 +68,25 @@ bool manager_owns_host_root_cgroup(Manager *m) {
return empty_or_root(m->cgroup_root);
}
bool unit_has_startup_cgroup_constraints(Unit *u) {
assert(u);
/* Returns true if this unit has any directives which apply during
* startup/shutdown phases. */
CGroupContext *c;
c = unit_get_cgroup_context(u);
if (!c)
return false;
return c->startup_cpu_shares != CGROUP_CPU_SHARES_INVALID ||
c->startup_io_weight != CGROUP_WEIGHT_INVALID ||
c->startup_blockio_weight != CGROUP_BLKIO_WEIGHT_INVALID ||
c->startup_cpuset_cpus.set ||
c->startup_cpuset_mems.set;
}
bool unit_has_host_root_cgroup(Unit *u) {
assert(u);
@ -844,7 +863,7 @@ static bool cgroup_context_has_allowed_mems(CGroupContext *c) {
}
static uint64_t cgroup_context_cpu_weight(CGroupContext *c, ManagerState state) {
if (IN_SET(state, MANAGER_STARTING, MANAGER_INITIALIZING) &&
if (IN_SET(state, MANAGER_STARTING, MANAGER_INITIALIZING, MANAGER_STOPPING) &&
c->startup_cpu_weight != CGROUP_WEIGHT_INVALID)
return c->startup_cpu_weight;
else if (c->cpu_weight != CGROUP_WEIGHT_INVALID)
@ -854,7 +873,7 @@ static uint64_t cgroup_context_cpu_weight(CGroupContext *c, ManagerState state)
}
static uint64_t cgroup_context_cpu_shares(CGroupContext *c, ManagerState state) {
if (IN_SET(state, MANAGER_STARTING, MANAGER_INITIALIZING) &&
if (IN_SET(state, MANAGER_STARTING, MANAGER_INITIALIZING, MANAGER_STOPPING) &&
c->startup_cpu_shares != CGROUP_CPU_SHARES_INVALID)
return c->startup_cpu_shares;
else if (c->cpu_shares != CGROUP_CPU_SHARES_INVALID)
@ -864,7 +883,7 @@ static uint64_t cgroup_context_cpu_shares(CGroupContext *c, ManagerState state)
}
static CPUSet *cgroup_context_allowed_cpus(CGroupContext *c, ManagerState state) {
if (IN_SET(state, MANAGER_STARTING, MANAGER_INITIALIZING) &&
if (IN_SET(state, MANAGER_STARTING, MANAGER_INITIALIZING, MANAGER_STOPPING) &&
c->startup_cpuset_cpus.set)
return &c->startup_cpuset_cpus;
else
@ -872,7 +891,7 @@ static CPUSet *cgroup_context_allowed_cpus(CGroupContext *c, ManagerState state)
}
static CPUSet *cgroup_context_allowed_mems(CGroupContext *c, ManagerState state) {
if (IN_SET(state, MANAGER_STARTING, MANAGER_INITIALIZING) &&
if (IN_SET(state, MANAGER_STARTING, MANAGER_INITIALIZING, MANAGER_STOPPING) &&
c->startup_cpuset_mems.set)
return &c->startup_cpuset_mems;
else
@ -993,7 +1012,7 @@ static bool cgroup_context_has_blockio_config(CGroupContext *c) {
}
static uint64_t cgroup_context_io_weight(CGroupContext *c, ManagerState state) {
if (IN_SET(state, MANAGER_STARTING, MANAGER_INITIALIZING) &&
if (IN_SET(state, MANAGER_STARTING, MANAGER_INITIALIZING, MANAGER_STOPPING) &&
c->startup_io_weight != CGROUP_WEIGHT_INVALID)
return c->startup_io_weight;
else if (c->io_weight != CGROUP_WEIGHT_INVALID)
@ -1003,7 +1022,7 @@ static uint64_t cgroup_context_io_weight(CGroupContext *c, ManagerState state) {
}
static uint64_t cgroup_context_blkio_weight(CGroupContext *c, ManagerState state) {
if (IN_SET(state, MANAGER_STARTING, MANAGER_INITIALIZING) &&
if (IN_SET(state, MANAGER_STARTING, MANAGER_INITIALIZING, MANAGER_STOPPING) &&
c->startup_blockio_weight != CGROUP_BLKIO_WEIGHT_INVALID)
return c->startup_blockio_weight;
else if (c->blockio_weight != CGROUP_BLKIO_WEIGHT_INVALID)
@ -3971,7 +3990,7 @@ void manager_invalidate_startup_units(Manager *m) {
assert(m);
SET_FOREACH(u, m->startup_units)
unit_invalidate_cgroup(u, CGROUP_MASK_CPU|CGROUP_MASK_IO|CGROUP_MASK_BLKIO);
unit_invalidate_cgroup(u, CGROUP_MASK_CPU|CGROUP_MASK_IO|CGROUP_MASK_BLKIO|CGROUP_MASK_CPUSET);
}
static int unit_get_nice(Unit *u) {

View file

@ -311,6 +311,8 @@ int unit_reset_accounting(Unit *u);
bool manager_owns_host_root_cgroup(Manager *m);
bool unit_has_host_root_cgroup(Unit *u);
bool unit_has_startup_cgroup_constraints(Unit *u);
int manager_notify_cgroup_empty(Manager *m, const char *group);
void unit_invalidate_cgroup(Unit *u, CGroupMask m);

View file

@ -1335,6 +1335,8 @@ void job_shutdown_magic(Job *j) {
/* In case messages on console has been disabled on boot */
j->unit->manager->no_console_output = false;
manager_invalidate_startup_units(j->unit->manager);
if (detect_container() > 0)
return;

View file

@ -1557,15 +1557,7 @@ static int unit_add_oomd_dependencies(Unit *u) {
}
static int unit_add_startup_units(Unit *u) {
CGroupContext *c;
c = unit_get_cgroup_context(u);
if (!c)
return 0;
if (c->startup_cpu_shares == CGROUP_CPU_SHARES_INVALID &&
c->startup_io_weight == CGROUP_WEIGHT_INVALID &&
c->startup_blockio_weight == CGROUP_BLKIO_WEIGHT_INVALID)
if (!unit_has_startup_cgroup_constraints(u))
return 0;
return set_ensure_put(&u->manager->startup_units, NULL, u);

View file

@ -1,9 +1,7 @@
mount
[Mount]
AllowedCPUs=
StartupAllowedCPUs=
AllowedMemoryNodes=
StartupAllowedMemoryNodes=
AmbientCapabilities=
AppArmorProfile=
BPFProgram=
@ -174,6 +172,8 @@ StandardInput=
StandardInputData=
StandardInputText=
StandardOutput=
StartupAllowedCPUs=
StartupAllowedMemoryNodes=
StartupBlockIOWeight=
StartupCPUShares=
StartupCPUWeight=

View file

@ -1,9 +1,7 @@
scope
[Scope]
AllowedCPUs=
StartupAllowedCPUs=
AllowedMemoryNodes=
StartupAllowedMemoryNodes=
BPFProgram=
BlockIOAccounting=
BlockIODeviceWeight=
@ -57,6 +55,8 @@ SendSIGKILL=
Slice=
SocketBindAllow=
SocketBindDeny=
StartupAllowedCPUs=
StartupAllowedMemoryNodes=
StartupBlockIOWeight=
StartupCPUShares=
StartupCPUWeight=

View file

@ -115,9 +115,7 @@ RequiredBy=
WantedBy=
[Service]
AllowedCPUs=
StartupAllowedCPUs=
AllowedMemoryNodes=
StartupAllowedMemoryNodes=
AmbientCapabilities=
AppArmorProfile=
BindPaths=
@ -308,6 +306,8 @@ StandardOutput=
StartLimitAction=
StartLimitBurst=
StartLimitInterval=
StartupAllowedCPUs=
StartupAllowedMemoryNodes=
StartupBlockIOWeight=
StartupCPUShares=
StartupCPUWeight=

View file

@ -1,9 +1,7 @@
slice
[Slice]
AllowedCPUs=
StartupAllowedCPUs=
AllowedMemoryNodes=
StartupAllowedMemoryNodes=
BPFProgram=
BlockIOAccounting=
BlockIODeviceWeight=
@ -50,6 +48,8 @@ RestrictNetworkInterfaces=
Slice=
SocketBindAllow=
SocketBindDeny=
StartupAllowedCPUs=
StartupAllowedMemoryNodes=
StartupBlockIOWeight=
StartupCPUShares=
StartupCPUWeight=

View file

@ -2,9 +2,7 @@ socket
[Socket]
Accept=
AllowedCPUs=
StartupAllowedCPUs=
AllowedMemoryNodes=
StartupAllowedMemoryNodes=
AmbientCapabilities=
AppArmorProfile=
BPFProgram=
@ -220,6 +218,8 @@ StandardInput=
StandardInputData=
StandardInputText=
StandardOutput=
StartupAllowedCPUs=
StartupAllowedMemoryNodes=
StartupBlockIOWeight=
StartupCPUShares=
StartupCPUWeight=

View file

@ -1,9 +1,7 @@
swap
[Swap]
AllowedCPUs=
StartupAllowedCPUs=
AllowedMemoryNodes=
StartupAllowedMemoryNodes=
AmbientCapabilities=
AppArmorProfile=
BPFProgram=
@ -170,6 +168,8 @@ StandardInput=
StandardInputData=
StandardInputText=
StandardOutput=
StartupAllowedCPUs=
StartupAllowedMemoryNodes=
StartupBlockIOWeight=
StartupCPUShares=
StartupCPUWeight=