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.
This commit is contained in:
Nick Rosbrook
2022-04-04 15:06:07 -04:00
parent c0da575a0e
commit 030bc91cb9
5 changed files with 25 additions and 25 deletions

View File

@@ -219,7 +219,7 @@ int convert_meminfo_value_to_uint64_bytes(const char *word, uint64_t *ret) {
}
int procfs_memory_get(uint64_t *ret_total, uint64_t *ret_used) {
uint64_t mem_total = UINT64_MAX, mem_free = UINT64_MAX;
uint64_t mem_total = UINT64_MAX, mem_available = UINT64_MAX;
_cleanup_fclose_ FILE *f = NULL;
int r;
@@ -242,9 +242,9 @@ int procfs_memory_get(uint64_t *ret_total, uint64_t *ret_used) {
if (p)
v = &mem_total;
else {
p = first_word(line, "MemFree:");
p = first_word(line, "MemAvailable:");
if (p)
v = &mem_free;
v = &mem_available;
else
continue;
}
@@ -253,16 +253,16 @@ int procfs_memory_get(uint64_t *ret_total, uint64_t *ret_used) {
if (r < 0)
return r;
if (mem_total != UINT64_MAX && mem_free != UINT64_MAX)
if (mem_total != UINT64_MAX && mem_available != UINT64_MAX)
break;
}
if (mem_free > mem_total)
if (mem_available > mem_total)
return -EINVAL;
if (ret_total)
*ret_total = mem_total;
if (ret_used)
*ret_used = mem_total - mem_free;
*ret_used = mem_total - mem_available;
return 0;
}