diff options
Diffstat (limited to 'mm/page_alloc.c')
-rw-r--r-- | mm/page_alloc.c | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index d315e1127dc9..43f757fcf30f 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/pagevec.h> | 27 | #include <linux/pagevec.h> |
28 | #include <linux/blkdev.h> | 28 | #include <linux/blkdev.h> |
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | #include <linux/oom.h> | ||
30 | #include <linux/notifier.h> | 31 | #include <linux/notifier.h> |
31 | #include <linux/topology.h> | 32 | #include <linux/topology.h> |
32 | #include <linux/sysctl.h> | 33 | #include <linux/sysctl.h> |
@@ -489,7 +490,7 @@ static void free_pages_bulk(struct zone *zone, int count, | |||
489 | struct list_head *list, int order) | 490 | struct list_head *list, int order) |
490 | { | 491 | { |
491 | spin_lock(&zone->lock); | 492 | spin_lock(&zone->lock); |
492 | zone->all_unreclaimable = 0; | 493 | zone_clear_flag(zone, ZONE_ALL_UNRECLAIMABLE); |
493 | zone->pages_scanned = 0; | 494 | zone->pages_scanned = 0; |
494 | while (count--) { | 495 | while (count--) { |
495 | struct page *page; | 496 | struct page *page; |
@@ -506,7 +507,7 @@ static void free_pages_bulk(struct zone *zone, int count, | |||
506 | static void free_one_page(struct zone *zone, struct page *page, int order) | 507 | static void free_one_page(struct zone *zone, struct page *page, int order) |
507 | { | 508 | { |
508 | spin_lock(&zone->lock); | 509 | spin_lock(&zone->lock); |
509 | zone->all_unreclaimable = 0; | 510 | zone_clear_flag(zone, ZONE_ALL_UNRECLAIMABLE); |
510 | zone->pages_scanned = 0; | 511 | zone->pages_scanned = 0; |
511 | __free_one_page(page, zone, order); | 512 | __free_one_page(page, zone, order); |
512 | spin_unlock(&zone->lock); | 513 | spin_unlock(&zone->lock); |
@@ -1586,6 +1587,11 @@ nofail_alloc: | |||
1586 | if (page) | 1587 | if (page) |
1587 | goto got_pg; | 1588 | goto got_pg; |
1588 | } else if ((gfp_mask & __GFP_FS) && !(gfp_mask & __GFP_NORETRY)) { | 1589 | } else if ((gfp_mask & __GFP_FS) && !(gfp_mask & __GFP_NORETRY)) { |
1590 | if (!try_set_zone_oom(zonelist)) { | ||
1591 | schedule_timeout_uninterruptible(1); | ||
1592 | goto restart; | ||
1593 | } | ||
1594 | |||
1589 | /* | 1595 | /* |
1590 | * Go through the zonelist yet one more time, keep | 1596 | * Go through the zonelist yet one more time, keep |
1591 | * very high watermark here, this is only to catch | 1597 | * very high watermark here, this is only to catch |
@@ -1594,14 +1600,19 @@ nofail_alloc: | |||
1594 | */ | 1600 | */ |
1595 | page = get_page_from_freelist(gfp_mask|__GFP_HARDWALL, order, | 1601 | page = get_page_from_freelist(gfp_mask|__GFP_HARDWALL, order, |
1596 | zonelist, ALLOC_WMARK_HIGH|ALLOC_CPUSET); | 1602 | zonelist, ALLOC_WMARK_HIGH|ALLOC_CPUSET); |
1597 | if (page) | 1603 | if (page) { |
1604 | clear_zonelist_oom(zonelist); | ||
1598 | goto got_pg; | 1605 | goto got_pg; |
1606 | } | ||
1599 | 1607 | ||
1600 | /* The OOM killer will not help higher order allocs so fail */ | 1608 | /* The OOM killer will not help higher order allocs so fail */ |
1601 | if (order > PAGE_ALLOC_COSTLY_ORDER) | 1609 | if (order > PAGE_ALLOC_COSTLY_ORDER) { |
1610 | clear_zonelist_oom(zonelist); | ||
1602 | goto nopage; | 1611 | goto nopage; |
1612 | } | ||
1603 | 1613 | ||
1604 | out_of_memory(zonelist, gfp_mask, order); | 1614 | out_of_memory(zonelist, gfp_mask, order); |
1615 | clear_zonelist_oom(zonelist); | ||
1605 | goto restart; | 1616 | goto restart; |
1606 | } | 1617 | } |
1607 | 1618 | ||
@@ -1850,7 +1861,7 @@ void show_free_areas(void) | |||
1850 | K(zone_page_state(zone, NR_INACTIVE)), | 1861 | K(zone_page_state(zone, NR_INACTIVE)), |
1851 | K(zone->present_pages), | 1862 | K(zone->present_pages), |
1852 | zone->pages_scanned, | 1863 | zone->pages_scanned, |
1853 | (zone->all_unreclaimable ? "yes" : "no") | 1864 | (zone_is_all_unreclaimable(zone) ? "yes" : "no") |
1854 | ); | 1865 | ); |
1855 | printk("lowmem_reserve[]:"); | 1866 | printk("lowmem_reserve[]:"); |
1856 | for (i = 0; i < MAX_NR_ZONES; i++) | 1867 | for (i = 0; i < MAX_NR_ZONES; i++) |
@@ -3371,7 +3382,7 @@ static void __meminit free_area_init_core(struct pglist_data *pgdat, | |||
3371 | zone->nr_scan_active = 0; | 3382 | zone->nr_scan_active = 0; |
3372 | zone->nr_scan_inactive = 0; | 3383 | zone->nr_scan_inactive = 0; |
3373 | zap_zone_vm_stats(zone); | 3384 | zap_zone_vm_stats(zone); |
3374 | atomic_set(&zone->reclaim_in_progress, 0); | 3385 | zone->flags = 0; |
3375 | if (!size) | 3386 | if (!size) |
3376 | continue; | 3387 | continue; |
3377 | 3388 | ||