Files
linux/include/linux
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
..
2017-08-28 15:26:48 +02:00
2017-07-03 01:43:45 -07:00
2017-06-08 18:52:36 -07:00
2017-02-10 15:52:24 -05:00
2017-07-17 17:26:14 +02:00
2017-07-06 16:24:33 -07:00
2017-01-25 13:17:47 -05:00
2017-07-01 16:15:13 -07:00
2017-07-03 02:22:52 -07:00
2017-07-03 16:56:28 -06:00
2017-05-24 12:43:30 -04:00
2017-06-05 16:59:12 +02:00
2017-04-18 20:41:12 +02:00
2017-08-31 17:32:38 -04:00
2017-06-22 15:43:47 +01:00
2017-09-04 00:05:22 +02:00
2017-09-04 00:06:02 +02:00
2017-08-10 12:28:57 +02:00
2017-06-09 11:52:07 +02:00
2017-08-24 13:23:03 -07:00
2017-07-17 13:42:48 +02:00
2017-04-27 05:13:04 -04:00
2017-07-07 20:09:10 -04:00
2017-06-05 16:59:10 +02:00
2017-03-21 10:15:47 +02:00
2017-05-18 10:07:41 -04:00
2017-05-18 10:07:40 -04:00
2017-06-21 14:37:12 -04:00
2017-07-10 16:32:34 -07:00
2017-07-31 22:01:21 -07:00
2017-08-14 13:33:39 -07:00
2017-05-03 15:52:10 -07:00
2017-02-24 17:46:57 -08:00
2017-08-28 20:51:22 +02:00
2017-08-18 15:32:01 -07:00
2017-09-06 17:27:29 -07:00
2017-09-06 17:27:24 -07:00
2017-04-24 14:30:46 -04:00
2017-07-13 16:00:15 -04:00
2017-07-06 11:30:07 -04:00
2017-07-25 18:05:25 +02:00
2017-05-26 10:10:37 +02:00
2017-09-06 17:27:26 -07:00
2017-08-21 12:47:31 -07:00
2017-08-16 16:28:47 -07:00
2017-02-13 21:44:09 -05:00
2017-06-29 10:48:57 +01:00
2017-05-03 15:52:10 -07:00
2017-07-12 23:11:23 +02:00
2017-06-08 10:35:49 +02:00
2017-07-06 16:24:30 -07:00
2017-08-16 16:28:47 -07:00
2017-06-15 12:12:40 -04:00
2017-06-08 18:52:42 -07:00
2017-06-01 14:53:04 -04:00
2017-03-09 15:42:33 +01:00
2017-08-28 16:15:42 +02:00
2017-07-24 17:50:37 +02:00
2017-05-09 16:43:22 +03:00
2017-08-31 18:50:14 +02:00
2017-08-18 15:32:01 -07:00