Messages in this thread Patch in this message | | | Date | Mon, 14 Mar 2011 20:05:30 +0100 | From | Oleg Nesterov <> | Subject | [PATCH 3/3 for 2.6.38] oom: oom_kill_process: fix the child_points logic |
| |
oom_kill_process() starts with victim_points == 0. This means that (most likely) any child has more points and can be killed erroneously.
Also, "children has a different mm" doesn't match the reality, we should check child->mm != t->mm. This check is not exactly correct if t->mm == NULL but this doesn't really matter, oom_kill_task() will kill them anyway.
Note: "Kill all processes sharing p->mm" in oom_kill_task() is wrong too.
Signed-off-by: Oleg Nesterov <oleg@redhat.com> ---
mm/oom_kill.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- 38/mm/oom_kill.c~3_fix_kill_chld 2011-03-14 18:52:39.000000000 +0100 +++ 38/mm/oom_kill.c 2011-03-14 19:36:01.000000000 +0100 @@ -459,10 +459,10 @@ static int oom_kill_process(struct task_ struct mem_cgroup *mem, nodemask_t *nodemask, const char *message) { - struct task_struct *victim = p; + struct task_struct *victim; struct task_struct *child; - struct task_struct *t = p; - unsigned int victim_points = 0; + struct task_struct *t; + unsigned int victim_points; if (printk_ratelimit()) dump_header(p, gfp_mask, order, mem, nodemask); @@ -488,10 +488,15 @@ static int oom_kill_process(struct task_ * parent. This attempts to lose the minimal amount of work done while * still freeing memory. */ + victim_points = oom_badness(p, mem, nodemask, totalpages); + victim = p; + t = p; do { list_for_each_entry(child, &t->children, sibling) { unsigned int child_points; + if (child->mm == t->mm) + continue; /* * oom_badness() returns 0 if the thread is unkillable */
| |