mirror of
https://github.com/systemd/systemd.git
synced 2025-03-31 14:50:15 +03:00
Merge pull request #12445 from cdown/dmm_docs
cgroup: Some memory protection fixes
This commit is contained in:
commit
180f1e3359
8
NEWS
8
NEWS
@ -19,6 +19,14 @@ CHANGES WITH 243 in spe:
|
||||
are harder to type, but we believe the change from 5 digit PIDs to 7
|
||||
digit PIDs is not too hampering for usability.
|
||||
|
||||
* MemoryLow and MemoryMin gained hierarchy-aware counterparts,
|
||||
DefaultMemoryLow and DefaultMemoryMin, which can be used to
|
||||
hierarchically set default memory protection values for a particular
|
||||
subtree of the unit hierarchy.
|
||||
|
||||
* Memory protection directives can now take a value of zero, allowing
|
||||
explicit opting out of a default value propagated by an ancestor.
|
||||
|
||||
…
|
||||
|
||||
CHANGES WITH 242:
|
||||
|
@ -227,6 +227,7 @@ All cgroup/resource control settings are available for transient units
|
||||
✓ CPUQuota=
|
||||
✓ CPUQuotaPeriodSec=
|
||||
✓ MemoryAccounting=
|
||||
✓ DefaultMemoryMin=
|
||||
✓ MemoryMin=
|
||||
✓ DefaultMemoryLow=
|
||||
✓ MemoryLow=
|
||||
|
@ -245,6 +245,10 @@
|
||||
|
||||
<para>This setting is supported only if the unified control group hierarchy is used and disables
|
||||
<varname>MemoryLimit=</varname>.</para>
|
||||
|
||||
<para>Units may have their children use a default <literal>memory.min</literal> value by specifying
|
||||
<varname>DefaultMemoryMin=</varname>, which has the same semantics as <varname>MemoryMin=</varname>. This setting
|
||||
does not affect <literal>memory.min</literal> in the unit itself.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
@ -266,8 +270,8 @@
|
||||
<para>This setting is supported only if the unified control group hierarchy is used and disables
|
||||
<varname>MemoryLimit=</varname>.</para>
|
||||
|
||||
<para>Units may can have their children use a default <literal>memory.low</literal> value by specifying
|
||||
<varname>DefaultMemoryLow=</varname>, which has the same usage as <varname>MemoryLow=</varname>. This setting
|
||||
<para>Units may have their children use a default <literal>memory.low</literal> value by specifying
|
||||
<varname>DefaultMemoryLow=</varname>, which has the same semantics as <varname>MemoryLow=</varname>. This setting
|
||||
does not affect <literal>memory.low</literal> in the unit itself.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
@ -348,6 +348,7 @@ const sd_bus_vtable bus_cgroup_vtable[] = {
|
||||
SD_BUS_PROPERTY("BlockIOWriteBandwidth", "a(st)", property_get_blockio_device_bandwidths, 0, 0),
|
||||
SD_BUS_PROPERTY("MemoryAccounting", "b", bus_property_get_bool, offsetof(CGroupContext, memory_accounting), 0),
|
||||
SD_BUS_PROPERTY("DefaultMemoryLow", "t", NULL, offsetof(CGroupContext, default_memory_low), 0),
|
||||
SD_BUS_PROPERTY("DefaultMemoryMin", "t", NULL, offsetof(CGroupContext, default_memory_min), 0),
|
||||
SD_BUS_PROPERTY("MemoryMin", "t", NULL, offsetof(CGroupContext, memory_min), 0),
|
||||
SD_BUS_PROPERTY("MemoryLow", "t", NULL, offsetof(CGroupContext, memory_low), 0),
|
||||
SD_BUS_PROPERTY("MemoryHigh", "t", NULL, offsetof(CGroupContext, memory_high), 0),
|
||||
@ -612,6 +613,7 @@ BUS_DEFINE_SET_CGROUP_WEIGHT(cpu_shares, CGROUP_MASK_CPU, CGROUP_CPU_SHARES_IS_O
|
||||
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);
|
||||
BUS_DEFINE_SET_CGROUP_LIMIT(memory, CGROUP_MASK_MEMORY, physical_memory_scale, 1);
|
||||
BUS_DEFINE_SET_CGROUP_LIMIT(memory_protection, CGROUP_MASK_MEMORY, physical_memory_scale, 0);
|
||||
BUS_DEFINE_SET_CGROUP_LIMIT(swap, CGROUP_MASK_MEMORY, physical_memory_scale, 0);
|
||||
BUS_DEFINE_SET_CGROUP_LIMIT(tasks_max, CGROUP_MASK_PIDS, system_tasks_max_scale, 1);
|
||||
#pragma GCC diagnostic pop
|
||||
@ -671,16 +673,16 @@ int bus_cgroup_set_property(
|
||||
return bus_cgroup_set_boolean(u, name, &c->memory_accounting, CGROUP_MASK_MEMORY, message, flags, error);
|
||||
|
||||
if (streq(name, "MemoryMin"))
|
||||
return bus_cgroup_set_memory(u, name, &c->memory_min, message, flags, error);
|
||||
return bus_cgroup_set_memory_protection(u, name, &c->memory_min, message, flags, error);
|
||||
|
||||
if (streq(name, "MemoryLow"))
|
||||
return bus_cgroup_set_memory(u, name, &c->memory_low, message, flags, error);
|
||||
return bus_cgroup_set_memory_protection(u, name, &c->memory_low, message, flags, error);
|
||||
|
||||
if (streq(name, "DefaultMemoryMin"))
|
||||
return bus_cgroup_set_memory(u, name, &c->default_memory_min, message, flags, error);
|
||||
return bus_cgroup_set_memory_protection(u, name, &c->default_memory_min, message, flags, error);
|
||||
|
||||
if (streq(name, "DefaultMemoryLow"))
|
||||
return bus_cgroup_set_memory(u, name, &c->default_memory_low, message, flags, error);
|
||||
return bus_cgroup_set_memory_protection(u, name, &c->default_memory_low, message, flags, error);
|
||||
|
||||
if (streq(name, "MemoryHigh"))
|
||||
return bus_cgroup_set_memory(u, name, &c->memory_high, message, flags, error);
|
||||
@ -695,16 +697,16 @@ int bus_cgroup_set_property(
|
||||
return bus_cgroup_set_memory(u, name, &c->memory_limit, message, flags, error);
|
||||
|
||||
if (streq(name, "MemoryMinScale"))
|
||||
return bus_cgroup_set_memory_scale(u, name, &c->memory_min, message, flags, error);
|
||||
return bus_cgroup_set_memory_protection_scale(u, name, &c->memory_min, message, flags, error);
|
||||
|
||||
if (streq(name, "MemoryLowScale"))
|
||||
return bus_cgroup_set_memory_scale(u, name, &c->memory_low, message, flags, error);
|
||||
return bus_cgroup_set_memory_protection_scale(u, name, &c->memory_low, message, flags, error);
|
||||
|
||||
if (streq(name, "DefaultMemoryMinScale"))
|
||||
return bus_cgroup_set_memory_scale(u, name, &c->default_memory_min, message, flags, error);
|
||||
return bus_cgroup_set_memory_protection_scale(u, name, &c->default_memory_min, message, flags, error);
|
||||
|
||||
if (streq(name, "DefaultMemoryLowScale"))
|
||||
return bus_cgroup_set_memory_scale(u, name, &c->default_memory_low, message, flags, error);
|
||||
return bus_cgroup_set_memory_protection_scale(u, name, &c->default_memory_low, message, flags, error);
|
||||
|
||||
if (streq(name, "MemoryHighScale"))
|
||||
return bus_cgroup_set_memory_scale(u, name, &c->memory_high, message, flags, error);
|
||||
|
@ -172,6 +172,7 @@ $1.CPUQuota, config_parse_cpu_quota, 0,
|
||||
$1.CPUQuotaPeriodSec, config_parse_sec_def_infinity, 0, offsetof($1, cgroup_context.cpu_quota_period_usec)
|
||||
$1.MemoryAccounting, config_parse_bool, 0, offsetof($1, cgroup_context.memory_accounting)
|
||||
$1.MemoryMin, config_parse_memory_limit, 0, offsetof($1, cgroup_context)
|
||||
$1.DefaultMemoryMin, config_parse_memory_limit, 0, offsetof($1, cgroup_context)
|
||||
$1.DefaultMemoryLow, config_parse_memory_limit, 0, offsetof($1, cgroup_context)
|
||||
$1.MemoryLow, config_parse_memory_limit, 0, offsetof($1, cgroup_context)
|
||||
$1.MemoryHigh, config_parse_memory_limit, 0, offsetof($1, cgroup_context)
|
||||
|
@ -3137,7 +3137,7 @@ int config_parse_memory_limit(
|
||||
bytes = physical_memory_scale(r, 1000U);
|
||||
|
||||
if (bytes >= UINT64_MAX ||
|
||||
(bytes <= 0 && !streq(lvalue, "MemorySwapMax"))) {
|
||||
(bytes <= 0 && !STR_IN_SET(lvalue, "MemorySwapMax", "MemoryLow", "MemoryMin", "DefaultMemoryLow", "DefaultMemoryMin"))) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0, "Memory limit '%s' out of range, ignoring.", rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
@ -413,7 +413,7 @@ static int bus_append_cgroup_property(sd_bus_message *m, const char *field, cons
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (STR_IN_SET(field, "MemoryMin", "DefaultMemoryLow", "MemoryLow", "MemoryHigh", "MemoryMax", "MemorySwapMax", "MemoryLimit", "TasksMax")) {
|
||||
if (STR_IN_SET(field, "MemoryMin", "DefaultMemoryLow", "DefaultMemoryMin", "MemoryLow", "MemoryHigh", "MemoryMax", "MemorySwapMax", "MemoryLimit", "TasksMax")) {
|
||||
|
||||
if (isempty(eq) || streq(eq, "infinity")) {
|
||||
r = sd_bus_message_append(m, "(sv)", field, "t", CGROUP_LIMIT_MAX);
|
||||
|
@ -794,7 +794,7 @@ static int bus_print_property(const char *name, const char *expected_value, sd_b
|
||||
|
||||
bus_print_property_value(name, expected_value, value, "[not set]");
|
||||
|
||||
else if ((STR_IN_SET(name, "DefaultMemoryLow", "MemoryLow", "MemoryHigh", "MemoryMax", "MemorySwapMax", "MemoryLimit") && u == CGROUP_LIMIT_MAX) ||
|
||||
else if ((STR_IN_SET(name, "DefaultMemoryLow", "DefaultMemoryMin", "MemoryLow", "MemoryHigh", "MemoryMax", "MemorySwapMax", "MemoryLimit") && u == CGROUP_LIMIT_MAX) ||
|
||||
(STR_IN_SET(name, "TasksMax", "DefaultTasksMax") && u == (uint64_t) -1) ||
|
||||
(startswith(name, "Limit") && u == (uint64_t) -1) ||
|
||||
(startswith(name, "DefaultLimit") && u == (uint64_t) -1))
|
||||
|
@ -39,7 +39,7 @@ static int test_default_memory_low(void) {
|
||||
* 1. dml-passthrough.slice sets MemoryLow=100. This should not affect its children, as only
|
||||
* DefaultMemoryLow is propagated, not MemoryLow. As such, all leaf services should end up with
|
||||
* memory.low as 50, inherited from dml.slice, *except* for dml-passthrough-set-ml.service, which
|
||||
* should have the value of 25, as it has MemoryLow explicitly set.
|
||||
* should have the value of 0, as it has MemoryLow explicitly set.
|
||||
*
|
||||
* ┌───────────┐
|
||||
* │ dml.slice │
|
||||
@ -49,7 +49,7 @@ static int test_default_memory_low(void) {
|
||||
* │ dml-passthrough.slice │
|
||||
* └───────────┬───────────┘
|
||||
* ┌───────────────────────────────────┼───────────────────────────────────┐
|
||||
* no new settings DefaultMemoryLow=15 MemoryLow=25
|
||||
* no new settings DefaultMemoryLow=15 MemoryLow=0
|
||||
* ┌───────────────┴───────────────┐ ┌────────────────┴────────────────┐ ┌───────────────┴────────────────┐
|
||||
* │ dml-passthrough-empty.service │ │ dml-passthrough-set-dml.service │ │ dml-passthrough-set-ml.service │
|
||||
* └───────────────────────────────┘ └─────────────────────────────────┘ └────────────────────────────────┘
|
||||
@ -122,7 +122,7 @@ static int test_default_memory_low(void) {
|
||||
assert_se(unit_get_ancestor_memory_low(dml_passthrough) == 100);
|
||||
assert_se(unit_get_ancestor_memory_low(dml_passthrough_empty) == dml_tree_default);
|
||||
assert_se(unit_get_ancestor_memory_low(dml_passthrough_set_dml) == 50);
|
||||
assert_se(unit_get_ancestor_memory_low(dml_passthrough_set_ml) == 25);
|
||||
assert_se(unit_get_ancestor_memory_low(dml_passthrough_set_ml) == 0);
|
||||
|
||||
assert_se(unit_get_ancestor_memory_low(dml_override) == dml_tree_default);
|
||||
assert_se(unit_get_ancestor_memory_low(dml_override_empty) == 10);
|
||||
|
@ -5,4 +5,4 @@ Description=DML passthrough set ML service
|
||||
Slice=dml-passthrough.slice
|
||||
Type=oneshot
|
||||
ExecStart=/bin/true
|
||||
MemoryLow=25
|
||||
MemoryLow=0
|
||||
|
Loading…
x
Reference in New Issue
Block a user