aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
Diffstat (limited to 'mm')
-rw-r--r--mm/page_alloc.c41
1 files changed, 30 insertions, 11 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index dbb53866c3aa..9b8e6243a524 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -1799,6 +1799,22 @@ static void zlc_clear_zones_full(struct zonelist *zonelist)
1799 bitmap_zero(zlc->fullzones, MAX_ZONES_PER_ZONELIST); 1799 bitmap_zero(zlc->fullzones, MAX_ZONES_PER_ZONELIST);
1800} 1800}
1801 1801
1802static bool zone_allows_reclaim(struct zone *local_zone, struct zone *zone)
1803{
1804 return node_isset(local_zone->node, zone->zone_pgdat->reclaim_nodes);
1805}
1806
1807static void __paginginit init_zone_allows_reclaim(int nid)
1808{
1809 int i;
1810
1811 for_each_online_node(i)
1812 if (node_distance(nid, i) <= RECLAIM_DISTANCE) {
1813 node_set(i, NODE_DATA(nid)->reclaim_nodes);
1814 zone_reclaim_mode = 1;
1815 }
1816}
1817
1802#else /* CONFIG_NUMA */ 1818#else /* CONFIG_NUMA */
1803 1819
1804static nodemask_t *zlc_setup(struct zonelist *zonelist, int alloc_flags) 1820static nodemask_t *zlc_setup(struct zonelist *zonelist, int alloc_flags)
@@ -1819,6 +1835,15 @@ static void zlc_mark_zone_full(struct zonelist *zonelist, struct zoneref *z)
1819static void zlc_clear_zones_full(struct zonelist *zonelist) 1835static void zlc_clear_zones_full(struct zonelist *zonelist)
1820{ 1836{
1821} 1837}
1838
1839static bool zone_allows_reclaim(struct zone *local_zone, struct zone *zone)
1840{
1841 return true;
1842}
1843
1844static inline void init_zone_allows_reclaim(int nid)
1845{
1846}
1822#endif /* CONFIG_NUMA */ 1847#endif /* CONFIG_NUMA */
1823 1848
1824/* 1849/*
@@ -1903,7 +1928,8 @@ zonelist_scan:
1903 did_zlc_setup = 1; 1928 did_zlc_setup = 1;
1904 } 1929 }
1905 1930
1906 if (zone_reclaim_mode == 0) 1931 if (zone_reclaim_mode == 0 ||
1932 !zone_allows_reclaim(preferred_zone, zone))
1907 goto this_zone_full; 1933 goto this_zone_full;
1908 1934
1909 /* 1935 /*
@@ -3364,21 +3390,13 @@ static void build_zonelists(pg_data_t *pgdat)
3364 j = 0; 3390 j = 0;
3365 3391
3366 while ((node = find_next_best_node(local_node, &used_mask)) >= 0) { 3392 while ((node = find_next_best_node(local_node, &used_mask)) >= 0) {
3367 int distance = node_distance(local_node, node);
3368
3369 /*
3370 * If another node is sufficiently far away then it is better
3371 * to reclaim pages in a zone before going off node.
3372 */
3373 if (distance > RECLAIM_DISTANCE)
3374 zone_reclaim_mode = 1;
3375
3376 /* 3393 /*
3377 * We don't want to pressure a particular node. 3394 * We don't want to pressure a particular node.
3378 * So adding penalty to the first node in same 3395 * So adding penalty to the first node in same
3379 * distance group to make it round-robin. 3396 * distance group to make it round-robin.
3380 */ 3397 */
3381 if (distance != node_distance(local_node, prev_node)) 3398 if (node_distance(local_node, node) !=
3399 node_distance(local_node, prev_node))
3382 node_load[node] = load; 3400 node_load[node] = load;
3383 3401
3384 prev_node = node; 3402 prev_node = node;
@@ -4552,6 +4570,7 @@ void __paginginit free_area_init_node(int nid, unsigned long *zones_size,
4552 4570
4553 pgdat->node_id = nid; 4571 pgdat->node_id = nid;
4554 pgdat->node_start_pfn = node_start_pfn; 4572 pgdat->node_start_pfn = node_start_pfn;
4573 init_zone_allows_reclaim(nid);
4555 calculate_node_totalpages(pgdat, zones_size, zholes_size); 4574 calculate_node_totalpages(pgdat, zones_size, zholes_size);
4556 4575
4557 alloc_node_mem_map(pgdat); 4576 alloc_node_mem_map(pgdat);