From: Pasha Vorobyev Date: Fri, 4 Feb 2022 19:49:46 +0000 (-0800) Subject: MemoryZSwapMax directive to configure new memory.zswap.max cgroup file X-Git-Tag: v253-rc1~524 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=d7fe0a67233100acfeadfe18a0f3a7d3d963f4d1;p=thirdparty%2Fsystemd.git MemoryZSwapMax directive to configure new memory.zswap.max cgroup file --- diff --git a/man/org.freedesktop.systemd1.xml b/man/org.freedesktop.systemd1.xml index 5e08b352341..758f52fe443 100644 --- a/man/org.freedesktop.systemd1.xml +++ b/man/org.freedesktop.systemd1.xml @@ -2707,6 +2707,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice { @org.freedesktop.DBus.Property.EmitsChangedSignal("false") readonly t MemorySwapMax = ...; @org.freedesktop.DBus.Property.EmitsChangedSignal("false") + readonly t MemoryZSwapMax = ...; + @org.freedesktop.DBus.Property.EmitsChangedSignal("false") readonly t MemoryLimit = ...; @org.freedesktop.DBus.Property.EmitsChangedSignal("false") readonly s DevicePolicy = '...'; @@ -3278,6 +3280,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice { + + @@ -3858,6 +3862,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice { + + @@ -4595,6 +4601,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket { @org.freedesktop.DBus.Property.EmitsChangedSignal("false") readonly t MemorySwapMax = ...; @org.freedesktop.DBus.Property.EmitsChangedSignal("false") + readonly t MemoryZSwapMax = ...; + @org.freedesktop.DBus.Property.EmitsChangedSignal("false") readonly t MemoryLimit = ...; @org.freedesktop.DBus.Property.EmitsChangedSignal("false") readonly s DevicePolicy = '...'; @@ -5190,6 +5198,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket { + + @@ -5764,6 +5774,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket { + + @@ -6390,6 +6402,8 @@ node /org/freedesktop/systemd1/unit/home_2emount { @org.freedesktop.DBus.Property.EmitsChangedSignal("false") readonly t MemorySwapMax = ...; @org.freedesktop.DBus.Property.EmitsChangedSignal("false") + readonly t MemoryZSwapMax = ...; + @org.freedesktop.DBus.Property.EmitsChangedSignal("false") readonly t MemoryLimit = ...; @org.freedesktop.DBus.Property.EmitsChangedSignal("false") readonly s DevicePolicy = '...'; @@ -6913,6 +6927,8 @@ node /org/freedesktop/systemd1/unit/home_2emount { + + @@ -7405,6 +7421,8 @@ node /org/freedesktop/systemd1/unit/home_2emount { + + @@ -8158,6 +8176,8 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap { @org.freedesktop.DBus.Property.EmitsChangedSignal("false") readonly t MemorySwapMax = ...; @org.freedesktop.DBus.Property.EmitsChangedSignal("false") + readonly t MemoryZSwapMax = ...; + @org.freedesktop.DBus.Property.EmitsChangedSignal("false") readonly t MemoryLimit = ...; @org.freedesktop.DBus.Property.EmitsChangedSignal("false") readonly s DevicePolicy = '...'; @@ -8667,6 +8687,8 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap { + + @@ -9145,6 +9167,8 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap { + + @@ -9757,6 +9781,8 @@ node /org/freedesktop/systemd1/unit/system_2eslice { @org.freedesktop.DBus.Property.EmitsChangedSignal("false") readonly t MemorySwapMax = ...; @org.freedesktop.DBus.Property.EmitsChangedSignal("false") + readonly t MemoryZSwapMax = ...; + @org.freedesktop.DBus.Property.EmitsChangedSignal("false") readonly t MemoryLimit = ...; @org.freedesktop.DBus.Property.EmitsChangedSignal("false") readonly s DevicePolicy = '...'; @@ -9908,6 +9934,8 @@ node /org/freedesktop/systemd1/unit/system_2eslice { + + @@ -10066,6 +10094,8 @@ node /org/freedesktop/systemd1/unit/system_2eslice { + + @@ -10246,6 +10276,8 @@ node /org/freedesktop/systemd1/unit/session_2d1_2escope { @org.freedesktop.DBus.Property.EmitsChangedSignal("false") readonly t MemorySwapMax = ...; @org.freedesktop.DBus.Property.EmitsChangedSignal("false") + readonly t MemoryZSwapMax = ...; + @org.freedesktop.DBus.Property.EmitsChangedSignal("false") readonly t MemoryLimit = ...; @org.freedesktop.DBus.Property.EmitsChangedSignal("false") readonly s DevicePolicy = '...'; @@ -10415,6 +10447,8 @@ node /org/freedesktop/systemd1/unit/session_2d1_2escope { + + @@ -10601,6 +10635,8 @@ node /org/freedesktop/systemd1/unit/session_2d1_2escope { + + diff --git a/man/systemd.resource-control.xml b/man/systemd.resource-control.xml index 2a0e40a17d2..b2b15d8e53c 100644 --- a/man/systemd.resource-control.xml +++ b/man/systemd.resource-control.xml @@ -325,14 +325,15 @@ MemorySwapMax=bytes + MemoryZSwapMax=bytes - Specify the absolute limit on swap usage of the executed processes in this unit. + Specify the absolute limit on (z)swap usage of the executed processes in this unit. Takes a swap size in bytes. If the value is suffixed with K, M, G or T, the specified swap size is parsed as Kilobytes, Megabytes, Gigabytes, or Terabytes (with the base 1024), respectively. If assigned the - special value infinity, no swap limit is applied. This controls the - memory.swap.max control group attribute. For details about this control group attribute, + special value infinity, no swap limit is applied. These settings control the + memory.(z)swap.max control group attributes. For details about these control group attributes, see Memory Interface Files. diff --git a/src/core/cgroup.c b/src/core/cgroup.c index c44966839cc..1e9cb758de9 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -151,6 +151,7 @@ void cgroup_context_init(CGroupContext *c) { .memory_high = CGROUP_LIMIT_MAX, .memory_max = CGROUP_LIMIT_MAX, .memory_swap_max = CGROUP_LIMIT_MAX, + .memory_zswap_max = CGROUP_LIMIT_MAX, .memory_limit = CGROUP_LIMIT_MAX, @@ -354,6 +355,9 @@ static int unit_compare_memory_limit(Unit *u, const char *property_name, uint64_ } else if (streq(property_name, "MemorySwapMax")) { unit_value = c->memory_swap_max; file = "memory.swap.max"; + } else if (streq(property_name, "MemoryZSwapMax")) { + unit_value = c->memory_zswap_max; + file = "memory.zswap.max"; } else return -EINVAL; @@ -396,9 +400,10 @@ static char *format_cgroup_memory_limit_comparison(char *buf, size_t l, Unit *u, /* memory.swap.max is special in that it relies on CONFIG_MEMCG_SWAP (and the default swapaccount=1). * In the absence of reliably being able to detect whether memcg swap support is available or not, - * only complain if the error is not ENOENT. */ + * only complain if the error is not ENOENT. This is similarly the case for memory.zswap.max relying + * on CONFIG_ZSWAP. */ if (r > 0 || IN_SET(r, -ENODATA, -EOWNERDEAD) || - (r == -ENOENT && streq(property_name, "MemorySwapMax"))) + (r == -ENOENT && STR_IN_SET(property_name, "MemorySwapMax", "MemoryZSwapMax"))) buf[0] = 0; else if (r < 0) { errno = -r; @@ -462,6 +467,7 @@ void cgroup_context_dump(Unit *u, FILE* f, const char *prefix) { "%sMemoryHigh: %" PRIu64 "%s\n" "%sMemoryMax: %" PRIu64 "%s\n" "%sMemorySwapMax: %" PRIu64 "%s\n" + "%sMemoryZSwapMax: %" PRIu64 "%s\n" "%sMemoryLimit: %" PRIu64 "\n" "%sTasksMax: %" PRIu64 "\n" "%sDevicePolicy: %s\n" @@ -498,6 +504,7 @@ void cgroup_context_dump(Unit *u, FILE* f, const char *prefix) { prefix, c->memory_high, format_cgroup_memory_limit_comparison(cdc, sizeof(cdc), u, "MemoryHigh"), prefix, c->memory_max, format_cgroup_memory_limit_comparison(cdd, sizeof(cdd), u, "MemoryMax"), 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, tasks_max_resolve(&c->tasks_max), prefix, cgroup_device_policy_to_string(c->device_policy), @@ -1209,7 +1216,7 @@ static bool unit_has_unified_memory_config(Unit *u) { return unit_get_ancestor_memory_min(u) > 0 || unit_get_ancestor_memory_low(u) > 0 || c->memory_high != CGROUP_LIMIT_MAX || c->memory_max != CGROUP_LIMIT_MAX || - c->memory_swap_max != CGROUP_LIMIT_MAX; + c->memory_swap_max != CGROUP_LIMIT_MAX || c->memory_zswap_max != CGROUP_LIMIT_MAX; } static void cgroup_apply_unified_memory_limit(Unit *u, const char *file, uint64_t v) { @@ -1569,11 +1576,12 @@ static void cgroup_context_apply( if ((apply_mask & CGROUP_MASK_MEMORY) && !is_local_root) { if (cg_all_unified() > 0) { - uint64_t max, swap_max = CGROUP_LIMIT_MAX; + uint64_t max, swap_max = CGROUP_LIMIT_MAX, zswap_max = CGROUP_LIMIT_MAX; if (unit_has_unified_memory_config(u)) { max = c->memory_max; swap_max = c->memory_swap_max; + zswap_max = c->memory_zswap_max; } else { max = c->memory_limit; @@ -1586,6 +1594,7 @@ static void cgroup_context_apply( cgroup_apply_unified_memory_limit(u, "memory.high", c->memory_high); cgroup_apply_unified_memory_limit(u, "memory.max", max); cgroup_apply_unified_memory_limit(u, "memory.swap.max", swap_max); + cgroup_apply_unified_memory_limit(u, "memory.zswap.max", zswap_max); (void) set_attribute_and_warn(u, "memory", "memory.oom.group", one_zero(c->memory_oom_group)); diff --git a/src/core/cgroup.h b/src/core/cgroup.h index 4413eeaaa0a..09352bafc63 100644 --- a/src/core/cgroup.h +++ b/src/core/cgroup.h @@ -149,6 +149,7 @@ struct CGroupContext { uint64_t memory_high; uint64_t memory_max; uint64_t memory_swap_max; + uint64_t memory_zswap_max; bool default_memory_min_set:1; bool default_memory_low_set:1; diff --git a/src/core/dbus-cgroup.c b/src/core/dbus-cgroup.c index cbadb5bc447..b5484eda78e 100644 --- a/src/core/dbus-cgroup.c +++ b/src/core/dbus-cgroup.c @@ -468,6 +468,7 @@ const sd_bus_vtable bus_cgroup_vtable[] = { SD_BUS_PROPERTY("MemoryHigh", "t", NULL, offsetof(CGroupContext, memory_high), 0), SD_BUS_PROPERTY("MemoryMax", "t", NULL, offsetof(CGroupContext, memory_max), 0), 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("DevicePolicy", "s", property_get_cgroup_device_policy, offsetof(CGroupContext, device_policy), 0), SD_BUS_PROPERTY("DeviceAllow", "a(ss)", property_get_device_allow, 0, 0), @@ -887,6 +888,7 @@ BUS_DEFINE_SET_CGROUP_WEIGHT(blockio_weight, CGROUP_MASK_BLKIO, CGROUP_BLKIO_WEI 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(zswap, CGROUP_MASK_MEMORY, physical_memory_scale, 0); REENABLE_WARNING; static int bus_cgroup_set_cpu_weight( @@ -1075,6 +1077,9 @@ int bus_cgroup_set_property( if (streq(name, "MemorySwapMax")) return bus_cgroup_set_swap(u, name, &c->memory_swap_max, message, flags, error); + if (streq(name, "MemoryZSwapMax")) + return bus_cgroup_set_zswap(u, name, &c->memory_zswap_max, message, flags, error); + if (streq(name, "MemoryMax")) return bus_cgroup_set_memory(u, name, &c->memory_max, message, flags, error); @@ -1115,6 +1120,9 @@ int bus_cgroup_set_property( if (streq(name, "MemorySwapMaxScale")) return bus_cgroup_set_swap_scale(u, name, &c->memory_swap_max, message, flags, error); + if (streq(name, "MemoryZSwapMaxScale")) + return bus_cgroup_set_zswap_scale(u, name, &c->memory_zswap_max, message, flags, error); + if (streq(name, "MemoryMaxScale")) return bus_cgroup_set_memory_scale(u, name, &c->memory_max, message, flags, error); diff --git a/src/core/load-fragment-gperf.gperf.in b/src/core/load-fragment-gperf.gperf.in index 7675b7bb2e7..bba6666a528 100644 --- a/src/core/load-fragment-gperf.gperf.in +++ b/src/core/load-fragment-gperf.gperf.in @@ -205,6 +205,7 @@ {{type}}.MemoryHigh, config_parse_memory_limit, 0, offsetof({{type}}, cgroup_context) {{type}}.MemoryMax, config_parse_memory_limit, 0, offsetof({{type}}, cgroup_context) {{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}}.DeviceAllow, config_parse_device_allow, 0, offsetof({{type}}, cgroup_context) {{type}}.DevicePolicy, config_parse_device_policy, 0, offsetof({{type}}, cgroup_context.device_policy) diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index 49d3c035914..734a5941cc1 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -3826,7 +3826,7 @@ int config_parse_memory_limit( bytes = physical_memory_scale(r, 10000U); if (bytes >= UINT64_MAX || - (bytes <= 0 && !STR_IN_SET(lvalue, "MemorySwapMax", "MemoryLow", "MemoryMin", "DefaultMemoryLow", "DefaultMemoryMin"))) { + (bytes <= 0 && !STR_IN_SET(lvalue, "MemorySwapMax", "MemoryZSwapMax", "MemoryLow", "MemoryMin", "DefaultMemoryLow", "DefaultMemoryMin"))) { log_syntax(unit, LOG_WARNING, filename, line, 0, "Memory limit '%s' out of range, ignoring.", rvalue); return 0; } @@ -3850,6 +3850,8 @@ int config_parse_memory_limit( c->memory_max = bytes; else if (streq(lvalue, "MemorySwapMax")) c->memory_swap_max = bytes; + else if (streq(lvalue, "MemoryZSwapMax")) + c->memory_zswap_max = 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 27b6f88cd05..b0267427fa1 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", "MemoryLimit", "MemoryAvailable") && u == CGROUP_LIMIT_MAX) || + else if ((STR_IN_SET(name, "DefaultMemoryLow", "DefaultMemoryMin", "MemoryLow", "MemoryHigh", "MemoryMax", "MemorySwapMax", "MemoryZSwapMax", "MemoryLimit", "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 b850a28e859..784ae7794dc 100644 --- a/src/shared/bus-unit-util.c +++ b/src/shared/bus-unit-util.c @@ -523,6 +523,7 @@ static int bus_append_cgroup_property(sd_bus_message *m, const char *field, cons "MemoryHigh", "MemoryMax", "MemorySwapMax", + "MemoryZSwapMax", "MemoryLimit", "TasksMax")) { diff --git a/src/systemctl/systemctl-show.c b/src/systemctl/systemctl-show.c index 24c7d564b8b..77dd075eb30 100644 --- a/src/systemctl/systemctl-show.c +++ b/src/systemctl/systemctl-show.c @@ -250,6 +250,7 @@ typedef struct UnitStatusInfo { uint64_t memory_high; uint64_t memory_max; uint64_t memory_swap_max; + uint64_t memory_zswap_max; uint64_t memory_limit; uint64_t memory_available; uint64_t cpu_usage_nsec; @@ -700,6 +701,7 @@ static void print_status_info( if (i->memory_min > 0 || i->memory_low > 0 || i->memory_high != CGROUP_LIMIT_MAX || i->memory_max != CGROUP_LIMIT_MAX || i->memory_swap_max != CGROUP_LIMIT_MAX || + i->memory_zswap_max != CGROUP_LIMIT_MAX || i->memory_available != CGROUP_LIMIT_MAX || i->memory_limit != CGROUP_LIMIT_MAX) { const char *prefix = ""; @@ -725,6 +727,10 @@ static void print_status_info( printf("%sswap max: %s", prefix, FORMAT_BYTES(i->memory_swap_max)); prefix = " "; } + if (i->memory_zswap_max != CGROUP_LIMIT_MAX) { + printf("%szswap max: %s", prefix, FORMAT_BYTES(i->memory_zswap_max)); + prefix = " "; + } if (i->memory_limit != CGROUP_LIMIT_MAX) { printf("%slimit: %s", prefix, FORMAT_BYTES(i->memory_limit)); prefix = " "; @@ -1935,6 +1941,7 @@ static int show_one( { "MemoryHigh", "t", NULL, offsetof(UnitStatusInfo, memory_high) }, { "MemoryMax", "t", NULL, offsetof(UnitStatusInfo, memory_max) }, { "MemorySwapMax", "t", NULL, offsetof(UnitStatusInfo, memory_swap_max) }, + { "MemoryZSwapMax", "t", NULL, offsetof(UnitStatusInfo, memory_zswap_max) }, { "MemoryLimit", "t", NULL, offsetof(UnitStatusInfo, memory_limit) }, { "CPUUsageNSec", "t", NULL, offsetof(UnitStatusInfo, cpu_usage_nsec) }, { "TasksCurrent", "t", NULL, offsetof(UnitStatusInfo, tasks_current) }, @@ -1969,6 +1976,7 @@ static int show_one( .memory_high = CGROUP_LIMIT_MAX, .memory_max = CGROUP_LIMIT_MAX, .memory_swap_max = CGROUP_LIMIT_MAX, + .memory_zswap_max = CGROUP_LIMIT_MAX, .memory_limit = UINT64_MAX, .memory_available = CGROUP_LIMIT_MAX, .cpu_usage_nsec = UINT64_MAX, diff --git a/test/fuzz/fuzz-unit-file/directives-all.service b/test/fuzz/fuzz-unit-file/directives-all.service index 621fb1cf1b6..b4cfca2814f 100644 --- a/test/fuzz/fuzz-unit-file/directives-all.service +++ b/test/fuzz/fuzz-unit-file/directives-all.service @@ -160,6 +160,7 @@ MemoryLimit= MemoryLow= MemoryMax= MemorySwapMax= +MemoryZSwapMax= MessageQueueMaxMessages= MessageQueueMessageSize= MountAPIVFS=