patch-2.2.16 linux/mm/vmscan.c
Next file: linux/net/appletalk/aarp.c
Previous file: linux/mm/page_io.c
Back to the patch index
Back to the overall index
- Lines: 96
- Date:
Wed Jun 7 14:26:44 2000
- Orig file:
v2.2.15/linux/mm/vmscan.c
- Orig date:
Wed May 3 17:16:53 2000
diff -urN v2.2.15/linux/mm/vmscan.c linux/mm/vmscan.c
@@ -333,6 +333,7 @@
for (; counter >= 0; counter--) {
max_cnt = 0;
+ assign = 0;
pbest = NULL;
select:
read_lock(&tasklist_lock);
@@ -377,10 +378,17 @@
* cluster them so that we get good swap-out behaviour. See
* the "free_memory()" macro for details.
*/
+#define FLUSH_COUNT 8
static int do_try_to_free_pages(unsigned int gfp_mask)
{
- int priority;
- int count = SWAP_CLUSTER_MAX;
+ int priority, count, swapcount;
+ int flushcount = FLUSH_COUNT;
+ int ret = 0;
+
+ /* Kswapd does nothing but freeing pages so we can do big bites. */
+ if (gfp_mask == GFP_KSWAPD)
+ flushcount = SWAP_CLUSTER_MAX;
+ count = flushcount;
lock_kernel();
@@ -390,6 +398,7 @@
priority = 6;
do {
while (shrink_mmap(priority, gfp_mask)) {
+ ret = 1;
if (!--count)
goto done;
}
@@ -397,23 +406,36 @@
/* Try to get rid of some shared memory pages.. */
if (gfp_mask & __GFP_IO) {
while (shm_swap(priority, gfp_mask)) {
+ ret = 1;
if (!--count)
goto done;
}
}
/* Then, try to page stuff out.. */
+ swapcount = flushcount;
while (swap_out(priority, gfp_mask)) {
- if (!--count)
- goto done;
+ if (!--swapcount)
+ break;
}
shrink_dcache_memory(priority, gfp_mask);
} while (--priority >= 0);
+
+ /* End with a shrink_mmap() to make sure we free something. */
+ while (shrink_mmap(0, gfp_mask)) {
+ ret = 1;
+ if (!--count)
+ goto done;
+ }
done:
unlock_kernel();
- return priority >= 0;
+ if (!ret)
+ printk("VM: do_try_to_free_pages failed for %s...\n",
+ current->comm);
+ /* Return success if we freed a page. */
+ return ret;
}
/*
@@ -485,10 +507,18 @@
* the processes needing more memory will wake us
* up on a more timely basis.
*/
+ int failed = 0;
+sleep:
interruptible_sleep_on(&kswapd_wait);
+ /* Enough free pages? -> call do_try_to_free_pages only once. */
+ if (nr_free_pages > freepages.low) {
+ do_try_to_free_pages(GFP_KSWAPD);
+ goto sleep;
+ }
+ /* Not enough free pages? -> free pages agressively. */
while (nr_free_pages < freepages.high)
{
- if (do_try_to_free_pages(GFP_KSWAPD))
+ if (do_try_to_free_pages(GFP_KSWAPD) && failed++ < 10)
{
if (tsk->need_resched)
schedule();
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)