mirror of
https://github.com/systemd/systemd.git
synced 2024-12-22 17:35:35 +03:00
core/cgroup: CPUWeight/CPUShares support idle input
Signed-off-by: wineway <wangyuweihx@gmail.com>
This commit is contained in:
parent
1cb3f4ad6e
commit
c8340822cf
1
.gitignore
vendored
1
.gitignore
vendored
@ -37,3 +37,4 @@ __pycache__/
|
||||
/mkosi.default.d/**/*local*.conf
|
||||
/tags
|
||||
.dir-locals-2.el
|
||||
.vscode/
|
||||
|
@ -180,14 +180,26 @@
|
||||
<term><varname>StartupCPUWeight=<replaceable>weight</replaceable></varname></term>
|
||||
|
||||
<listitem>
|
||||
<para>Assign the specified CPU time weight to the processes executed, if the unified control group
|
||||
hierarchy is used on the system. These options take an integer value and control the
|
||||
<literal>cpu.weight</literal> control group attribute. The allowed range is 1 to 10000. Defaults to
|
||||
100. For details about this control group attribute, see <ulink
|
||||
url="https://docs.kernel.org/admin-guide/cgroup-v2.html">Control Groups v2</ulink>
|
||||
and <ulink url="https://docs.kernel.org/scheduler/sched-design-CFS.html">CFS
|
||||
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>These options accept an integer value or a the special string "idle":</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>If set to an integer value, assign the specified CPU time weight to the processes executed,
|
||||
if the unified control group hierarchy is used on the system. These options control the
|
||||
<literal>cpu.weight</literal> control group attribute. The allowed range is 1 to 10000. Defaults to
|
||||
100. For details about this control group attribute, see <ulink
|
||||
url="https://docs.kernel.org/admin-guide/cgroup-v2.html">Control Groups v2</ulink>
|
||||
and <ulink url="https://docs.kernel.org/scheduler/sched-design-CFS.html">CFS
|
||||
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>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>If set to the special string "idle", mark the cgroup for "idle scheduling", which means
|
||||
that it will get CPU resources only when there are no processes not marked in this way to execute in this
|
||||
cgroup or its siblings. This setting corresponds to the <literal>cpu.idle</literal> cgroup attribute.</para>
|
||||
|
||||
<para>Note that this value only has an effect on cgroup-v2, for cgroup-v1 it is equivalent to the minimum weight.</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<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
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
|
@ -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" },
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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) ||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user