lowmem-controller: Split up lowmem-controller feature from lowmem module 13/287613/8 accepted/tizen/unified/20230207.165818
authorSangYoun Kwak <sy.kwak@samsung.com>
Wed, 1 Feb 2023 09:10:41 +0000 (18:10 +0900)
committerSangYoun Kwak <sy.kwak@samsung.com>
Thu, 2 Feb 2023 09:48:25 +0000 (18:48 +0900)
The lowmem-controller.c was created by extracting the killing-process
feature from lowmem.c.
    * Newly created: lowmem-controller.c, lowmem-controller.h
    * "lowmem_controller_kill_candidates" function of
      lowmem-controller.c kills procs/apps from candidates list provided
      by the core(lowmem.c).
    * Symbols used only in lowmem-controller.c were moved from lowmem.c
      to lowmem-controller.c.
    * Symbols used both lowmem.c and lowmem-controller.c were moved from
      lowmem.c to lowmem.h.

Change-Id: I8bd0f65acc9df771385c1839096f1283424ce2a5
Signed-off-by: SangYoun Kwak <sy.kwak@samsung.com>
src/resource-limiter/memory/lowmem-controller.c [new file with mode: 0644]
src/resource-limiter/memory/lowmem-controller.h [new file with mode: 0644]
src/resource-limiter/memory/lowmem.c

