diff options
author | Oleg Nesterov <oleg@redhat.com> | 2014-01-21 18:50:00 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-01-21 19:19:46 -0500 |
commit | ad96244179fbd55b40c00f10f399bc04739b8e1f (patch) | |
tree | 8bb173d243351b07f38cce9e6bb1b67db628222f | |
parent | 1da4db0cd5c8a31d4468ec906b413e75e604b465 (diff) |
oom_kill: has_intersects_mems_allowed() needs rcu_read_lock()
At least out_of_memory() calls has_intersects_mems_allowed() without
even rcu_read_lock(), this is obviously buggy.
Add the necessary rcu_read_lock(). This means that we can not simply
return from the loop, we need "bool ret" and "break".
While at it, swap the names of task_struct's (the argument and the
local). This cleans up the code a little bit and avoids the unnecessary
initialization.
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Reviewed-by: Sergey Dyasly <dserrg@gmail.com>
Tested-by: Sergey Dyasly <dserrg@gmail.com>
Reviewed-by: Sameer Nanda <snanda@chromium.org>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Mandeep Singh Baines <msb@chromium.org>
Cc: "Ma, Xindong" <xindong.ma@intel.com>
Reviewed-by: Michal Hocko <mhocko@suse.cz>
Cc: "Tu, Xiaobing" <xiaobing.tu@intel.com>
Acked-by: David Rientjes <rientjes@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | mm/oom_kill.c | 19 |
1 files changed, 11 insertions, 8 deletions
diff --git a/mm/oom_kill.c b/mm/oom_kill.c index 96d7945f75a6..0d8ad1ebd1d1 100644 --- a/mm/oom_kill.c +++ b/mm/oom_kill.c | |||
@@ -47,18 +47,20 @@ static DEFINE_SPINLOCK(zone_scan_lock); | |||
47 | #ifdef CONFIG_NUMA | 47 | #ifdef CONFIG_NUMA |
48 | /** | 48 | /** |
49 | * has_intersects_mems_allowed() - check task eligiblity for kill | 49 | * has_intersects_mems_allowed() - check task eligiblity for kill |
50 | * @tsk: task struct of which task to consider | 50 | * @start: task struct of which task to consider |
51 | * @mask: nodemask passed to page allocator for mempolicy ooms | 51 | * @mask: nodemask passed to page allocator for mempolicy ooms |
52 | * | 52 | * |
53 | * Task eligibility is determined by whether or not a candidate task, @tsk, | 53 | * Task eligibility is determined by whether or not a candidate task, @tsk, |
54 | * shares the same mempolicy nodes as current if it is bound by such a policy | 54 | * shares the same mempolicy nodes as current if it is bound by such a policy |
55 | * and whether or not it has the same set of allowed cpuset nodes. | 55 | * and whether or not it has the same set of allowed cpuset nodes. |
56 | */ | 56 | */ |
57 | static bool has_intersects_mems_allowed(struct task_struct *tsk, | 57 | static bool has_intersects_mems_allowed(struct task_struct *start, |
58 | const nodemask_t *mask) | 58 | const nodemask_t *mask) |
59 | { | 59 | { |
60 | struct task_struct *start = tsk; | 60 | struct task_struct *tsk; |
61 | bool ret = false; | ||
61 | 62 | ||
63 | rcu_read_lock(); | ||
62 | for_each_thread(start, tsk) { | 64 | for_each_thread(start, tsk) { |
63 | if (mask) { | 65 | if (mask) { |
64 | /* | 66 | /* |
@@ -67,19 +69,20 @@ static bool has_intersects_mems_allowed(struct task_struct *tsk, | |||
67 | * mempolicy intersects current, otherwise it may be | 69 | * mempolicy intersects current, otherwise it may be |
68 | * needlessly killed. | 70 | * needlessly killed. |
69 | */ | 71 | */ |
70 | if (mempolicy_nodemask_intersects(tsk, mask)) | 72 | ret = mempolicy_nodemask_intersects(tsk, mask); |
71 | return true; | ||
72 | } else { | 73 | } else { |
73 | /* | 74 | /* |
74 | * This is not a mempolicy constrained oom, so only | 75 | * This is not a mempolicy constrained oom, so only |
75 | * check the mems of tsk's cpuset. | 76 | * check the mems of tsk's cpuset. |
76 | */ | 77 | */ |
77 | if (cpuset_mems_allowed_intersects(current, tsk)) | 78 | ret = cpuset_mems_allowed_intersects(current, tsk); |
78 | return true; | ||
79 | } | 79 | } |
80 | if (ret) | ||
81 | break; | ||
80 | } | 82 | } |
83 | rcu_read_unlock(); | ||
81 | 84 | ||
82 | return false; | 85 | return ret; |
83 | } | 86 | } |
84 | #else | 87 | #else |
85 | static bool has_intersects_mems_allowed(struct task_struct *tsk, | 88 | static bool has_intersects_mems_allowed(struct task_struct *tsk, |