Update memory limit 16/272316/3
authorUnsung Lee <unsung.lee@samsung.com>
Mon, 14 Mar 2022 11:44:07 +0000 (20:44 +0900)
committerUnsung Lee <unsung.lee@samsung.com>
Tue, 15 Mar 2022 03:29:16 +0000 (12:29 +0900)
send SIGTERM and SIGKILL after 2 seconds &
set memory.limit_in_bytes and memory.memsw.limit_in_bytes for safety

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

index 1696794..846a957 100644 (file)
@@ -65,11 +65,10 @@ struct memory_limit_event {
        unsigned int threshold;
        char *path;
        enum proc_action action;
+       GSource *sigterm_timer;
+       int pid;
 };
 
-bool memory_action_cb(int fd, void *data);
-void memory_limit_hash_destroy(gpointer data);
-
 /**
  * @desc execute /usr/bin/memps and make log file with pid and process name
  */
index 9da5412..69e1720 100644 (file)
@@ -148,7 +148,7 @@ static pid_t get_main_pid(const char *dir, unsigned int *max_mem)
        return main_pid;
 }
 
-void memory_limit_hash_destroy(gpointer data)
+static void memory_limit_hash_destroy(gpointer data)
 {
        struct memory_limit_event *mle = (struct memory_limit_event *)data;
        if (!mle) {
@@ -204,7 +204,31 @@ static int lowmem_limit_broadcast(pid_t pid)
        return ret;
 }
 
-bool memory_action_cb(int fd, void *data)
+static gboolean liveness_check_cb(gpointer data)
+{
+       struct memory_limit_event *mle = (struct memory_limit_event *)data;
+
+       if (!mle) {
+               _E("[DEBUG] memory limit event structure is NULL");
+               goto timer_out;
+       }
+
+       if (mle->pid <= 0) {
+               _E("[DEBUG] pid should be larger than 0");
+               goto mle_timer_init;
+       }
+
+       if (kill(mle->pid, 0) == 0)
+               safe_kill(mle->pid, SIGKILL);
+
+mle_timer_init:
+       mle->pid = -1;
+       mle->sigterm_timer = NULL;
+timer_out:
+       return G_SOURCE_REMOVE;
+}
+
+static bool memory_action_cb(int fd, void *data)
 {
        int result;
        pid_t main_pid;
@@ -233,12 +257,12 @@ bool memory_action_cb(int fd, void *data)
        }
 
        result = cgroup_read_node_uint32(cg_dir, MEMCG_SWAP_USAGE, &usage);
-       if (result < 0)
-               result = cgroup_read_node_uint32(cg_dir, MEMCG_USAGE, &usage);
-
        if (result < 0) {
-               _D("[DEBUG] there is no (%s) cgroup any longer, removed it", cg_dir);
-               goto remove_mle;
+               result = cgroup_read_node_uint32(cg_dir, MEMCG_USAGE, &usage);
+               if (result < 0) {
+                       _D("[DEBUG] there is no (%s) cgroup any longer, removed it", cg_dir);
+                       goto remove_mle;
+               }
        }
 
        if (usage < mle->threshold) {
@@ -261,8 +285,6 @@ bool memory_action_cb(int fd, void *data)
                return true;
        }
 
-       _I("[DEBUG] action: %d", mle->action);
-
        switch (mle->action) {
                case PROC_ACTION_BROADCAST:
                        main_pid = get_main_pid(cg_dir, &max_mem);
@@ -285,8 +307,12 @@ bool memory_action_cb(int fd, void *data)
                                _D("[DEBUG] there is no victim, removed cgroup : %s", cg_dir);
                                goto remove_mle;
                        }
-
                        safe_kill(main_pid, SIGTERM);
+
+                       if (mle->sigterm_timer == NULL) {
+                               mle->pid = main_pid;
+                               g_timeout_add_seconds(2, liveness_check_cb, mle);
+                       }
                        break;
                default:
                        _E("[DEBUG] Unkown action of memory threshold");
@@ -303,6 +329,8 @@ int lowmem_reassign_limit(const char *dir,
                unsigned int limit, enum proc_action action)
 {
        int fd;
+       int error;
+       unsigned int prev;
        fd_handler_h fdh = NULL;
        gpointer hash_entry;
        struct memory_limit_event *mle = NULL;
@@ -330,9 +358,22 @@ int lowmem_reassign_limit(const char *dir,
                }
        }
 
+       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 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));
+       }
+       else {
+               cgroup_write_node_uint32(dir, MEMCG_SWAP_LIMIT_BYTE, (limit * 1.2));
+               cgroup_write_node_uint32(dir, MEMCG_LIMIT_BYTE, (limit * 1.2));
+       }
+
        snprintf(buf, sizeof(buf), "%d", limit);
-       cgroup_write_node_uint32(dir, MEMCG_LIMIT_BYTE, (limit * 1.2));
-       cgroup_write_node_uint32(dir, MEMCG_SWAP_LIMIT_BYTE, (limit * 1.5));
 
        if (mle) {
                mle->threshold = limit;
@@ -356,10 +397,12 @@ 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,
-                   (gpointer)mle);
+                               (gpointer)mle);
 
                _I("[DEBUG] a memory cgroup notificatoin is registered at %s", dir);
                return RESOURCED_ERROR_NONE;
@@ -400,7 +443,7 @@ static int memlimit_config_parse(struct parse_result *result, void *user_data)
                return RESOURCED_ERROR_NONE;
 
        if (strncmp(result->section, MEMLIMIT_CONFIG_SECTION,
-           sizeof(MEMLIMIT_CONFIG_SECTION)))
+                               sizeof(MEMLIMIT_CONFIG_SECTION)))
                return RESOURCED_ERROR_NONE;
 
        if (!result->name || !result->value)
@@ -449,7 +492,7 @@ void lowmem_limit_set_system_service(pid_t pid, unsigned int limit,
        result = cgroup_make_subdir(MEMCG_HIGH_PP_PATH, name, NULL);
        if (result < 0) {
                _E("[DEBUG] Failed to create cgroup subdir '%s/%s'",
-                  MEMCG_HIGH_PP_PATH, name);
+                               MEMCG_HIGH_PP_PATH, name);
                return;
        }
 
@@ -489,7 +532,7 @@ int lowmem_limit_set_app(unsigned int limit, struct proc_app_info *pai,
        result = cgroup_make_subdir(MEMCG_HIGH_PP_PATH, pai->appid, NULL);
        if (result < 0) {
                _E("Failed to create cgroup subdir '%s/%s'",
-                  MEMCG_HIGH_PP_PATH, pai->appid);
+                               MEMCG_HIGH_PP_PATH, pai->appid);
                return result;
        }