Signed-off-by: Andrew Morton --- 25-akpm/mm/vmscan.c | 24 +++++++++++++++++------- 1 files changed, 17 insertions(+), 7 deletions(-) diff -puN mm/vmscan.c~no-wild-kswapd-kswapd-continue mm/vmscan.c --- 25/mm/vmscan.c~no-wild-kswapd-kswapd-continue 2004-10-16 22:47:32.172599168 -0700 +++ 25-akpm/mm/vmscan.c 2004-10-16 22:47:32.177598408 -0700 @@ -1002,7 +1002,7 @@ out: * pages than that. Once the required number of pages have been reclaimed from * each zone, we're done. kwsapd will go back to sleep until someone wakes it. */ -static int balance_pgdat(pg_data_t *pgdat, int nr_pages) +static int balance_pgdat(pg_data_t *pgdat, int nr_pages, int *more_to_do) { int to_free = nr_pages; int priority; @@ -1127,10 +1127,15 @@ static int balance_pgdat(pg_data_t *pgda blk_congestion_wait(WRITE, HZ/10); } out: + *more_to_do = 0; for (i = 0; i < pgdat->nr_zones; i++) { struct zone *zone = pgdat->node_zones + i; zone->prev_priority = zone->temp_priority; + if (zone->free_pages < zone->pages_high && + zone->present_pages && !zone->all_unreclaimable) + *more_to_do = 1; + } return total_reclaimed; } @@ -1157,6 +1162,7 @@ int kswapd(void *p) .reclaimed_slab = 0, }; cpumask_t cpumask; + int more_to_do = 0; daemonize("kswapd%d", pgdat->node_id); cpumask = node_to_cpumask(pgdat->node_id); @@ -1181,11 +1187,13 @@ int kswapd(void *p) for ( ; ; ) { if (current->flags & PF_FREEZE) refrigerator(PF_FREEZE); - prepare_to_wait(&pgdat->kswapd_wait, &wait, TASK_INTERRUPTIBLE); - schedule(); - finish_wait(&pgdat->kswapd_wait, &wait); - - balance_pgdat(pgdat, 0); + if (!more_to_do) { + prepare_to_wait(&pgdat->kswapd_wait, + &wait, TASK_INTERRUPTIBLE); + schedule(); + finish_wait(&pgdat->kswapd_wait, &wait); + } + balance_pgdat(pgdat, 0, &more_to_do); } return 0; } @@ -1223,7 +1231,9 @@ int shrink_all_memory(int nr_pages) current->reclaim_state = &reclaim_state; for_each_pgdat(pgdat) { int freed; - freed = balance_pgdat(pgdat, nr_to_free); + int more_to_do; + + freed = balance_pgdat(pgdat, nr_to_free, &more_to_do); ret += freed; nr_to_free -= freed; if (nr_to_free <= 0) _