Does the following patch work for you? The problem is that kswapd
ends up taking longer than its wakeup interval to run. This patch
forces kswapd to sleep for a little while after waking up.
-b
diff -u dist/mm/swapfile.c lin/mm/swapfile.c
--- dist/mm/swapfile.c Sun Nov 3 23:11:26 1996
+++ lin/mm/swapfile.c Fri Sep 13 18:08:29 1996
@@ -82,6 +82,8 @@
type = swap_list.next;
if (type < 0)
return 0;
+ if (nr_swap_pages == 0)
+ return 0;
while (1) {
p = &swap_info[type];
diff -u dist/mm/vmscan.c lin/mm/vmscan.c
--- dist/mm/vmscan.c Sun Nov 3 23:20:50 1996
+++ lin/mm/vmscan.c Fri Sep 13 11:50:23 1996
@@ -108,13 +108,8 @@
} else {
if (page_map->count != 1)
return 0;
- if (!(entry = get_swap_page())) {
- /* Aieee!!! Out of swap space! */
- int retval = -1;
- if (nr_swapfiles == 0)
- retval = 0;
- return retval;
- }
+ if (!(entry = get_swap_page()))
+ return 0;
vma->vm_mm->rss--;
flush_cache_page(vma, address);
set_pte(page_table, __pte(entry));
@@ -317,9 +312,6 @@
if (!--p->swap_cnt)
swap_task++;
switch (swap_out_process(p, dma, wait)) {
- /* out of swap space? */
- case -1:
- return 0;
case 0:
if (p->swap_cnt)
swap_task++;
@@ -428,9 +420,22 @@
void swap_tick(void)
{
- if ((nr_free_pages + nr_async_pages) < free_pages_low ||
- ((nr_free_pages + nr_async_pages) < free_pages_high &&
- jiffies >= next_swap_jiffies)) {
+ int want_wakeup = 0;
+ static int last_wakeup_low = 0;
+
+ if ((nr_free_pages + nr_async_pages) < free_pages_low) {
+ if (last_wakeup_low)
+ want_wakeup = jiffies >= next_swap_jiffies;
+ else
+ last_wakeup_low = want_wakeup = 1;
+ }
+ else if (((nr_free_pages + nr_async_pages) < free_pages_high) &&
+ jiffies >= next_swap_jiffies) {
+ last_wakeup_low = 0;
+ want_wakeup = 1;
+ }
+
+ if (want_wakeup) {
if (!kswapd_awake && kswapd_ctl.maxpages > 0) {
wake_up(&kswapd_wait);
need_resched = 1;