From: Michal Koutný Date: Thu, 7 Sep 2023 16:50:08 +0000 (+0200) Subject: cgroup: Fix MemoryAvailable= by considering physical memory X-Git-Tag: v255-rc1~538^2~3 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=3565c709f587a3d29d412d81355f8dd9d565a39e;p=thirdparty%2Fsystemd.git cgroup: Fix MemoryAvailable= by considering physical memory Currently, querying a unit's available memory would result in infinity if there are no limits set on the unit or ancestors. That undermines semantics implied by the name, so look at the physical memory if the search propagates up to the -.slice. This makes sense even in systemd user instances, limits of -.slice are still looked at too. Also change printed representation of infinite MemoryAvailable which means we could not figure out a good estimate. --- diff --git a/src/core/cgroup.c b/src/core/cgroup.c index 91ef33b12c9..a5c8687252c 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -3791,7 +3791,7 @@ int unit_get_memory_available(Unit *u, uint64_t *ret) { available = LESS_BY(MIN(unit_context->memory_max, unit_context->memory_high), unit_current); for (Unit *slice = UNIT_GET_SLICE(u); slice; slice = UNIT_GET_SLICE(slice)) { - uint64_t slice_current, slice_available = UINT64_MAX; + uint64_t slice_current, slice_available, slice_limit = UINT64_MAX; CGroupContext *slice_context; /* No point in continuing if we can't go any lower */ @@ -3805,14 +3805,17 @@ int unit_get_memory_available(Unit *u, uint64_t *ret) { if (!slice_context) continue; - if (slice_context->memory_max == UINT64_MAX && slice_context->memory_high == UINT64_MAX) + if (unit_has_name(slice, SPECIAL_ROOT_SLICE)) + slice_limit = physical_memory(); + else if (slice_context->memory_max == UINT64_MAX && slice_context->memory_high == UINT64_MAX) continue; + slice_limit = MIN3(slice_limit, slice_context->memory_max, slice_context->memory_high); r = cg_get_attribute_as_uint64("memory", slice->cgroup_path, memory_file, &slice_current); if (r < 0) continue; - slice_available = LESS_BY(MIN(slice_context->memory_max, slice_context->memory_high), slice_current); + slice_available = LESS_BY(slice_limit, slice_current); available = MIN(slice_available, available); } diff --git a/src/shared/bus-print-properties.c b/src/shared/bus-print-properties.c index db41ad24957..8999a1a4fad 100644 --- a/src/shared/bus-print-properties.c +++ b/src/shared/bus-print-properties.c @@ -157,12 +157,12 @@ static int bus_print_property(const char *name, const char *expected_value, sd_b else if ((STR_IN_SET(name, "CPUWeight", "StartupCPUWeight", "IOWeight", "StartupIOWeight") && u == CGROUP_WEIGHT_INVALID) || (STR_IN_SET(name, "CPUShares", "StartupCPUShares") && u == CGROUP_CPU_SHARES_INVALID) || (STR_IN_SET(name, "BlockIOWeight", "StartupBlockIOWeight") && u == CGROUP_BLKIO_WEIGHT_INVALID) || - (STR_IN_SET(name, "MemoryCurrent", "TasksCurrent") && u == UINT64_MAX) || + (STR_IN_SET(name, "MemoryCurrent", "MemoryAvailable", "TasksCurrent") && u == UINT64_MAX) || (endswith(name, "NSec") && u == UINT64_MAX)) 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") && 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))