1 /* SPDX-License-Identifier: LGPL-2.1+ */
9 #define GROWING_SIZE_PERCENTILE 80
11 extern const struct hash_ops oomd_cgroup_ctx_hash_ops
;
13 typedef struct OomdCGroupContext OomdCGroupContext
;
14 typedef struct OomdSystemContext OomdSystemContext
;
16 typedef int (oomd_compare_t
)(OomdCGroupContext
* const *, OomdCGroupContext
* const *);
18 struct OomdCGroupContext
{
21 ResourcePressure memory_pressure
;
23 uint64_t current_memory_usage
;
32 /* These are only used by oomd_pressure_above for acting on high memory pressure. */
33 loadavg_t mem_pressure_limit
;
34 usec_t last_hit_mem_pressure_limit
;
37 struct OomdSystemContext
{
42 OomdCGroupContext
*oomd_cgroup_context_free(OomdCGroupContext
*ctx
);
43 DEFINE_TRIVIAL_CLEANUP_FUNC(OomdCGroupContext
*, oomd_cgroup_context_free
);
45 /* All hashmaps used with these functions are expected to be of the form
46 * key: cgroup paths -> value: OomdCGroupContext. */
48 /* Scans all the OomdCGroupContexts in `h` and returns 1 and a set of pointers to those OomdCGroupContexts in `ret`
49 * if any of them have exceeded their supplied memory pressure limits for the `duration` length of time.
50 * `last_hit_mem_pressure_limit` is updated accordingly for each entry when the limit is exceeded, and when it returns
52 * Returns 0 and sets `ret` to an empty set if no entries exceeded limits for `duration`.
53 * Returns -ENOMEM for allocation errors. */
54 int oomd_pressure_above(Hashmap
*h
, usec_t duration
, Set
**ret
);
56 /* Sum up current OomdCGroupContexts' pgscan values and last interval's pgscan values in `h`. Returns true if the
57 * current sum is higher than the last interval's sum (there was some reclaim activity). */
58 bool oomd_memory_reclaim(Hashmap
*h
);
60 /* Returns true if the amount of swap free is below the percentage of swap specified by `threshold_percent`. */
61 bool oomd_swap_free_below(const OomdSystemContext
*ctx
, uint64_t threshold_percent
);
63 static inline int compare_pgscan(OomdCGroupContext
* const *c1
, OomdCGroupContext
* const *c2
) {
67 if ((*c1
)->pgscan
> (*c2
)->pgscan
)
69 else if ((*c1
)->pgscan
< (*c2
)->pgscan
)
75 static inline int compare_swap_usage(OomdCGroupContext
* const *c1
, OomdCGroupContext
* const *c2
) {
79 if ((*c1
)->swap_usage
> (*c2
)->swap_usage
)
81 else if ((*c1
)->swap_usage
< (*c2
)->swap_usage
)
87 /* Get an array of OomdCGroupContexts from `h`, qsorted from largest to smallest values according to `compare_func`.
88 * If `prefix` is not NULL, only include OomdCGroupContexts whose paths start with prefix. Otherwise all paths are sorted.
89 * Returns the number of sorted items; negative on error. */
90 int oomd_sort_cgroup_contexts(Hashmap
*h
, oomd_compare_t compare_func
, const char *prefix
, OomdCGroupContext
***ret
);
92 /* Returns a negative value on error, 0 if no processes were killed, or 1 if processes were killed. */
93 int oomd_cgroup_kill(const char *path
, bool recurse
, bool dry_run
);
95 /* The following oomd_kill_by_* functions return 1 if processes were killed, or negative otherwise. */
96 /* If `prefix` is supplied, only cgroups whose paths start with `prefix` are eligible candidates. Otherwise,
97 * everything in `h` is a candidate. */
98 int oomd_kill_by_pgscan(Hashmap
*h
, const char *prefix
, bool dry_run
);
99 int oomd_kill_by_swap_usage(Hashmap
*h
, bool dry_run
);
101 int oomd_cgroup_context_acquire(const char *path
, OomdCGroupContext
**ret
);
102 int oomd_system_context_acquire(const char *proc_swaps_path
, OomdSystemContext
*ret
);
104 /* Get the OomdCGroupContext of `path` and insert it into `new_h`. The key for the inserted context will be `path`.
106 * `old_h` is used to get data used to calculate prior interval information. `old_h` can be NULL in which case there
107 * was no prior data to reference. */
108 int oomd_insert_cgroup_context(Hashmap
*old_h
, Hashmap
*new_h
, const char *path
);
110 void oomd_dump_swap_cgroup_context(const OomdCGroupContext
*ctx
, FILE *f
, const char *prefix
);
111 void oomd_dump_memory_pressure_cgroup_context(const OomdCGroupContext
*ctx
, FILE *f
, const char *prefix
);
112 void oomd_dump_system_context(const OomdSystemContext
*ctx
, FILE *f
, const char *prefix
);