diff options
-rw-r--r-- | mm/oom_kill.c | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/mm/oom_kill.c b/mm/oom_kill.c index 4395f371bc7c..7dcca55ede7c 100644 --- a/mm/oom_kill.c +++ b/mm/oom_kill.c | |||
@@ -404,16 +404,40 @@ static void dump_header(struct task_struct *p, gfp_t gfp_mask, int order, | |||
404 | #define K(x) ((x) << (PAGE_SHIFT-10)) | 404 | #define K(x) ((x) << (PAGE_SHIFT-10)) |
405 | static int oom_kill_task(struct task_struct *p, struct mem_cgroup *mem) | 405 | static int oom_kill_task(struct task_struct *p, struct mem_cgroup *mem) |
406 | { | 406 | { |
407 | struct task_struct *q; | ||
408 | struct mm_struct *mm; | ||
409 | |||
407 | p = find_lock_task_mm(p); | 410 | p = find_lock_task_mm(p); |
408 | if (!p) | 411 | if (!p) |
409 | return 1; | 412 | return 1; |
410 | 413 | ||
414 | /* mm cannot be safely dereferenced after task_unlock(p) */ | ||
415 | mm = p->mm; | ||
416 | |||
411 | pr_err("Killed process %d (%s) total-vm:%lukB, anon-rss:%lukB, file-rss:%lukB\n", | 417 | pr_err("Killed process %d (%s) total-vm:%lukB, anon-rss:%lukB, file-rss:%lukB\n", |
412 | task_pid_nr(p), p->comm, K(p->mm->total_vm), | 418 | task_pid_nr(p), p->comm, K(p->mm->total_vm), |
413 | K(get_mm_counter(p->mm, MM_ANONPAGES)), | 419 | K(get_mm_counter(p->mm, MM_ANONPAGES)), |
414 | K(get_mm_counter(p->mm, MM_FILEPAGES))); | 420 | K(get_mm_counter(p->mm, MM_FILEPAGES))); |
415 | task_unlock(p); | 421 | task_unlock(p); |
416 | 422 | ||
423 | /* | ||
424 | * Kill all processes sharing p->mm in other thread groups, if any. | ||
425 | * They don't get access to memory reserves or a higher scheduler | ||
426 | * priority, though, to avoid depletion of all memory or task | ||
427 | * starvation. This prevents mm->mmap_sem livelock when an oom killed | ||
428 | * task cannot exit because it requires the semaphore and its contended | ||
429 | * by another thread trying to allocate memory itself. That thread will | ||
430 | * now get access to memory reserves since it has a pending fatal | ||
431 | * signal. | ||
432 | */ | ||
433 | for_each_process(q) | ||
434 | if (q->mm == mm && !same_thread_group(q, p)) { | ||
435 | task_lock(q); /* Protect ->comm from prctl() */ | ||
436 | pr_err("Kill process %d (%s) sharing same memory\n", | ||
437 | task_pid_nr(q), q->comm); | ||
438 | task_unlock(q); | ||
439 | force_sig(SIGKILL, q); | ||
440 | } | ||
417 | 441 | ||
418 | set_tsk_thread_flag(p, TIF_MEMDIE); | 442 | set_tsk_thread_flag(p, TIF_MEMDIE); |
419 | force_sig(SIGKILL, p); | 443 | force_sig(SIGKILL, p); |