Enhance exception handling of memlimit 56/272356/5
authorUnsung Lee <unsung.lee@samsung.com>
Tue, 15 Mar 2022 07:32:51 +0000 (16:32 +0900)
committerUnsung Lee <unsung.lee@samsung.com>
Tue, 15 Mar 2022 07:56:17 +0000 (16:56 +0900)
consider panic on oom case

Change-Id: Ie609129858b035b3e2a14a69d1ff834c1b1c3563
Signed-off-by: Unsung Lee <unsung.lee@samsung.com>
src/resource-limiter/memory/lowmem-handler.h
src/resource-limiter/memory/lowmem-limit.c

index 846a957..02e5b89 100644 (file)
@@ -65,7 +65,6 @@ struct memory_limit_event {
        unsigned int threshold;
        char *path;
        enum proc_action action;
-       GSource *sigterm_timer;
        int pid;
 };
 
index 69e1720..3be0115 100644 (file)
@@ -51,6 +51,7 @@
 #include "fd-handler.h"
 #include "dbus-handler.h"
 #include "safe-kill.h"
+#include "file-helper.h"
 
 #define MEM_CONF_FILE                   RD_CONFIG_FILE(limiter)
 #define MEMLIMIT_CONFIG_SECTION        "MemLimit"
@@ -223,7 +224,6 @@ static gboolean liveness_check_cb(gpointer data)
 
 mle_timer_init:
        mle->pid = -1;
-       mle->sigterm_timer = NULL;
 timer_out:
        return G_SOURCE_REMOVE;
 }
@@ -232,7 +232,7 @@ static bool memory_action_cb(int fd, void *data)
 {
        int result;
        pid_t main_pid;
-       uint32_t usage, anon_usage, max_mem;
+       uint32_t usage, max_mem;
        uint64_t dummy_efd;
        char *cg_dir = (char *)data;
        struct memory_limit_event *mle;
@@ -277,13 +277,13 @@ static bool memory_action_cb(int fd, void *data)
                goto remove_mle;
        }
 
-       anon_usage = mem_stat->value[CGROUP_MEMORY_STAT_RSS] +
+/*     anon_usage = mem_stat->value[CGROUP_MEMORY_STAT_RSS] +
                mem_stat->value[CGROUP_MEMORY_STAT_SWAP];
        if (anon_usage < mle->threshold) {
                _D("[DEBUG] (%s) cgroup escaped low memory status. usage(%d), anon usage (%d), threshold(%d)",
                                cg_dir, usage, anon_usage, mle->threshold);
                return true;
-       }
+       }*/
 
        switch (mle->action) {
                case PROC_ACTION_BROADCAST:
@@ -309,10 +309,11 @@ static bool memory_action_cb(int fd, void *data)
                        }
                        safe_kill(main_pid, SIGTERM);
 
-                       if (mle->sigterm_timer == NULL) {
+                       if (mle->pid == -1) {
                                mle->pid = main_pid;
                                g_timeout_add_seconds(2, liveness_check_cb, mle);
                        }
+
                        break;
                default:
                        _E("[DEBUG] Unkown action of memory threshold");
@@ -325,12 +326,33 @@ remove_mle:
        return false;
 }
 
+static void set_limit_in_bytes(const char *dir, unsigned int limit)
+{
+       int error;
+       unsigned int prev;
+
+       error = cgroup_read_node_uint32(dir, MEMCG_LIMIT_BYTE, &prev);
+       if (error) {
+               _E("[DEBUG] Failed to get %s from %s", MEMCG_LIMIT_BYTE, dir);
+               return;
+       }
+
+       if (prev > (limit * 1.2)) {
+               cgroup_write_node_uint32(dir, MEMCG_LIMIT_BYTE, (limit * 1.2));
+               cgroup_write_node_uint32(dir, MEMCG_SWAP_LIMIT_BYTE, (limit * 1.2));
+       }
+       else {
+               cgroup_write_node_uint32(dir, MEMCG_SWAP_LIMIT_BYTE, (limit * 1.2));
+               cgroup_write_node_uint32(dir, MEMCG_LIMIT_BYTE, (limit * 1.2));
+       }
+}
+
 int lowmem_reassign_limit(const char *dir,
                unsigned int limit, enum proc_action action)
 {
        int fd;
        int error;
-       unsigned int prev;
+       unsigned int poo;
        fd_handler_h fdh = NULL;
        gpointer hash_entry;
        struct memory_limit_event *mle = NULL;
@@ -358,19 +380,21 @@ int lowmem_reassign_limit(const char *dir,
                }
        }
 
-       error = cgroup_read_node_uint32(dir, MEMCG_LIMIT_BYTE, &prev);
+       error = fread_uint("/proc/sys/vm/panic_on_oom", &poo);
        if (error) {
-               _E("[DEBUG] Failed to get %s from %s", MEMCG_LIMIT_BYTE, dir);
+               _E("[DEBUG] Failed to get %s from %s", "/proc/sys/vm/panic_on_oom", dir);
                return RESOURCED_ERROR_FAIL;
        }
 
-       if (prev > (limit * 1.2)) {
-               cgroup_write_node_uint32(dir, MEMCG_LIMIT_BYTE, (limit * 1.2));
-               cgroup_write_node_uint32(dir, MEMCG_SWAP_LIMIT_BYTE, (limit * 1.2));
+       /* If panic_on_oom is true (> 1), oom should be disabled  */
+       if (poo != 0) {
+               _I("%s's value is %d. That is, kernel panic will be inevitable, when oom happens", "proc/sys/vm/panic_on_oom", poo);
+               error = cgroup_write_node_uint32(dir, MEMCG_OOM_CONTROL, 1);
+               if (!error)
+                       set_limit_in_bytes(dir, limit);
        }
        else {
-               cgroup_write_node_uint32(dir, MEMCG_SWAP_LIMIT_BYTE, (limit * 1.2));
-               cgroup_write_node_uint32(dir, MEMCG_LIMIT_BYTE, (limit * 1.2));
+               set_limit_in_bytes(dir, limit);
        }
 
        snprintf(buf, sizeof(buf), "%d", limit);
@@ -398,7 +422,6 @@ int lowmem_reassign_limit(const char *dir,
                mle->action = action;
                mle->threshold = limit;
                mle->pid = -1;
-               mle->sigterm_timer = NULL;
                add_fd_read_handler(fd, memory_action_cb, mle->path, NULL, &fdh);
                mle->fdh = fdh;
                g_hash_table_insert(memory_limit_hash, (gpointer)mle->path,
@@ -496,7 +519,11 @@ void lowmem_limit_set_system_service(pid_t pid, unsigned int limit,
                return;
        }
 
-       lowmem_reassign_limit(path, limit, action);
+       result = lowmem_reassign_limit(path, limit, action);
+       if (result < 0) {
+               _W("Failed to reassign limit for %s", path);
+               return;
+       }
 
        result = cgroup_write_node_uint32(path, MEMCG_MOVE_CHARGE, 3U);
        if (result < 0)