diff options
author | Michal Hocko <mhocko@suse.com> | 2016-06-03 14:55:55 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-06-03 16:02:56 -0700 |
commit | cbdcf7f78900625de35173961b9b95cde22bce45 (patch) | |
tree | 313e8398a476f95583156893e8459c3f3592201a /mm | |
parent | 83b9355bf6f449c7d1231206c300ea89d3313a9d (diff) | |
download | linux-stable-cbdcf7f78900625de35173961b9b95cde22bce45.tar.gz linux-stable-cbdcf7f78900625de35173961b9b95cde22bce45.tar.bz2 linux-stable-cbdcf7f78900625de35173961b9b95cde22bce45.zip |
mm, oom_reaper: do not use siglock in try_oom_reaper()
Oleg has noted that siglock usage in try_oom_reaper is both pointless
and dangerous. signal_group_exit can be checked lockless. The problem
is that sighand becomes NULL in __exit_signal so we can crash.
Fixes: 3ef22dfff239 ("oom, oom_reaper: try to reap tasks which skip regular OOM killer path")
Link: http://lkml.kernel.org/r/1464679423-30218-1-git-send-email-mhocko@kernel.org
Signed-off-by: Michal Hocko <mhocko@suse.com>
Suggested-by: Oleg Nesterov <oleg@redhat.com>
Cc: Tetsuo Handa <penguin-kernel@i-love.sakura.ne.jp>
Cc: David Rientjes <rientjes@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm')
-rw-r--r-- | mm/oom_kill.c | 7 |
1 files changed, 1 insertions, 6 deletions
diff --git a/mm/oom_kill.c b/mm/oom_kill.c index dfb1ab61fb23..acbc432d1a52 100644 --- a/mm/oom_kill.c +++ b/mm/oom_kill.c @@ -625,8 +625,6 @@ void try_oom_reaper(struct task_struct *tsk) if (atomic_read(&mm->mm_users) > 1) { rcu_read_lock(); for_each_process(p) { - bool exiting; - if (!process_shares_mm(p, mm)) continue; if (fatal_signal_pending(p)) @@ -636,10 +634,7 @@ void try_oom_reaper(struct task_struct *tsk) * If the task is exiting make sure the whole thread group * is exiting and cannot acces mm anymore. */ - spin_lock_irq(&p->sighand->siglock); - exiting = signal_group_exit(p->signal); - spin_unlock_irq(&p->sighand->siglock); - if (exiting) + if (signal_group_exit(p->signal)) continue; /* Give up */ |