- Off-by-one in balance_pgdat means that we're not scanning the zones all the way down to priority=0. - Always set zone->temp_priority in shrink_caches(). I'm not sure why I had the `if (zone->free_pages < zone->pages_high)' test in there, but it's preventing us from setting ->prev_priority correctly on the try_to_free_pages() path. - Set zone->prev_priority to the current priority if it's currently a "lower" priority. This allows us to build up the pressure on mapped pages on the first scanning pass rather than only on successive passes. Signed-off-by: Andrew Morton --- 25-akpm/mm/vmscan.c | 9 ++++++--- 1 files changed, 6 insertions(+), 3 deletions(-) diff -puN mm/vmscan.c~shrink_all_memory-fix mm/vmscan.c --- 25/mm/vmscan.c~shrink_all_memory-fix 2004-05-31 03:04:05.669374824 -0700 +++ 25-akpm/mm/vmscan.c 2004-05-31 03:15:23.490330376 -0700 @@ -813,8 +813,9 @@ shrink_caches(struct zone **zones, int p struct zone *zone = zones[i]; int max_scan; - if (zone->free_pages < zone->pages_high) - zone->temp_priority = priority; + zone->temp_priority = priority; + if (zone->prev_priority > priority) + zone->prev_priority = priority; if (zone->all_unreclaimable && priority != DEF_PRIORITY) continue; /* Let kswapd poll it */ @@ -945,7 +946,7 @@ static int balance_pgdat(pg_data_t *pgda zone->temp_priority = DEF_PRIORITY; } - for (priority = DEF_PRIORITY; priority; priority--) { + for (priority = DEF_PRIORITY; priority >= 0; priority--) { int all_zones_ok = 1; int end_zone = 0; /* Inclusive. 0 = ZONE_DMA */ @@ -995,6 +996,8 @@ scan: all_zones_ok = 0; } zone->temp_priority = priority; + if (zone->prev_priority > priority) + zone->prev_priority = priority; max_scan = (zone->nr_active + zone->nr_inactive) >> priority; reclaimed = shrink_zone(zone, max_scan, GFP_KERNEL, _