]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
oomd: avoid unnecessary wake-ups for ManagedOOMSwap
authorChristian Hergert <chergert@redhat.com>
Tue, 29 Aug 2023 21:58:10 +0000 (14:58 -0700)
committerLuca Boccassi <luca.boccassi@gmail.com>
Sat, 2 Sep 2023 01:25:58 +0000 (02:25 +0100)
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>
src/oom/oomd-manager.c

index 514a4750d27aef7277d0a73be3e747f822131770..49896ea7f110be9b96eb46c0fa0ba1ceb6fd984b 100644 (file)
@@ -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;