]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/oom/oomd-util.h
Merge pull request #18481 from keszybz/rpm-restart-post-trans
[thirdparty/systemd.git] / src / oom / oomd-util.h
CommitLineData
db9ecf05 1/* SPDX-License-Identifier: LGPL-2.1-or-later */
61ff7397
AZ
2#pragma once
3
4#include <stdbool.h>
5
59331b8e 6#include "cgroup-util.h"
61ff7397
AZ
7#include "hashmap.h"
8#include "psi-util.h"
9
10#define GROWING_SIZE_PERCENTILE 80
11
12extern const struct hash_ops oomd_cgroup_ctx_hash_ops;
13
14typedef struct OomdCGroupContext OomdCGroupContext;
15typedef struct OomdSystemContext OomdSystemContext;
16
17typedef int (oomd_compare_t)(OomdCGroupContext * const *, OomdCGroupContext * const *);
18
19struct OomdCGroupContext {
20 char *path;
21
22 ResourcePressure memory_pressure;
23
24 uint64_t current_memory_usage;
25
26 uint64_t memory_min;
27 uint64_t memory_low;
28 uint64_t swap_usage;
29
30 uint64_t last_pgscan;
31 uint64_t pgscan;
32
59331b8e
AZ
33 ManagedOOMPreference preference;
34
61ff7397
AZ
35 /* These are only used by oomd_pressure_above for acting on high memory pressure. */
36 loadavg_t mem_pressure_limit;
c20aa7b1 37 usec_t mem_pressure_duration_usec;
61ff7397
AZ
38 usec_t last_hit_mem_pressure_limit;
39};
40
41struct OomdSystemContext {
42 uint64_t swap_total;
43 uint64_t swap_used;
44};
45
46OomdCGroupContext *oomd_cgroup_context_free(OomdCGroupContext *ctx);
47DEFINE_TRIVIAL_CLEANUP_FUNC(OomdCGroupContext*, oomd_cgroup_context_free);
48
49/* All hashmaps used with these functions are expected to be of the form
50 * key: cgroup paths -> value: OomdCGroupContext. */
51
52/* Scans all the OomdCGroupContexts in `h` and returns 1 and a set of pointers to those OomdCGroupContexts in `ret`
53 * if any of them have exceeded their supplied memory pressure limits for the `duration` length of time.
54 * `last_hit_mem_pressure_limit` is updated accordingly for each entry when the limit is exceeded, and when it returns
55 * below the limit.
56 * Returns 0 and sets `ret` to an empty set if no entries exceeded limits for `duration`.
57 * Returns -ENOMEM for allocation errors. */
58int oomd_pressure_above(Hashmap *h, usec_t duration, Set **ret);
59
60/* Sum up current OomdCGroupContexts' pgscan values and last interval's pgscan values in `h`. Returns true if the
61 * current sum is higher than the last interval's sum (there was some reclaim activity). */
62bool oomd_memory_reclaim(Hashmap *h);
63
64/* Returns true if the amount of swap free is below the percentage of swap specified by `threshold_percent`. */
65bool oomd_swap_free_below(const OomdSystemContext *ctx, uint64_t threshold_percent);
66
59331b8e
AZ
67/* The compare functions will sort from largest to smallest, putting all the contexts with "avoid" at the end
68 * (after the smallest values). */
1f76411b
AZ
69static inline int compare_pgscan_and_memory_usage(OomdCGroupContext * const *c1, OomdCGroupContext * const *c2) {
70 int r;
71
61ff7397
AZ
72 assert(c1);
73 assert(c2);
74
59331b8e
AZ
75 r = CMP((*c1)->preference, (*c2)->preference);
76 if (r != 0)
77 return r;
78
1f76411b
AZ
79 r = CMP((*c2)->pgscan, (*c1)->pgscan);
80 if (r != 0)
81 return r;
82
83 return CMP((*c2)->current_memory_usage, (*c1)->current_memory_usage);
61ff7397
AZ
84}
85
86static inline int compare_swap_usage(OomdCGroupContext * const *c1, OomdCGroupContext * const *c2) {
59331b8e
AZ
87 int r;
88
61ff7397
AZ
89 assert(c1);
90 assert(c2);
91
59331b8e
AZ
92 r = CMP((*c1)->preference, (*c2)->preference);
93 if (r != 0)
94 return r;
95
95ca39f0 96 return CMP((*c2)->swap_usage, (*c1)->swap_usage);
61ff7397
AZ
97}
98
99/* Get an array of OomdCGroupContexts from `h`, qsorted from largest to smallest values according to `compare_func`.
100 * If `prefix` is not NULL, only include OomdCGroupContexts whose paths start with prefix. Otherwise all paths are sorted.
101 * Returns the number of sorted items; negative on error. */
102int oomd_sort_cgroup_contexts(Hashmap *h, oomd_compare_t compare_func, const char *prefix, OomdCGroupContext ***ret);
103
104/* Returns a negative value on error, 0 if no processes were killed, or 1 if processes were killed. */
105int oomd_cgroup_kill(const char *path, bool recurse, bool dry_run);
106
107/* The following oomd_kill_by_* functions return 1 if processes were killed, or negative otherwise. */
108/* If `prefix` is supplied, only cgroups whose paths start with `prefix` are eligible candidates. Otherwise,
109 * everything in `h` is a candidate. */
110int oomd_kill_by_pgscan(Hashmap *h, const char *prefix, bool dry_run);
111int oomd_kill_by_swap_usage(Hashmap *h, bool dry_run);
112
113int oomd_cgroup_context_acquire(const char *path, OomdCGroupContext **ret);
114int oomd_system_context_acquire(const char *proc_swaps_path, OomdSystemContext *ret);
115
116/* Get the OomdCGroupContext of `path` and insert it into `new_h`. The key for the inserted context will be `path`.
117 *
118 * `old_h` is used to get data used to calculate prior interval information. `old_h` can be NULL in which case there
119 * was no prior data to reference. */
120int oomd_insert_cgroup_context(Hashmap *old_h, Hashmap *new_h, const char *path);
5c616ecf
AZ
121
122void oomd_dump_swap_cgroup_context(const OomdCGroupContext *ctx, FILE *f, const char *prefix);
123void oomd_dump_memory_pressure_cgroup_context(const OomdCGroupContext *ctx, FILE *f, const char *prefix);
124void oomd_dump_system_context(const OomdSystemContext *ctx, FILE *f, const char *prefix);