@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 = '...';
<!--property MemorySwapMax is not documented!-->
+ <!--property MemoryZSwapMax is not documented!-->
+
<!--property MemoryLimit is not documented!-->
<!--property DevicePolicy is not documented!-->
<variablelist class="dbus-property" generated="True" extra-ref="MemorySwapMax"/>
+ <variablelist class="dbus-property" generated="True" extra-ref="MemoryZSwapMax"/>
+
<variablelist class="dbus-property" generated="True" extra-ref="MemoryLimit"/>
<variablelist class="dbus-property" generated="True" extra-ref="DevicePolicy"/>
@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 = '...';
<!--property MemorySwapMax is not documented!-->
+ <!--property MemoryZSwapMax is not documented!-->
+
<!--property MemoryLimit is not documented!-->
<!--property DevicePolicy is not documented!-->
<variablelist class="dbus-property" generated="True" extra-ref="MemorySwapMax"/>
+ <variablelist class="dbus-property" generated="True" extra-ref="MemoryZSwapMax"/>
+
<variablelist class="dbus-property" generated="True" extra-ref="MemoryLimit"/>
<variablelist class="dbus-property" generated="True" extra-ref="DevicePolicy"/>
@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 = '...';
<!--property MemorySwapMax is not documented!-->
+ <!--property MemoryZSwapMax is not documented!-->
+
<!--property MemoryLimit is not documented!-->
<!--property DevicePolicy is not documented!-->
<variablelist class="dbus-property" generated="True" extra-ref="MemorySwapMax"/>
+ <variablelist class="dbus-property" generated="True" extra-ref="MemoryZSwapMax"/>
+
<variablelist class="dbus-property" generated="True" extra-ref="MemoryLimit"/>
<variablelist class="dbus-property" generated="True" extra-ref="DevicePolicy"/>
@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 = '...';
<!--property MemorySwapMax is not documented!-->
+ <!--property MemoryZSwapMax is not documented!-->
+
<!--property MemoryLimit is not documented!-->
<!--property DevicePolicy is not documented!-->
<variablelist class="dbus-property" generated="True" extra-ref="MemorySwapMax"/>
+ <variablelist class="dbus-property" generated="True" extra-ref="MemoryZSwapMax"/>
+
<variablelist class="dbus-property" generated="True" extra-ref="MemoryLimit"/>
<variablelist class="dbus-property" generated="True" extra-ref="DevicePolicy"/>
@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 = '...';
<!--property MemorySwapMax is not documented!-->
+ <!--property MemoryZSwapMax is not documented!-->
+
<!--property MemoryLimit is not documented!-->
<!--property DevicePolicy is not documented!-->
<variablelist class="dbus-property" generated="True" extra-ref="MemorySwapMax"/>
+ <variablelist class="dbus-property" generated="True" extra-ref="MemoryZSwapMax"/>
+
<variablelist class="dbus-property" generated="True" extra-ref="MemoryLimit"/>
<variablelist class="dbus-property" generated="True" extra-ref="DevicePolicy"/>
@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 = '...';
<!--property MemorySwapMax is not documented!-->
+ <!--property MemoryZSwapMax is not documented!-->
+
<!--property MemoryLimit is not documented!-->
<!--property DevicePolicy is not documented!-->
<variablelist class="dbus-property" generated="True" extra-ref="MemorySwapMax"/>
+ <variablelist class="dbus-property" generated="True" extra-ref="MemoryZSwapMax"/>
+
<variablelist class="dbus-property" generated="True" extra-ref="MemoryLimit"/>
<variablelist class="dbus-property" generated="True" extra-ref="DevicePolicy"/>
<varlistentry>
<term><varname>MemorySwapMax=<replaceable>bytes</replaceable></varname></term>
+ <term><varname>MemoryZSwapMax=<replaceable>bytes</replaceable></varname></term>
<listitem>
- <para>Specify the absolute limit on swap usage of the executed processes in this unit.</para>
+ <para>Specify the absolute limit on (z)swap usage of the executed processes in this unit.</para>
<para>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 <literal>infinity</literal>, no swap limit is applied. This controls the
- <literal>memory.swap.max</literal> control group attribute. For details about this control group attribute,
+ special value <literal>infinity</literal>, no swap limit is applied. These settings control the
+ <literal>memory.(z)swap.max</literal> control group attributes. For details about these control group attributes,
see <ulink url="https://docs.kernel.org/admin-guide/cgroup-v2.html#memory-interface-files">Memory Interface Files</ulink>.</para>
</listitem>
</varlistentry>
.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,
} 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;
/* 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;
"%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"
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),
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) {
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;
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));
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;
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),
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(
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);
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);
{{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)
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;
}
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.");
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))
"MemoryHigh",
"MemoryMax",
"MemorySwapMax",
+ "MemoryZSwapMax",
"MemoryLimit",
"TasksMax")) {
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;
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 = "";
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 = " ";
{ "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) },
.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,
MemoryLow=
MemoryMax=
MemorySwapMax=
+MemoryZSwapMax=
MessageQueueMaxMessages=
MessageQueueMessageSize=
MountAPIVFS=