patch-2.1.132 linux/mm/vmscan.c
Next file: linux/net/802/tr.c
Previous file: linux/mm/swap_state.c
Back to the patch index
Back to the overall index
- Lines: 171
- Date:
Tue Dec 22 13:04:24 1998
- Orig file:
v2.1.131/linux/mm/vmscan.c
- Orig date:
Wed Dec 16 10:32:56 1998
diff -u --recursive --new-file v2.1.131/linux/mm/vmscan.c linux/mm/vmscan.c
@@ -418,45 +418,6 @@
}
/*
- * We are much more aggressive about trying to swap out than we used
- * to be. This works out OK, because we now do proper aging on page
- * contents.
- */
-static int do_try_to_free_page(int gfp_mask)
-{
- static int state = 0;
- int i=6;
-
- /* Always trim SLAB caches when memory gets low. */
- kmem_cache_reap(gfp_mask);
-
- if (buffer_over_borrow() || pgcache_over_borrow())
- state = 0;
-
- switch (state) {
- do {
- case 0:
- if (shrink_mmap(i, gfp_mask))
- return 1;
- state = 1;
- case 1:
- if (shm_swap(i, gfp_mask))
- return 1;
- state = 2;
- case 2:
- if (swap_out(i, gfp_mask))
- return 1;
- state = 3;
- case 3:
- shrink_dcache_memory(i, gfp_mask);
- state = 0;
- i--;
- } while (i >= 0);
- }
- return 0;
-}
-
-/*
* Before we start the kernel thread, print out the
* kswapd initialization message (otherwise the init message
* may be printed in the middle of another driver's init
@@ -467,6 +428,8 @@
int i;
char *revision="$Revision: 1.5 $", *s, *e;
+ swap_setup();
+
if ((s = strchr(revision, ':')) &&
(e = strchr(s, '$')))
s++, i = e - s;
@@ -475,6 +438,44 @@
printk ("Starting kswapd v%.*s\n", i, s);
}
+#define free_memory(fn) \
+ count++; do { if (!--count) goto done; } while (fn)
+
+static int kswapd_free_pages(int kswapd_state)
+{
+ unsigned long end_time;
+
+ /* Always trim SLAB caches when memory gets low. */
+ kmem_cache_reap(0);
+
+ /* max one hundreth of a second */
+ end_time = jiffies + (HZ-1)/100;
+ do {
+ int priority = 5;
+ int count = pager_daemon.swap_cluster;
+
+ switch (kswapd_state) {
+ do {
+ default:
+ free_memory(shrink_mmap(priority, 0));
+ kswapd_state++;
+ case 1:
+ free_memory(shm_swap(priority, 0));
+ kswapd_state++;
+ case 2:
+ free_memory(swap_out(priority, 0));
+ shrink_dcache_memory(priority, 0);
+ kswapd_state = 0;
+ } while (--priority >= 0);
+ return kswapd_state;
+ }
+done:
+ if (nr_free_pages > freepages.high + pager_daemon.swap_cluster)
+ break;
+ } while (time_before_eq(jiffies,end_time));
+ return kswapd_state;
+}
+
/*
* The background pageout daemon.
* Started as a kernel thread from the init process.
@@ -517,22 +518,14 @@
init_swap_timer();
kswapd_task = current;
while (1) {
- unsigned long end_time;
+ int state = 0;
current->state = TASK_INTERRUPTIBLE;
flush_signals(current);
run_task_queue(&tq_disk);
schedule();
swapstats.wakeups++;
-
- /* max one hundreth of a second */
- end_time = jiffies + (HZ-1)/100;
- do {
- if (!do_try_to_free_page(0))
- break;
- if (nr_free_pages > freepages.high + SWAP_CLUSTER_MAX)
- break;
- } while (time_before_eq(jiffies,end_time));
+ state = kswapd_free_pages(state);
}
/* As if we could ever get here - maybe we want to make this killable */
kswapd_task = NULL;
@@ -549,23 +542,39 @@
* if we need more memory as part of a swap-out effort we
* will just silently return "success" to tell the page
* allocator to accept the allocation.
+ *
+ * We want to try to free "count" pages, and we need to
+ * cluster them so that we get good swap-out behaviour. See
+ * the "free_memory()" macro for details.
*/
int try_to_free_pages(unsigned int gfp_mask, int count)
{
- int retval = 1;
+ int retval;
lock_kernel();
+
+ /* Always trim SLAB caches when memory gets low. */
+ kmem_cache_reap(gfp_mask);
+
+ retval = 1;
if (!(current->flags & PF_MEMALLOC)) {
+ int priority;
+
current->flags |= PF_MEMALLOC;
+
+ priority = 5;
do {
- retval = do_try_to_free_page(gfp_mask);
- if (!retval)
- break;
- count--;
- } while (count > 0);
+ free_memory(shrink_mmap(priority, gfp_mask));
+ free_memory(shm_swap(priority, gfp_mask));
+ free_memory(swap_out(priority, gfp_mask));
+ shrink_dcache_memory(priority, gfp_mask);
+ } while (--priority >= 0);
+ retval = 0;
+done:
current->flags &= ~PF_MEMALLOC;
}
unlock_kernel();
+
return retval;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov