lmkd: add logic to kill the heaviest of the eligible processes
(cherry pick from commit 662492ab1d21f138483a8f3943483924e8779d29)
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
Merged-In: Ie1ef7f33f3e79698a9b4120c14490386d6129f9b
Signed-off-by: Suren Baghdasaryan <surenb@google.com>
diff --git a/lmkd/lmkd.c b/lmkd/lmkd.c
index d438203..17ebb14 100644
--- a/lmkd/lmkd.c
+++ b/lmkd/lmkd.c
@@ -91,6 +91,7 @@
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 @@
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 @@
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 @@
(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);
// MCL_ONFAULT pins pages as they fault instead of loading