diff options
Diffstat (limited to 'mm/page_alloc.c')
-rw-r--r-- | mm/page_alloc.c | 77 |
1 files changed, 50 insertions, 27 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 5717f27a0704..850c4a7e2fe5 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -234,6 +234,12 @@ static void bad_page(struct page *page) | |||
234 | static unsigned long nr_shown; | 234 | static unsigned long nr_shown; |
235 | static unsigned long nr_unshown; | 235 | static unsigned long nr_unshown; |
236 | 236 | ||
237 | /* Don't complain about poisoned pages */ | ||
238 | if (PageHWPoison(page)) { | ||
239 | __ClearPageBuddy(page); | ||
240 | return; | ||
241 | } | ||
242 | |||
237 | /* | 243 | /* |
238 | * Allow a burst of 60 reports, then keep quiet for that minute; | 244 | * Allow a burst of 60 reports, then keep quiet for that minute; |
239 | * or allow a steady drip of one report per second. | 245 | * or allow a steady drip of one report per second. |
@@ -480,7 +486,6 @@ static inline void __free_one_page(struct page *page, | |||
480 | zone->free_area[order].nr_free++; | 486 | zone->free_area[order].nr_free++; |
481 | } | 487 | } |
482 | 488 | ||
483 | #ifdef CONFIG_HAVE_MLOCKED_PAGE_BIT | ||
484 | /* | 489 | /* |
485 | * free_page_mlock() -- clean up attempts to free and mlocked() page. | 490 | * free_page_mlock() -- clean up attempts to free and mlocked() page. |
486 | * Page should not be on lru, so no need to fix that up. | 491 | * Page should not be on lru, so no need to fix that up. |
@@ -491,9 +496,6 @@ static inline void free_page_mlock(struct page *page) | |||
491 | __dec_zone_page_state(page, NR_MLOCK); | 496 | __dec_zone_page_state(page, NR_MLOCK); |
492 | __count_vm_event(UNEVICTABLE_MLOCKFREED); | 497 | __count_vm_event(UNEVICTABLE_MLOCKFREED); |
493 | } | 498 | } |
494 | #else | ||
495 | static void free_page_mlock(struct page *page) { } | ||
496 | #endif | ||
497 | 499 | ||
498 | static inline int free_pages_check(struct page *page) | 500 | static inline int free_pages_check(struct page *page) |
499 | { | 501 | { |
@@ -666,7 +668,7 @@ static inline void expand(struct zone *zone, struct page *page, | |||
666 | /* | 668 | /* |
667 | * This page is about to be returned from the page allocator | 669 | * This page is about to be returned from the page allocator |
668 | */ | 670 | */ |
669 | static int prep_new_page(struct page *page, int order, gfp_t gfp_flags) | 671 | static inline int check_new_page(struct page *page) |
670 | { | 672 | { |
671 | if (unlikely(page_mapcount(page) | | 673 | if (unlikely(page_mapcount(page) | |
672 | (page->mapping != NULL) | | 674 | (page->mapping != NULL) | |
@@ -675,6 +677,18 @@ static int prep_new_page(struct page *page, int order, gfp_t gfp_flags) | |||
675 | bad_page(page); | 677 | bad_page(page); |
676 | return 1; | 678 | return 1; |
677 | } | 679 | } |
680 | return 0; | ||
681 | } | ||
682 | |||
683 | static int prep_new_page(struct page *page, int order, gfp_t gfp_flags) | ||
684 | { | ||
685 | int i; | ||
686 | |||
687 | for (i = 0; i < (1 << order); i++) { | ||
688 | struct page *p = page + i; | ||
689 | if (unlikely(check_new_page(p))) | ||
690 | return 1; | ||
691 | } | ||
678 | 692 | ||
679 | set_page_private(page, 0); | 693 | set_page_private(page, 0); |
680 | set_page_refcounted(page); | 694 | set_page_refcounted(page); |
@@ -1640,12 +1654,22 @@ __alloc_pages_may_oom(gfp_t gfp_mask, unsigned int order, | |||
1640 | if (page) | 1654 | if (page) |
1641 | goto out; | 1655 | goto out; |
1642 | 1656 | ||
1643 | /* The OOM killer will not help higher order allocs */ | 1657 | if (!(gfp_mask & __GFP_NOFAIL)) { |
1644 | if (order > PAGE_ALLOC_COSTLY_ORDER && !(gfp_mask & __GFP_NOFAIL)) | 1658 | /* The OOM killer will not help higher order allocs */ |
1645 | goto out; | 1659 | if (order > PAGE_ALLOC_COSTLY_ORDER) |
1646 | 1660 | goto out; | |
1661 | /* | ||
1662 | * GFP_THISNODE contains __GFP_NORETRY and we never hit this. | ||
1663 | * Sanity check for bare calls of __GFP_THISNODE, not real OOM. | ||
1664 | * The caller should handle page allocation failure by itself if | ||
1665 | * it specifies __GFP_THISNODE. | ||
1666 | * Note: Hugepage uses it but will hit PAGE_ALLOC_COSTLY_ORDER. | ||
1667 | */ | ||
1668 | if (gfp_mask & __GFP_THISNODE) | ||
1669 | goto out; | ||
1670 | } | ||
1647 | /* Exhausted what can be done so it's blamo time */ | 1671 | /* Exhausted what can be done so it's blamo time */ |
1648 | out_of_memory(zonelist, gfp_mask, order); | 1672 | out_of_memory(zonelist, gfp_mask, order, nodemask); |
1649 | 1673 | ||
1650 | out: | 1674 | out: |
1651 | clear_zonelist_oom(zonelist, gfp_mask); | 1675 | clear_zonelist_oom(zonelist, gfp_mask); |
@@ -1751,7 +1775,7 @@ gfp_to_alloc_flags(gfp_t gfp_mask) | |||
1751 | * See also cpuset_zone_allowed() comment in kernel/cpuset.c. | 1775 | * See also cpuset_zone_allowed() comment in kernel/cpuset.c. |
1752 | */ | 1776 | */ |
1753 | alloc_flags &= ~ALLOC_CPUSET; | 1777 | alloc_flags &= ~ALLOC_CPUSET; |
1754 | } else if (unlikely(rt_task(p))) | 1778 | } else if (unlikely(rt_task(p)) && !in_interrupt()) |
1755 | alloc_flags |= ALLOC_HARDER; | 1779 | alloc_flags |= ALLOC_HARDER; |
1756 | 1780 | ||
1757 | if (likely(!(gfp_mask & __GFP_NOMEMALLOC))) { | 1781 | if (likely(!(gfp_mask & __GFP_NOMEMALLOC))) { |
@@ -1799,9 +1823,9 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order, | |||
1799 | if (NUMA_BUILD && (gfp_mask & GFP_THISNODE) == GFP_THISNODE) | 1823 | if (NUMA_BUILD && (gfp_mask & GFP_THISNODE) == GFP_THISNODE) |
1800 | goto nopage; | 1824 | goto nopage; |
1801 | 1825 | ||
1826 | restart: | ||
1802 | wake_all_kswapd(order, zonelist, high_zoneidx); | 1827 | wake_all_kswapd(order, zonelist, high_zoneidx); |
1803 | 1828 | ||
1804 | restart: | ||
1805 | /* | 1829 | /* |
1806 | * OK, we're below the kswapd watermark and have kicked background | 1830 | * OK, we're below the kswapd watermark and have kicked background |
1807 | * reclaim. Now things get more complex, so set up alloc_flags according | 1831 | * reclaim. Now things get more complex, so set up alloc_flags according |
@@ -2165,7 +2189,7 @@ void show_free_areas(void) | |||
2165 | printk("active_anon:%lu inactive_anon:%lu isolated_anon:%lu\n" | 2189 | printk("active_anon:%lu inactive_anon:%lu isolated_anon:%lu\n" |
2166 | " active_file:%lu inactive_file:%lu isolated_file:%lu\n" | 2190 | " active_file:%lu inactive_file:%lu isolated_file:%lu\n" |
2167 | " unevictable:%lu" | 2191 | " unevictable:%lu" |
2168 | " dirty:%lu writeback:%lu unstable:%lu buffer:%lu\n" | 2192 | " dirty:%lu writeback:%lu unstable:%lu\n" |
2169 | " free:%lu slab_reclaimable:%lu slab_unreclaimable:%lu\n" | 2193 | " free:%lu slab_reclaimable:%lu slab_unreclaimable:%lu\n" |
2170 | " mapped:%lu shmem:%lu pagetables:%lu bounce:%lu\n", | 2194 | " mapped:%lu shmem:%lu pagetables:%lu bounce:%lu\n", |
2171 | global_page_state(NR_ACTIVE_ANON), | 2195 | global_page_state(NR_ACTIVE_ANON), |
@@ -2178,7 +2202,6 @@ void show_free_areas(void) | |||
2178 | global_page_state(NR_FILE_DIRTY), | 2202 | global_page_state(NR_FILE_DIRTY), |
2179 | global_page_state(NR_WRITEBACK), | 2203 | global_page_state(NR_WRITEBACK), |
2180 | global_page_state(NR_UNSTABLE_NFS), | 2204 | global_page_state(NR_UNSTABLE_NFS), |
2181 | nr_blockdev_pages(), | ||
2182 | global_page_state(NR_FREE_PAGES), | 2205 | global_page_state(NR_FREE_PAGES), |
2183 | global_page_state(NR_SLAB_RECLAIMABLE), | 2206 | global_page_state(NR_SLAB_RECLAIMABLE), |
2184 | global_page_state(NR_SLAB_UNRECLAIMABLE), | 2207 | global_page_state(NR_SLAB_UNRECLAIMABLE), |
@@ -2373,7 +2396,7 @@ early_param("numa_zonelist_order", setup_numa_zonelist_order); | |||
2373 | * sysctl handler for numa_zonelist_order | 2396 | * sysctl handler for numa_zonelist_order |
2374 | */ | 2397 | */ |
2375 | int numa_zonelist_order_handler(ctl_table *table, int write, | 2398 | int numa_zonelist_order_handler(ctl_table *table, int write, |
2376 | struct file *file, void __user *buffer, size_t *length, | 2399 | void __user *buffer, size_t *length, |
2377 | loff_t *ppos) | 2400 | loff_t *ppos) |
2378 | { | 2401 | { |
2379 | char saved_string[NUMA_ZONELIST_ORDER_LEN]; | 2402 | char saved_string[NUMA_ZONELIST_ORDER_LEN]; |
@@ -2382,7 +2405,7 @@ int numa_zonelist_order_handler(ctl_table *table, int write, | |||
2382 | if (write) | 2405 | if (write) |
2383 | strncpy(saved_string, (char*)table->data, | 2406 | strncpy(saved_string, (char*)table->data, |
2384 | NUMA_ZONELIST_ORDER_LEN); | 2407 | NUMA_ZONELIST_ORDER_LEN); |
2385 | ret = proc_dostring(table, write, file, buffer, length, ppos); | 2408 | ret = proc_dostring(table, write, buffer, length, ppos); |
2386 | if (ret) | 2409 | if (ret) |
2387 | return ret; | 2410 | return ret; |
2388 | if (write) { | 2411 | if (write) { |
@@ -3110,7 +3133,7 @@ static int __cpuinit process_zones(int cpu) | |||
3110 | 3133 | ||
3111 | if (percpu_pagelist_fraction) | 3134 | if (percpu_pagelist_fraction) |
3112 | setup_pagelist_highmark(zone_pcp(zone, cpu), | 3135 | setup_pagelist_highmark(zone_pcp(zone, cpu), |
3113 | (zone->present_pages / percpu_pagelist_fraction)); | 3136 | (zone->present_pages / percpu_pagelist_fraction)); |
3114 | } | 3137 | } |
3115 | 3138 | ||
3116 | return 0; | 3139 | return 0; |
@@ -4706,9 +4729,9 @@ module_init(init_per_zone_wmark_min) | |||
4706 | * changes. | 4729 | * changes. |
4707 | */ | 4730 | */ |
4708 | int min_free_kbytes_sysctl_handler(ctl_table *table, int write, | 4731 | int min_free_kbytes_sysctl_handler(ctl_table *table, int write, |
4709 | struct file *file, void __user *buffer, size_t *length, loff_t *ppos) | 4732 | void __user *buffer, size_t *length, loff_t *ppos) |
4710 | { | 4733 | { |
4711 | proc_dointvec(table, write, file, buffer, length, ppos); | 4734 | proc_dointvec(table, write, buffer, length, ppos); |
4712 | if (write) | 4735 | if (write) |
4713 | setup_per_zone_wmarks(); | 4736 | setup_per_zone_wmarks(); |
4714 | return 0; | 4737 | return 0; |
@@ -4716,12 +4739,12 @@ int min_free_kbytes_sysctl_handler(ctl_table *table, int write, | |||
4716 | 4739 | ||
4717 | #ifdef CONFIG_NUMA | 4740 | #ifdef CONFIG_NUMA |
4718 | int sysctl_min_unmapped_ratio_sysctl_handler(ctl_table *table, int write, | 4741 | int sysctl_min_unmapped_ratio_sysctl_handler(ctl_table *table, int write, |
4719 | struct file *file, void __user *buffer, size_t *length, loff_t *ppos) | 4742 | void __user *buffer, size_t *length, loff_t *ppos) |
4720 | { | 4743 | { |
4721 | struct zone *zone; | 4744 | struct zone *zone; |
4722 | int rc; | 4745 | int rc; |
4723 | 4746 | ||
4724 | rc = proc_dointvec_minmax(table, write, file, buffer, length, ppos); | 4747 | rc = proc_dointvec_minmax(table, write, buffer, length, ppos); |
4725 | if (rc) | 4748 | if (rc) |
4726 | return rc; | 4749 | return rc; |
4727 | 4750 | ||
@@ -4732,12 +4755,12 @@ int sysctl_min_unmapped_ratio_sysctl_handler(ctl_table *table, int write, | |||
4732 | } | 4755 | } |
4733 | 4756 | ||
4734 | int sysctl_min_slab_ratio_sysctl_handler(ctl_table *table, int write, | 4757 | int sysctl_min_slab_ratio_sysctl_handler(ctl_table *table, int write, |
4735 | struct file *file, void __user *buffer, size_t *length, loff_t *ppos) | 4758 | void __user *buffer, size_t *length, loff_t *ppos) |
4736 | { | 4759 | { |
4737 | struct zone *zone; | 4760 | struct zone *zone; |
4738 | int rc; | 4761 | int rc; |
4739 | 4762 | ||
4740 | rc = proc_dointvec_minmax(table, write, file, buffer, length, ppos); | 4763 | rc = proc_dointvec_minmax(table, write, buffer, length, ppos); |
4741 | if (rc) | 4764 | if (rc) |
4742 | return rc; | 4765 | return rc; |
4743 | 4766 | ||
@@ -4758,9 +4781,9 @@ int sysctl_min_slab_ratio_sysctl_handler(ctl_table *table, int write, | |||
4758 | * if in function of the boot time zone sizes. | 4781 | * if in function of the boot time zone sizes. |
4759 | */ | 4782 | */ |
4760 | int lowmem_reserve_ratio_sysctl_handler(ctl_table *table, int write, | 4783 | int lowmem_reserve_ratio_sysctl_handler(ctl_table *table, int write, |
4761 | struct file *file, void __user *buffer, size_t *length, loff_t *ppos) | 4784 | void __user *buffer, size_t *length, loff_t *ppos) |
4762 | { | 4785 | { |
4763 | proc_dointvec_minmax(table, write, file, buffer, length, ppos); | 4786 | proc_dointvec_minmax(table, write, buffer, length, ppos); |
4764 | setup_per_zone_lowmem_reserve(); | 4787 | setup_per_zone_lowmem_reserve(); |
4765 | return 0; | 4788 | return 0; |
4766 | } | 4789 | } |
@@ -4772,13 +4795,13 @@ int lowmem_reserve_ratio_sysctl_handler(ctl_table *table, int write, | |||
4772 | */ | 4795 | */ |
4773 | 4796 | ||
4774 | int percpu_pagelist_fraction_sysctl_handler(ctl_table *table, int write, | 4797 | int percpu_pagelist_fraction_sysctl_handler(ctl_table *table, int write, |
4775 | struct file *file, void __user *buffer, size_t *length, loff_t *ppos) | 4798 | void __user *buffer, size_t *length, loff_t *ppos) |
4776 | { | 4799 | { |
4777 | struct zone *zone; | 4800 | struct zone *zone; |
4778 | unsigned int cpu; | 4801 | unsigned int cpu; |
4779 | int ret; | 4802 | int ret; |
4780 | 4803 | ||
4781 | ret = proc_dointvec_minmax(table, write, file, buffer, length, ppos); | 4804 | ret = proc_dointvec_minmax(table, write, buffer, length, ppos); |
4782 | if (!write || (ret == -EINVAL)) | 4805 | if (!write || (ret == -EINVAL)) |
4783 | return ret; | 4806 | return ret; |
4784 | for_each_populated_zone(zone) { | 4807 | for_each_populated_zone(zone) { |