diff --git a/src/resource-limiter/memory/lowmem-controller.c b/src/resource-limiter/memory/lowmem-controller.c
new file mode 100644 (file)
index 0000000..118b7cb
--- /dev/null
@@ -0,0 +1,193 @@
+/**
+ * resourced
+ *
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either excontroller or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file lowmem-controller.c
+ * @desc Provides controller functionalities to kill procs/apps
+ */
+
+#include <string.h>
+#include <limits.h>
+
+#include "lowmem.h"
+#include "lowmem-controller.h"
+#include "proc-common.h"
+#include "proc-main.h"
+#include "resourced.h"
+#include "procfs.h"
+#include "trace.h"
+#include "util.h"
+#include "safe-kill.h"
+
+#define MAX_VICTIMS_BETWEEN_CHECK  3
+
+static int num_vict_between_check = MAX_VICTIMS_BETWEEN_CHECK;
+
+static int lowmem_kill_victim(const struct task_info *tsk, int flags,
+                               int memps_log, unsigned int *victim_size,
+                               void(*oom_popup)(void))
+{
+       pid_t pid;
+       int ret;
+       char appname[PATH_MAX];
+       int sigterm = 0;
+       struct proc_app_info *pai;
+
+       pid = tsk->pid;
+
+       if (pid <= 0 || pid == getpid())
+               return RESOURCED_ERROR_FAIL;
+
+       ret = proc_get_cmdline(pid, appname, sizeof appname);
+       if (ret == RESOURCED_ERROR_FAIL)
+               return RESOURCED_ERROR_FAIL;
+
+       if (!strcmp("memps", appname) ||
+                       !strcmp("crash-worker", appname) ||
+                       !strcmp("system-syspopup", appname)) {
+               _E("%s(%d) was selected, skip it", appname, pid);
+               return RESOURCED_ERROR_FAIL;
+       }
+
+       pai = tsk->pai;
+       if (pai) {
+               resourced_proc_status_change(PROC_CGROUP_SET_TERMINATE_REQUEST,
+                       pid, NULL, NULL, PROC_TYPE_NONE);
+
+               if (tsk->oom_score_lru <= OOMADJ_BACKGRD_LOCKED) {
+                       sigterm = 1;
+               } else if (tsk->oom_score_lru > OOMADJ_BACKGRD_LOCKED &&
+                               tsk->oom_score_lru < OOMADJ_BACKGRD_UNLOCKED) {
+                       int app_flag = pai->flags;
+                       sigterm = app_flag & PROC_SIGTERM;
+               }
+
+               if (pai->memory.oom_killed)
+                       sigterm = 0;
+
+               pai->memory.oom_killed = true;
+       }
+
+       if (sigterm)
+               safe_kill(pid, SIGTERM);
+       else
+               safe_kill(pid, SIGKILL);
+
+       _D("[LMK] we killed, force(%d), %d (%s) score = %d, size: rss = %u KB, sigterm = %d\n",
+                       flags & OOM_FORCE, pid, appname, tsk->oom_score_adj,
+                       tsk->size, sigterm);
+       *victim_size = tsk->size;
+
+       if (tsk->oom_score_lru > OOMADJ_FOREGRD_UNLOCKED)
+               return RESOURCED_ERROR_NONE;
+
+       oom_popup();
+
+       return RESOURCED_ERROR_NONE;
+}
+
+/* return LOWMEM_RECLAIM_CONT when killing should be continued */
+static int lowmem_check_kill_continued(struct task_info *tsk, int flags,
+                                       unsigned lmk_start_threshold_mb)
+{
+       unsigned int available_mb = 0;
+
+       /**
+        * Processes with the priority higher than perceptible are killed
+        * only when the available memory is less than dynamic oom threshold.
+        */
+       if (tsk->oom_score_lru > OOMADJ_BACKGRD_PERCEPTIBLE)
+               return LOWMEM_RECLAIM_CONT;
+
+       if (flags & (OOM_FORCE | OOM_SINGLE_SHOT)) {
+               _I("[LMK] %d is dropped during force kill, flag=%d",
+                       tsk->pid, flags);
+               return LOWMEM_RECLAIM_DROP;
+       }
+       available_mb = proc_get_mem_available();
+       if (available_mb > lmk_start_threshold_mb) {
+               _I("[LMK] available=%d MB, larger than %u MB, do not kill foreground",
+                       available_mb, lmk_start_threshold_mb);
+               return LOWMEM_RECLAIM_RETRY;
+       }
+       return LOWMEM_RECLAIM_CONT;
+}
+
+int lowmem_controller_kill_candidates(GArray *candidates,
+                       unsigned should_be_freed, unsigned int threshold,
+                       int max_victims, int flags,
+                       int *status, unsigned int *total_victim_size,
+                       unsigned lmk_start_threshold_mb,
+                       void(*oom_popup)(void))
+{
+       int ret_kill = 0;
+       int victim_cnt = 0;
+       unsigned int victim_size = 0;
+       unsigned int victim_size_sum = 0;
+       int killer_status = *status;
+       int should_be_freed_kb = MBYTE_TO_KBYTE(should_be_freed);
+
+       for (int i = 0; i < candidates->len; i++) {
+               struct task_info *tsk;
+
+               if (i >= max_victims) {
+                       killer_status = LOWMEM_RECLAIM_NEXT_TYPE;
+                       break;
+               }
+
+               /**
+                * Available memory is checking only every
+                * num_vict_between_check process for reducing burden.
+                */
+               if (!(i % num_vict_between_check) &&
+                               proc_get_mem_available() > threshold) {
+                       killer_status = LOWMEM_RECLAIM_DONE;
+                       break;
+               }
+
+               if (!(flags & OOM_NOMEMORY_CHECK) &&
+                               victim_size_sum >= should_be_freed_kb) {
+                       _D("[LMK] victim=%d, max_victims=%d, total_size=%uKB",
+                               victim_cnt, max_victims, victim_size_sum);
+                       killer_status = LOWMEM_RECLAIM_DONE;
+                       break;
+               }
+
+               tsk = &g_array_index(candidates, struct task_info, i);
+
+               killer_status = lowmem_check_kill_continued(tsk, flags,
+                                                       lmk_start_threshold_mb);
+               if (killer_status != LOWMEM_RECLAIM_CONT)
+                       break;
+
+               _I("[LMK] select victims from proc_app_list pid(%d) with oom_score_adj(%d)\n",
+                               tsk->pid, tsk->oom_score_adj);
+
+               ret_kill = lowmem_kill_victim(tsk, flags, i, &victim_size,
+                                               oom_popup);
+               if (ret_kill != RESOURCED_ERROR_NONE)
+                       continue;
+               victim_cnt++;
+               victim_size_sum += victim_size;
+       }
+
+       *status = killer_status;
+       *total_victim_size = victim_size_sum;
+
+       return victim_cnt;
+}
diff --git a/src/resource-limiter/memory/lowmem-controller.h b/src/resource-limiter/memory/lowmem-controller.h
new file mode 100644 (file)
index 0000000..d848f79
--- /dev/null
@@ -0,0 +1,35 @@
+/**
+ * resourced
+ *
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either excontroller or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/**
+ * @file lowmem-controller.h
+ * @desc Functions for controller features.
+ */
+
+#ifndef __LOWMEM_CONTROLLER_H__
+#define __LOWMEM_CONTROLLER_H__
+
+int lowmem_controller_kill_candidates(GArray *candidates,
+                       unsigned should_be_freed, unsigned int threshold,
+                       int max_victims, int flags,
+                       int *status, unsigned int *total_victim_size,
+                       unsigned lmk_start_threshold_mb,
+                       void(*oom_popup)(void));
+
+#endif /* __LOWMEM_CONTROLLER_H__ */
index aca7a6b..98dcbfe 100644 (file)
@@ -51,6 +51,7 @@
 #include "lowmem-system.h"
 #include "lowmem-limit.h"
 #include "lowmem-governor.h"
