1
0
mirror of https://github.com/systemd/systemd.git synced 2025-03-23 10:50:16 +03:00

oomd: avoid unnecessary wake-ups for ManagedOOMSwap

If there are no "ManagedOOMSwap" entries to monitor, then the event source
can be completely disabled. This scenario appears to be common and avoiding
the wake-ups can save idle energy consumption.

This was discovered while using Sysprof for various GNOME 45 performance
tuning. systemd-oomd goes from waking up a few times a second to no
wake-ups helping keep a laptop in deep(er) sleep.

Signed-off-by: Christian Hergert <chergert@redhat.com>
This commit is contained in:
Christian Hergert 2023-08-29 14:58:10 -07:00 committed by Luca Boccassi
parent ad5db9404e
commit b63beb4d28

@ -127,6 +127,12 @@ static int process_managed_oom_message(Manager *m, uid_t uid, JsonVariant *param
ctx->mem_pressure_limit = limit;
}
/* Toggle wake-ups for "ManagedOOMSwap" if entries are present. */
r = sd_event_source_set_enabled(m->swap_context_event_source,
hashmap_isempty(m->monitored_swap_cgroup_contexts) ? SD_EVENT_OFF : SD_EVENT_ON);
if (r < 0)
return log_error_errno(r, "Failed to toggle enabled state of swap context source: %m");
return 0;
}
@ -348,6 +354,7 @@ static int monitor_swap_contexts_handler(sd_event_source *s, uint64_t usec, void
int r;
assert(s);
assert(!hashmap_isempty(m->monitored_swap_cgroup_contexts));
/* Reset timer */
r = sd_event_now(sd_event_source_get_event(s), CLOCK_MONOTONIC, &usec_now);
@ -368,13 +375,9 @@ static int monitor_swap_contexts_handler(sd_event_source *s, uint64_t usec, void
/* We still try to acquire system information for oomctl even if no units want swap monitoring */
r = oomd_system_context_acquire("/proc/meminfo", &m->system_context);
/* If there are no units depending on swap actions, the only error we exit on is ENOMEM. */
if (r == -ENOMEM || (r < 0 && !hashmap_isempty(m->monitored_swap_cgroup_contexts)))
if (r < 0)
return log_error_errno(r, "Failed to acquire system context: %m");
/* Return early if nothing is requesting swap monitoring */
if (hashmap_isempty(m->monitored_swap_cgroup_contexts))
return 0;
/* Note that m->monitored_swap_cgroup_contexts does not need to be updated every interval because only the
* system context is used for deciding whether the swap threshold is hit. m->monitored_swap_cgroup_contexts
* is only used to decide which cgroups to kill (and even then only the resource usages of its descendent
@ -594,7 +597,7 @@ static int monitor_swap_contexts(Manager *m) {
if (r < 0)
return r;
r = sd_event_source_set_enabled(s, SD_EVENT_ON);
r = sd_event_source_set_enabled(s, SD_EVENT_OFF);
if (r < 0)
return r;