Commit dc1b83ab08f1954335692cdcd499f78c94f4c42a

Authored by Oleg Nesterov
Committed by Linus Torvalds
1 parent 5f40d42094

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>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 1 changed file with 8 additions and 3 deletions Side-by-side Diff

... ... @@ -458,10 +458,10 @@
458 458 struct mem_cgroup *mem, nodemask_t *nodemask,
459 459 const char *message)
460 460 {
461   - struct task_struct *victim = p;
  461 + struct task_struct *victim;
462 462 struct task_struct *child;
463   - struct task_struct *t = p;
464   - unsigned int victim_points = 0;
  463 + struct task_struct *t;
  464 + unsigned int victim_points;
465 465  
466 466 if (printk_ratelimit())
467 467 dump_header(p, gfp_mask, order, mem, nodemask);
468 468  
... ... @@ -487,10 +487,15 @@
487 487 * parent. This attempts to lose the minimal amount of work done while
488 488 * still freeing memory.
489 489 */
  490 + victim_points = oom_badness(p, mem, nodemask, totalpages);
  491 + victim = p;
  492 + t = p;
490 493 do {
491 494 list_for_each_entry(child, &t->children, sibling) {
492 495 unsigned int child_points;
493 496  
  497 + if (child->mm == t->mm)
  498 + continue;
494 499 /*
495 500 * oom_badness() returns 0 if the thread is unkillable
496 501 */