Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 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-07 23:46:23.991681464 -0700
+++ 25-akpm/mm/vmscan.c	2004-10-07 23:46:23.996680704 -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;
@@ -1126,10 +1126,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;
 }
@@ -1156,6 +1161,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);
@@ -1180,11 +1186,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;
 }
@@ -1222,7 +1230,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)
_