linux-stable/include/linux/sched
Andrea Arcangeli 2129258024 mm: oom: let oom_reap_task and exit_mmap run concurrently
This is purely required because exit_aio() may block and exit_mmap() may
never start, if the oom_reap_task cannot start running on a mm with
mm_users == 0.

At the same time if the OOM reaper doesn't wait at all for the memory of
the current OOM candidate to be freed by exit_mmap->unmap_vmas, it would
generate a spurious OOM kill.

If it wasn't because of the exit_aio or similar blocking functions in
the last mmput, it would be enough to change the oom_reap_task() in the
case it finds mm_users == 0, to wait for a timeout or to wait for
__mmput to set MMF_OOM_SKIP itself, but it's not just exit_mmap the
problem here so the concurrency of exit_mmap and oom_reap_task is
apparently warranted.

It's a non standard runtime, exit_mmap() runs without mmap_sem, and
oom_reap_task runs with the mmap_sem for reading as usual (kind of
MADV_DONTNEED).

The race between the two is solved with a combination of
tsk_is_oom_victim() (serialized by task_lock) and MMF_OOM_SKIP
(serialized by a dummy down_write/up_write cycle on the same lines of
the ksm_exit method).

If the oom_reap_task() may be running concurrently during exit_mmap,
exit_mmap will wait it to finish in down_write (before taking down mm
structures that would make the oom_reap_task fail with use after free).

If exit_mmap comes first, oom_reap_task() will skip the mm if
MMF_OOM_SKIP is already set and in turn all memory is already freed and
furthermore the mm data structures may already have been taken down by
free_pgtables.

[aarcange@redhat.com: incremental one liner]
  Link: http://lkml.kernel.org/r/20170726164319.GC29716@redhat.com
[rientjes@google.com: remove unused mmput_async]
  Link: http://lkml.kernel.org/r/alpine.DEB.2.10.1708141733130.50317@chino.kir.corp.google.com
[aarcange@redhat.com: microoptimization]
  Link: http://lkml.kernel.org/r/20170817171240.GB5066@redhat.com
Link: http://lkml.kernel.org/r/20170726162912.GA29716@redhat.com
Fixes: 26db62f179 ("oom: keep mm of the killed task available")
Signed-off-by: Andrea Arcangeli <aarcange@redhat.com>
Signed-off-by: David Rientjes <rientjes@google.com>
Reported-by: David Rientjes <rientjes@google.com>
Tested-by: David Rientjes <rientjes@google.com>
Reviewed-by: Michal Hocko <mhocko@suse.com>
Cc: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Hugh Dickins <hughd@google.com>
Cc: "Kirill A. Shutemov" <kirill@shutemov.name>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2017-09-06 17:27:30 -07:00
..
autogroup.h sched/headers: Remove <linux/sched.h> from <linux/sched/autogroup.h> 2017-03-03 01:45:29 +01:00
clock.h sched/clock: Use late_initcall() instead of sched_init_smp() 2017-05-15 10:15:21 +02:00
coredump.h mm: make PR_SET_THP_DISABLE immediately active 2017-07-10 16:32:31 -07:00
cpufreq.h sched/headers: Remove <linux/sched.h> from <linux/sched/cpufreq.h> 2017-03-03 01:45:32 +01:00
cputime.h sched/headers: Move cputime functionality from <linux/sched.h> and <linux/cputime.h> into <linux/sched/cputime.h> 2017-03-03 01:45:22 +01:00
deadline.h
debug.h sched/debug: Use task_pid_nr_ns in /proc/$pid/sched 2017-08-10 12:18:19 +02:00
hotplug.h sched/headers: Remove <linux/sched.h> from <linux/sched/hotplug.h> 2017-03-03 01:45:35 +01:00
idle.h sched/headers: Remove tsk_is_polling() 2017-03-03 01:45:27 +01:00
init.h sched/headers: Remove <linux/sched.h> from <linux/sched/init.h> 2017-03-03 01:45:38 +01:00
jobctl.h sched/headers: Move the JOBCTL_ defines and methods from <linux/sched.h> to <linux/sched/jobctl.h> 2017-03-03 01:43:41 +01:00
loadavg.h sched/headers: Remove <linux/sched.h> from <linux/sched/loadavg.h> 2017-03-03 01:45:28 +01:00
mm.h mm: oom: let oom_reap_task and exit_mmap run concurrently 2017-09-06 17:27:30 -07:00
nohz.h MAINTAINERS: Add Frederic Weisbecker as nohz/dyntics maintainer 2017-07-05 16:26:37 +02:00
numa_balancing.h sched/headers: Move the NUMA balancing interfaces from <linux/sched.h> to <linux/sched/numa_balancing.h> 2017-03-03 01:43:40 +01:00
prio.h
rt.h sched/rtmutex: Refactor rt_mutex_setprio() 2017-04-04 11:44:06 +02:00
signal.h randstruct: Mark various structs for randomization 2017-06-30 12:00:51 -07:00
stat.h sched/headers: Remove <linux/sched.h> from <linux/sched/stat.h> 2017-03-03 01:45:34 +01:00
sysctl.h
task.h sched/core: Remove unnecessary initialization init_idle_bootup_task() 2017-08-10 12:18:18 +02:00
task_stack.h sched/headers: Move kstack_end() from <linux/sched.h> to <linux/sched/task_stack.h> 2017-03-03 01:45:24 +01:00
topology.h sched/fair: Fix wake_affine() for !NUMA_BALANCING 2017-08-10 13:25:14 +02:00
user.h sched/headers: Remove <linux/sched.h> from <linux/sched/user.h> 2017-03-03 01:45:30 +01:00
wake_q.h
xacct.h sched/headers: Move CONFIG_TASK_XACCT bits from <linux/sched.h> to <linux/sched/xacct.h> 2017-03-03 01:43:41 +01:00