1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2 #pragma once
3 
4 #include "sd-bus.h"
5 #include "sd-event.h"
6 
7 #include "conf-parser.h"
8 #include "oomd-util.h"
9 #include "varlink.h"
10 
11 /* Polling interval for monitoring stats */
12 #define SWAP_INTERVAL_USEC 150000 /* 0.15 seconds */
13 /* Pressure counters are lagging (~2 seconds) compared to swap so polling too frequently just wastes CPU */
14 #define MEM_PRESSURE_INTERVAL_USEC (1 * USEC_PER_SEC)
15 
16 /* Take action if 10s of memory pressure > 60 for more than 30s. We use the "full" value from PSI so this is the
17  * percentage of time all tasks were delayed (i.e. unproductive).
18  * Generally 60 or higher might be acceptable for something like system.slice with no memory.high set; processes in
19  * system.slice are assumed to be less latency sensitive. */
20 #define DEFAULT_MEM_PRESSURE_DURATION_USEC (30 * USEC_PER_SEC)
21 #define DEFAULT_MEM_PRESSURE_LIMIT_PERCENT 60
22 #define DEFAULT_SWAP_USED_LIMIT_PERCENT 90
23 
24 /* Only tackle candidates with large swap usage. */
25 #define THRESHOLD_SWAP_USED_PERCENT 5
26 
27 #define RECLAIM_DURATION_USEC (30 * USEC_PER_SEC)
28 #define POST_ACTION_DELAY_USEC (15 * USEC_PER_SEC)
29 
30 typedef struct Manager Manager;
31 
32 struct Manager {
33         sd_bus *bus;
34         sd_event *event;
35 
36         Hashmap *polkit_registry;
37 
38         bool dry_run;
39         int swap_used_limit_permyriad;
40         loadavg_t default_mem_pressure_limit;
41         usec_t default_mem_pressure_duration_usec;
42 
43         /* k: cgroup paths -> v: OomdCGroupContext
44          * Used to detect when to take action. */
45         Hashmap *monitored_swap_cgroup_contexts;
46         Hashmap *monitored_mem_pressure_cgroup_contexts;
47         Hashmap *monitored_mem_pressure_cgroup_contexts_candidates;
48 
49         OomdSystemContext system_context;
50 
51         usec_t mem_pressure_post_action_delay_start;
52 
53         sd_event_source *swap_context_event_source;
54         sd_event_source *mem_pressure_context_event_source;
55 
56         /* This varlink object is used to manage the subscription from systemd-oomd to PID1 which it uses to
57          * listen for changes in ManagedOOM settings (oomd client - systemd server). */
58         Varlink *varlink_client;
59         /* This varlink server object is used to manage systemd-oomd's varlink server which is used by user
60          * managers to report changes in ManagedOOM settings (oomd server - systemd client). */
61         VarlinkServer *varlink_server;
62 };
63 
64 Manager* manager_free(Manager *m);
65 DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free);
66 
67 int manager_new(Manager **ret);
68 
69 int manager_start(Manager *m, bool dry_run, int swap_used_limit_permyriad, int mem_pressure_limit_permyriad, usec_t mem_pressure_usec, int fd);
70 
71 int manager_get_dump_string(Manager *m, char **ret);
72 
73 CONFIG_PARSER_PROTOTYPE(config_parse_oomd_default);
74