summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/resource-limiter/memory/lowmem.c94
1 files changed, 94 insertions, 0 deletions
diff --git a/src/resource-limiter/memory/lowmem.c b/src/resource-limiter/memory/lowmem.c
index 2c7d6114..9d5e62a5 100644
--- a/src/resource-limiter/memory/lowmem.c
+++ b/src/resource-limiter/memory/lowmem.c
@@ -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;
}