diff options
author | Suren Baghdasaryan <surenb@google.com> | 2017-12-08 13:17:06 -0800 |
---|---|---|
committer | Suren Baghdasaryan <surenb@google.com> | 2018-01-16 15:42:33 -0800 |
commit | 662492ab1d21f138483a8f3943483924e8779d29 (patch) | |
tree | 05970736966b501884290741665e3c28f9ae1cb3 /lmkd | |
parent | ad2fd9150bdbb9abdbc26c6a395f007b4cca7567 (diff) | |
download | core-662492ab1d21f138483a8f3943483924e8779d29.tar.gz core-662492ab1d21f138483a8f3943483924e8779d29.tar.bz2 core-662492ab1d21f138483a8f3943483924e8779d29.zip |
lmkd: add logic to kill the heaviest of the eligible processes
Killing the most memory-demanding process from the set of eligible
processes yields better results on high-performance devices than
killing the first one we could find. This is in line with how in-kernel
lowmemorykiller driver chooses its victims.
Bug: 63631020
Test: alloc-stress
Change-Id: Ie1ef7f33f3e79698a9b4120c14490386d6129f9b
Signed-off-by: Suren Baghdasaryan <surenb@google.com>
Diffstat (limited to 'lmkd')
-rw-r--r-- | lmkd/lmkd.c | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/lmkd/lmkd.c b/lmkd/lmkd.c index e76c07ceb..fb7cc0003 100644 --- a/lmkd/lmkd.c +++ b/lmkd/lmkd.c @@ -91,6 +91,7 @@ static bool enable_pressure_upgrade; static int64_t upgrade_pressure; static int64_t downgrade_pressure; static bool is_go_device; +static bool kill_heaviest_task; /* control socket listen and data */ static int ctrl_lfd; @@ -593,6 +594,29 @@ static struct proc *proc_adj_lru(int oomadj) { return (struct proc *)adjslot_tail(&procadjslot_list[ADJTOSLOT(oomadj)]); } +static struct proc *proc_get_heaviest(int oomadj) { + struct adjslot_list *head = &procadjslot_list[ADJTOSLOT(oomadj)]; + struct adjslot_list *curr = head->next; + struct proc *maxprocp = NULL; + int maxsize = 0; + while (curr != head) { + int pid = ((struct proc *)curr)->pid; + int tasksize = proc_get_size(pid); + if (tasksize <= 0) { + struct adjslot_list *next = curr->next; + pid_remove(pid); + curr = next; + } else { + if (tasksize > maxsize) { + maxsize = tasksize; + maxprocp = (struct proc *)curr; + } + curr = curr->next; + } + } + return maxprocp; +} + /* Kill one process specified by procp. Returns the size of the process killed */ static int kill_one_process(struct proc* procp, int min_score_adj, enum vmpressure_level level) { @@ -643,7 +667,10 @@ static int find_and_kill_process(enum vmpressure_level level) { struct proc *procp; retry: - procp = proc_adj_lru(i); + if (kill_heaviest_task) + procp = proc_get_heaviest(i); + else + procp = proc_adj_lru(i); if (procp) { killed_size = kill_one_process(procp, min_score_adj, level); @@ -929,6 +956,8 @@ int main(int argc __unused, char **argv __unused) { (int64_t)property_get_int32("ro.lmk.upgrade_pressure", 100); downgrade_pressure = (int64_t)property_get_int32("ro.lmk.downgrade_pressure", 100); + kill_heaviest_task = + property_get_bool("ro.lmk.kill_heaviest_task", true); is_go_device = property_get_bool("ro.config.low_ram", false); if (mlockall(MCL_CURRENT | MCL_FUTURE)) |