mirror of
https://github.com/systemd/systemd-stable.git
synced 2024-10-26 08:55:18 +03:00
oomd: get memory total and free as part of system context
This commit is contained in:
parent
47136b9d9a
commit
eeeaa42284
@ -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;
|
||||
|
||||
@ -362,7 +372,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);
|
||||
@ -382,11 +392,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;
|
||||
@ -394,19 +410,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;
|
||||
@ -525,14 +548,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));
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user