linux/kernel/power
Michal Hocko 7407054209 oom, suspend: fix oom_reaper vs. oom_killer_disable race
Tetsuo has reported the following potential oom_killer_disable vs.
oom_reaper race:

 (1) freeze_processes() starts freezing user space threads.
 (2) Somebody (maybe a kenrel thread) calls out_of_memory().
 (3) The OOM killer calls mark_oom_victim() on a user space thread
     P1 which is already in __refrigerator().
 (4) oom_killer_disable() sets oom_killer_disabled = true.
 (5) P1 leaves __refrigerator() and enters do_exit().
 (6) The OOM reaper calls exit_oom_victim(P1) before P1 can call
     exit_oom_victim(P1).
 (7) oom_killer_disable() returns while P1 not yet finished
 (8) P1 perform IO/interfere with the freezer.

This situation is unfortunate.  We cannot move oom_killer_disable after
all the freezable kernel threads are frozen because the oom victim might
depend on some of those kthreads to make a forward progress to exit so
we could deadlock.  It is also far from trivial to teach the oom_reaper
to not call exit_oom_victim() because then we would lose a guarantee of
the OOM killer and oom_killer_disable forward progress because
exit_mm->mmput might block and never call exit_oom_victim.

It seems the easiest way forward is to workaround this race by calling
try_to_freeze_tasks again after oom_killer_disable.  This will make sure
that all the tasks are frozen or it bails out.

Fixes: 449d777d7a ("mm, oom_reaper: clear TIF_MEMDIE for all tasks queued for oom_reaper")
Link: http://lkml.kernel.org/r/1466597634-16199-1-git-send-email-mhocko@kernel.org
Signed-off-by: Michal Hocko <mhocko@suse.com>
Reported-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2016-06-24 17:23:52 -07:00
..
Kconfig PM: APM_EMULATION does not depend on PM 2016-01-27 23:20:14 +01:00
Makefile suspend: simplify block I/O handling 2015-05-19 09:19:59 -06:00
autosleep.c PM / Sleep: avoid 'autosleep' in shutdown progress 2013-07-15 01:31:37 +02:00
console.c arm, pm, vmpressure: add missing slab.h includes 2014-02-03 13:24:01 -05:00
hibernate.c Merge branches 'pm-avs', 'pm-clk', 'pm-devfreq' and 'pm-sleep' 2016-03-25 00:58:18 +01:00
main.c PM / sleep: Add support for read-only sysfs attributes 2016-01-04 22:28:59 +01:00
power.h PM / sleep: Add support for read-only sysfs attributes 2016-01-04 22:28:59 +01:00
poweroff.c power/sysrq: fix inconstistent help message of sysrq key 2013-04-30 17:04:10 -07:00
process.c oom, suspend: fix oom_reaper vs. oom_killer_disable race 2016-06-24 17:23:52 -07:00
qos.c PM / QoS: Add debugfs support to view the list of constraints 2015-01-23 22:16:21 +01:00
snapshot.c mm, page_alloc: distinguish between being unable to sleep, unwilling to sleep and avoiding waking kswapd 2015-11-06 17:50:42 -08:00
suspend.c kernel/...: convert pr_warning to pr_warn 2016-03-22 15:36:02 -07:00
suspend_test.c PM / sleep: Enhance test_suspend option with repeat capability 2014-09-09 01:48:02 +02:00
swap.c PM / Hibernate: Call flush_icache_range() on pages restored in-place 2016-04-28 13:35:48 +01:00
user.c PM / hibernate: introduce "nohibernate" boot parameter 2014-06-16 23:29:39 +02:00
wakelock.c PM / autosleep: Use workqueue for user space wakeup sources garbage collector 2015-07-14 21:04:48 +02:00