Commit 1e7e5a90 authored by Martin Hicks's avatar Martin Hicks Committed by Linus Torvalds

[PATCH] VM: rate limit early reclaim

When early zone reclaim is turned on the LRU is scanned more frequently when a
zone is low on memory.  This limits when the zone reclaim can be called by
skipping the scan if another thread (either via kswapd or sync reclaim) is
already reclaiming from the zone.
Signed-off-by: default avatarMartin Hicks <mort@sgi.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 0c35bbad
...@@ -149,6 +149,8 @@ struct zone { ...@@ -149,6 +149,8 @@ struct zone {
* as it fails a watermark_ok() in __alloc_pages? * as it fails a watermark_ok() in __alloc_pages?
*/ */
int reclaim_pages; int reclaim_pages;
/* A count of how many reclaimers are scanning this zone */
atomic_t reclaim_in_progress;
/* /*
* prev_priority holds the scanning priority for this zone. It is * prev_priority holds the scanning priority for this zone. It is
......
...@@ -1738,6 +1738,7 @@ static void __init free_area_init_core(struct pglist_data *pgdat, ...@@ -1738,6 +1738,7 @@ static void __init free_area_init_core(struct pglist_data *pgdat,
zone->nr_scan_inactive = 0; zone->nr_scan_inactive = 0;
zone->nr_active = 0; zone->nr_active = 0;
zone->nr_inactive = 0; zone->nr_inactive = 0;
atomic_set(&zone->reclaim_in_progress, -1);
if (!size) if (!size)
continue; continue;
......
...@@ -900,7 +900,9 @@ shrink_caches(struct zone **zones, struct scan_control *sc) ...@@ -900,7 +900,9 @@ shrink_caches(struct zone **zones, struct scan_control *sc)
if (zone->all_unreclaimable && sc->priority != DEF_PRIORITY) if (zone->all_unreclaimable && sc->priority != DEF_PRIORITY)
continue; /* Let kswapd poll it */ continue; /* Let kswapd poll it */
atomic_inc(&zone->reclaim_in_progress);
shrink_zone(zone, sc); shrink_zone(zone, sc);
atomic_dec(&zone->reclaim_in_progress);
} }
} }
...@@ -1111,7 +1113,9 @@ static int balance_pgdat(pg_data_t *pgdat, int nr_pages, int order) ...@@ -1111,7 +1113,9 @@ static int balance_pgdat(pg_data_t *pgdat, int nr_pages, int order)
sc.nr_reclaimed = 0; sc.nr_reclaimed = 0;
sc.priority = priority; sc.priority = priority;
sc.swap_cluster_max = nr_pages? nr_pages : SWAP_CLUSTER_MAX; sc.swap_cluster_max = nr_pages? nr_pages : SWAP_CLUSTER_MAX;
atomic_inc(&zone->reclaim_in_progress);
shrink_zone(zone, &sc); shrink_zone(zone, &sc);
atomic_dec(&zone->reclaim_in_progress);
reclaim_state->reclaimed_slab = 0; reclaim_state->reclaimed_slab = 0;
nr_slab = shrink_slab(sc.nr_scanned, GFP_KERNEL, nr_slab = shrink_slab(sc.nr_scanned, GFP_KERNEL,
lru_pages); lru_pages);
...@@ -1354,9 +1358,15 @@ int zone_reclaim(struct zone *zone, unsigned int gfp_mask, unsigned int order) ...@@ -1354,9 +1358,15 @@ int zone_reclaim(struct zone *zone, unsigned int gfp_mask, unsigned int order)
else else
sc.swap_cluster_max = SWAP_CLUSTER_MAX; sc.swap_cluster_max = SWAP_CLUSTER_MAX;
/* Don't reclaim the zone if there are other reclaimers active */
if (!atomic_inc_and_test(&zone->reclaim_in_progress))
goto out;
shrink_zone(zone, &sc); shrink_zone(zone, &sc);
total_reclaimed = sc.nr_reclaimed; total_reclaimed = sc.nr_reclaimed;
out:
atomic_dec(&zone->reclaim_in_progress);
return total_reclaimed; return total_reclaimed;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment