diff options
Diffstat (limited to 'mm/oom_kill.c')
-rw-r--r-- | mm/oom_kill.c | 49 |
1 files changed, 26 insertions, 23 deletions
diff --git a/mm/oom_kill.c b/mm/oom_kill.c index fc81cb22869e..4029583a1024 100644 --- a/mm/oom_kill.c +++ b/mm/oom_kill.c | |||
@@ -121,8 +121,8 @@ struct task_struct *find_lock_task_mm(struct task_struct *p) | |||
121 | } | 121 | } |
122 | 122 | ||
123 | /* return true if the task is not adequate as candidate victim task. */ | 123 | /* return true if the task is not adequate as candidate victim task. */ |
124 | static bool oom_unkillable_task(struct task_struct *p, struct mem_cgroup *mem, | 124 | static bool oom_unkillable_task(struct task_struct *p, |
125 | const nodemask_t *nodemask) | 125 | const struct mem_cgroup *mem, const nodemask_t *nodemask) |
126 | { | 126 | { |
127 | if (is_global_init(p)) | 127 | if (is_global_init(p)) |
128 | return true; | 128 | return true; |
@@ -208,8 +208,13 @@ unsigned int oom_badness(struct task_struct *p, struct mem_cgroup *mem, | |||
208 | */ | 208 | */ |
209 | points += p->signal->oom_score_adj; | 209 | points += p->signal->oom_score_adj; |
210 | 210 | ||
211 | if (points < 0) | 211 | /* |
212 | return 0; | 212 | * Never return 0 for an eligible task that may be killed since it's |
213 | * possible that no single user task uses more than 0.1% of memory and | ||
214 | * no single admin tasks uses more than 3.0%. | ||
215 | */ | ||
216 | if (points <= 0) | ||
217 | return 1; | ||
213 | return (points < 1000) ? points : 1000; | 218 | return (points < 1000) ? points : 1000; |
214 | } | 219 | } |
215 | 220 | ||
@@ -339,26 +344,24 @@ static struct task_struct *select_bad_process(unsigned int *ppoints, | |||
339 | /** | 344 | /** |
340 | * dump_tasks - dump current memory state of all system tasks | 345 | * dump_tasks - dump current memory state of all system tasks |
341 | * @mem: current's memory controller, if constrained | 346 | * @mem: current's memory controller, if constrained |
347 | * @nodemask: nodemask passed to page allocator for mempolicy ooms | ||
342 | * | 348 | * |
343 | * Dumps the current memory state of all system tasks, excluding kernel threads. | 349 | * Dumps the current memory state of all eligible tasks. Tasks not in the same |
350 | * memcg, not in the same cpuset, or bound to a disjoint set of mempolicy nodes | ||
351 | * are not shown. | ||
344 | * State information includes task's pid, uid, tgid, vm size, rss, cpu, oom_adj | 352 | * State information includes task's pid, uid, tgid, vm size, rss, cpu, oom_adj |
345 | * value, oom_score_adj value, and name. | 353 | * value, oom_score_adj value, and name. |
346 | * | 354 | * |
347 | * If the actual is non-NULL, only tasks that are a member of the mem_cgroup are | ||
348 | * shown. | ||
349 | * | ||
350 | * Call with tasklist_lock read-locked. | 355 | * Call with tasklist_lock read-locked. |
351 | */ | 356 | */ |
352 | static void dump_tasks(const struct mem_cgroup *mem) | 357 | static void dump_tasks(const struct mem_cgroup *mem, const nodemask_t *nodemask) |
353 | { | 358 | { |
354 | struct task_struct *p; | 359 | struct task_struct *p; |
355 | struct task_struct *task; | 360 | struct task_struct *task; |
356 | 361 | ||
357 | pr_info("[ pid ] uid tgid total_vm rss cpu oom_adj oom_score_adj name\n"); | 362 | pr_info("[ pid ] uid tgid total_vm rss cpu oom_adj oom_score_adj name\n"); |
358 | for_each_process(p) { | 363 | for_each_process(p) { |
359 | if (p->flags & PF_KTHREAD) | 364 | if (oom_unkillable_task(p, mem, nodemask)) |
360 | continue; | ||
361 | if (mem && !task_in_mem_cgroup(p, mem)) | ||
362 | continue; | 365 | continue; |
363 | 366 | ||
364 | task = find_lock_task_mm(p); | 367 | task = find_lock_task_mm(p); |
@@ -381,7 +384,7 @@ static void dump_tasks(const struct mem_cgroup *mem) | |||
381 | } | 384 | } |
382 | 385 | ||
383 | static void dump_header(struct task_struct *p, gfp_t gfp_mask, int order, | 386 | static void dump_header(struct task_struct *p, gfp_t gfp_mask, int order, |
384 | struct mem_cgroup *mem) | 387 | struct mem_cgroup *mem, const nodemask_t *nodemask) |
385 | { | 388 | { |
386 | task_lock(current); | 389 | task_lock(current); |
387 | pr_warning("%s invoked oom-killer: gfp_mask=0x%x, order=%d, " | 390 | pr_warning("%s invoked oom-killer: gfp_mask=0x%x, order=%d, " |
@@ -394,7 +397,7 @@ static void dump_header(struct task_struct *p, gfp_t gfp_mask, int order, | |||
394 | mem_cgroup_print_oom_info(mem, p); | 397 | mem_cgroup_print_oom_info(mem, p); |
395 | show_mem(); | 398 | show_mem(); |
396 | if (sysctl_oom_dump_tasks) | 399 | if (sysctl_oom_dump_tasks) |
397 | dump_tasks(mem); | 400 | dump_tasks(mem, nodemask); |
398 | } | 401 | } |
399 | 402 | ||
400 | #define K(x) ((x) << (PAGE_SHIFT-10)) | 403 | #define K(x) ((x) << (PAGE_SHIFT-10)) |
@@ -436,7 +439,7 @@ static int oom_kill_process(struct task_struct *p, gfp_t gfp_mask, int order, | |||
436 | unsigned int victim_points = 0; | 439 | unsigned int victim_points = 0; |
437 | 440 | ||
438 | if (printk_ratelimit()) | 441 | if (printk_ratelimit()) |
439 | dump_header(p, gfp_mask, order, mem); | 442 | dump_header(p, gfp_mask, order, mem, nodemask); |
440 | 443 | ||
441 | /* | 444 | /* |
442 | * If the task is already exiting, don't alarm the sysadmin or kill | 445 | * If the task is already exiting, don't alarm the sysadmin or kill |
@@ -482,7 +485,7 @@ static int oom_kill_process(struct task_struct *p, gfp_t gfp_mask, int order, | |||
482 | * Determines whether the kernel must panic because of the panic_on_oom sysctl. | 485 | * Determines whether the kernel must panic because of the panic_on_oom sysctl. |
483 | */ | 486 | */ |
484 | static void check_panic_on_oom(enum oom_constraint constraint, gfp_t gfp_mask, | 487 | static void check_panic_on_oom(enum oom_constraint constraint, gfp_t gfp_mask, |
485 | int order) | 488 | int order, const nodemask_t *nodemask) |
486 | { | 489 | { |
487 | if (likely(!sysctl_panic_on_oom)) | 490 | if (likely(!sysctl_panic_on_oom)) |
488 | return; | 491 | return; |
@@ -496,7 +499,7 @@ static void check_panic_on_oom(enum oom_constraint constraint, gfp_t gfp_mask, | |||
496 | return; | 499 | return; |
497 | } | 500 | } |
498 | read_lock(&tasklist_lock); | 501 | read_lock(&tasklist_lock); |
499 | dump_header(NULL, gfp_mask, order, NULL); | 502 | dump_header(NULL, gfp_mask, order, NULL, nodemask); |
500 | read_unlock(&tasklist_lock); | 503 | read_unlock(&tasklist_lock); |
501 | panic("Out of memory: %s panic_on_oom is enabled\n", | 504 | panic("Out of memory: %s panic_on_oom is enabled\n", |
502 | sysctl_panic_on_oom == 2 ? "compulsory" : "system-wide"); | 505 | sysctl_panic_on_oom == 2 ? "compulsory" : "system-wide"); |
@@ -509,7 +512,7 @@ void mem_cgroup_out_of_memory(struct mem_cgroup *mem, gfp_t gfp_mask) | |||
509 | unsigned int points = 0; | 512 | unsigned int points = 0; |
510 | struct task_struct *p; | 513 | struct task_struct *p; |
511 | 514 | ||
512 | check_panic_on_oom(CONSTRAINT_MEMCG, gfp_mask, 0); | 515 | check_panic_on_oom(CONSTRAINT_MEMCG, gfp_mask, 0, NULL); |
513 | limit = mem_cgroup_get_limit(mem) >> PAGE_SHIFT; | 516 | limit = mem_cgroup_get_limit(mem) >> PAGE_SHIFT; |
514 | read_lock(&tasklist_lock); | 517 | read_lock(&tasklist_lock); |
515 | retry: | 518 | retry: |
@@ -641,6 +644,7 @@ static void clear_system_oom(void) | |||
641 | void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask, | 644 | void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask, |
642 | int order, nodemask_t *nodemask) | 645 | int order, nodemask_t *nodemask) |
643 | { | 646 | { |
647 | const nodemask_t *mpol_mask; | ||
644 | struct task_struct *p; | 648 | struct task_struct *p; |
645 | unsigned long totalpages; | 649 | unsigned long totalpages; |
646 | unsigned long freed = 0; | 650 | unsigned long freed = 0; |
@@ -670,7 +674,8 @@ void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask, | |||
670 | */ | 674 | */ |
671 | constraint = constrained_alloc(zonelist, gfp_mask, nodemask, | 675 | constraint = constrained_alloc(zonelist, gfp_mask, nodemask, |
672 | &totalpages); | 676 | &totalpages); |
673 | check_panic_on_oom(constraint, gfp_mask, order); | 677 | mpol_mask = (constraint == CONSTRAINT_MEMORY_POLICY) ? nodemask : NULL; |
678 | check_panic_on_oom(constraint, gfp_mask, order, mpol_mask); | ||
674 | 679 | ||
675 | read_lock(&tasklist_lock); | 680 | read_lock(&tasklist_lock); |
676 | if (sysctl_oom_kill_allocating_task && | 681 | if (sysctl_oom_kill_allocating_task && |
@@ -688,15 +693,13 @@ void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask, | |||
688 | } | 693 | } |
689 | 694 | ||
690 | retry: | 695 | retry: |
691 | p = select_bad_process(&points, totalpages, NULL, | 696 | p = select_bad_process(&points, totalpages, NULL, mpol_mask); |
692 | constraint == CONSTRAINT_MEMORY_POLICY ? nodemask : | ||
693 | NULL); | ||
694 | if (PTR_ERR(p) == -1UL) | 697 | if (PTR_ERR(p) == -1UL) |
695 | goto out; | 698 | goto out; |
696 | 699 | ||
697 | /* Found nothing?!?! Either we hang forever, or we panic. */ | 700 | /* Found nothing?!?! Either we hang forever, or we panic. */ |
698 | if (!p) { | 701 | if (!p) { |
699 | dump_header(NULL, gfp_mask, order, NULL); | 702 | dump_header(NULL, gfp_mask, order, NULL, mpol_mask); |
700 | read_unlock(&tasklist_lock); | 703 | read_unlock(&tasklist_lock); |
701 | panic("Out of memory and no killable processes...\n"); | 704 | panic("Out of memory and no killable processes...\n"); |
702 | } | 705 | } |