lowmem-governor: Remove app with LmkKillException from the LMK victim list 96/303596/1
authorUnsung Lee <unsung.lee@samsung.com>
Fri, 10 Nov 2023 07:46:29 +0000 (16:46 +0900)
committerUnsung Lee <unsung.lee@samsung.com>
Tue, 2 Jan 2024 08:45:20 +0000 (17:45 +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.c

index 2c7d611..9d5e62a 100644 (file)
@@ -193,6 +193,9 @@ static GArray *lowmem_kill_candidates = NULL;
 static GArray *lowmem_task_info_app_array = NULL;
 static GArray *lowmem_task_info_proc_array = NULL;
 
+static GHashTable *g_lmk_kill_exception_pid_list;
+static bool is_lmk_kill_exception_pid(pid_t pid);
+
 //static int memlog_enabled;
 //static int memlog_nr_max = DEFAULT_MEMLOG_NR_MAX;
 /* remove logfiles to reduce to this threshold.
@@ -593,6 +596,7 @@ static GArray *lowmem_get_task_info_app(int killer_flags, int start_oom, int end
 {
        GSList *iter = NULL;
        GSList *proc_app_list = proc_app_list_open();
+       GSList *iterchild;
 
        if (!lowmem_task_info_app_array)
                lowmem_task_info_app_array = g_array_new(false, false, sizeof(struct task_info));
@@ -600,6 +604,7 @@ static GArray *lowmem_get_task_info_app(int killer_flags, int start_oom, int end
        gslist_for_each_item(iter, proc_app_list) {
                struct proc_app_info *pai = (struct proc_app_info *)(iter->data);
                struct task_info task;
+               bool found = false;
 
                if (!pai->appid)
                        continue;
@@ -619,6 +624,25 @@ static GArray *lowmem_get_task_info_app(int killer_flags, int start_oom, int end
                        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;
+
                memset(&task, 0, sizeof(struct task_info));
 
                task.pid = pai->main_pid;
@@ -684,6 +708,7 @@ static GArray *lowmem_get_task_info_proc()
                struct task_info task;
                pid_t pid, pgid;
                int oom_score_adj = 0;
+               char *appid;
 
                if (!isdigit(dentry->d_name[0]))
                        continue;
@@ -713,6 +738,13 @@ static GArray *lowmem_get_task_info_proc()
                if (oom_score_adj > OOMADJ_SU && oom_score_adj <= 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;
+               }
+
                memset(&task, 0, sizeof(struct task_info));
 
                /**
@@ -1634,6 +1666,56 @@ static void print_mem_configs(void)
        _I("Background reclaim enabled = %d", g_bg_reclaim);
 }
 
+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;
+}
+
 /* To Do: should we need lowmem_fd_start, lowmem_fd_stop ?? */
 static int lowmem_init(void)
 {
@@ -1666,7 +1748,14 @@ static int lowmem_init(void)
        lowmem_limit_init();
        lowmem_system_init();
 
+       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_PRELAUNCH, lowmem_prelaunch_handler);
+       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);
 
        return ret;
 }
@@ -1677,7 +1766,12 @@ static int lowmem_exit(void)
        lowmem_limit_exit();
        lowmem_system_exit();
 
+       g_hash_table_destroy(g_lmk_kill_exception_pid_list);
+
        unregister_notifier(RESOURCED_NOTIFIER_APP_PRELAUNCH, lowmem_prelaunch_handler);
+       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);
 
        return RESOURCED_ERROR_NONE;
 }