patch-2.1.91 linux/mm/vmscan.c

Next file: linux/net/core/datagram.c
Previous file: linux/mm/swap.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.90/linux/mm/vmscan.c linux/mm/vmscan.c
@@ -31,7 +31,7 @@
 /* 
  * When are we next due for a page scan? 
  */
-static int next_swap_jiffies = 0;
+static unsigned long next_swap_jiffies = 0;
 
 /* 
  * How often do we do a pageout scan during normal conditions?
@@ -44,11 +44,6 @@
  */
 static struct wait_queue * kswapd_wait = NULL;
 
-/* 
- * We avoid doing a reschedule if the pageout daemon is already awake;
- */
-static int kswapd_awake = 0;
-
 static void init_swap_timer(void);
 
 /*
@@ -456,14 +451,14 @@
 	stop = 3;
 	if (gfp_mask & __GFP_WAIT)
 		stop = 0;
-	if (BUFFER_MEM > buffer_mem.borrow_percent * num_physpages / 100)
+	if (((buffermem >> PAGE_SHIFT) * 100 > buffer_mem.borrow_percent * num_physpages)
+		   || (page_cache_size * 100 > page_cache.borrow_percent * num_physpages))
 		state = 0;
 
 	switch (state) {
 		do {
 		case 0:
-			if (BUFFER_MEM > (buffer_mem.min_percent * num_physpages /100) &&
-					shrink_mmap(i, gfp_mask))
+			if (shrink_mmap(i, gfp_mask))
 				return 1;
 			state = 1;
 		case 1:
@@ -545,30 +540,41 @@
 	add_wait_queue(&kswapd_wait, &wait);
 	while (1) {
 		int tries;
+		int tried = 0;
 
 		current->state = TASK_INTERRUPTIBLE;
-		kswapd_awake = 0;
 		flush_signals(current);
 		run_task_queue(&tq_disk);
 		schedule();
-		kswapd_awake = 1;
 		swapstats.wakeups++;
-		/* Do the background pageout: 
-		 * When we've got loads of memory, we try
-		 * (freepages.high - nr_free_pages) times to
-		 * free memory. As memory gets tighter, kswapd
-		 * gets more and more agressive. -- Rik.
+	
+		/*
+		 * Do the background pageout: be
+		 * more aggressive if we're really
+		 * low on free memory.
+		 *
+		 * Normally this is called 4 times
+		 * a second if we need more memory,
+		 * so this has a normal rate of
+		 * X*4 pages of memory free'd per
+		 * second. That rate goes up when
+		 *
+		 * - we're really low on memory (we get woken
+		 *   up a lot more)
+		 * - other processes fail to allocate memory,
+		 *   at which time they try to do their own
+		 *   freeing.
+		 *
+		 * A "tries" value of 50 means up to 200 pages
+		 * per second (1.6MB/s). This should be a /proc
+		 * thing.
 		 */
-		tries = freepages.high - nr_free_pages;
-		if (tries < freepages.min) {
-			tries = freepages.min;
-		}
-		if (nr_free_pages < freepages.high + freepages.low)
-			tries <<= 1;
+		tries = (50 << 2) >> free_memory_available(3);
+	
 		while (tries--) {
 			int gfp_mask;
 
-			if (free_memory_available())
+			if (++tried > SWAP_CLUSTER_MAX && free_memory_available(0))
 				break;
 			gfp_mask = __GFP_IO;
 			try_to_free_page(gfp_mask);
@@ -589,27 +595,38 @@
 /* 
  * The swap_tick function gets called on every clock tick.
  */
-
 void swap_tick(void)
 {
-	int want_wakeup = 0, memory_low = 0;
-	int pages = nr_free_pages + atomic_read(&nr_async_pages);
+	unsigned long now, want;
+	int want_wakeup = 0;
 
-	if (pages < freepages.low)
-		memory_low = want_wakeup = 1;
-	else if ((pages < freepages.high || BUFFER_MEM > (num_physpages * buffer_mem.max_percent / 100))
-			&& jiffies >= next_swap_jiffies)
-		want_wakeup = 1;
+	want = next_swap_jiffies;
+	now = jiffies;
 
-	if (want_wakeup) { 
-		if (!kswapd_awake) {
+	/*
+	 * Examine the memory queues. Mark memory low
+	 * if there is nothing available in the three
+	 * highest queues.
+	 *
+	 * Schedule for wakeup if there isn't lots
+	 * of free memory.
+	 */
+	switch (free_memory_available(3)) {
+	case 0:
+		want = now;
+		/* Fall through */
+	case 1 ... 3:
+		want_wakeup = 1;
+	default:
+	}
+ 
+	if ((long) (now - want) >= 0) {
+		if (want_wakeup || (num_physpages * buffer_mem.max_percent) < (buffermem >> PAGE_SHIFT) * 100
+				|| (num_physpages * page_cache.max_percent < page_cache_size)) {
+			/* Set the next wake-up time */
+			next_swap_jiffies = now + swapout_interval;
 			wake_up(&kswapd_wait);
-			need_resched = 1;
 		}
-		/* Set the next wake-up time */
-		next_swap_jiffies = jiffies;
-		if (!memory_low) 
-			next_swap_jiffies += swapout_interval;
 	}
 	timer_active |= (1<<SWAP_TIMER);
 }

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov