summaryrefslogtreecommitdiffstats
path: root/mm/page_alloc.c
diff options
context:
space:
mode:
authorMel Gorman <mgorman@techsingularity.net>2016-07-28 18:46:11 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-07-28 19:07:41 -0400
commit281e37265f2826ed401d84d6790226448ef3f0e8 (patch)
treea29b375b754c242f29082cd9e0df1a48c8109ac2 /mm/page_alloc.c
parent1e6b10857f91685c60c341703ece4ae9bb775cf3 (diff)
mm, page_alloc: consider dirtyable memory in terms of nodes
Historically dirty pages were spread among zones but now that LRUs are per-node it is more appropriate to consider dirty pages in a node. Link: http://lkml.kernel.org/r/1467970510-21195-17-git-send-email-mgorman@techsingularity.net Signed-off-by: Mel Gorman <mgorman@techsingularity.net> Signed-off-by: Johannes Weiner <hannes@cmpxchg.org> Acked-by: Vlastimil Babka <vbabka@suse.cz> Acked-by: Michal Hocko <mhocko@suse.com> Cc: Hillf Danton <hillf.zj@alibaba-inc.com> Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com> Cc: Minchan Kim <minchan@kernel.org> Cc: Rik van Riel <riel@surriel.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/page_alloc.c')
-rw-r--r--mm/page_alloc.c26
1 files changed, 11 insertions, 15 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 749b3c358ead..73b018df6e42 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -2912,31 +2912,24 @@ zonelist_scan:
2912 } 2912 }
2913 /* 2913 /*
2914 * When allocating a page cache page for writing, we 2914 * When allocating a page cache page for writing, we
2915 * want to get it from a zone that is within its dirty 2915 * want to get it from a node that is within its dirty
2916 * limit, such that no single zone holds more than its 2916 * limit, such that no single node holds more than its
2917 * proportional share of globally allowed dirty pages. 2917 * proportional share of globally allowed dirty pages.
2918 * The dirty limits take into account the zone's 2918 * The dirty limits take into account the node's
2919 * lowmem reserves and high watermark so that kswapd 2919 * lowmem reserves and high watermark so that kswapd
2920 * should be able to balance it without having to 2920 * should be able to balance it without having to
2921 * write pages from its LRU list. 2921 * write pages from its LRU list.
2922 * 2922 *
2923 * This may look like it could increase pressure on
2924 * lower zones by failing allocations in higher zones
2925 * before they are full. But the pages that do spill
2926 * over are limited as the lower zones are protected
2927 * by this very same mechanism. It should not become
2928 * a practical burden to them.
2929 *
2930 * XXX: For now, allow allocations to potentially 2923 * XXX: For now, allow allocations to potentially
2931 * exceed the per-zone dirty limit in the slowpath 2924 * exceed the per-node dirty limit in the slowpath
2932 * (spread_dirty_pages unset) before going into reclaim, 2925 * (spread_dirty_pages unset) before going into reclaim,
2933 * which is important when on a NUMA setup the allowed 2926 * which is important when on a NUMA setup the allowed
2934 * zones are together not big enough to reach the 2927 * nodes are together not big enough to reach the
2935 * global limit. The proper fix for these situations 2928 * global limit. The proper fix for these situations
2936 * will require awareness of zones in the 2929 * will require awareness of nodes in the
2937 * dirty-throttling and the flusher threads. 2930 * dirty-throttling and the flusher threads.
2938 */ 2931 */
2939 if (ac->spread_dirty_pages && !zone_dirty_ok(zone)) 2932 if (ac->spread_dirty_pages && !node_dirty_ok(zone->zone_pgdat))
2940 continue; 2933 continue;
2941 2934
2942 mark = zone->watermark[alloc_flags & ALLOC_WMARK_MASK]; 2935 mark = zone->watermark[alloc_flags & ALLOC_WMARK_MASK];
@@ -6701,6 +6694,9 @@ static void calculate_totalreserve_pages(void)
6701 enum zone_type i, j; 6694 enum zone_type i, j;
6702 6695
6703 for_each_online_pgdat(pgdat) { 6696 for_each_online_pgdat(pgdat) {
6697
6698 pgdat->totalreserve_pages = 0;
6699
6704 for (i = 0; i < MAX_NR_ZONES; i++) { 6700 for (i = 0; i < MAX_NR_ZONES; i++) {
6705 struct zone *zone = pgdat->node_zones + i; 6701 struct zone *zone = pgdat->node_zones + i;
6706 long max = 0; 6702 long max = 0;
@@ -6717,7 +6713,7 @@ static void calculate_totalreserve_pages(void)
6717 if (max > zone->managed_pages) 6713 if (max > zone->managed_pages)
6718 max = zone->managed_pages; 6714 max = zone->managed_pages;
6719 6715
6720 zone->totalreserve_pages = max; 6716 pgdat->totalreserve_pages += max;
6721 6717
6722 reserve_pages += max; 6718 reserve_pages += max;
6723 } 6719 }