diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/basic/cgroup-util.h | 1 | ||||
-rw-r--r-- | src/core/cgroup.c | 20 | ||||
-rw-r--r-- | src/core/dbus-cgroup.c | 30 | ||||
-rw-r--r-- | src/core/load-fragment-gperf.gperf.in | 4 | ||||
-rw-r--r-- | src/core/load-fragment.c | 2 | ||||
-rw-r--r-- | src/core/load-fragment.h | 1 | ||||
-rw-r--r-- | src/login/pam_systemd.c | 6 | ||||
-rw-r--r-- | src/shared/bus-print-properties.c | 5 | ||||
-rw-r--r-- | src/shared/bus-unit-util.c | 7 | ||||
-rw-r--r-- | src/shared/cgroup-setup.c | 6 | ||||
-rw-r--r-- | src/shared/cgroup-setup.h | 1 | ||||
-rw-r--r-- | src/shared/user-record-show.c | 4 |
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) |