diff options
author | Nick Rosbrook <nick.rosbrook@canonical.com> | 2022-04-04 15:06:07 -0400 |
---|---|---|
committer | Nick Rosbrook <nick.rosbrook@canonical.com> | 2022-04-05 09:51:25 -0400 |
commit | 030bc91cb98385904b28a839d1e04bb4160a52d2 (patch) | |
tree | 199eb4e79b045c7437ae59b667054f77fe07264d /src/oom/oomd-util.c | |
parent | c0da575a0e94e7ecae7f5f0c72dea0be853af352 (diff) | |
download | systemd-030bc91cb98385904b28a839d1e04bb4160a52d2.tar.gz |
oomd: calculate 'used' memory with MemAvailable instead of MemFree
The calculation for used memory in oomd_system_context_acquire is given
by MemTotal - MemFree from /proc/meminfo. This is too strict of a
calculation because it does not consider memory that is still available
for starting new applictions without swapping (MemAvailable). As a
result, systemd-oomd can start to kill processes before it is necessary.
This is more apparent on systems with low swap space.
Instead, compute 'used' memory as MemTotal - MemAvailable in
oomd_system_context_acquire and procfs_memory_get (which is used by
oomd_cgroup_context_acquire). And, rename oomd_mem_free_below to
oomd_mem_available_below for clarity.
Diffstat (limited to 'src/oom/oomd-util.c')
-rw-r--r-- | src/oom/oomd-util.c | 22 |
1 files changed, 11 insertions, 11 deletions
diff --git a/src/oom/oomd-util.c b/src/oom/oomd-util.c index a135824c53..d1ab528a0e 100644 --- a/src/oom/oomd-util.c +++ b/src/oom/oomd-util.c @@ -122,7 +122,7 @@ uint64_t oomd_pgscan_rate(const OomdCGroupContext *c) { return c->pgscan - last_pgscan; } -bool oomd_mem_free_below(const OomdSystemContext *ctx, int threshold_permyriad) { +bool oomd_mem_available_below(const OomdSystemContext *ctx, int threshold_permyriad) { uint64_t mem_threshold; assert(ctx); @@ -418,15 +418,15 @@ int oomd_system_context_acquire(const char *proc_meminfo_path, OomdSystemContext _cleanup_fclose_ FILE *f = NULL; unsigned field_filled = 0; OomdSystemContext ctx = {}; - uint64_t mem_free, swap_free; + uint64_t mem_available, swap_free; int r; enum { MEM_TOTAL = 1U << 0, - MEM_FREE = 1U << 1, + MEM_AVAILABLE = 1U << 1, SWAP_TOTAL = 1U << 2, SWAP_FREE = 1U << 3, - ALL = MEM_TOTAL|MEM_FREE|SWAP_TOTAL|SWAP_FREE, + ALL = MEM_TOTAL|MEM_AVAILABLE|SWAP_TOTAL|SWAP_FREE, }; assert(proc_meminfo_path); @@ -449,9 +449,9 @@ int oomd_system_context_acquire(const char *proc_meminfo_path, OomdSystemContext if ((word = startswith(line, "MemTotal:"))) { field_filled |= MEM_TOTAL; r = convert_meminfo_value_to_uint64_bytes(word, &ctx.mem_total); - } else if ((word = startswith(line, "MemFree:"))) { - field_filled |= MEM_FREE; - r = convert_meminfo_value_to_uint64_bytes(word, &mem_free); + } else if ((word = startswith(line, "MemAvailable:"))) { + field_filled |= MEM_AVAILABLE; + r = convert_meminfo_value_to_uint64_bytes(word, &mem_available); } else if ((word = startswith(line, "SwapTotal:"))) { field_filled |= SWAP_TOTAL; r = convert_meminfo_value_to_uint64_bytes(word, &ctx.swap_total); @@ -471,10 +471,10 @@ int oomd_system_context_acquire(const char *proc_meminfo_path, OomdSystemContext if (field_filled != ALL) return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "%s is missing expected fields", proc_meminfo_path); - if (mem_free > ctx.mem_total) + if (mem_available > ctx.mem_total) return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), - "MemFree (%" PRIu64 ") cannot be greater than MemTotal (%" PRIu64 ") %m", - mem_free, + "MemAvailable (%" PRIu64 ") cannot be greater than MemTotal (%" PRIu64 ") %m", + mem_available, ctx.mem_total); if (swap_free > ctx.swap_total) @@ -483,7 +483,7 @@ int oomd_system_context_acquire(const char *proc_meminfo_path, OomdSystemContext swap_free, ctx.swap_total); - ctx.mem_used = ctx.mem_total - mem_free; + ctx.mem_used = ctx.mem_total - mem_available; ctx.swap_used = ctx.swap_total - swap_free; *ret = ctx; |