--- .orig/mm/vmscan.c 2004-07-22 20:32:01.658676745 -0400 +++ 2.6.8-rc1-vmfix/mm/vmscan.c 2004-07-19 00:52:02.000000000 -0400 @@ -798,6 +798,7 @@ static void shrink_zone(struct zone *zone, struct scan_control *sc) { + int nr_pages; unsigned long nr_active; unsigned long nr_inactive; @@ -819,7 +820,7 @@ else nr_inactive = 0; - sc->nr_to_reclaim = SWAP_CLUSTER_MAX; + nr_pages = sc->nr_to_reclaim; while (nr_active || nr_inactive) { if (nr_active) { @@ -834,7 +835,9 @@ (unsigned long)SWAP_CLUSTER_MAX); nr_inactive -= sc->nr_to_scan; shrink_cache(zone, sc); - if (sc->nr_to_reclaim <= 0) + if (nr_pages == 0 && zone->free_pages > zone->pages_high) + break; + if (nr_pages && sc->nr_to_reclaim <= 0) break; } } @@ -871,6 +874,7 @@ if (zone->all_unreclaimable && sc->priority != DEF_PRIORITY) continue; /* Let kswapd poll it */ + sc->nr_to_reclaim = SWAP_CLUSTER_MAX; shrink_zone(zone, sc); } } @@ -917,12 +921,12 @@ sc.nr_reclaimed += reclaim_state->reclaimed_slab; reclaim_state->reclaimed_slab = 0; } - if (sc.nr_reclaimed >= SWAP_CLUSTER_MAX) { + total_scanned += sc.nr_scanned; + total_reclaimed += sc.nr_reclaimed; + if (total_reclaimed >= SWAP_CLUSTER_MAX) { ret = 1; goto out; } - total_scanned += sc.nr_scanned; - total_reclaimed += sc.nr_reclaimed; /* * Try to write back as many pages as we just scanned. This @@ -1039,7 +1043,9 @@ if (nr_pages == 0) { /* Not software suspend */ if (zone->free_pages <= zone->pages_high) all_zones_ok = 0; - } + sc.nr_to_reclaim = 0; + } else + sc.nr_to_reclaim = to_free - total_reclaimed; zone->temp_priority = priority; if (zone->prev_priority > priority) zone->prev_priority = priority;