+#include "lowmem-controller.h"
 #include "proc-common.h"
 #include "procfs.h"
 #include "freezer.h"
 #include "util.h"
 #include "fd-handler.h"
 #include "resourced-helper-worker.h"
-#include "safe-kill.h"
 #include "dedup-common.h"
 
-#define MAX_VICTIMS_BETWEEN_CHECK           3
 #define MAX_PROACTIVE_HIGH_VICTIMS          4
 #define FOREGROUND_VICTIMS                  1
 #define OOM_KILLER_PRIORITY                 -20
@@ -282,7 +281,6 @@ static void lmk_act(void);
 
 static size_t cur_mem_state = MEM_LEVEL_HIGH;
 static int num_max_victims = MAX_MEMORY_CGROUP_VICTIMS;
-static int num_vict_between_check = MAX_VICTIMS_BETWEEN_CHECK;
 
 static unsigned long long totalram_bytes;
 static unsigned long totalram_kb;
@@ -388,96 +386,6 @@ unsigned int lowmem_get_task_mem_usage_rss(const struct task_info *tsk)
        return total_size_kb;
 }
 
-static int lowmem_kill_victim(const struct task_info *tsk,
-               int flags, int memps_log, unsigned int *victim_size)
-{
-       pid_t pid;
-       int ret;
-       char appname[PATH_MAX];
-       int sigterm = 0;
-       struct proc_app_info *pai;
-
-       pid = tsk->pid;
-
-       if (pid <= 0 || pid == getpid())
-               return RESOURCED_ERROR_FAIL;
-
-       ret = proc_get_cmdline(pid, appname, sizeof appname);
-       if (ret == RESOURCED_ERROR_FAIL)
-               return RESOURCED_ERROR_FAIL;
-
-       if (!strcmp("memps", appname) ||
-           !strcmp("crash-worker", appname) ||
-           !strcmp("system-syspopup", appname)) {
-               _E("%s(%d) was selected, skip it", appname, pid);
-               return RESOURCED_ERROR_FAIL;
-       }
-
-       pai = tsk->pai;
-       if (pai) {
-               resourced_proc_status_change(PROC_CGROUP_SET_TERMINATE_REQUEST,
-                       pid, NULL, NULL, PROC_TYPE_NONE);
-
-               if (tsk->oom_score_lru <= OOMADJ_BACKGRD_LOCKED) {
-                       sigterm = 1;
-               } else if (tsk->oom_score_lru > OOMADJ_BACKGRD_LOCKED && tsk->oom_score_lru < OOMADJ_BACKGRD_UNLOCKED) {
-                       int app_flag = pai->flags;
-                       sigterm = app_flag & PROC_SIGTERM;
-               }
-
-               if (pai->memory.oom_killed)
-                       sigterm = 0;
-
-               pai->memory.oom_killed = true;
-       }
-
-       if (sigterm)
-               safe_kill(pid, SIGTERM);
-       else
-               safe_kill(pid, SIGKILL);
-
-       _D("[LMK] we killed, force(%d), %d (%s) score = %d, size: rss = %u KB, sigterm = %d\n",
-          flags & OOM_FORCE, pid, appname, tsk->oom_score_adj,
-          tsk->size, sigterm);
-       *victim_size = tsk->size;
-
-       if (tsk->oom_score_lru > OOMADJ_FOREGRD_UNLOCKED)
-               return RESOURCED_ERROR_NONE;
-
-       if (oom_popup_enable && !oom_popup) {
-               lowmem_launch_oompopup();
-               oom_popup = true;
-       }
-
-       return RESOURCED_ERROR_NONE;
-}
-
-/* return LOWMEM_RECLAIM_CONT when killing should be continued */
-static int lowmem_check_kill_continued(struct task_info *tsk, int flags)
-{
-       unsigned int available_mb;
-
-       /*
-        * Processes with the priority higher than perceptible are killed
-        * only when the available memory is less than dynamic oom threshold.
-        */
-       if (tsk->oom_score_lru > OOMADJ_BACKGRD_PERCEPTIBLE)
-               return LOWMEM_RECLAIM_CONT;
-
-       if (flags & (OOM_FORCE|OOM_SINGLE_SHOT)) {
-               _I("[LMK] %d is dropped during force kill, flag=%d",
-                       tsk->pid, flags);
-               return LOWMEM_RECLAIM_DROP;
-       }
-       available_mb = proc_get_mem_available();
-       if (available_mb > lmk_start_threshold_mb) {
-               _I("[LMK] available=%d MB, larger than %u MB, do not kill foreground",
-                       available_mb, lmk_start_threshold_mb);
-               return LOWMEM_RECLAIM_RETRY;
-       }
-       return LOWMEM_RECLAIM_CONT;
-}
-
 static void lowmem_free_task_info_array(GArray *array)
 {
        int i;
@@ -517,6 +425,14 @@ static unsigned int is_memory_recovered(unsigned int *avail, unsigned int thres)
        return should_be_freed_mb;
 }
 
