Commit bb8a4b7f authored by Michal Hocko's avatar Michal Hocko Committed by Linus Torvalds

mm, oom_reaper: hide oom reaped tasks from OOM killer more carefully

Commit 36324a99 ("oom: clear TIF_MEMDIE after oom_reaper managed to
unmap the address space") not only clears TIF_MEMDIE for oom reaped task
but also set OOM_SCORE_ADJ_MIN for the target task to hide it from the
oom killer.  This works in simple cases but it is not sufficient for
(unlikely) cases where the mm is shared between independent processes
(as they do not share signal struct).  If the mm had only small amount
of memory which could be reaped then another task sharing the mm could
be selected and that wouldn't help to move out from the oom situation.

Introduce MMF_OOM_REAPED mm flag which is checked in oom_badness (same
as OOM_SCORE_ADJ_MIN) and task is skipped if the flag is set.  Set the
flag after __oom_reap_task is done with a task.  This will force the
select_bad_process() to ignore all already oom reaped tasks as well as
no such task is sacrificed for its parent.
Signed-off-by: default avatarMichal Hocko <mhocko@suse.com>
Cc: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Cc: David Rientjes <rientjes@google.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 31e49bfd
...@@ -521,6 +521,7 @@ static inline int get_dumpable(struct mm_struct *mm) ...@@ -521,6 +521,7 @@ static inline int get_dumpable(struct mm_struct *mm)
#define MMF_HAS_UPROBES 19 /* has uprobes */ #define MMF_HAS_UPROBES 19 /* has uprobes */
#define MMF_RECALC_UPROBES 20 /* MMF_HAS_UPROBES can be wrong */ #define MMF_RECALC_UPROBES 20 /* MMF_HAS_UPROBES can be wrong */
#define MMF_OOM_REAPED 21 /* mm has been already reaped */
#define MMF_INIT_MASK (MMF_DUMPABLE_MASK | MMF_DUMP_FILTER_MASK) #define MMF_INIT_MASK (MMF_DUMPABLE_MASK | MMF_DUMP_FILTER_MASK)
......
...@@ -174,8 +174,13 @@ unsigned long oom_badness(struct task_struct *p, struct mem_cgroup *memcg, ...@@ -174,8 +174,13 @@ unsigned long oom_badness(struct task_struct *p, struct mem_cgroup *memcg,
if (!p) if (!p)
return 0; return 0;
/*
* Do not even consider tasks which are explicitly marked oom
* unkillable or have been already oom reaped.
*/
adj = (long)p->signal->oom_score_adj; adj = (long)p->signal->oom_score_adj;
if (adj == OOM_SCORE_ADJ_MIN) { if (adj == OOM_SCORE_ADJ_MIN ||
test_bit(MMF_OOM_REAPED, &p->mm->flags)) {
task_unlock(p); task_unlock(p);
return 0; return 0;
} }
...@@ -513,7 +518,7 @@ static bool __oom_reap_task(struct task_struct *tsk) ...@@ -513,7 +518,7 @@ static bool __oom_reap_task(struct task_struct *tsk)
* This task can be safely ignored because we cannot do much more * This task can be safely ignored because we cannot do much more
* to release its memory. * to release its memory.
*/ */
tsk->signal->oom_score_adj = OOM_SCORE_ADJ_MIN; set_bit(MMF_OOM_REAPED, &mm->flags);
out: out:
mmput(mm); mmput(mm);
return ret; return ret;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment