diff options
-rw-r--r-- | include/linux/oom.h | 1 | ||||
-rw-r--r-- | mm/oom_kill.c | 53 |
2 files changed, 30 insertions, 24 deletions
diff --git a/include/linux/oom.h b/include/linux/oom.h index 537662315627..3ae6d94d0540 100644 --- a/include/linux/oom.h +++ b/include/linux/oom.h | |||
@@ -22,6 +22,7 @@ enum oom_constraint { | |||
22 | CONSTRAINT_NONE, | 22 | CONSTRAINT_NONE, |
23 | CONSTRAINT_CPUSET, | 23 | CONSTRAINT_CPUSET, |
24 | CONSTRAINT_MEMORY_POLICY, | 24 | CONSTRAINT_MEMORY_POLICY, |
25 | CONSTRAINT_MEMCG, | ||
25 | }; | 26 | }; |
26 | 27 | ||
27 | extern int try_set_zone_oom(struct zonelist *zonelist, gfp_t gfp_flags); | 28 | extern int try_set_zone_oom(struct zonelist *zonelist, gfp_t gfp_flags); |
diff --git a/mm/oom_kill.c b/mm/oom_kill.c index 01b5e01e52cb..fca886d8b5fb 100644 --- a/mm/oom_kill.c +++ b/mm/oom_kill.c | |||
@@ -521,17 +521,40 @@ static int oom_kill_process(struct task_struct *p, gfp_t gfp_mask, int order, | |||
521 | return oom_kill_task(victim); | 521 | return oom_kill_task(victim); |
522 | } | 522 | } |
523 | 523 | ||
524 | /* | ||
525 | * Determines whether the kernel must panic because of the panic_on_oom sysctl. | ||
526 | */ | ||
527 | static void check_panic_on_oom(enum oom_constraint constraint, gfp_t gfp_mask, | ||
528 | int order) | ||
529 | { | ||
530 | if (likely(!sysctl_panic_on_oom)) | ||
531 | return; | ||
532 | if (sysctl_panic_on_oom != 2) { | ||
533 | /* | ||
534 | * panic_on_oom == 1 only affects CONSTRAINT_NONE, the kernel | ||
535 | * does not panic for cpuset, mempolicy, or memcg allocation | ||
536 | * failures. | ||
537 | */ | ||
538 | if (constraint != CONSTRAINT_NONE) | ||
539 | return; | ||
540 | } | ||
541 | read_lock(&tasklist_lock); | ||
542 | dump_header(NULL, gfp_mask, order, NULL); | ||
543 | read_unlock(&tasklist_lock); | ||
544 | panic("Out of memory: %s panic_on_oom is enabled\n", | ||
545 | sysctl_panic_on_oom == 2 ? "compulsory" : "system-wide"); | ||
546 | } | ||
547 | |||
524 | #ifdef CONFIG_CGROUP_MEM_RES_CTLR | 548 | #ifdef CONFIG_CGROUP_MEM_RES_CTLR |
525 | void mem_cgroup_out_of_memory(struct mem_cgroup *mem, gfp_t gfp_mask) | 549 | void mem_cgroup_out_of_memory(struct mem_cgroup *mem, gfp_t gfp_mask) |
526 | { | 550 | { |
527 | unsigned long points = 0; | 551 | unsigned long points = 0; |
528 | struct task_struct *p; | 552 | struct task_struct *p; |
529 | 553 | ||
530 | if (sysctl_panic_on_oom == 2) | 554 | check_panic_on_oom(CONSTRAINT_MEMCG, gfp_mask, 0); |
531 | panic("out of memory(memcg). panic_on_oom is selected.\n"); | ||
532 | read_lock(&tasklist_lock); | 555 | read_lock(&tasklist_lock); |
533 | retry: | 556 | retry: |
534 | p = select_bad_process(&points, mem, CONSTRAINT_NONE, NULL); | 557 | p = select_bad_process(&points, mem, CONSTRAINT_MEMCG, NULL); |
535 | if (!p || PTR_ERR(p) == -1UL) | 558 | if (!p || PTR_ERR(p) == -1UL) |
536 | goto out; | 559 | goto out; |
537 | 560 | ||
@@ -632,8 +655,8 @@ retry: | |||
632 | 655 | ||
633 | /* Found nothing?!?! Either we hang forever, or we panic. */ | 656 | /* Found nothing?!?! Either we hang forever, or we panic. */ |
634 | if (!p) { | 657 | if (!p) { |
635 | read_unlock(&tasklist_lock); | ||
636 | dump_header(NULL, gfp_mask, order, NULL); | 658 | dump_header(NULL, gfp_mask, order, NULL); |
659 | read_unlock(&tasklist_lock); | ||
637 | panic("Out of memory and no killable processes...\n"); | 660 | panic("Out of memory and no killable processes...\n"); |
638 | } | 661 | } |
639 | 662 | ||
@@ -655,9 +678,7 @@ void pagefault_out_of_memory(void) | |||
655 | /* Got some memory back in the last second. */ | 678 | /* Got some memory back in the last second. */ |
656 | return; | 679 | return; |
657 | 680 | ||
658 | if (sysctl_panic_on_oom) | 681 | check_panic_on_oom(CONSTRAINT_NONE, 0, 0); |
659 | panic("out of memory from page fault. panic_on_oom is selected.\n"); | ||
660 | |||
661 | read_lock(&tasklist_lock); | 682 | read_lock(&tasklist_lock); |
662 | /* unknown gfp_mask and order */ | 683 | /* unknown gfp_mask and order */ |
663 | __out_of_memory(0, 0, CONSTRAINT_NONE, NULL); | 684 | __out_of_memory(0, 0, CONSTRAINT_NONE, NULL); |
@@ -704,29 +725,13 @@ void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask, | |||
704 | return; | 725 | return; |
705 | } | 726 | } |
706 | 727 | ||
707 | if (sysctl_panic_on_oom == 2) { | ||
708 | dump_header(NULL, gfp_mask, order, NULL); | ||
709 | panic("out of memory. Compulsory panic_on_oom is selected.\n"); | ||
710 | } | ||
711 | |||
712 | /* | 728 | /* |
713 | * Check if there were limitations on the allocation (only relevant for | 729 | * Check if there were limitations on the allocation (only relevant for |
714 | * NUMA) that may require different handling. | 730 | * NUMA) that may require different handling. |
715 | */ | 731 | */ |
716 | constraint = constrained_alloc(zonelist, gfp_mask, nodemask); | 732 | constraint = constrained_alloc(zonelist, gfp_mask, nodemask); |
733 | check_panic_on_oom(constraint, gfp_mask, order); | ||
717 | read_lock(&tasklist_lock); | 734 | read_lock(&tasklist_lock); |
718 | if (unlikely(sysctl_panic_on_oom)) { | ||
719 | /* | ||
720 | * panic_on_oom only affects CONSTRAINT_NONE, the kernel | ||
721 | * should not panic for cpuset or mempolicy induced memory | ||
722 | * failures. | ||
723 | */ | ||
724 | if (constraint == CONSTRAINT_NONE) { | ||
725 | dump_header(NULL, gfp_mask, order, NULL); | ||
726 | read_unlock(&tasklist_lock); | ||
727 | panic("Out of memory: panic_on_oom is enabled\n"); | ||
728 | } | ||
729 | } | ||
730 | __out_of_memory(gfp_mask, order, constraint, nodemask); | 735 | __out_of_memory(gfp_mask, order, constraint, nodemask); |
731 | read_unlock(&tasklist_lock); | 736 | read_unlock(&tasklist_lock); |
732 | 737 | ||