summaryrefslogtreecommitdiffstats
path: root/lmkd
diff options
context:
space:
mode:
authorSuren Baghdasaryan <surenb@google.com>2017-12-08 13:17:06 -0800
committerSuren Baghdasaryan <surenb@google.com>2018-01-16 15:42:33 -0800
commit662492ab1d21f138483a8f3943483924e8779d29 (patch)
tree05970736966b501884290741665e3c28f9ae1cb3 /lmkd
parentad2fd9150bdbb9abdbc26c6a395f007b4cca7567 (diff)
downloadcore-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.c31
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))