ANDROID: mm, oom: Avoid killing tasks with negative ADJ scores

Only kill a task with a negative ADJ score if there are no tasks with
non-negative ADJ scores.  Otherwise, kill the task with the most
badness points whose ADJ score is also positive, if such a suitable
task exists.

Bug: 173837271
Signed-off-by: Chris Goldsworthy <cgoldswo@codeaurora.org>
Change-Id: I70fe48a3eeb853085bb1acfb422f88cd36d1f14d
This commit is contained in:
Chris Goldsworthy
2021-01-05 14:57:00 -08:00
committed by Suren Baghdasaryan
parent f9ebdfbf70
commit 91ce4829f6
2 changed files with 38 additions and 1 deletions

View File

@@ -339,7 +339,24 @@ static int oom_evaluate_task(struct task_struct *task, void *arg)
}
points = oom_badness(task, oc->totalpages);
if (points == LONG_MIN || points < oc->chosen_points)
if (points == LONG_MIN)
goto next;
/*
* Check to see if this is the worst task with a non-negative
* ADJ score seen so far
*/
if (task->signal->oom_score_adj >= 0 &&
points > oc->chosen_non_negative_adj_points) {
if (oc->chosen_non_negative_adj)
put_task_struct(oc->chosen_non_negative_adj);
get_task_struct(task);
oc->chosen_non_negative_adj = task;
oc->chosen_non_negative_adj_points = points;
}
if (points < oc->chosen_points)
goto next;
select:
@@ -351,6 +368,8 @@ select:
next:
return 0;
abort:
if (oc->chosen_non_negative_adj)
put_task_struct(oc->chosen_non_negative_adj);
if (oc->chosen)
put_task_struct(oc->chosen);
oc->chosen = (void *)-1UL;
@@ -364,6 +383,8 @@ abort:
static void select_bad_process(struct oom_control *oc)
{
oc->chosen_points = LONG_MIN;
oc->chosen_non_negative_adj_points = LONG_MIN;
oc->chosen_non_negative_adj = NULL;
if (is_memcg_oom(oc))
mem_cgroup_scan_tasks(oc->memcg, oom_evaluate_task, oc);
@@ -376,6 +397,20 @@ static void select_bad_process(struct oom_control *oc)
break;
rcu_read_unlock();
}
if (oc->chosen_non_negative_adj) {
/*
* If oc->chosen has a negative ADJ, and we found a task with
* a postive ADJ to kill, kill the task with the positive ADJ
* instead.
*/
if (oc->chosen && oc->chosen->signal->oom_score_adj < 0) {
put_task_struct(oc->chosen);
oc->chosen = oc->chosen_non_negative_adj;
oc->chosen_points = oc->chosen_non_negative_adj_points;
} else
put_task_struct(oc->chosen_non_negative_adj);
}
}
static int dump_task(struct task_struct *p, void *arg)