]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
oom: fix reclaim activity detection
authorAnita Zhang <the.anitazha@gmail.com>
Sun, 24 Jan 2021 09:22:51 +0000 (01:22 -0800)
committerAnita Zhang <the.anitazha@gmail.com>
Sun, 24 Jan 2021 10:02:09 +0000 (02:02 -0800)
This should have been checking for any reclaim activity within a larger interval
of time rather than within the past second. On systems with swap this
doesn't seem to have mattered too much as reclaim would always increase when
memory pressure was elevated. But testing in the no swap case having
this larger interval made a difference between oomd killing or not.

src/oom/oomd-manager.c
src/oom/oomd-manager.h

index 814fda51f31fddad3b730efc59da9e86ca1dcfa7..3efa629002e72b8fecd040350de2842ef306b670 100644 (file)
@@ -302,6 +302,9 @@ static int monitor_cgroup_contexts_handler(sd_event_source *s, uint64_t usec, vo
         else if (r == -ENOENT)
                 zero(m->system_context);
 
+        if (oomd_memory_reclaim(m->monitored_mem_pressure_cgroup_contexts))
+                m->last_reclaim_at = usec_now;
+
         /* If we're still recovering from a kill, don't try to kill again yet */
         if (m->post_action_delay_start > 0) {
                 if (m->post_action_delay_start + POST_ACTION_DELAY_USEC > usec_now)
@@ -314,12 +317,12 @@ static int monitor_cgroup_contexts_handler(sd_event_source *s, uint64_t usec, vo
         if (r == -ENOMEM)
                 return log_error_errno(r, "Failed to check if memory pressure exceeded limits");
         else if (r == 1) {
-                /* Check if there was reclaim activity in the last interval. The concern is the following case:
+                /* Check if there was reclaim activity in the given interval. The concern is the following case:
                  * Pressure climbed, a lot of high-frequency pages were reclaimed, and we killed the offending
                  * cgroup. Even after this, well-behaved processes will fault in recently resident pages and
                  * this will cause pressure to remain high. Thus if there isn't any reclaim pressure, no need
                  * to kill something (it won't help anyways). */
-                if (oomd_memory_reclaim(m->monitored_mem_pressure_cgroup_contexts)) {
+                if ((usec_now - m->last_reclaim_at) <= RECLAIM_DURATION_USEC) {
                         _cleanup_hashmap_free_ Hashmap *candidates = NULL;
                         OomdCGroupContext *t;
 
index ede9903e5a6176b12453fd65de0f56fa42881e93..ee17abced267c28ef8443c06762e99228ef463fe 100644 (file)
@@ -20,6 +20,7 @@
 #define DEFAULT_MEM_PRESSURE_LIMIT 60
 #define DEFAULT_SWAP_USED_LIMIT 90
 
+#define RECLAIM_DURATION_USEC (30 * USEC_PER_SEC)
 #define POST_ACTION_DELAY_USEC (15 * USEC_PER_SEC)
 
 typedef struct Manager Manager;
@@ -42,6 +43,7 @@ struct Manager {
 
         OomdSystemContext system_context;
 
+        usec_t last_reclaim_at;
         usec_t post_action_delay_start;
 
         sd_event_source *cgroup_context_event_source;