Merge pull request #12445 from cdown/dmm_docs

cgroup: Some memory protection fixes
This commit is contained in:
Zbigniew Jędrzejewski-Szmek 2019-05-08 18:09:45 +02:00 committed by GitHub
commit 180f1e3359
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 33 additions and 17 deletions

8
NEWS
View File

@ -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:

View File

@ -227,6 +227,7 @@ All cgroup/resource control settings are available for transient units
✓ CPUQuota=
✓ CPUQuotaPeriodSec=
✓ MemoryAccounting=
✓ DefaultMemoryMin=
✓ MemoryMin=
✓ DefaultMemoryLow=
✓ MemoryLow=

View File

@ -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>

View File

@ -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);

View File

@ -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)

View File

@ -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;
}

View File

@ -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);

View File

@ -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))

View File

@ -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);

View File

@ -5,4 +5,4 @@ Description=DML passthrough set ML service
Slice=dml-passthrough.slice
Type=oneshot
ExecStart=/bin/true
MemoryLow=25
MemoryLow=0