diff options
Diffstat (limited to 'mm/page_alloc.c')
-rw-r--r-- | mm/page_alloc.c | 44 |
1 files changed, 31 insertions, 13 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 5717f27a0704..bf720550b44d 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. |
@@ -666,7 +672,7 @@ static inline void expand(struct zone *zone, struct page *page, | |||
666 | /* | 672 | /* |
667 | * This page is about to be returned from the page allocator | 673 | * This page is about to be returned from the page allocator |
668 | */ | 674 | */ |
669 | static int prep_new_page(struct page *page, int order, gfp_t gfp_flags) | 675 | static inline int check_new_page(struct page *page) |
670 | { | 676 | { |
671 | if (unlikely(page_mapcount(page) | | 677 | if (unlikely(page_mapcount(page) | |
672 | (page->mapping != NULL) | | 678 | (page->mapping != NULL) | |
@@ -675,6 +681,18 @@ static int prep_new_page(struct page *page, int order, gfp_t gfp_flags) | |||
675 | bad_page(page); | 681 | bad_page(page); |
676 | return 1; | 682 | return 1; |
677 | } | 683 | } |
684 | return 0; | ||
685 | } | ||
686 | |||
687 | static int prep_new_page(struct page *page, int order, gfp_t gfp_flags) | ||
688 | { | ||
689 | int i; | ||
690 | |||
691 | for (i = 0; i < (1 << order); i++) { | ||
692 | struct page *p = page + i; | ||
693 | if (unlikely(check_new_page(p))) | ||
694 | return 1; | ||
695 | } | ||
678 | 696 | ||
679 | set_page_private(page, 0); | 697 | set_page_private(page, 0); |
680 | set_page_refcounted(page); | 698 | set_page_refcounted(page); |
@@ -2373,7 +2391,7 @@ early_param("numa_zonelist_order", setup_numa_zonelist_order); | |||
2373 | * sysctl handler for numa_zonelist_order | 2391 | * sysctl handler for numa_zonelist_order |
2374 | */ | 2392 | */ |
2375 | int numa_zonelist_order_handler(ctl_table *table, int write, | 2393 | int numa_zonelist_order_handler(ctl_table *table, int write, |
2376 | struct file *file, void __user *buffer, size_t *length, | 2394 | void __user *buffer, size_t *length, |
2377 | loff_t *ppos) | 2395 | loff_t *ppos) |
2378 | { | 2396 | { |
2379 | char saved_string[NUMA_ZONELIST_ORDER_LEN]; | 2397 | char saved_string[NUMA_ZONELIST_ORDER_LEN]; |
@@ -2382,7 +2400,7 @@ int numa_zonelist_order_handler(ctl_table *table, int write, | |||
2382 | if (write) | 2400 | if (write) |
2383 | strncpy(saved_string, (char*)table->data, | 2401 | strncpy(saved_string, (char*)table->data, |
2384 | NUMA_ZONELIST_ORDER_LEN); | 2402 | NUMA_ZONELIST_ORDER_LEN); |
2385 | ret = proc_dostring(table, write, file, buffer, length, ppos); | 2403 | ret = proc_dostring(table, write, buffer, length, ppos); |
2386 | if (ret) | 2404 | if (ret) |
2387 | return ret; | 2405 | return ret; |
2388 | if (write) { | 2406 | if (write) { |
@@ -4706,9 +4724,9 @@ module_init(init_per_zone_wmark_min) | |||
4706 | * changes. | 4724 | * changes. |
4707 | */ | 4725 | */ |
4708 | int min_free_kbytes_sysctl_handler(ctl_table *table, int write, | 4726 | int min_free_kbytes_sysctl_handler(ctl_table *table, int write, |
4709 | struct file *file, void __user *buffer, size_t *length, loff_t *ppos) | 4727 | void __user *buffer, size_t *length, loff_t *ppos) |
4710 | { | 4728 | { |
4711 | proc_dointvec(table, write, file, buffer, length, ppos); | 4729 | proc_dointvec(table, write, buffer, length, ppos); |
4712 | if (write) | 4730 | if (write) |
4713 | setup_per_zone_wmarks(); | 4731 | setup_per_zone_wmarks(); |
4714 | return 0; | 4732 | return 0; |
@@ -4716,12 +4734,12 @@ int min_free_kbytes_sysctl_handler(ctl_table *table, int write, | |||
4716 | 4734 | ||
4717 | #ifdef CONFIG_NUMA | 4735 | #ifdef CONFIG_NUMA |
4718 | int sysctl_min_unmapped_ratio_sysctl_handler(ctl_table *table, int write, | 4736 | 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) | 4737 | void __user *buffer, size_t *length, loff_t *ppos) |
4720 | { | 4738 | { |
4721 | struct zone *zone; | 4739 | struct zone *zone; |
4722 | int rc; | 4740 | int rc; |
4723 | 4741 | ||
4724 | rc = proc_dointvec_minmax(table, write, file, buffer, length, ppos); | 4742 | rc = proc_dointvec_minmax(table, write, buffer, length, ppos); |
4725 | if (rc) | 4743 | if (rc) |
4726 | return rc; | 4744 | return rc; |
4727 | 4745 | ||
@@ -4732,12 +4750,12 @@ int sysctl_min_unmapped_ratio_sysctl_handler(ctl_table *table, int write, | |||
4732 | } | 4750 | } |
4733 | 4751 | ||
4734 | int sysctl_min_slab_ratio_sysctl_handler(ctl_table *table, int write, | 4752 | 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) | 4753 | void __user *buffer, size_t *length, loff_t *ppos) |
4736 | { | 4754 | { |
4737 | struct zone *zone; | 4755 | struct zone *zone; |
4738 | int rc; | 4756 | int rc; |
4739 | 4757 | ||
4740 | rc = proc_dointvec_minmax(table, write, file, buffer, length, ppos); | 4758 | rc = proc_dointvec_minmax(table, write, buffer, length, ppos); |
4741 | if (rc) | 4759 | if (rc) |
4742 | return rc; | 4760 | return rc; |
4743 | 4761 | ||
@@ -4758,9 +4776,9 @@ int sysctl_min_slab_ratio_sysctl_handler(ctl_table *table, int write, | |||
4758 | * if in function of the boot time zone sizes. | 4776 | * if in function of the boot time zone sizes. |
4759 | */ | 4777 | */ |
4760 | int lowmem_reserve_ratio_sysctl_handler(ctl_table *table, int write, | 4778 | int lowmem_reserve_ratio_sysctl_handler(ctl_table *table, int write, |
4761 | struct file *file, void __user *buffer, size_t *length, loff_t *ppos) | 4779 | void __user *buffer, size_t *length, loff_t *ppos) |
4762 | { | 4780 | { |
4763 | proc_dointvec_minmax(table, write, file, buffer, length, ppos); | 4781 | proc_dointvec_minmax(table, write, buffer, length, ppos); |
4764 | setup_per_zone_lowmem_reserve(); | 4782 | setup_per_zone_lowmem_reserve(); |
4765 | return 0; | 4783 | return 0; |
4766 | } | 4784 | } |
@@ -4772,13 +4790,13 @@ int lowmem_reserve_ratio_sysctl_handler(ctl_table *table, int write, | |||
4772 | */ | 4790 | */ |
4773 | 4791 | ||
4774 | int percpu_pagelist_fraction_sysctl_handler(ctl_table *table, int write, | 4792 | int percpu_pagelist_fraction_sysctl_handler(ctl_table *table, int write, |
4775 | struct file *file, void __user *buffer, size_t *length, loff_t *ppos) | 4793 | void __user *buffer, size_t *length, loff_t *ppos) |
4776 | { | 4794 | { |
4777 | struct zone *zone; | 4795 | struct zone *zone; |
4778 | unsigned int cpu; | 4796 | unsigned int cpu; |
4779 | int ret; | 4797 | int ret; |
4780 | 4798 | ||
4781 | ret = proc_dointvec_minmax(table, write, file, buffer, length, ppos); | 4799 | ret = proc_dointvec_minmax(table, write, buffer, length, ppos); |
4782 | if (!write || (ret == -EINVAL)) | 4800 | if (!write || (ret == -EINVAL)) |
4783 | return ret; | 4801 | return ret; |
4784 | for_each_populated_zone(zone) { | 4802 | for_each_populated_zone(zone) { |