--- linux-2.6-npiggin/mm/vmscan.c | 14 +++++++++++++- 1 files changed, 13 insertions(+), 1 deletion(-) diff -puN mm/vmscan.c~vm-no-wild-kswapd mm/vmscan.c --- linux-2.6/mm/vmscan.c~vm-no-wild-kswapd 2004-09-25 10:09:16.000000000 +1000 +++ linux-2.6-npiggin/mm/vmscan.c 2004-09-25 10:15:58.000000000 +1000 @@ -993,10 +993,13 @@ static int balance_pgdat(pg_data_t *pgda int to_free = nr_pages; int priority; int i; - int total_scanned = 0, total_reclaimed = 0; + int total_scanned, total_reclaimed; struct reclaim_state *reclaim_state = current->reclaim_state; struct scan_control sc; +loop_again: + total_scanned = 0; + total_reclaimed = 0; sc.gfp_mask = GFP_KERNEL; sc.may_writepage = 0; sc.nr_mapped = read_page_state(nr_mapped); @@ -1095,6 +1098,15 @@ scan: */ if (total_scanned && priority < DEF_PRIORITY - 2) blk_congestion_wait(WRITE, HZ/10); + + /* + * We do this so kswapd doesn't build up large priorities for + * example when it is freeing in parallel with allocators. It + * matches the direct reclaim path behaviour in terms of impact + * on zone->*_priority. + */ + if (total_reclaimed >= 32) + goto loop_again; } out: for (i = 0; i < pgdat->nr_zones; i++) { _