diff options
-rw-r--r-- | include/linux/mmzone.h | 2 | ||||
-rw-r--r-- | mm/page_alloc.c | 1 | ||||
-rw-r--r-- | mm/vmscan.c | 10 |
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 | ||