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 | ||
