lowmem-governor: Remove app with LmkKillException from the LMK victim list 30/301330/6
authorUnsung Lee <unsung.lee@samsung.com>
Fri, 10 Nov 2023 07:46:29 +0000 (16:46 +0900)
committerUnsung Lee <unsung.lee@samsung.com>
Tue, 21 Nov 2023 07:56:06 +0000 (16:56 +0900)
Remove app with LmkKillException configuration property (yes|1|ok|on|)
from the LMK victim list during LMK. If LmkKillException is not declared in
limiter.conf.d, then the process can be included in LMK victim list during LMK
(default is no|0|off).

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

index d249129..d748850 100644 (file)
 #include "proc-common.h"
 #include "macro.h"
 #include "trace.h"
+#include "notifier.h"
 
 #define BUFF_MAX      255
 #define APP_ATTR_PATH "/proc/%d/attr/current"
 
 static unsigned long totalram_kb;
+static GHashTable *g_lmk_kill_exception_pid_list;
+
+static bool is_lmk_kill_exception_pid(pid_t pid);
 
 static int get_privilege(pid_t pid, char *name, size_t len)
 {
@@ -100,6 +104,7 @@ static int lowmem_get_pids_proc(GArray *pids)
                struct task_info tsk;
                pid_t pid = 0, pgid = 0;
                int oom = 0;
+               char *appid;
 
                if (!isdigit(dentry->d_name[0]))
                        continue;
@@ -130,6 +135,13 @@ static int lowmem_get_pids_proc(GArray *pids)
                if (oom > OOMADJ_SU && oom <= OOMADJ_APP_MAX)
                        continue;
 
+               appid = (char *)g_hash_table_lookup(g_lmk_kill_exception_pid_list, &pid);
+               if (appid) {
+                       _D("[LMK] Don't kill %s, (pid = %d) is lmk kill exception pid",
+                                       appid, pid);
+                       continue;
+               }
+
                /**
                 * Currently, for tasks in the memory cgroup,
                 * do not consider multiple tasks with one pgid.
@@ -175,6 +187,7 @@ GArray *lowmem_governor_get_kill_candidates(GSList *proc_app_list, int start_oom
 
        gslist_for_each_item(iter, proc_app_list) {
                struct task_info ti;
+               bool found = false;
 
                proc_app_count++;
                pai = (struct proc_app_info *)iter->data;
@@ -189,6 +202,25 @@ GArray *lowmem_governor_get_kill_candidates(GSList *proc_app_list, int start_oom
                if ((killer_flags & OOM_REVISE) && pai->memory.oom_killed)
                        continue;
 
+               if (is_lmk_kill_exception_pid(pai->main_pid)) {
+                       _D("[LMK] Don't kill %s, (pid = %d) is lmk kill exception pid",
+                                       pai->appid, pai->main_pid);
+                       continue;
+               }
+
+               gslist_for_each_item(iterchild, pai->childs) {
+                       pid_t child = GPOINTER_TO_PID(iterchild->data);
+                       if (is_lmk_kill_exception_pid(child)) {
+                               _D("[LMK] Don't kill %s, (pid = %d) is lmk kill exception pid",
+                                               pai->appid, child);
+                               found = true;
+                               break;
+                       }
+               }
+
+               if (found)
+                       continue;
+
                ti.pid = pai->main_pid;
                ti.pgid = getpgid(ti.pid);
                ti.oom_score_adj = oom_score_adj;
@@ -246,3 +278,72 @@ GArray *lowmem_governor_get_kill_candidates(GSList *proc_app_list, int start_oom
        return candidates;
 }
 
+static bool is_lmk_kill_exception_pid(pid_t pid)
+{
+       if (g_hash_table_contains(g_lmk_kill_exception_pid_list, &pid))
+               return true;
+
+       return false;
+}
+
+static int lowmem_governor_add_exception_pid(void *data)
+{
+       struct proc_status *ps = (struct proc_status *)data;
+       struct proc_conf_info *pci;
+       gint *pid;
+
+       if (!ps)
+               return RESOURCED_ERROR_INVALID_PARAMETER;
+
+       if (ps->pid < 0)
+               return RESOURCED_ERROR_INVALID_PARAMETER;
+
+       if (!ps->pai)
+               return RESOURCED_ERROR_INVALID_PARAMETER;
+
+       pci = fixed_app_and_service_exist_check(ps->pai->appid, APP_TYPE);
+       if (!pci || !(pci->is_lmk_kill_exception))
+               return RESOURCED_ERROR_NONE;
+
+       _D("%s (pid = %d) is registered as LMK kill exception pid",
+                       ps->pai->appid, ps->pid);
+       pid = g_new(gint, 1);
+       *pid = ps->pid;
+       g_hash_table_insert(g_lmk_kill_exception_pid_list, (gpointer)pid, pci->name);
+
+       return RESOURCED_ERROR_NONE;
+}
+
+static int lowmem_governor_remove_exception_pid(void *data)
+{
+       struct proc_status *ps = (struct proc_status *)data;
+       int pid = ps->pid;
+
+       if (g_hash_table_contains(g_lmk_kill_exception_pid_list, &pid)) {
+               _D("%s (pid = %d) is unregistered as LMK kill exceptoin pid",
+                               ps->pai->appid, ps->pid);
+               g_hash_table_remove(g_lmk_kill_exception_pid_list, &pid);
+       }
+
+       return RESOURCED_ERROR_NONE;
+}
+
+void lowmem_governor_init(void)
+{
+       g_lmk_kill_exception_pid_list = g_hash_table_new_full(g_int_hash,
+                       g_int_equal, g_free, NULL);
+       g_assert(g_lmk_kill_exception_pid_list);
+
+       register_notifier(RESOURCED_NOTIFIER_APP_LAUNCH, lowmem_governor_add_exception_pid);
+       register_notifier(RESOURCED_NOTIFIER_SERVICE_LAUNCH, lowmem_governor_add_exception_pid);
+       register_notifier(RESOURCED_NOTIFIER_APP_TERMINATED, lowmem_governor_remove_exception_pid);
+}
+
+void lowmem_governor_exit(void)
+{
+       g_hash_table_destroy(g_lmk_kill_exception_pid_list);
+
+       unregister_notifier(RESOURCED_NOTIFIER_APP_LAUNCH, lowmem_governor_add_exception_pid);
+       unregister_notifier(RESOURCED_NOTIFIER_SERVICE_LAUNCH, lowmem_governor_add_exception_pid);
+       unregister_notifier(RESOURCED_NOTIFIER_APP_TERMINATED, lowmem_governor_remove_exception_pid);
+}
index ebd34ae..c0458ae 100644 (file)
@@ -27,4 +27,6 @@
 
 GArray *lowmem_governor_get_kill_candidates(GSList *proc_app_list, int start_oom, int end_oom, int killer_flags);
 
+void lowmem_governor_init(void);
+void lowmem_governor_exit(void);
 #endif /* __LOWMEM_GOVERNOR_H__ */
index 0eb622f..3562198 100644 (file)
@@ -1498,6 +1498,9 @@ static int lowmem_init(void)
        memcg_write_limiter_params();
        print_mem_configs();
 
+       /* Initalize lowmem governor module before making a low memory killer */
+       lowmem_governor_init();
+
        /* make a worker thread called low memory killer */
        ret = lowmem_activate_worker();
        if (ret) {
@@ -1527,6 +1530,7 @@ static int lowmem_init(void)
 static int lowmem_exit(void)
 {
        lowmem_deactivate_worker();
+       lowmem_governor_exit();
        lowmem_limit_exit();
        lowmem_system_exit();