From: Yu Watanabe Date: Sat, 12 Oct 2024 01:59:12 +0000 (+0900) Subject: oomd-util: use FOREACH_ARRAY() more X-Git-Tag: v257-rc1~226^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=refs%2Fpull%2F34744%2Fhead;p=thirdparty%2Fsystemd.git oomd-util: use FOREACH_ARRAY() more --- diff --git a/src/oom/oomd-util.c b/src/oom/oomd-util.c index b0b13d6c3c4..6307c2783e0 100644 --- a/src/oom/oomd-util.c +++ b/src/oom/oomd-util.c @@ -281,27 +281,45 @@ int oomd_cgroup_kill(const char *path, bool recurse, bool dry_run) { typedef void (*dump_candidate_func)(const OomdCGroupContext *ctx, FILE *f, const char *prefix); -static int dump_kill_candidates(OomdCGroupContext **sorted, int n, int dump_until, dump_candidate_func dump_func) { +static int dump_kill_candidates( + OomdCGroupContext *sorted[], + size_t n, + const OomdCGroupContext *killed, + dump_candidate_func dump_func) { + _cleanup_(memstream_done) MemStream m = {}; FILE *f; /* Try dumping top offendors, ignoring any errors that might happen. */ + assert(sorted || n == 0); + assert(dump_func); + + /* If nothing killed, then limit the number of contexts to be dumped, for safety. */ + if (!killed) + n = MIN(n, DUMP_ON_KILL_COUNT); + f = memstream_init(&m); if (!f) return -ENOMEM; - fprintf(f, "Considered %d cgroups for killing, top candidates were:\n", n); - for (int i = 0; i < dump_until; i++) - dump_func(sorted[i], f, "\t"); + fprintf(f, "Considered %zu cgroups for killing, top candidates were:\n", n); + FOREACH_ARRAY(i, sorted, n) { + const OomdCGroupContext *c = *i; + + dump_func(c, f, "\t"); + + if (c == killed) + break; + } return memstream_dump(LOG_INFO, &m); } int oomd_kill_by_pgscan_rate(Hashmap *h, const char *prefix, bool dry_run, char **ret_selected) { _cleanup_free_ OomdCGroupContext **sorted = NULL; + const OomdCGroupContext *killed = NULL; int n, r, ret = 0; - int dump_until; assert(h); assert(ret_selected); @@ -310,14 +328,15 @@ int oomd_kill_by_pgscan_rate(Hashmap *h, const char *prefix, bool dry_run, char if (n < 0) return n; - dump_until = MIN(n, DUMP_ON_KILL_COUNT); - for (int i = 0; i < n; i++) { + FOREACH_ARRAY(i, sorted, n) { + const OomdCGroupContext *c = *i; + /* Skip cgroups with no reclaim and memory usage; it won't alleviate pressure. * Continue since there might be "avoid" cgroups at the end. */ - if (sorted[i]->pgscan == 0 && sorted[i]->current_memory_usage == 0) + if (c->pgscan == 0 && c->current_memory_usage == 0) continue; - r = oomd_cgroup_kill(sorted[i]->path, /* recurse= */ true, /* dry_run= */ dry_run); + r = oomd_cgroup_kill(c->path, /* recurse= */ true, /* dry_run= */ dry_run); if (r == -ENOMEM) return r; /* Treat oom as a hard error */ if (r < 0) { @@ -325,24 +344,23 @@ int oomd_kill_by_pgscan_rate(Hashmap *h, const char *prefix, bool dry_run, char continue; /* Try to find something else to kill */ } - dump_until = MAX(dump_until, i + 1); - ret = r; - r = strdup_to(ret_selected, sorted[i]->path); + r = strdup_to(ret_selected, c->path); if (r < 0) return r; + + killed = c; break; } - dump_kill_candidates(sorted, n, dump_until, oomd_dump_memory_pressure_cgroup_context); - + (void) dump_kill_candidates(sorted, n, killed, oomd_dump_memory_pressure_cgroup_context); return ret; } int oomd_kill_by_swap_usage(Hashmap *h, uint64_t threshold_usage, bool dry_run, char **ret_selected) { _cleanup_free_ OomdCGroupContext **sorted = NULL; + const OomdCGroupContext *killed = NULL; int n, r, ret = 0; - int dump_until; assert(h); assert(ret_selected); @@ -351,16 +369,18 @@ int oomd_kill_by_swap_usage(Hashmap *h, uint64_t threshold_usage, bool dry_run, if (n < 0) return n; - dump_until = MIN(n, DUMP_ON_KILL_COUNT); /* Try to kill cgroups with non-zero swap usage until we either succeed in killing or we get to a cgroup with * no swap usage. Threshold killing only cgroups with more than threshold swap usage. */ - for (int i = 0; i < n; i++) { + + FOREACH_ARRAY(i, sorted, n) { + const OomdCGroupContext *c = *i; + /* Skip over cgroups with not enough swap usage. Don't break since there might be "avoid" * cgroups at the end. */ - if (sorted[i]->swap_usage <= threshold_usage) + if (c->swap_usage <= threshold_usage) continue; - r = oomd_cgroup_kill(sorted[i]->path, /* recurse= */ true, /* dry_run= */ dry_run); + r = oomd_cgroup_kill(c->path, /* recurse= */ true, /* dry_run= */ dry_run); if (r == -ENOMEM) return r; /* Treat oom as a hard error */ if (r < 0) { @@ -368,17 +388,16 @@ int oomd_kill_by_swap_usage(Hashmap *h, uint64_t threshold_usage, bool dry_run, continue; /* Try to find something else to kill */ } - dump_until = MAX(dump_until, i + 1); - ret = r; - r = strdup_to(ret_selected, sorted[i]->path); + r = strdup_to(ret_selected, c->path); if (r < 0) return r; + + killed = c; break; } - dump_kill_candidates(sorted, n, dump_until, oomd_dump_swap_cgroup_context); - + (void) dump_kill_candidates(sorted, n, killed, oomd_dump_swap_cgroup_context); return ret; } diff --git a/src/oom/oomd-util.h b/src/oom/oomd-util.h index f53e4c47e8b..95a236f48f4 100644 --- a/src/oom/oomd-util.h +++ b/src/oom/oomd-util.h @@ -7,7 +7,7 @@ #include "hashmap.h" #include "psi-util.h" -#define DUMP_ON_KILL_COUNT 10 +#define DUMP_ON_KILL_COUNT 10u #define GROWING_SIZE_PERCENTILE 80 extern const struct hash_ops oomd_cgroup_ctx_hash_ops;