From cfb8a3cf09d9a958388ca1181bb92d9f77ab100e Mon Sep 17 00:00:00 2001 From: licunlong Date: Thu, 6 May 2021 09:38:54 +0800 Subject: [PATCH] core-cgroup: support memorysw Upstream systemd dosen't support setting memory.memsw.limit_in_bytes. This patch enables setting memory.memsw.limit_in_bytes by MemoryMemswLimit. --- src/core/cgroup.c | 17 +++++++++++++++-- src/core/cgroup.h | 1 + src/core/dbus-cgroup.c | 4 ++++ src/core/load-fragment-gperf.gperf.in | 1 + src/core/load-fragment.c | 10 ++++++---- src/shared/bus-print-properties.c | 2 +- src/shared/bus-unit-util.c | 1 + test/fuzz/fuzz-unit-file/directives-all.service | 1 + 8 files changed, 30 insertions(+), 7 deletions(-) diff --git a/src/core/cgroup.c b/src/core/cgroup.c index 7d1e59b..f827219 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -154,6 +154,7 @@ void cgroup_context_init(CGroupContext *c) { .memory_zswap_max = CGROUP_LIMIT_MAX, .memory_limit = CGROUP_LIMIT_MAX, + .memory_memsw_limit = CGROUP_LIMIT_MAX, .io_weight = CGROUP_WEIGHT_INVALID, .startup_io_weight = CGROUP_WEIGHT_INVALID, @@ -481,6 +482,7 @@ void cgroup_context_dump(Unit *u, FILE* f, const char *prefix) { "%sMemorySwapMax: %" PRIu64 "%s\n" "%sMemoryZSwapMax: %" PRIu64 "%s\n" "%sMemoryLimit: %" PRIu64 "\n" + "%sMemoryMemswLimit=%" PRIu64 "\n" "%sCPUSetCpus=%s\n" "%sCPUSetMems=%s\n" "%sCPUSetCloneChildren=%s\n" @@ -525,6 +527,7 @@ void cgroup_context_dump(Unit *u, FILE* f, const char *prefix) { prefix, c->memory_swap_max, format_cgroup_memory_limit_comparison(cde, sizeof(cde), u, "MemorySwapMax"), prefix, c->memory_zswap_max, format_cgroup_memory_limit_comparison(cde, sizeof(cde), u, "MemoryZSwapMax"), prefix, c->memory_limit, + prefix, c->memory_memsw_limit, prefix, c->cpuset_cpus, prefix, c->cpuset_mems, prefix, yes_no(c->cpuset_clone_children), @@ -1673,14 +1676,17 @@ static void cgroup_context_apply( } else { char buf[DECIMAL_STR_MAX(uint64_t) + 1]; - uint64_t val; + uint64_t val, sw_val; if (unit_has_unified_memory_config(u)) { val = c->memory_max; + sw_val = CGROUP_LIMIT_MAX; if (val != CGROUP_LIMIT_MAX) log_cgroup_compat(u, "Applying MemoryMax=%" PRIu64 " as MemoryLimit=", val); - } else + } else { val = c->memory_limit; + sw_val = c->memory_memsw_limit; + } if (val == CGROUP_LIMIT_MAX) strncpy(buf, "-1\n", sizeof(buf)); @@ -1688,6 +1694,12 @@ static void cgroup_context_apply( xsprintf(buf, "%" PRIu64 "\n", val); (void) set_attribute_and_warn(u, "memory", "memory.limit_in_bytes", buf); + + if (sw_val == CGROUP_LIMIT_MAX) + strncpy(buf, "-1\n", sizeof(buf)); + else + xsprintf(buf, "%" PRIu64 "\n", sw_val); + (void) set_attribute_and_warn(u, "memory", "memory.memsw.limit_in_bytes", buf); } } @@ -1883,6 +1895,7 @@ static CGroupMask unit_get_cgroup_mask(Unit *u) { if (c->memory_accounting || c->memory_limit != CGROUP_LIMIT_MAX || + c->memory_memsw_limit != CGROUP_LIMIT_MAX || unit_has_unified_memory_config(u)) mask |= CGROUP_MASK_MEMORY; diff --git a/src/core/cgroup.h b/src/core/cgroup.h index 2251548..313b63c 100644 --- a/src/core/cgroup.h +++ b/src/core/cgroup.h @@ -187,6 +187,7 @@ struct CGroupContext { LIST_HEAD(CGroupBlockIODeviceBandwidth, blockio_device_bandwidths); uint64_t memory_limit; + uint64_t memory_memsw_limit; CGroupDevicePolicy device_policy; LIST_HEAD(CGroupDeviceAllow, device_allow); diff --git a/src/core/dbus-cgroup.c b/src/core/dbus-cgroup.c index c51a8b7..e54657e 100644 --- a/src/core/dbus-cgroup.c +++ b/src/core/dbus-cgroup.c @@ -470,6 +470,7 @@ const sd_bus_vtable bus_cgroup_vtable[] = { SD_BUS_PROPERTY("MemorySwapMax", "t", NULL, offsetof(CGroupContext, memory_swap_max), 0), SD_BUS_PROPERTY("MemoryZSwapMax", "t", NULL, offsetof(CGroupContext, memory_zswap_max), 0), SD_BUS_PROPERTY("MemoryLimit", "t", NULL, offsetof(CGroupContext, memory_limit), 0), + SD_BUS_PROPERTY("MemoryMemswLimit", "t", NULL, offsetof(CGroupContext, memory_memsw_limit), 0), SD_BUS_PROPERTY("CPUSetAccounting", "b", bus_property_get_bool, offsetof(CGroupContext, cpuset_accounting), 0), SD_BUS_PROPERTY("CPUSetCpus", "s", NULL, offsetof(CGroupContext, cpuset_cpus), 0), SD_BUS_PROPERTY("CPUSetMems", "s", NULL, offsetof(CGroupContext, cpuset_mems), 0), @@ -1093,6 +1094,9 @@ int bus_cgroup_set_property( if (streq(name, "MemoryLimit")) return bus_cgroup_set_memory(u, name, &c->memory_limit, message, flags, error); + if (streq(name, "MemoryMemswLimit")) + return bus_cgroup_set_memory(u, name, &c->memory_memsw_limit, message, flags, error); + if (streq(name, "MemoryMinScale")) { r = bus_cgroup_set_memory_protection_scale(u, name, &c->memory_min, message, flags, error); if (r > 0) diff --git a/src/core/load-fragment-gperf.gperf.in b/src/core/load-fragment-gperf.gperf.in index eb68807..c1bc771 100644 --- a/src/core/load-fragment-gperf.gperf.in +++ b/src/core/load-fragment-gperf.gperf.in @@ -208,6 +208,7 @@ {{type}}.MemorySwapMax, config_parse_memory_limit, 0, offsetof({{type}}, cgroup_context) {{type}}.MemoryZSwapMax, config_parse_memory_limit, 0, offsetof({{type}}, cgroup_context) {{type}}.MemoryLimit, config_parse_memory_limit, 0, offsetof({{type}}, cgroup_context) +{{type}}.MemoryMemswLimit, config_parse_memory_limit, 0, offsetof({{type}}, cgroup_context) {{type}}.CPUSetAccounting, config_parse_bool, 0, offsetof({{type}}, cgroup_context.cpuset_accounting) {{type}}.CPUSetCpus, config_parse_cpuset_cpumems, 0, offsetof({{type}}, cgroup_context.cpuset_cpus) {{type}}.CPUSetMems, config_parse_cpuset_cpumems, 0, offsetof({{type}}, cgroup_context.cpuset_mems) diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index d01b6c4..8d2171f 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -3854,6 +3854,8 @@ int config_parse_memory_limit( c->memory_swap_max = bytes; else if (streq(lvalue, "MemoryZSwapMax")) c->memory_zswap_max = bytes; + else if (streq(lvalue, "MemoryMemswLimit")) + c->memory_memsw_limit = bytes; else if (streq(lvalue, "MemoryLimit")) { log_syntax(unit, LOG_WARNING, filename, line, 0, "Unit uses MemoryLimit=; please use MemoryMax= instead. Support for MemoryLimit= will be removed soon."); diff --git a/src/shared/bus-print-properties.c b/src/shared/bus-print-properties.c index 9369866..9e26b71 100644 --- a/src/shared/bus-print-properties.c +++ b/src/shared/bus-print-properties.c @@ -162,7 +162,7 @@ static int bus_print_property(const char *name, const char *expected_value, sd_b bus_print_property_value(name, expected_value, flags, "[not set]"); - else if ((STR_IN_SET(name, "DefaultMemoryLow", "DefaultMemoryMin", "MemoryLow", "MemoryHigh", "MemoryMax", "MemorySwapMax", "MemoryZSwapMax", "MemoryLimit", "MemoryAvailable") && u == CGROUP_LIMIT_MAX) || + else if ((STR_IN_SET(name, "DefaultMemoryLow", "DefaultMemoryMin", "MemoryLow", "MemoryHigh", "MemoryMax", "MemorySwapMax", "MemoryZSwapMax", "MemoryLimit", "MemoryMemswLimit", "MemoryAvailable") && u == CGROUP_LIMIT_MAX) || (STR_IN_SET(name, "TasksMax", "DefaultTasksMax") && u == UINT64_MAX) || (startswith(name, "Limit") && u == UINT64_MAX) || (startswith(name, "DefaultLimit") && u == UINT64_MAX)) diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c index a174e3e..984dfa9 100644 --- a/src/shared/bus-unit-util.c +++ b/src/shared/bus-unit-util.c @@ -547,6 +547,7 @@ static int bus_append_cgroup_property(sd_bus_message *m, const char *field, cons "MemorySwapMax", "MemoryZSwapMax", "MemoryLimit", + "MemoryMemswLimit", "TasksMax")) { if (streq(eq, "infinity")) { diff --git a/test/fuzz/fuzz-unit-file/directives-all.service b/test/fuzz/fuzz-unit-file/directives-all.service index 1a5cd5d..59c693d 100644 --- a/test/fuzz/fuzz-unit-file/directives-all.service +++ b/test/fuzz/fuzz-unit-file/directives-all.service @@ -166,6 +166,7 @@ MemoryHigh= MemoryLimit= MemoryLow= MemoryMax= +MemoryMemswLimit= MemorySwapMax= MemoryZSwapMax= MessageQueueMaxMessages= -- 2.33.0