diff options
author | Anita Zhang <the.anitazha@gmail.com> | 2021-06-24 03:11:07 -0700 |
---|---|---|
committer | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2021-07-12 13:30:54 +0200 |
commit | d6ebf0023b0d9e728f42e2594f7ee12e6b24b7c9 (patch) | |
tree | d0be0ce3d4a0406d4be4ad4418bb528de9736ab4 | |
parent | f82008321e4d5ff70bd73a334839e70fdcead9e2 (diff) | |
download | systemd-d6ebf0023b0d9e728f42e2594f7ee12e6b24b7c9.tar.gz |
oomd: get memory total and free as part of system context
(cherry picked from commit eeeaa422845a045bded6c44732d5e9b025084011)
-rw-r--r-- | src/oom/oomd-util.c | 44 | ||||
-rw-r--r-- | src/oom/oomd-util.h | 5 | ||||
-rw-r--r-- | src/oom/test-oomd-util.c | 19 |
3 files changed, 54 insertions, 14 deletions
diff --git a/src/oom/oomd-util.c b/src/oom/oomd-util.c index 4789f56d49..f49cbe8e81 100644 --- a/src/oom/oomd-util.c +++ b/src/oom/oomd-util.c @@ -122,6 +122,16 @@ uint64_t oomd_pgscan_rate(const OomdCGroupContext *c) { return c->pgscan - last_pgscan; } +bool oomd_mem_free_below(const OomdSystemContext *ctx, int threshold_permyriad) { + uint64_t mem_threshold; + + assert(ctx); + assert(threshold_permyriad <= 10000); + + mem_threshold = ctx->mem_total * threshold_permyriad / (uint64_t) 10000; + return (ctx->mem_total - ctx->mem_used) < mem_threshold; +} + bool oomd_swap_free_below(const OomdSystemContext *ctx, int threshold_permyriad) { uint64_t swap_threshold; @@ -358,7 +368,7 @@ int oomd_system_context_acquire(const char *proc_meminfo_path, OomdSystemContext _cleanup_fclose_ FILE *f = NULL; unsigned field_filled = 0; OomdSystemContext ctx = {}; - uint64_t swap_free; + uint64_t mem_free, swap_free; int r; assert(proc_meminfo_path); @@ -378,11 +388,17 @@ int oomd_system_context_acquire(const char *proc_meminfo_path, OomdSystemContext if (r == 0) return -EINVAL; - if ((word = startswith(line, "SwapTotal:"))) { + if ((word = startswith(line, "MemTotal:"))) { field_filled |= 1U << 0; + r = convert_meminfo_value_to_uint64_bytes(word, &ctx.mem_total); + } else if ((word = startswith(line, "MemFree:"))) { + field_filled |= 1U << 1; + r = convert_meminfo_value_to_uint64_bytes(word, &mem_free); + } else if ((word = startswith(line, "SwapTotal:"))) { + field_filled |= 1U << 2; r = convert_meminfo_value_to_uint64_bytes(word, &ctx.swap_total); } else if ((word = startswith(line, "SwapFree:"))) { - field_filled |= 1U << 1; + field_filled |= 1U << 3; r = convert_meminfo_value_to_uint64_bytes(word, &swap_free); } else continue; @@ -390,19 +406,26 @@ int oomd_system_context_acquire(const char *proc_meminfo_path, OomdSystemContext if (r < 0) return log_debug_errno(r, "Error converting '%s' from %s to uint64_t: %m", line, proc_meminfo_path); - if (field_filled == 3U) + if (field_filled == 15U) break; } - if (field_filled != 3U) + if (field_filled != 15U) return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "%s is missing expected fields", proc_meminfo_path); + if (mem_free > ctx.mem_total) + return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), + "MemFree (%" PRIu64 ") cannot be greater than MemTotal (%" PRIu64 ") %m", + mem_free, + ctx.mem_total); + if (swap_free > ctx.swap_total) return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "SwapFree (%" PRIu64 ") cannot be greater than SwapTotal (%" PRIu64 ") %m", swap_free, ctx.swap_total); + ctx.mem_used = ctx.mem_total - mem_free; ctx.swap_used = ctx.swap_total - swap_free; *ret = ctx; @@ -521,14 +544,19 @@ void oomd_dump_memory_pressure_cgroup_context(const OomdCGroupContext *ctx, FILE } void oomd_dump_system_context(const OomdSystemContext *ctx, FILE *f, const char *prefix) { - char used[FORMAT_BYTES_MAX], total[FORMAT_BYTES_MAX]; + char mem_used[FORMAT_BYTES_MAX], mem_total[FORMAT_BYTES_MAX]; + char swap_used[FORMAT_BYTES_MAX], swap_total[FORMAT_BYTES_MAX]; assert(ctx); assert(f); fprintf(f, + "%sMemory: Used: %s Total: %s\n" "%sSwap: Used: %s Total: %s\n", strempty(prefix), - format_bytes(used, sizeof(used), ctx->swap_used), - format_bytes(total, sizeof(total), ctx->swap_total)); + format_bytes(mem_used, sizeof(mem_used), ctx->mem_used), + format_bytes(mem_total, sizeof(mem_total), ctx->mem_total), + strempty(prefix), + format_bytes(swap_used, sizeof(swap_used), ctx->swap_used), + format_bytes(swap_total, sizeof(swap_total), ctx->swap_total)); } diff --git a/src/oom/oomd-util.h b/src/oom/oomd-util.h index 81fdc5e088..3a91a31352 100644 --- a/src/oom/oomd-util.h +++ b/src/oom/oomd-util.h @@ -39,6 +39,8 @@ struct OomdCGroupContext { }; struct OomdSystemContext { + uint64_t mem_total; + uint64_t mem_used; uint64_t swap_total; uint64_t swap_used; }; @@ -57,6 +59,9 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(OomdCGroupContext*, oomd_cgroup_context_free); * Returns -ENOMEM for allocation errors. */ int oomd_pressure_above(Hashmap *h, usec_t duration, Set **ret); +/* Returns true if the amount of memory free is below the permyriad of memory specified by `threshold_permyriad`. */ +bool oomd_mem_free_below(const OomdSystemContext *ctx, int threshold_permyriad); + /* Returns true if the amount of swap free is below the permyriad of swap specified by `threshold_permyriad`. */ bool oomd_swap_free_below(const OomdSystemContext *ctx, int threshold_permyriad); diff --git a/src/oom/test-oomd-util.c b/src/oom/test-oomd-util.c index c7d2778200..776c65820e 100644 --- a/src/oom/test-oomd-util.c +++ b/src/oom/test-oomd-util.c @@ -258,10 +258,6 @@ static void test_oomd_system_context_acquire(void) { "SwapFree: 7604 kB bad\n", WRITE_STRING_FILE_CREATE) == 0); assert_se(oomd_system_context_acquire(path, &ctx) == -EINVAL); - assert_se(oomd_system_context_acquire("/proc/meminfo", &ctx) == 0); - assert_se(ctx.swap_total > 0); - assert_se(ctx.swap_used <= ctx.swap_total); - assert_se(write_string_file(path, "MemTotal: 32495256 kB\n" "MemFree: 9880512 kB\n" "MemAvailable: 21777088 kB\n" @@ -272,6 +268,8 @@ static void test_oomd_system_context_acquire(void) { "SwapTotal: 8388604 kB\n" "SwapFree: 7604 kB\n", WRITE_STRING_FILE_CREATE) == 0); assert_se(oomd_system_context_acquire(path, &ctx) == 0); + assert_se(ctx.mem_total == 33275142144); + assert_se(ctx.mem_used == 23157497856); assert_se(ctx.swap_total == 8589930496); assert_se(ctx.swap_used == 8582144000); } @@ -324,23 +322,32 @@ static void test_oomd_pressure_above(void) { assert_se(c->mem_pressure_limit_hit_start == 0); } -static void test_oomd_swap_free_below(void) { +static void test_oomd_mem_and_swap_free_below(void) { OomdSystemContext ctx = (OomdSystemContext) { + .mem_total = 20971512 * 1024U, + .mem_used = 3310136 * 1024U, .swap_total = 20971512 * 1024U, .swap_used = 20971440 * 1024U, }; + assert_se(oomd_mem_free_below(&ctx, 2000) == false); assert_se(oomd_swap_free_below(&ctx, 2000) == true); ctx = (OomdSystemContext) { + .mem_total = 20971512 * 1024U, + .mem_used = 20971440 * 1024U, .swap_total = 20971512 * 1024U, .swap_used = 3310136 * 1024U, }; + assert_se(oomd_mem_free_below(&ctx, 2000) == true); assert_se(oomd_swap_free_below(&ctx, 2000) == false); ctx = (OomdSystemContext) { + .mem_total = 0, + .mem_used = 0, .swap_total = 0, .swap_used = 0, }; + assert_se(oomd_mem_free_below(&ctx, 2000) == false); assert_se(oomd_swap_free_below(&ctx, 2000) == false); } @@ -440,7 +447,7 @@ int main(void) { test_oomd_update_cgroup_contexts_between_hashmaps(); test_oomd_system_context_acquire(); test_oomd_pressure_above(); - test_oomd_swap_free_below(); + test_oomd_mem_and_swap_free_below(); test_oomd_sort_cgroups(); /* The following tests operate on live cgroups */ |