summaryrefslogtreecommitdiff
path: root/src/core/cgroup.c
diff options
context:
space:
mode:
authorPeter Morrow <pemorrow@linux.microsoft.com>2021-09-14 17:14:53 +0100
committerPeter Morrow <pemorrow@linux.microsoft.com>2021-09-15 09:30:12 +0100
commit31d3a520297980ac31186e27396a05f928fde49f (patch)
treeb51a6ceddd6847ffddd7f49a0510a119cdd660c4 /src/core/cgroup.c
parent74973e3ed0de8f60ed5b7aa335d723c1de5655ca (diff)
downloadsystemd-31d3a520297980ac31186e27396a05f928fde49f.tar.gz
cgroup: add support for StartupAllowedCPUs and StartupAllowedMemoryNodes
Add new settings which can be used to control cpuset based cpu affinity during the startup phase only. Signed-off-by: Peter Morrow <pemorrow@linux.microsoft.com>
Diffstat (limited to 'src/core/cgroup.c')
-rw-r--r--src/core/cgroup.c40
1 files changed, 36 insertions, 4 deletions
diff --git a/src/core/cgroup.c b/src/core/cgroup.c
index 2d136793f9..17e93d7af1 100644
--- a/src/core/cgroup.c
+++ b/src/core/cgroup.c
@@ -251,7 +251,9 @@ void cgroup_context_done(CGroupContext *c) {
c->restrict_network_interfaces = set_free(c->restrict_network_interfaces);
cpu_set_reset(&c->cpuset_cpus);
+ cpu_set_reset(&c->startup_cpuset_cpus);
cpu_set_reset(&c->cpuset_mems);
+ cpu_set_reset(&c->startup_cpuset_mems);
}
static int unit_get_kernel_memory_limit(Unit *u, const char *file, uint64_t *ret) {
@@ -386,7 +388,7 @@ static char *format_cgroup_memory_limit_comparison(char *buf, size_t l, Unit *u,
}
void cgroup_context_dump(Unit *u, FILE* f, const char *prefix) {
- _cleanup_free_ char *disable_controllers_str = NULL, *cpuset_cpus = NULL, *cpuset_mems = NULL;
+ _cleanup_free_ char *disable_controllers_str = NULL, *cpuset_cpus = NULL, *cpuset_mems = NULL, *startup_cpuset_cpus = NULL, *startup_cpuset_mems = NULL;
CGroupIODeviceLimit *il;
CGroupIODeviceWeight *iw;
CGroupIODeviceLatency *l;
@@ -415,7 +417,9 @@ void cgroup_context_dump(Unit *u, FILE* f, const char *prefix) {
(void) cg_mask_to_string(c->disable_controllers, &disable_controllers_str);
cpuset_cpus = cpu_set_to_range_string(&c->cpuset_cpus);
+ startup_cpuset_cpus = cpu_set_to_range_string(&c->startup_cpuset_cpus);
cpuset_mems = cpu_set_to_range_string(&c->cpuset_mems);
+ startup_cpuset_mems = cpu_set_to_range_string(&c->startup_cpuset_mems);
fprintf(f,
"%sCPUAccounting: %s\n"
@@ -431,7 +435,9 @@ void cgroup_context_dump(Unit *u, FILE* f, const char *prefix) {
"%sCPUQuotaPerSecSec: %s\n"
"%sCPUQuotaPeriodSec: %s\n"
"%sAllowedCPUs: %s\n"
+ "%sStartupAllowedCPUs: %s\n"
"%sAllowedMemoryNodes: %s\n"
+ "%sStartupAllowedMemoryNodes: %s\n"
"%sIOWeight: %" PRIu64 "\n"
"%sStartupIOWeight: %" PRIu64 "\n"
"%sBlockIOWeight: %" PRIu64 "\n"
@@ -465,7 +471,9 @@ void cgroup_context_dump(Unit *u, FILE* f, const char *prefix) {
prefix, FORMAT_TIMESPAN(c->cpu_quota_per_sec_usec, 1),
prefix, FORMAT_TIMESPAN(c->cpu_quota_period_usec, 1),
prefix, strempty(cpuset_cpus),
+ prefix, strempty(startup_cpuset_cpus),
prefix, strempty(cpuset_mems),
+ prefix, strempty(startup_cpuset_mems),
prefix, c->io_weight,
prefix, c->startup_io_weight,
prefix, c->blockio_weight,
@@ -827,6 +835,14 @@ static bool cgroup_context_has_cpu_shares(CGroupContext *c) {
c->startup_cpu_shares != CGROUP_CPU_SHARES_INVALID;
}
+static bool cgroup_context_has_allowed_cpus(CGroupContext *c) {
+ return c->cpuset_cpus.set || c->startup_cpuset_cpus.set;
+}
+
+static bool cgroup_context_has_allowed_mems(CGroupContext *c) {
+ return c->cpuset_mems.set || c->startup_cpuset_mems.set;
+}
+
static uint64_t cgroup_context_cpu_weight(CGroupContext *c, ManagerState state) {
if (IN_SET(state, MANAGER_STARTING, MANAGER_INITIALIZING) &&
c->startup_cpu_weight != CGROUP_WEIGHT_INVALID)
@@ -847,6 +863,22 @@ static uint64_t cgroup_context_cpu_shares(CGroupContext *c, ManagerState state)
return CGROUP_CPU_SHARES_DEFAULT;
}
+static CPUSet *cgroup_context_allowed_cpus(CGroupContext *c, ManagerState state) {
+ if (IN_SET(state, MANAGER_STARTING, MANAGER_INITIALIZING) &&
+ c->startup_cpuset_cpus.set)
+ return &c->startup_cpuset_cpus;
+ else
+ return &c->cpuset_cpus;
+}
+
+static CPUSet *cgroup_context_allowed_mems(CGroupContext *c, ManagerState state) {
+ if (IN_SET(state, MANAGER_STARTING, MANAGER_INITIALIZING) &&
+ c->startup_cpuset_mems.set)
+ return &c->startup_cpuset_mems;
+ else
+ return &c->cpuset_mems;
+}
+
usec_t cgroup_cpu_adjust_period(usec_t period, usec_t quota, usec_t resolution, usec_t max_period) {
/* kernel uses a minimum resolution of 1ms, so both period and (quota * period)
* need to be higher than that boundary. quota is specified in USecPerSec.
@@ -1302,8 +1334,8 @@ static void cgroup_context_apply(
}
if ((apply_mask & CGROUP_MASK_CPUSET) && !is_local_root) {
- cgroup_apply_unified_cpuset(u, &c->cpuset_cpus, "cpuset.cpus");
- cgroup_apply_unified_cpuset(u, &c->cpuset_mems, "cpuset.mems");
+ cgroup_apply_unified_cpuset(u, cgroup_context_allowed_cpus(c, state), "cpuset.cpus");
+ cgroup_apply_unified_cpuset(u, cgroup_context_allowed_mems(c, state), "cpuset.mems");
}
/* The 'io' controller attributes are not exported on the host's root cgroup (being a pure cgroup v2
@@ -1627,7 +1659,7 @@ static CGroupMask unit_get_cgroup_mask(Unit *u) {
c->cpu_quota_per_sec_usec != USEC_INFINITY)
mask |= CGROUP_MASK_CPU;
- if (c->cpuset_cpus.set || c->cpuset_mems.set)
+ if (cgroup_context_has_allowed_cpus(c) || cgroup_context_has_allowed_mems(c))
mask |= CGROUP_MASK_CPUSET;
if (cgroup_context_has_io_config(c) || cgroup_context_has_blockio_config(c))