diff options
Diffstat (limited to 'mm/oom_kill.c')
-rw-r--r-- | mm/oom_kill.c | 81 |
1 files changed, 42 insertions, 39 deletions
diff --git a/mm/oom_kill.c b/mm/oom_kill.c index 40ba05061a4f..a7b2460e922b 100644 --- a/mm/oom_kill.c +++ b/mm/oom_kill.c | |||
@@ -55,7 +55,7 @@ static DEFINE_SPINLOCK(zone_scan_lock); | |||
55 | 55 | ||
56 | unsigned long badness(struct task_struct *p, unsigned long uptime) | 56 | unsigned long badness(struct task_struct *p, unsigned long uptime) |
57 | { | 57 | { |
58 | unsigned long points, cpu_time, run_time, s; | 58 | unsigned long points, cpu_time, run_time; |
59 | struct mm_struct *mm; | 59 | struct mm_struct *mm; |
60 | struct task_struct *child; | 60 | struct task_struct *child; |
61 | 61 | ||
@@ -110,12 +110,10 @@ unsigned long badness(struct task_struct *p, unsigned long uptime) | |||
110 | else | 110 | else |
111 | run_time = 0; | 111 | run_time = 0; |
112 | 112 | ||
113 | s = int_sqrt(cpu_time); | 113 | if (cpu_time) |
114 | if (s) | 114 | points /= int_sqrt(cpu_time); |
115 | points /= s; | 115 | if (run_time) |
116 | s = int_sqrt(int_sqrt(run_time)); | 116 | points /= int_sqrt(int_sqrt(run_time)); |
117 | if (s) | ||
118 | points /= s; | ||
119 | 117 | ||
120 | /* | 118 | /* |
121 | * Niced processes are most likely less important, so double | 119 | * Niced processes are most likely less important, so double |
@@ -286,22 +284,28 @@ static void dump_tasks(const struct mem_cgroup *mem) | |||
286 | printk(KERN_INFO "[ pid ] uid tgid total_vm rss cpu oom_adj " | 284 | printk(KERN_INFO "[ pid ] uid tgid total_vm rss cpu oom_adj " |
287 | "name\n"); | 285 | "name\n"); |
288 | do_each_thread(g, p) { | 286 | do_each_thread(g, p) { |
289 | /* | 287 | struct mm_struct *mm; |
290 | * total_vm and rss sizes do not exist for tasks with a | 288 | |
291 | * detached mm so there's no need to report them. | ||
292 | */ | ||
293 | if (!p->mm) | ||
294 | continue; | ||
295 | if (mem && !task_in_mem_cgroup(p, mem)) | 289 | if (mem && !task_in_mem_cgroup(p, mem)) |
296 | continue; | 290 | continue; |
297 | if (!thread_group_leader(p)) | 291 | if (!thread_group_leader(p)) |
298 | continue; | 292 | continue; |
299 | 293 | ||
300 | task_lock(p); | 294 | task_lock(p); |
295 | mm = p->mm; | ||
296 | if (!mm) { | ||
297 | /* | ||
298 | * total_vm and rss sizes do not exist for tasks with no | ||
299 | * mm so there's no need to report them; they can't be | ||
300 | * oom killed anyway. | ||
301 | */ | ||
302 | task_unlock(p); | ||
303 | continue; | ||
304 | } | ||
301 | printk(KERN_INFO "[%5d] %5d %5d %8lu %8lu %3d %3d %s\n", | 305 | printk(KERN_INFO "[%5d] %5d %5d %8lu %8lu %3d %3d %s\n", |
302 | p->pid, __task_cred(p)->uid, p->tgid, | 306 | p->pid, __task_cred(p)->uid, p->tgid, mm->total_vm, |
303 | p->mm->total_vm, get_mm_rss(p->mm), (int)task_cpu(p), | 307 | get_mm_rss(mm), (int)task_cpu(p), p->oomkilladj, |
304 | p->oomkilladj, p->comm); | 308 | p->comm); |
305 | task_unlock(p); | 309 | task_unlock(p); |
306 | } while_each_thread(g, p); | 310 | } while_each_thread(g, p); |
307 | } | 311 | } |
@@ -396,6 +400,7 @@ static int oom_kill_process(struct task_struct *p, gfp_t gfp_mask, int order, | |||
396 | cpuset_print_task_mems_allowed(current); | 400 | cpuset_print_task_mems_allowed(current); |
397 | task_unlock(current); | 401 | task_unlock(current); |
398 | dump_stack(); | 402 | dump_stack(); |
403 | mem_cgroup_print_oom_info(mem, current); | ||
399 | show_mem(); | 404 | show_mem(); |
400 | if (sysctl_oom_dump_tasks) | 405 | if (sysctl_oom_dump_tasks) |
401 | dump_tasks(mem); | 406 | dump_tasks(mem); |
@@ -515,34 +520,32 @@ void clear_zonelist_oom(struct zonelist *zonelist, gfp_t gfp_mask) | |||
515 | */ | 520 | */ |
516 | static void __out_of_memory(gfp_t gfp_mask, int order) | 521 | static void __out_of_memory(gfp_t gfp_mask, int order) |
517 | { | 522 | { |
518 | if (sysctl_oom_kill_allocating_task) { | 523 | struct task_struct *p; |
519 | oom_kill_process(current, gfp_mask, order, 0, NULL, | 524 | unsigned long points; |
520 | "Out of memory (oom_kill_allocating_task)"); | ||
521 | |||
522 | } else { | ||
523 | unsigned long points; | ||
524 | struct task_struct *p; | ||
525 | |||
526 | retry: | ||
527 | /* | ||
528 | * Rambo mode: Shoot down a process and hope it solves whatever | ||
529 | * issues we may have. | ||
530 | */ | ||
531 | p = select_bad_process(&points, NULL); | ||
532 | 525 | ||
533 | if (PTR_ERR(p) == -1UL) | 526 | if (sysctl_oom_kill_allocating_task) |
527 | if (!oom_kill_process(current, gfp_mask, order, 0, NULL, | ||
528 | "Out of memory (oom_kill_allocating_task)")) | ||
534 | return; | 529 | return; |
530 | retry: | ||
531 | /* | ||
532 | * Rambo mode: Shoot down a process and hope it solves whatever | ||
533 | * issues we may have. | ||
534 | */ | ||
535 | p = select_bad_process(&points, NULL); | ||
535 | 536 | ||
536 | /* Found nothing?!?! Either we hang forever, or we panic. */ | 537 | if (PTR_ERR(p) == -1UL) |
537 | if (!p) { | 538 | return; |
538 | read_unlock(&tasklist_lock); | ||
539 | panic("Out of memory and no killable processes...\n"); | ||
540 | } | ||
541 | 539 | ||
542 | if (oom_kill_process(p, gfp_mask, order, points, NULL, | 540 | /* Found nothing?!?! Either we hang forever, or we panic. */ |
543 | "Out of memory")) | 541 | if (!p) { |
544 | goto retry; | 542 | read_unlock(&tasklist_lock); |
543 | panic("Out of memory and no killable processes...\n"); | ||
545 | } | 544 | } |
545 | |||
546 | if (oom_kill_process(p, gfp_mask, order, points, NULL, | ||
547 | "Out of memory")) | ||
548 | goto retry; | ||
546 | } | 549 | } |
547 | 550 | ||
548 | /* | 551 | /* |