#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)
{
struct task_info tsk;
pid_t pid = 0, pgid = 0;
int oom = 0;
+ char *appid;
if (!isdigit(dentry->d_name[0]))
continue;
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.
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;
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;
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);
+}