mirror of
https://github.com/morgan9e/systemd
synced 2026-04-14 16:37:19 +09:00
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.
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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))
|
||||
|
||||
Reference in New Issue
Block a user