summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/basic/cgroup-util.h1
-rw-r--r--src/core/cgroup.c20
-rw-r--r--src/core/dbus-cgroup.c30
-rw-r--r--src/core/load-fragment-gperf.gperf.in4
-rw-r--r--src/core/load-fragment.c2
-rw-r--r--src/core/load-fragment.h1
-rw-r--r--src/login/pam_systemd.c6
-rw-r--r--src/shared/bus-print-properties.c5
-rw-r--r--src/shared/bus-unit-util.c7
-rw-r--r--src/shared/cgroup-setup.c6
-rw-r--r--src/shared/cgroup-setup.h1
-rw-r--r--src/shared/user-record-show.c4
12 files changed, 78 insertions, 9 deletions
diff --git a/src/basic/cgroup-util.h b/src/basic/cgroup-util.h
index 4c413a8d17..df6d5b7bbb 100644
--- a/src/basic/cgroup-util.h
+++ b/src/basic/cgroup-util.h
@@ -86,6 +86,7 @@ bool cpu_accounting_is_cheap(void);
/* Special values for all weight knobs on unified hierarchy */
#define CGROUP_WEIGHT_INVALID UINT64_MAX
+#define CGROUP_WEIGHT_IDLE UINT64_C(0)
#define CGROUP_WEIGHT_MIN UINT64_C(1)
#define CGROUP_WEIGHT_MAX UINT64_C(10000)
#define CGROUP_WEIGHT_DEFAULT UINT64_C(100)
diff --git a/src/core/cgroup.c b/src/core/cgroup.c
index 8b38934615..8ecbd69031 100644
--- a/src/core/cgroup.c
+++ b/src/core/cgroup.c
@@ -949,10 +949,25 @@ static usec_t cgroup_cpu_adjust_period_and_log(Unit *u, usec_t period, usec_t qu
static void cgroup_apply_unified_cpu_weight(Unit *u, uint64_t weight) {
char buf[DECIMAL_STR_MAX(uint64_t) + 2];
+ if (weight == CGROUP_WEIGHT_IDLE)
+ return;
xsprintf(buf, "%" PRIu64 "\n", weight);
(void) set_attribute_and_warn(u, "cpu", "cpu.weight", buf);
}
+static void cgroup_apply_unified_cpu_idle(Unit *u, uint64_t weight) {
+ int r;
+ bool is_idle;
+ const char *idle_val;
+
+ is_idle = weight == CGROUP_WEIGHT_IDLE;
+ idle_val = one_zero(is_idle);
+ r = cg_set_attribute("cpu", u->cgroup_path, "cpu.idle", idle_val);
+ if (r < 0 && (r != -ENOENT || is_idle))
+ log_unit_full_errno(u, LOG_LEVEL_CGROUP_WRITE(r), r, "Failed to set '%s' attribute on '%s' to '%s': %m",
+ "cpu.idle", empty_to_root(u->cgroup_path), idle_val);
+}
+
static void cgroup_apply_unified_cpu_quota(Unit *u, usec_t quota, usec_t period) {
char buf[(DECIMAL_STR_MAX(usec_t) + 1) * 2 + 1];
@@ -993,6 +1008,10 @@ static uint64_t cgroup_cpu_shares_to_weight(uint64_t shares) {
}
static uint64_t cgroup_cpu_weight_to_shares(uint64_t weight) {
+ /* we don't support idle in cgroupv1 */
+ if (weight == CGROUP_WEIGHT_IDLE)
+ return CGROUP_CPU_SHARES_MIN;
+
return CLAMP(weight * CGROUP_CPU_SHARES_DEFAULT / CGROUP_WEIGHT_DEFAULT,
CGROUP_CPU_SHARES_MIN, CGROUP_CPU_SHARES_MAX);
}
@@ -1398,6 +1417,7 @@ static void cgroup_context_apply(
} else
weight = CGROUP_WEIGHT_DEFAULT;
+ cgroup_apply_unified_cpu_idle(u, weight);
cgroup_apply_unified_cpu_weight(u, weight);
cgroup_apply_unified_cpu_quota(u, c->cpu_quota_per_sec_usec, c->cpu_quota_period_usec);
diff --git a/src/core/dbus-cgroup.c b/src/core/dbus-cgroup.c
index 4fc4fb0021..015dc238d6 100644
--- a/src/core/dbus-cgroup.c
+++ b/src/core/dbus-cgroup.c
@@ -894,7 +894,6 @@ static int bus_cgroup_set_boolean(
}
DISABLE_WARNING_TYPE_LIMITS;
-BUS_DEFINE_SET_CGROUP_WEIGHT(cpu_weight, CGROUP_MASK_CPU, CGROUP_WEIGHT_IS_OK, CGROUP_WEIGHT_INVALID);
BUS_DEFINE_SET_CGROUP_WEIGHT(cpu_shares, CGROUP_MASK_CPU, CGROUP_CPU_SHARES_IS_OK, CGROUP_CPU_SHARES_INVALID);
BUS_DEFINE_SET_CGROUP_WEIGHT(io_weight, CGROUP_MASK_IO, CGROUP_WEIGHT_IS_OK, CGROUP_WEIGHT_INVALID);
BUS_DEFINE_SET_CGROUP_WEIGHT(blockio_weight, CGROUP_MASK_BLKIO, CGROUP_BLKIO_WEIGHT_IS_OK, CGROUP_BLKIO_WEIGHT_INVALID);
@@ -903,6 +902,35 @@ BUS_DEFINE_SET_CGROUP_LIMIT(memory_protection, CGROUP_MASK_MEMORY, physical_memo
BUS_DEFINE_SET_CGROUP_LIMIT(swap, CGROUP_MASK_MEMORY, physical_memory_scale, 0);
REENABLE_WARNING;
+static int bus_cgroup_set_cpu_weight(
+ Unit *u,
+ const char *name,
+ uint64_t *p,
+ sd_bus_message *message,
+ UnitWriteFlags flags,
+ sd_bus_error *error) {
+ uint64_t v;
+ int r;
+ assert(p);
+ r = sd_bus_message_read(message, "t", &v);
+ if (r < 0)
+ return r;
+ if (!CGROUP_WEIGHT_IS_OK(v) && v != CGROUP_WEIGHT_IDLE)
+ return sd_bus_error_setf(
+ error, SD_BUS_ERROR_INVALID_ARGS, "Value specified in %s is out of range", name);
+ if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
+ *p = v;
+ unit_invalidate_cgroup(u, CGROUP_MASK_CPU);
+ if (v == CGROUP_WEIGHT_INVALID)
+ unit_write_settingf(u, flags, name, "%s=", name);
+ else if (v == CGROUP_WEIGHT_IDLE)
+ unit_write_settingf(u, flags, name, "%s=idle", name);
+ else
+ unit_write_settingf(u, flags, name, "%s=%" PRIu64, name, v);
+ }
+ return 1;
+}
+
static int bus_cgroup_set_tasks_max(
Unit *u,
const char *name,
diff --git a/src/core/load-fragment-gperf.gperf.in b/src/core/load-fragment-gperf.gperf.in
index 54c1c0bb56..7675b7bb2e 100644
--- a/src/core/load-fragment-gperf.gperf.in
+++ b/src/core/load-fragment-gperf.gperf.in
@@ -191,8 +191,8 @@
{{type}}.AllowedMemoryNodes, config_parse_allowed_cpuset, 0, offsetof({{type}}, cgroup_context.cpuset_mems)
{{type}}.StartupAllowedMemoryNodes, config_parse_allowed_cpuset, 0, offsetof({{type}}, cgroup_context.startup_cpuset_mems)
{{type}}.CPUAccounting, config_parse_bool, 0, offsetof({{type}}, cgroup_context.cpu_accounting)
-{{type}}.CPUWeight, config_parse_cg_weight, 0, offsetof({{type}}, cgroup_context.cpu_weight)
-{{type}}.StartupCPUWeight, config_parse_cg_weight, 0, offsetof({{type}}, cgroup_context.startup_cpu_weight)
+{{type}}.CPUWeight, config_parse_cg_cpu_weight, 0, offsetof({{type}}, cgroup_context.cpu_weight)
+{{type}}.StartupCPUWeight, config_parse_cg_cpu_weight, 0, offsetof({{type}}, cgroup_context.startup_cpu_weight)
{{type}}.CPUShares, config_parse_cpu_shares, 0, offsetof({{type}}, cgroup_context.cpu_shares)
{{type}}.StartupCPUShares, config_parse_cpu_shares, 0, offsetof({{type}}, cgroup_context.startup_cpu_shares)
{{type}}.CPUQuota, config_parse_cpu_quota, 0, offsetof({{type}}, cgroup_context)
diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c
index d16c7b1df2..0a2d4d4035 100644
--- a/src/core/load-fragment.c
+++ b/src/core/load-fragment.c
@@ -147,6 +147,7 @@ DEFINE_CONFIG_PARSE_ENUM(config_parse_managed_oom_preference, managed_oom_prefer
DEFINE_CONFIG_PARSE_ENUM_WITH_DEFAULT(config_parse_ip_tos, ip_tos, int, -1, "Failed to parse IP TOS value");
DEFINE_CONFIG_PARSE_PTR(config_parse_blockio_weight, cg_blkio_weight_parse, uint64_t, "Invalid block IO weight");
DEFINE_CONFIG_PARSE_PTR(config_parse_cg_weight, cg_weight_parse, uint64_t, "Invalid weight");
+DEFINE_CONFIG_PARSE_PTR(config_parse_cg_cpu_weight, cg_cpu_weight_parse, uint64_t, "Invalid CPU weight");
DEFINE_CONFIG_PARSE_PTR(config_parse_cpu_shares, cg_cpu_shares_parse, uint64_t, "Invalid CPU shares");
DEFINE_CONFIG_PARSE_PTR(config_parse_exec_mount_flags, mount_propagation_flags_from_string, unsigned long, "Failed to parse mount flag");
DEFINE_CONFIG_PARSE_ENUM_WITH_DEFAULT(config_parse_numa_policy, mpol, int, -1, "Invalid NUMA policy type");
@@ -6286,6 +6287,7 @@ void unit_dump_config_items(FILE *f) {
{ config_parse_restrict_filesystems, "FILESYSTEMS" },
{ config_parse_cpu_shares, "SHARES" },
{ config_parse_cg_weight, "WEIGHT" },
+ { config_parse_cg_cpu_weight, "CPUWEIGHT" },
{ config_parse_memory_limit, "LIMIT" },
{ config_parse_device_allow, "DEVICE" },
{ config_parse_device_policy, "POLICY" },
diff --git a/src/core/load-fragment.h b/src/core/load-fragment.h
index 26b8de28f7..8842d7ddc8 100644
--- a/src/core/load-fragment.h
+++ b/src/core/load-fragment.h
@@ -78,6 +78,7 @@ CONFIG_PARSER_PROTOTYPE(config_parse_pass_environ);
CONFIG_PARSER_PROTOTYPE(config_parse_unset_environ);
CONFIG_PARSER_PROTOTYPE(config_parse_unit_slice);
CONFIG_PARSER_PROTOTYPE(config_parse_cg_weight);
+CONFIG_PARSER_PROTOTYPE(config_parse_cg_cpu_weight);
CONFIG_PARSER_PROTOTYPE(config_parse_cpu_shares);
CONFIG_PARSER_PROTOTYPE(config_parse_memory_limit);
CONFIG_PARSER_PROTOTYPE(config_parse_tasks_max);
diff --git a/src/login/pam_systemd.c b/src/login/pam_systemd.c
index cb6a6fb514..98736856ee 100644
--- a/src/login/pam_systemd.c
+++ b/src/login/pam_systemd.c
@@ -411,16 +411,18 @@ static int append_session_tasks_max(pam_handle_t *handle, sd_bus_message *m, con
static int append_session_cg_weight(pam_handle_t *handle, sd_bus_message *m, const char *limit, const char *field) {
uint64_t val;
int r;
+ bool is_cpu_weight;
+ is_cpu_weight = streq(field, "CPUWeight");
if (isempty(limit))
return PAM_SUCCESS;
- r = cg_weight_parse(limit, &val);
+ r = is_cpu_weight ? cg_cpu_weight_parse(limit, &val) : cg_weight_parse(limit, &val);
if (r >= 0) {
r = sd_bus_message_append(m, "(sv)", field, "t", val);
if (r < 0)
return pam_bus_log_create_error(handle, r);
- } else if (streq(field, "CPUWeight"))
+ } else if (is_cpu_weight)
pam_syslog(handle, LOG_WARNING, "Failed to parse systemd.cpu_weight, ignoring: %s", limit);
else
pam_syslog(handle, LOG_WARNING, "Failed to parse systemd.io_weight, ignoring: %s", limit);
diff --git a/src/shared/bus-print-properties.c b/src/shared/bus-print-properties.c
index 737bbd3d36..27b6f88cd0 100644
--- a/src/shared/bus-print-properties.c
+++ b/src/shared/bus-print-properties.c
@@ -151,7 +151,10 @@ static int bus_print_property(const char *name, const char *expected_value, sd_b
bus_print_property_value(name, expected_value, flags, s);
- } else if ((STR_IN_SET(name, "CPUWeight", "StartupCPUWeight", "IOWeight", "StartupIOWeight") && u == CGROUP_WEIGHT_INVALID) ||
+ } else if (STR_IN_SET(name, "CPUWeight", "StartupCPUWeight") && u == CGROUP_WEIGHT_IDLE)
+ bus_print_property_value(name, expected_value, flags, "idle");
+
+ else if ((STR_IN_SET(name, "CPUWeight", "StartupCPUWeight", "IOWeight", "StartupIOWeight") && u == CGROUP_WEIGHT_INVALID) ||
(STR_IN_SET(name, "CPUShares", "StartupCPUShares") && u == CGROUP_CPU_SHARES_INVALID) ||
(STR_IN_SET(name, "BlockIOWeight", "StartupBlockIOWeight") && u == CGROUP_BLKIO_WEIGHT_INVALID) ||
(STR_IN_SET(name, "MemoryCurrent", "TasksCurrent") && u == UINT64_MAX) ||
diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c
index 1c96519b55..edc2cfa937 100644
--- a/src/shared/bus-unit-util.c
+++ b/src/shared/bus-unit-util.c
@@ -130,6 +130,7 @@ DEFINE_BUS_APPEND_PARSE_PTR("t", uint64_t, nsec_t, parse_nsec);
DEFINE_BUS_APPEND_PARSE_PTR("t", uint64_t, uint64_t, cg_blkio_weight_parse);
DEFINE_BUS_APPEND_PARSE_PTR("t", uint64_t, uint64_t, cg_cpu_shares_parse);
DEFINE_BUS_APPEND_PARSE_PTR("t", uint64_t, uint64_t, cg_weight_parse);
+DEFINE_BUS_APPEND_PARSE_PTR("t", uint64_t, uint64_t, cg_cpu_weight_parse);
DEFINE_BUS_APPEND_PARSE_PTR("t", uint64_t, unsigned long, mount_propagation_flags_from_string);
DEFINE_BUS_APPEND_PARSE_PTR("t", uint64_t, uint64_t, safe_atou64);
DEFINE_BUS_APPEND_PARSE_PTR("u", uint32_t, mode_t, parse_mode);
@@ -466,8 +467,10 @@ static int bus_append_cgroup_property(sd_bus_message *m, const char *field, cons
return bus_append_parse_boolean(m, field, eq);
if (STR_IN_SET(field, "CPUWeight",
- "StartupCPUWeight",
- "IOWeight",
+ "StartupCPUWeight"))
+ return bus_append_cg_cpu_weight_parse(m, field, eq);
+
+ if (STR_IN_SET(field, "IOWeight",
"StartupIOWeight"))
return bus_append_cg_weight_parse(m, field, eq);
diff --git a/src/shared/cgroup-setup.c b/src/shared/cgroup-setup.c
index a1fabc73c1..c3bf7348ff 100644
--- a/src/shared/cgroup-setup.c
+++ b/src/shared/cgroup-setup.c
@@ -173,6 +173,12 @@ int cg_weight_parse(const char *s, uint64_t *ret) {
return 0;
}
+int cg_cpu_weight_parse(const char *s, uint64_t *ret) {
+ if (streq_ptr(s, "idle"))
+ return *ret = CGROUP_WEIGHT_IDLE;
+ return cg_weight_parse(s, ret);
+}
+
int cg_cpu_shares_parse(const char *s, uint64_t *ret) {
uint64_t u;
int r;
diff --git a/src/shared/cgroup-setup.h b/src/shared/cgroup-setup.h
index 7eabce2451..95a515339d 100644
--- a/src/shared/cgroup-setup.h
+++ b/src/shared/cgroup-setup.h
@@ -12,6 +12,7 @@ bool cg_is_legacy_wanted(void);
bool cg_is_hybrid_wanted(void);
int cg_weight_parse(const char *s, uint64_t *ret);
+int cg_cpu_weight_parse(const char *s, uint64_t *ret);
int cg_cpu_shares_parse(const char *s, uint64_t *ret);
int cg_blkio_weight_parse(const char *s, uint64_t *ret);
diff --git a/src/shared/user-record-show.c b/src/shared/user-record-show.c
index 95895a8e45..4e46a2fe3f 100644
--- a/src/shared/user-record-show.c
+++ b/src/shared/user-record-show.c
@@ -276,7 +276,9 @@ void user_record_show(UserRecord *hr, bool show_full_group_info) {
if (hr->memory_max != UINT64_MAX)
printf(" Memory Max: %s\n", FORMAT_BYTES(hr->memory_max));
- if (hr->cpu_weight != UINT64_MAX)
+ if (hr->cpu_weight == CGROUP_WEIGHT_IDLE)
+ printf(" CPU Weight: %s\n", "idle");
+ else if (hr->cpu_weight != UINT64_MAX)
printf(" CPU Weight: %" PRIu64 "\n", hr->cpu_weight);
if (hr->io_weight != UINT64_MAX)