|
@@ -1799,6 +1799,22 @@ static void zlc_clear_zones_full(struct zonelist *zonelist)
|
|
|
bitmap_zero(zlc->fullzones, MAX_ZONES_PER_ZONELIST);
|
|
|
}
|
|
|
|
|
|
+static bool zone_allows_reclaim(struct zone *local_zone, struct zone *zone)
|
|
|
+{
|
|
|
+ return node_isset(local_zone->node, zone->zone_pgdat->reclaim_nodes);
|
|
|
+}
|
|
|
+
|
|
|
+static void __paginginit init_zone_allows_reclaim(int nid)
|
|
|
+{
|
|
|
+ int i;
|
|
|
+
|
|
|
+ for_each_online_node(i)
|
|
|
+ if (node_distance(nid, i) <= RECLAIM_DISTANCE) {
|
|
|
+ node_set(i, NODE_DATA(nid)->reclaim_nodes);
|
|
|
+ zone_reclaim_mode = 1;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
#else /* CONFIG_NUMA */
|
|
|
|
|
|
static 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)
|
|
|
static void zlc_clear_zones_full(struct zonelist *zonelist)
|
|
|
{
|
|
|
}
|
|
|
+
|
|
|
+static bool zone_allows_reclaim(struct zone *local_zone, struct zone *zone)
|
|
|
+{
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
+static inline void init_zone_allows_reclaim(int nid)
|
|
|
+{
|
|
|
+}
|
|
|
#endif /* CONFIG_NUMA */
|
|
|
|
|
|
/*
|
|
@@ -1903,7 +1928,8 @@ zonelist_scan:
|
|
|
did_zlc_setup = 1;
|
|
|
}
|
|
|
|
|
|
- if (zone_reclaim_mode == 0)
|
|
|
+ if (zone_reclaim_mode == 0 ||
|
|
|
+ !zone_allows_reclaim(preferred_zone, zone))
|
|
|
goto this_zone_full;
|
|
|
|
|
|
/*
|
|
@@ -3364,21 +3390,13 @@ static void build_zonelists(pg_data_t *pgdat)
|
|
|
j = 0;
|
|
|
|
|
|
while ((node = find_next_best_node(local_node, &used_mask)) >= 0) {
|
|
|
- int distance = node_distance(local_node, node);
|
|
|
-
|
|
|
- /*
|
|
|
- * If another node is sufficiently far away then it is better
|
|
|
- * to reclaim pages in a zone before going off node.
|
|
|
- */
|
|
|
- if (distance > RECLAIM_DISTANCE)
|
|
|
- zone_reclaim_mode = 1;
|
|
|
-
|
|
|
/*
|
|
|
* We don't want to pressure a particular node.
|
|
|
* So adding penalty to the first node in same
|
|
|
* distance group to make it round-robin.
|
|
|
*/
|
|
|
- if (distance != node_distance(local_node, prev_node))
|
|
|
+ if (node_distance(local_node, node) !=
|
|
|
+ node_distance(local_node, prev_node))
|
|
|
node_load[node] = load;
|
|
|
|
|
|
prev_node = node;
|
|
@@ -4552,6 +4570,7 @@ void __paginginit free_area_init_node(int nid, unsigned long *zones_size,
|
|
|
|
|
|
pgdat->node_id = nid;
|
|
|
pgdat->node_start_pfn = node_start_pfn;
|
|
|
+ init_zone_allows_reclaim(nid);
|
|
|
calculate_node_totalpages(pgdat, zones_size, zholes_size);
|
|
|
|
|
|
alloc_node_mem_map(pgdat);
|