From 3565c709f587a3d29d412d81355f8dd9d565a39e Mon Sep 17 00:00:00 2001 From: =?utf8?q?Michal=20Koutn=C3=BD?= Date: Thu, 7 Sep 2023 18:50:08 +0200 Subject: [PATCH] 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. --- src/core/cgroup.c | 9 ++++++--- src/shared/bus-print-properties.c | 4 ++-- 2 files changed, 8 insertions(+), 5 deletions(-) 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)) -- 2.47.3