Index: linux-2.6.16-rc2/mm/vmscan.c =================================================================== --- linux-2.6.16-rc2.orig/mm/vmscan.c 2006-02-04 20:55:33.000000000 -0800 +++ linux-2.6.16-rc2/mm/vmscan.c 2006-02-04 21:23:52.000000000 -0800 @@ -55,9 +55,6 @@ struct scan_control { /* Incremented by the number of inactive pages that were scanned */ unsigned long nr_scanned; - /* Incremented by the number of pages reclaimed */ - unsigned long nr_reclaimed; - /* This context's SWAP_CLUSTER_MAX. If freeing memory for * suspend, we effectively ignore SWAP_CLUSTER_MAX. * In this context, it doesn't matter that we scan the @@ -80,7 +77,6 @@ struct scan_control { static inline void init_scan_control(struct scan_control *sc, int nr_pages) { sc->nr_scanned = 0; - sc->nr_reclaimed = 0; if (nr_pages > SWAP_CLUSTER_MAX) sc->swap_cluster_max = nr_pages; else @@ -582,7 +578,6 @@ keep: if (pagevec_count(&freed_pvec)) __pagevec_release_nonlru(&freed_pvec); mod_page_state(pgactivate, pgactivate); - sc->nr_reclaimed += reclaimed; return reclaimed; } @@ -1091,11 +1086,12 @@ static int isolate_lru_pages(int nr_to_s /* * shrink_cache() adds the number of pages reclaimed to sc->nr_reclaimed */ -static void shrink_cache(int max_scan, struct zone *zone, gfp_t gfp_mask, +static int shrink_cache(int max_scan, struct zone *zone, gfp_t gfp_mask, struct scan_control *sc) { LIST_HEAD(page_list); struct pagevec pvec; + int nr_reclaimed = 0; pagevec_init(&pvec, 1); @@ -1118,7 +1114,7 @@ static void shrink_cache(int max_scan, s goto done; max_scan -= nr_scan; - nr_freed = shrink_list(&page_list, gfp_mask, sc); + nr_reclaimed += nr_freed = shrink_list(&page_list, gfp_mask, sc); local_irq_disable(); if (current_is_kswapd()) { @@ -1151,6 +1147,7 @@ static void shrink_cache(int max_scan, s spin_unlock_irq(&zone->lru_lock); done: pagevec_release(&pvec); + return nr_reclaimed; } /* @@ -1301,12 +1298,13 @@ refill_inactive_zone(int nr_pages, struc /* * This is a basic per-zone page freer. Used by both kswapd and direct reclaim. */ -static void +static int shrink_zone(int priority, struct zone *zone, gfp_t gfp_mask, struct scan_control *sc) { unsigned long nr_active; unsigned long nr_inactive; unsigned long nr_to_scan; + unsigned long nr_reclaimed = 0; atomic_inc(&zone->reclaim_in_progress); @@ -1340,13 +1338,14 @@ shrink_zone(int priority, struct zone *z nr_to_scan = min(nr_inactive, (unsigned long)sc->swap_cluster_max); nr_inactive -= nr_to_scan; - shrink_cache(nr_to_scan, zone, gfp_mask, sc); + nr_reclaimed += shrink_cache(nr_to_scan, zone, gfp_mask, sc); } } throttle_vm_writeout(); atomic_dec(&zone->reclaim_in_progress); + return nr_reclaimed; } /* @@ -1365,11 +1364,12 @@ shrink_zone(int priority, struct zone *z * If a zone is deemed to be full of pinned pages then just give it a light * scan then give up on it. */ -static void +static int shrink_caches(int priority, struct zone **zones, gfp_t gfp_mask, struct scan_control *sc) { int i; + int nr_reclaimed = 0; for (i = 0; zones[i] != NULL; i++) { struct zone *zone = zones[i]; @@ -1387,8 +1387,9 @@ shrink_caches(int priority, struct zone if (zone->all_unreclaimable && priority != DEF_PRIORITY) continue; /* Let kswapd poll it */ - shrink_zone(priority, zone, gfp_mask, sc); + nr_reclaimed += shrink_zone(priority, zone, gfp_mask, sc); } + return nr_reclaimed; } /* @@ -1436,14 +1437,13 @@ int try_to_free_pages(struct zone **zone if (!priority) disable_swap_token(); - shrink_caches(priority, zones, gfp_mask, &sc); + total_reclaimed += shrink_caches(priority, zones, gfp_mask, &sc); shrink_slab(sc.nr_scanned, gfp_mask, lru_pages); if (reclaim_state) { - sc.nr_reclaimed += reclaim_state->reclaimed_slab; + total_reclaimed += reclaim_state->reclaimed_slab; reclaim_state->reclaimed_slab = 0; } total_scanned += sc.nr_scanned; - total_reclaimed += sc.nr_reclaimed; if (total_reclaimed >= sc.swap_cluster_max) { ret = 1; goto out; @@ -1601,13 +1601,12 @@ scan: init_scan_control(&sc, nr_pages); atomic_inc(&zone->reclaim_in_progress); - shrink_zone(priority, zone, gfp_mask, &sc); + total_reclaimed += shrink_zone(priority, zone, gfp_mask, &sc); atomic_dec(&zone->reclaim_in_progress); reclaim_state->reclaimed_slab = 0; nr_slab = shrink_slab(sc.nr_scanned, GFP_KERNEL, lru_pages); - sc.nr_reclaimed += reclaim_state->reclaimed_slab; - total_reclaimed += sc.nr_reclaimed; + total_reclaimed += reclaim_state->reclaimed_slab; total_scanned += sc.nr_scanned; if (zone->all_unreclaimable) continue; @@ -1858,6 +1857,7 @@ int zone_reclaim(struct zone *zone, gfp_ cpumask_t mask; int node_id; int priority; + int total_reclaimed; if (time_before(jiffies, zone->last_unsuccessful_zone_reclaim + zone_reclaim_interval)) @@ -1882,6 +1882,7 @@ int zone_reclaim(struct zone *zone, gfp_ nr_pages = 1 << order; init_scan_control(&sc, nr_pages); + total_reclaimed = 0; cond_resched(); p->flags |= PF_MEMALLOC; @@ -1893,12 +1894,12 @@ int zone_reclaim(struct zone *zone, gfp_ * until we have enough memory freed. */ for (priority = ZONE_RECLAIM_PRIORITY; - priority >=0 && sc.nr_reclaimed < nr_pages; + priority >=0 && total_reclaimed < nr_pages; priority--) - shrink_zone(priority, zone, gfp_mask, &sc); + total_reclaimed += shrink_zone(priority, zone, gfp_mask, &sc); - if (sc.nr_reclaimed < nr_pages && (zone_reclaim_mode & RECLAIM_SLAB)) { + if (total_reclaimed < nr_pages && (zone_reclaim_mode & RECLAIM_SLAB)) { /* * shrink_slab does not currently allow us to determine * how many pages were freed in the zone. So we just @@ -1908,16 +1909,16 @@ int zone_reclaim(struct zone *zone, gfp_ * a long time. */ shrink_slab(sc.nr_scanned, gfp_mask, order); - sc.nr_reclaimed = 1; /* Avoid getting the off node timeout */ + total_reclaimed = 1; /* Avoid getting the off node timeout */ } p->reclaim_state = NULL; current->flags &= ~PF_MEMALLOC; - if (sc.nr_reclaimed == 0) + if (total_reclaimed == 0) zone->last_unsuccessful_zone_reclaim = jiffies; - return sc.nr_reclaimed >= nr_pages; + return total_reclaimed >= nr_pages; } #endif