From: Michal Koutný Date: Thu, 7 Sep 2023 17:48:48 +0000 (+0200) Subject: cgroup: Estimate MemoryAvailable= when DefaultMemoryAccounting=no X-Git-Tag: v255-rc1~538^2~1 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=8db929a1e235794053853a0b0f720e509dde75d9;p=thirdparty%2Fsystemd.git cgroup: Estimate MemoryAvailable= when DefaultMemoryAccounting=no Without memory accounting explicitly disabled, we may not obtain current consumption from all units on the ancestry path. Use a descendant value as lower bound estimate for ancestors if ancestor's consumption cannot be directly queried. This makes MemoryAvailable= an upper bound of available values. --- diff --git a/src/core/cgroup.c b/src/core/cgroup.c index 9fd62b2b5b9..b304b39e8c1 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -3751,8 +3751,7 @@ int manager_notify_cgroup_empty(Manager *m, const char *cgroup) { } int unit_get_memory_available(Unit *u, uint64_t *ret) { - uint64_t available = UINT64_MAX; - int r; + uint64_t available = UINT64_MAX, current = 0; assert(u); assert(ret); @@ -3762,7 +3761,7 @@ int unit_get_memory_available(Unit *u, uint64_t *ret) { * and MemoryMax, and also any slice the unit might be nested below. */ do { - uint64_t unit_current, unit_available, unit_limit = UINT64_MAX; + uint64_t unit_available, unit_limit = UINT64_MAX; CGroupContext *unit_context; /* No point in continuing if we can't go any lower */ @@ -3776,17 +3775,16 @@ int unit_get_memory_available(Unit *u, uint64_t *ret) { if (!u->cgroup_path) continue; + (void) unit_get_memory_current(u, ¤t); + /* in case of error, previous current propagates as lower bound */ + if (unit_has_name(u, SPECIAL_ROOT_SLICE)) unit_limit = physical_memory(); else if (unit_context->memory_max == UINT64_MAX && unit_context->memory_high == UINT64_MAX) continue; unit_limit = MIN3(unit_limit, unit_context->memory_max, unit_context->memory_high); - r = unit_get_memory_current(u, &unit_current); - if (r < 0) - continue; - - unit_available = LESS_BY(unit_limit, unit_current); + unit_available = LESS_BY(unit_limit, current); available = MIN(unit_available, available); } while ((u = UNIT_GET_SLICE(u)));