From 6c1efde3d979f368e1409120515417f378142b73 Mon Sep 17 00:00:00 2001 From: Patrick Daly Date: Wed, 16 Oct 2019 15:27:37 -0700 Subject: [PATCH] mm/oom-kill: Adjust oom_badness per Android expectations Allow selecting only tasks with oom_score_adj >= 0. Change-Id: Iebbb487c711da98b8fcb367ba838b5fe0b260d4f Signed-off-by: Patrick Daly Signed-off-by: Richard Raya --- fs/proc/base.c | 2 +- include/linux/oom.h | 8 +++++++- mm/oom_kill.c | 10 +++++++--- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/fs/proc/base.c b/fs/proc/base.c index d1ff027dbc99..14aebb53d078 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -515,7 +515,7 @@ static int proc_oom_score(struct seq_file *m, struct pid_namespace *ns, unsigned long totalpages = totalram_pages + total_swap_pages; unsigned long points = 0; - points = oom_badness(task, NULL, NULL, totalpages) * + points = oom_badness(task, NULL, NULL, totalpages, true) * 1000 / totalpages; seq_printf(m, "%lu\n", points); diff --git a/include/linux/oom.h b/include/linux/oom.h index a6fb1e835c85..d033eecd2a84 100644 --- a/include/linux/oom.h +++ b/include/linux/oom.h @@ -38,6 +38,12 @@ struct oom_control { */ const int order; + /* + * Only kill positive adj tasks. Used to behave more like Android's + * lowmemorykiller. + */ + const bool only_positive_adj; + /* Used by oom implementation, do not set */ unsigned long totalpages; struct task_struct *chosen; @@ -104,7 +110,7 @@ bool __oom_reap_task_mm(struct mm_struct *mm); extern unsigned long oom_badness(struct task_struct *p, struct mem_cgroup *memcg, const nodemask_t *nodemask, - unsigned long totalpages); + unsigned long totalpages, bool only_positive_adj); extern bool out_of_memory(struct oom_control *oc); diff --git a/mm/oom_kill.c b/mm/oom_kill.c index 4c17d9ac7010..ead741ce7291 100644 --- a/mm/oom_kill.c +++ b/mm/oom_kill.c @@ -176,7 +176,8 @@ static bool oom_unkillable_task(struct task_struct *p, * task consuming the most memory to avoid subsequent oom failures. */ unsigned long oom_badness(struct task_struct *p, struct mem_cgroup *memcg, - const nodemask_t *nodemask, unsigned long totalpages) + const nodemask_t *nodemask, unsigned long totalpages, + bool only_positive_adj) { long points; long adj; @@ -195,6 +196,7 @@ unsigned long oom_badness(struct task_struct *p, struct mem_cgroup *memcg, */ adj = (long)p->signal->oom_score_adj; if (adj == OOM_SCORE_ADJ_MIN || + (only_positive_adj && adj < 0) || test_bit(MMF_OOM_SKIP, &p->mm->flags) || in_vfork(p)) { task_unlock(p); @@ -316,7 +318,8 @@ static int oom_evaluate_task(struct task_struct *task, void *arg) goto select; } - points = oom_badness(task, NULL, oc->nodemask, oc->totalpages); + points = oom_badness(task, NULL, oc->nodemask, oc->totalpages, + oc->only_positive_adj); if (!points || points < oc->chosen_points) goto next; @@ -876,7 +879,8 @@ static void oom_kill_process(struct oom_control *oc, const char *message) * oom_badness() returns 0 if the thread is unkillable */ child_points = oom_badness(child, - oc->memcg, oc->nodemask, oc->totalpages); + oc->memcg, oc->nodemask, oc->totalpages, + oc->only_positive_adj); if (child_points > victim_points) { put_task_struct(victim); victim = child;