diff options
Diffstat (limited to 'mm/page_alloc.c')
-rw-r--r-- | mm/page_alloc.c | 135 |
1 files changed, 78 insertions, 57 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 9119faae6e6a..9dd443d89d8b 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -318,6 +318,7 @@ static void bad_page(struct page *page) | |||
318 | current->comm, page_to_pfn(page)); | 318 | current->comm, page_to_pfn(page)); |
319 | dump_page(page); | 319 | dump_page(page); |
320 | 320 | ||
321 | print_modules(); | ||
321 | dump_stack(); | 322 | dump_stack(); |
322 | out: | 323 | out: |
323 | /* Leave bad fields for debug, except PageBuddy could make trouble */ | 324 | /* Leave bad fields for debug, except PageBuddy could make trouble */ |
@@ -1370,21 +1371,12 @@ failed: | |||
1370 | 1371 | ||
1371 | #ifdef CONFIG_FAIL_PAGE_ALLOC | 1372 | #ifdef CONFIG_FAIL_PAGE_ALLOC |
1372 | 1373 | ||
1373 | static struct fail_page_alloc_attr { | 1374 | static struct { |
1374 | struct fault_attr attr; | 1375 | struct fault_attr attr; |
1375 | 1376 | ||
1376 | u32 ignore_gfp_highmem; | 1377 | u32 ignore_gfp_highmem; |
1377 | u32 ignore_gfp_wait; | 1378 | u32 ignore_gfp_wait; |
1378 | u32 min_order; | 1379 | u32 min_order; |
1379 | |||
1380 | #ifdef CONFIG_FAULT_INJECTION_DEBUG_FS | ||
1381 | |||
1382 | struct dentry *ignore_gfp_highmem_file; | ||
1383 | struct dentry *ignore_gfp_wait_file; | ||
1384 | struct dentry *min_order_file; | ||
1385 | |||
1386 | #endif /* CONFIG_FAULT_INJECTION_DEBUG_FS */ | ||
1387 | |||
1388 | } fail_page_alloc = { | 1380 | } fail_page_alloc = { |
1389 | .attr = FAULT_ATTR_INITIALIZER, | 1381 | .attr = FAULT_ATTR_INITIALIZER, |
1390 | .ignore_gfp_wait = 1, | 1382 | .ignore_gfp_wait = 1, |
@@ -1418,36 +1410,27 @@ static int __init fail_page_alloc_debugfs(void) | |||
1418 | { | 1410 | { |
1419 | mode_t mode = S_IFREG | S_IRUSR | S_IWUSR; | 1411 | mode_t mode = S_IFREG | S_IRUSR | S_IWUSR; |
1420 | struct dentry *dir; | 1412 | struct dentry *dir; |
1421 | int err; | ||
1422 | |||
1423 | err = init_fault_attr_dentries(&fail_page_alloc.attr, | ||
1424 | "fail_page_alloc"); | ||
1425 | if (err) | ||
1426 | return err; | ||
1427 | dir = fail_page_alloc.attr.dentries.dir; | ||
1428 | |||
1429 | fail_page_alloc.ignore_gfp_wait_file = | ||
1430 | debugfs_create_bool("ignore-gfp-wait", mode, dir, | ||
1431 | &fail_page_alloc.ignore_gfp_wait); | ||
1432 | |||
1433 | fail_page_alloc.ignore_gfp_highmem_file = | ||
1434 | debugfs_create_bool("ignore-gfp-highmem", mode, dir, | ||
1435 | &fail_page_alloc.ignore_gfp_highmem); | ||
1436 | fail_page_alloc.min_order_file = | ||
1437 | debugfs_create_u32("min-order", mode, dir, | ||
1438 | &fail_page_alloc.min_order); | ||
1439 | |||
1440 | if (!fail_page_alloc.ignore_gfp_wait_file || | ||
1441 | !fail_page_alloc.ignore_gfp_highmem_file || | ||
1442 | !fail_page_alloc.min_order_file) { | ||
1443 | err = -ENOMEM; | ||
1444 | debugfs_remove(fail_page_alloc.ignore_gfp_wait_file); | ||
1445 | debugfs_remove(fail_page_alloc.ignore_gfp_highmem_file); | ||
1446 | debugfs_remove(fail_page_alloc.min_order_file); | ||
1447 | cleanup_fault_attr_dentries(&fail_page_alloc.attr); | ||
1448 | } | ||
1449 | 1413 | ||
1450 | return err; | 1414 | dir = fault_create_debugfs_attr("fail_page_alloc", NULL, |
1415 | &fail_page_alloc.attr); | ||
1416 | if (IS_ERR(dir)) | ||
1417 | return PTR_ERR(dir); | ||
1418 | |||
1419 | if (!debugfs_create_bool("ignore-gfp-wait", mode, dir, | ||
1420 | &fail_page_alloc.ignore_gfp_wait)) | ||
1421 | goto fail; | ||
1422 | if (!debugfs_create_bool("ignore-gfp-highmem", mode, dir, | ||
1423 | &fail_page_alloc.ignore_gfp_highmem)) | ||
1424 | goto fail; | ||
1425 | if (!debugfs_create_u32("min-order", mode, dir, | ||
1426 | &fail_page_alloc.min_order)) | ||
1427 | goto fail; | ||
1428 | |||
1429 | return 0; | ||
1430 | fail: | ||
1431 | debugfs_remove_recursive(dir); | ||
1432 | |||
1433 | return -ENOMEM; | ||
1451 | } | 1434 | } |
1452 | 1435 | ||
1453 | late_initcall(fail_page_alloc_debugfs); | 1436 | late_initcall(fail_page_alloc_debugfs); |
@@ -1616,6 +1599,21 @@ static void zlc_mark_zone_full(struct zonelist *zonelist, struct zoneref *z) | |||
1616 | set_bit(i, zlc->fullzones); | 1599 | set_bit(i, zlc->fullzones); |
1617 | } | 1600 | } |
1618 | 1601 | ||
1602 | /* | ||
1603 | * clear all zones full, called after direct reclaim makes progress so that | ||
1604 | * a zone that was recently full is not skipped over for up to a second | ||
1605 | */ | ||
1606 | static void zlc_clear_zones_full(struct zonelist *zonelist) | ||
1607 | { | ||
1608 | struct zonelist_cache *zlc; /* cached zonelist speedup info */ | ||
1609 | |||
1610 | zlc = zonelist->zlcache_ptr; | ||
1611 | if (!zlc) | ||
1612 | return; | ||
1613 | |||
1614 | bitmap_zero(zlc->fullzones, MAX_ZONES_PER_ZONELIST); | ||
1615 | } | ||
1616 | |||
1619 | #else /* CONFIG_NUMA */ | 1617 | #else /* CONFIG_NUMA */ |
1620 | 1618 | ||
1621 | static nodemask_t *zlc_setup(struct zonelist *zonelist, int alloc_flags) | 1619 | static nodemask_t *zlc_setup(struct zonelist *zonelist, int alloc_flags) |
@@ -1632,6 +1630,10 @@ static int zlc_zone_worth_trying(struct zonelist *zonelist, struct zoneref *z, | |||
1632 | static void zlc_mark_zone_full(struct zonelist *zonelist, struct zoneref *z) | 1630 | static void zlc_mark_zone_full(struct zonelist *zonelist, struct zoneref *z) |
1633 | { | 1631 | { |
1634 | } | 1632 | } |
1633 | |||
1634 | static void zlc_clear_zones_full(struct zonelist *zonelist) | ||
1635 | { | ||
1636 | } | ||
1635 | #endif /* CONFIG_NUMA */ | 1637 | #endif /* CONFIG_NUMA */ |
1636 | 1638 | ||
1637 | /* | 1639 | /* |
@@ -1664,7 +1666,7 @@ zonelist_scan: | |||
1664 | continue; | 1666 | continue; |
1665 | if ((alloc_flags & ALLOC_CPUSET) && | 1667 | if ((alloc_flags & ALLOC_CPUSET) && |
1666 | !cpuset_zone_allowed_softwall(zone, gfp_mask)) | 1668 | !cpuset_zone_allowed_softwall(zone, gfp_mask)) |
1667 | goto try_next_zone; | 1669 | continue; |
1668 | 1670 | ||
1669 | BUILD_BUG_ON(ALLOC_NO_WATERMARKS < NR_WMARK); | 1671 | BUILD_BUG_ON(ALLOC_NO_WATERMARKS < NR_WMARK); |
1670 | if (!(alloc_flags & ALLOC_NO_WATERMARKS)) { | 1672 | if (!(alloc_flags & ALLOC_NO_WATERMARKS)) { |
@@ -1676,17 +1678,36 @@ zonelist_scan: | |||
1676 | classzone_idx, alloc_flags)) | 1678 | classzone_idx, alloc_flags)) |
1677 | goto try_this_zone; | 1679 | goto try_this_zone; |
1678 | 1680 | ||
1681 | if (NUMA_BUILD && !did_zlc_setup && nr_online_nodes > 1) { | ||
1682 | /* | ||
1683 | * we do zlc_setup if there are multiple nodes | ||
1684 | * and before considering the first zone allowed | ||
1685 | * by the cpuset. | ||
1686 | */ | ||
1687 | allowednodes = zlc_setup(zonelist, alloc_flags); | ||
1688 | zlc_active = 1; | ||
1689 | did_zlc_setup = 1; | ||
1690 | } | ||
1691 | |||
1679 | if (zone_reclaim_mode == 0) | 1692 | if (zone_reclaim_mode == 0) |
1680 | goto this_zone_full; | 1693 | goto this_zone_full; |
1681 | 1694 | ||
1695 | /* | ||
1696 | * As we may have just activated ZLC, check if the first | ||
1697 | * eligible zone has failed zone_reclaim recently. | ||
1698 | */ | ||
1699 | if (NUMA_BUILD && zlc_active && | ||
1700 | !zlc_zone_worth_trying(zonelist, z, allowednodes)) | ||
1701 | continue; | ||
1702 | |||
1682 | ret = zone_reclaim(zone, gfp_mask, order); | 1703 | ret = zone_reclaim(zone, gfp_mask, order); |
1683 | switch (ret) { | 1704 | switch (ret) { |
1684 | case ZONE_RECLAIM_NOSCAN: | 1705 | case ZONE_RECLAIM_NOSCAN: |
1685 | /* did not scan */ | 1706 | /* did not scan */ |
1686 | goto try_next_zone; | 1707 | continue; |
1687 | case ZONE_RECLAIM_FULL: | 1708 | case ZONE_RECLAIM_FULL: |
1688 | /* scanned but unreclaimable */ | 1709 | /* scanned but unreclaimable */ |
1689 | goto this_zone_full; | 1710 | continue; |
1690 | default: | 1711 | default: |
1691 | /* did we reclaim enough */ | 1712 | /* did we reclaim enough */ |
1692 | if (!zone_watermark_ok(zone, order, mark, | 1713 | if (!zone_watermark_ok(zone, order, mark, |
@@ -1703,16 +1724,6 @@ try_this_zone: | |||
1703 | this_zone_full: | 1724 | this_zone_full: |
1704 | if (NUMA_BUILD) | 1725 | if (NUMA_BUILD) |
1705 | zlc_mark_zone_full(zonelist, z); | 1726 | zlc_mark_zone_full(zonelist, z); |
1706 | try_next_zone: | ||
1707 | if (NUMA_BUILD && !did_zlc_setup && nr_online_nodes > 1) { | ||
1708 | /* | ||
1709 | * we do zlc_setup after the first zone is tried but only | ||
1710 | * if there are multiple nodes make it worthwhile | ||
1711 | */ | ||
1712 | allowednodes = zlc_setup(zonelist, alloc_flags); | ||
1713 | zlc_active = 1; | ||
1714 | did_zlc_setup = 1; | ||
1715 | } | ||
1716 | } | 1727 | } |
1717 | 1728 | ||
1718 | if (unlikely(NUMA_BUILD && page == NULL && zlc_active)) { | 1729 | if (unlikely(NUMA_BUILD && page == NULL && zlc_active)) { |
@@ -1743,7 +1754,6 @@ static DEFINE_RATELIMIT_STATE(nopage_rs, | |||
1743 | 1754 | ||
1744 | void warn_alloc_failed(gfp_t gfp_mask, int order, const char *fmt, ...) | 1755 | void warn_alloc_failed(gfp_t gfp_mask, int order, const char *fmt, ...) |
1745 | { | 1756 | { |
1746 | va_list args; | ||
1747 | unsigned int filter = SHOW_MEM_FILTER_NODES; | 1757 | unsigned int filter = SHOW_MEM_FILTER_NODES; |
1748 | 1758 | ||
1749 | if ((gfp_mask & __GFP_NOWARN) || !__ratelimit(&nopage_rs)) | 1759 | if ((gfp_mask & __GFP_NOWARN) || !__ratelimit(&nopage_rs)) |
@@ -1762,14 +1772,21 @@ void warn_alloc_failed(gfp_t gfp_mask, int order, const char *fmt, ...) | |||
1762 | filter &= ~SHOW_MEM_FILTER_NODES; | 1772 | filter &= ~SHOW_MEM_FILTER_NODES; |
1763 | 1773 | ||
1764 | if (fmt) { | 1774 | if (fmt) { |
1765 | printk(KERN_WARNING); | 1775 | struct va_format vaf; |
1776 | va_list args; | ||
1777 | |||
1766 | va_start(args, fmt); | 1778 | va_start(args, fmt); |
1767 | vprintk(fmt, args); | 1779 | |
1780 | vaf.fmt = fmt; | ||
1781 | vaf.va = &args; | ||
1782 | |||
1783 | pr_warn("%pV", &vaf); | ||
1784 | |||
1768 | va_end(args); | 1785 | va_end(args); |
1769 | } | 1786 | } |
1770 | 1787 | ||
1771 | pr_warning("%s: page allocation failure: order:%d, mode:0x%x\n", | 1788 | pr_warn("%s: page allocation failure: order:%d, mode:0x%x\n", |
1772 | current->comm, order, gfp_mask); | 1789 | current->comm, order, gfp_mask); |
1773 | 1790 | ||
1774 | dump_stack(); | 1791 | dump_stack(); |
1775 | if (!should_suppress_show_mem()) | 1792 | if (!should_suppress_show_mem()) |
@@ -1954,6 +1971,10 @@ __alloc_pages_direct_reclaim(gfp_t gfp_mask, unsigned int order, | |||
1954 | if (unlikely(!(*did_some_progress))) | 1971 | if (unlikely(!(*did_some_progress))) |
1955 | return NULL; | 1972 | return NULL; |
1956 | 1973 | ||
1974 | /* After successful reclaim, reconsider all zones for allocation */ | ||
1975 | if (NUMA_BUILD) | ||
1976 | zlc_clear_zones_full(zonelist); | ||
1977 | |||
1957 | retry: | 1978 | retry: |
1958 | page = get_page_from_freelist(gfp_mask, nodemask, order, | 1979 | page = get_page_from_freelist(gfp_mask, nodemask, order, |
1959 | zonelist, high_zoneidx, | 1980 | zonelist, high_zoneidx, |