aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/mmzone.h2
-rw-r--r--mm/page_alloc.c1
-rw-r--r--mm/vmscan.c10
3 files changed, 13 insertions, 0 deletions
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index dfc2452ccb10..18fed8b67943 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -149,6 +149,8 @@ struct zone {
149 * as it fails a watermark_ok() in __alloc_pages? 149 * as it fails a watermark_ok() in __alloc_pages?
150 */ 150 */
151 int reclaim_pages; 151 int reclaim_pages;
152 /* A count of how many reclaimers are scanning this zone */
153 atomic_t reclaim_in_progress;
152 154
153 /* 155 /*
154 * prev_priority holds the scanning priority for this zone. It is 156 * prev_priority holds the scanning priority for this zone. It is
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index a9da20bc2ed0..2019c1b19254 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -1738,6 +1738,7 @@ static void __init free_area_init_core(struct pglist_data *pgdat,
1738 zone->nr_scan_inactive = 0; 1738 zone->nr_scan_inactive = 0;
1739 zone->nr_active = 0; 1739 zone->nr_active = 0;
1740 zone->nr_inactive = 0; 1740 zone->nr_inactive = 0;
1741 atomic_set(&zone->reclaim_in_progress, -1);
1741 if (!size) 1742 if (!size)
1742 continue; 1743 continue;
1743 1744
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 7da846960d8a..24da725a30f0 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -900,7 +900,9 @@ shrink_caches(struct zone **zones, struct scan_control *sc)
900 if (zone->all_unreclaimable && sc->priority != DEF_PRIORITY) 900 if (zone->all_unreclaimable && sc->priority != DEF_PRIORITY)
901 continue; /* Let kswapd poll it */ 901 continue; /* Let kswapd poll it */
902 902
903 atomic_inc(&zone->reclaim_in_progress);
903 shrink_zone(zone, sc); 904 shrink_zone(zone, sc);
905 atomic_dec(&zone->reclaim_in_progress);
904 } 906 }
905} 907}
906 908
@@ -1111,7 +1113,9 @@ scan:
1111 sc.nr_reclaimed = 0; 1113 sc.nr_reclaimed = 0;
1112 sc.priority = priority; 1114 sc.priority = priority;
1113 sc.swap_cluster_max = nr_pages? nr_pages : SWAP_CLUSTER_MAX; 1115 sc.swap_cluster_max = nr_pages? nr_pages : SWAP_CLUSTER_MAX;
1116 atomic_inc(&zone->reclaim_in_progress);
1114 shrink_zone(zone, &sc); 1117 shrink_zone(zone, &sc);
1118 atomic_dec(&zone->reclaim_in_progress);
1115 reclaim_state->reclaimed_slab = 0; 1119 reclaim_state->reclaimed_slab = 0;
1116 nr_slab = shrink_slab(sc.nr_scanned, GFP_KERNEL, 1120 nr_slab = shrink_slab(sc.nr_scanned, GFP_KERNEL,
1117 lru_pages); 1121 lru_pages);
@@ -1354,9 +1358,15 @@ int zone_reclaim(struct zone *zone, unsigned int gfp_mask, unsigned int order)
1354 else 1358 else
1355 sc.swap_cluster_max = SWAP_CLUSTER_MAX; 1359 sc.swap_cluster_max = SWAP_CLUSTER_MAX;
1356 1360
1361 /* Don't reclaim the zone if there are other reclaimers active */
1362 if (!atomic_inc_and_test(&zone->reclaim_in_progress))
1363 goto out;
1364
1357 shrink_zone(zone, &sc); 1365 shrink_zone(zone, &sc);
1358 total_reclaimed = sc.nr_reclaimed; 1366 total_reclaimed = sc.nr_reclaimed;
1359 1367
1368 out:
1369 atomic_dec(&zone->reclaim_in_progress);
1360 return total_reclaimed; 1370 return total_reclaimed;
1361} 1371}
1362 1372