+static void lowmem_oom_popup_once(void)
+{
+       if (oom_popup_enable && !oom_popup) {
+               lowmem_launch_oompopup();
+               oom_popup = true;
+       }
+}
+
 /**
  * @brief Terminate up to max_victims processes after finding them from pai.
        It depends on proc_app_info lists
@@ -536,12 +452,10 @@ static int lowmem_kill_victims(int max_victims,
        unsigned int *total_size, int *completed, unsigned int threshold)
 {
        GSList *proc_app_list = NULL;
-       int i, ret, victim = 0;
-       unsigned int victim_size = 0;
        unsigned int total_victim_size = 0;
+       int victim_cnt = 0;
        int status = LOWMEM_RECLAIM_NONE;
        GArray *candidates = NULL;
-       int should_be_freed_kb = MBYTE_TO_KBYTE(should_be_freed);
 
        proc_app_list = proc_app_list_open();
 
@@ -556,47 +470,12 @@ static int lowmem_kill_victims(int max_victims,
                goto leave;
        }
 
-       for (i = 0; i < candidates->len; i++) {
-               struct task_info *tsk;
-
-               if (i >= max_victims) {
-                       status = LOWMEM_RECLAIM_NEXT_TYPE;
-                       break;
-               }
-
-               /*
-                * Available memory is checking only every
-                * num_vict_between_check process for reducing burden.
-                */
-               if (!(i % num_vict_between_check)) {
-                       if (proc_get_mem_available() > threshold) {
-                               status = LOWMEM_RECLAIM_DONE;
-                               break;
-                       }
-               }
-
-               if (!(flags & OOM_NOMEMORY_CHECK) &&
-                   total_victim_size >= should_be_freed_kb) {
-                       _D("[LMK] victim=%d, max_victims=%d, total_size=%uKB",
-                               victim, max_victims, total_victim_size);
-                       status = LOWMEM_RECLAIM_DONE;
-                       break;
-               }
-
-               tsk = &g_array_index(candidates, struct task_info, i);
-
-               status = lowmem_check_kill_continued(tsk, flags);
-               if (status != LOWMEM_RECLAIM_CONT)
-                       break;
-
-               _I("[LMK] select victims from proc_app_list pid(%d) with oom_score_adj(%d)\n", tsk->pid, tsk->oom_score_adj);
-
-               ret = lowmem_kill_victim(tsk, flags, i, &victim_size);
-               if (ret != RESOURCED_ERROR_NONE)
-                       continue;
-               victim++;
-               total_victim_size += victim_size;
-       }
+       victim_cnt = lowmem_controller_kill_candidates(candidates,
+                                               should_be_freed, threshold,
+                                               max_victims, flags,
+                                               &status, &total_victim_size,
+                                               lmk_start_threshold_mb,
+                                               lowmem_oom_popup_once);
 
 leave:
        lowmem_free_task_info_array(candidates);
@@ -605,7 +484,7 @@ leave:
                *completed = status;
        else
                *completed = LOWMEM_RECLAIM_NEXT_TYPE;
-       return victim;
+       return victim_cnt;
 }
 
 static int calculate_range_of_oom(enum oom_score score, int *min, int *max)