Well, here it is. 

I would like to know if this makes a big difference on highmem (2GB or
more) machines with heavy IO workloads.

I don't have such a machine here to be able to test it. (it works with a
1GB machine, but it needs to be tested with lots of highmem to show the
improvement)


diff -Nur linux.orig/fs/buffer.c linux/fs/buffer.c
--- linux.orig/fs/buffer.c      Fri Mar 16 13:01:09 2001
+++ linux/fs/buffer.c   Fri Mar 16 13:37:27 2001
@@ -2557,7 +2557,7 @@
    as all dirty buffers lives _only_ in the DIRTY lru list.
    As we never browse the LOCKED and CLEAN lru lists they are infact
    completly useless. */
-static int flush_dirty_buffers(int check_flushtime)
+int flush_dirty_buffers(int check_flushtime, int lowmem)
 {
        struct buffer_head * bh, *next;
        int flushed = 0, i;
@@ -2577,6 +2577,11 @@
                if (buffer_locked(bh))
                        continue;
 
+#ifdef CONFIG_HIGHMEM
+               if (lowmem && PageHighMem(bh->b_page))
+                       continue;
+#endif
+
                if (check_flushtime) {
                        /* The dirty lru list is chronologically ordered so
                           if the current bh is not yet timed out,
@@ -2616,7 +2621,7 @@
                wake_up_process(bdflush_tsk);
 
                if (block)
-                       flush_dirty_buffers(0);
+                       flush_dirty_buffers(0, 0);
        }
 }
 
@@ -2635,7 +2640,7 @@
        sync_inodes(0);
        unlock_kernel();
 
-       flush_dirty_buffers(1);
+       flush_dirty_buffers(1, 0);
        /* must really sync all the active I/O request to disk here */
        run_task_queue(&tq_disk);
        return 0;
@@ -2732,7 +2737,7 @@
        for (;;) {
                CHECK_EMERGENCY_SYNC
 
-               flushed = flush_dirty_buffers(0);
+               flushed = flush_dirty_buffers(0, 0);
                if (free_shortage())
                        flushed += page_launder(GFP_KERNEL, 0);
 
diff -Nur linux.orig/include/linux/fs.h linux/include/linux/fs.h
--- linux.orig/include/linux/fs.h       Fri Mar 16 13:01:14 2001
+++ linux/include/linux/fs.h    Fri Mar 16 13:36:57 2001
@@ -1288,6 +1288,7 @@
 extern unsigned int get_hardblocksize(kdev_t);
 extern struct buffer_head * bread(kdev_t, int, int);
 extern void wakeup_bdflush(int wait);
+extern int flush_dirty_buffers(int, int);
 
 extern int brw_page(int, struct page *, kdev_t, int [], int);
 
diff -Nur linux.orig/mm/highmem.c linux/mm/highmem.c
--- linux.orig/mm/highmem.c     Fri Mar 16 13:01:13 2001
+++ linux/mm/highmem.c  Fri Mar 16 13:44:01 2001
@@ -21,6 +21,7 @@
 #include <linux/highmem.h>
 #include <linux/swap.h>
 #include <linux/slab.h>
+#include <linux/fs.h>
 
 /*
  * Virtual_count is not a pure "count".
@@ -280,9 +281,11 @@
        if (page)
                return page;
        /*
-        * No luck. First, kick the VM so it doesnt idle around while
-        * we are using up our emergency rations.
+        * No luck. First, try to flush some low memory buffers.
+        * This will throttle highmem writes when low memory gets full.
         */
+       flush_dirty_buffers(0, 1);
+
        wakeup_bdflush(0);
 
        /*
@@ -317,9 +320,11 @@
        if (bh)
                return bh;
        /*
-        * No luck. First, kick the VM so it doesnt idle around while
-        * we are using up our emergency rations.
+        * No luck. First, try to flush some low memory buffers.
+        * This will throttle highmem writes when low memory gets full.
         */
+       flush_dirty_buffers(0, 1);
+       
        wakeup_bdflush(0);
 
        /*

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to