protected buffer unbalance

From: Andrea Arcangeli (andrea@suse.de)
Date: Sat Jan 08 2000 - 11:18:40 EST


This patch (I announced it some day ago) fixes a VM balance problem with
protected buffers. Without the patch the protected buffers are accounted
as freeable by the VM.

diff -urN 2.3.35pre4/drivers/block/rd.c 2.3.35pre4-ramdisk-oom/drivers/block/rd.c
--- 2.3.35pre4/drivers/block/rd.c Mon Dec 27 00:17:03 1999
+++ 2.3.35pre4-ramdisk-oom/drivers/block/rd.c Tue Dec 28 14:35:28 1999
@@ -270,7 +270,7 @@
                 }
         }
         if (rbh) {
- set_bit(BH_Protected, &rbh->b_state);
+ mark_buffer_protected(rbh);
                 brelse(rbh);
         }
 
diff -urN 2.3.35pre4/fs/buffer.c 2.3.35pre4-ramdisk-oom/fs/buffer.c
--- 2.3.35pre4/fs/buffer.c Fri Dec 24 02:00:56 1999
+++ 2.3.35pre4-ramdisk-oom/fs/buffer.c Tue Dec 28 15:31:56 1999
@@ -820,6 +820,7 @@
 
         dirty = size_buffers_type[BUF_DIRTY] >> PAGE_SHIFT;
         tot = nr_free_buffer_pages();
+ tot -= size_buffers_type[BUF_PROTECTED] >> PAGE_SHIFT;
         hard_dirty_limit = tot * bdf_prm.b_un.nfract / 100;
         soft_dirty_limit = hard_dirty_limit >> 1;
 
@@ -871,6 +872,8 @@
                 dispose = BUF_LOCKED;
         if (buffer_dirty(bh))
                 dispose = BUF_DIRTY;
+ if (buffer_protected(bh))
+ dispose = BUF_PROTECTED;
         if (dispose != bh->b_list) {
                 __remove_from_lru_list(bh, bh->b_list);
                 bh->b_list = dispose;
@@ -2071,7 +2074,7 @@
         int found = 0, locked = 0, dirty = 0, used = 0, lastused = 0;
         int protected = 0;
         int nlist;
- static char *buf_types[NR_LIST] = { "CLEAN", "LOCKED", "DIRTY" };
+ static char *buf_types[NR_LIST] = { "CLEAN", "LOCKED", "DIRTY", "PROTECTED", };
 #endif
 
         printk("Buffer memory: %6dkB\n",
@@ -2097,10 +2100,16 @@
                                 used++, lastused = found;
                         bh = bh->b_next_free;
                 } while (bh != lru_list[nlist]);
- printk("%8s: %d buffers, %d used (last=%d), "
+ {
+ int tmp = nr_buffers_type[nlist];
+ if (found != tmp)
+ printk("%9s: BUG -> found %d, reported %d\n",
+ buf_types[nlist], found, tmp);
+ }
+ printk("%9s: %d buffers, %lu kbyte, %d used (last=%d), "
                        "%d locked, %d protected, %d dirty\n",
- buf_types[nlist], found, used, lastused,
- locked, protected, dirty);
+ buf_types[nlist], found, size_buffers_type[nlist]>>10,
+ used, lastused, locked, protected, dirty);
         }
         spin_unlock(&lru_list_lock);
 #endif
diff -urN 2.3.35pre4/include/linux/fs.h 2.3.35pre4-ramdisk-oom/include/linux/fs.h
--- 2.3.35pre4/include/linux/fs.h Fri Dec 24 02:20:17 1999
+++ 2.3.35pre4-ramdisk-oom/include/linux/fs.h Tue Dec 28 15:32:38 1999
@@ -788,7 +788,8 @@
 #define BUF_CLEAN 0
 #define BUF_LOCKED 1 /* Buffers scheduled for write */
 #define BUF_DIRTY 2 /* Dirty buffers, not yet scheduled for write */
-#define NR_LIST 3
+#define BUF_PROTECTED 3 /* Ramdisk persistent storage */
+#define NR_LIST 4
 
 /*
  * This is called by bh->b_end_io() handlers when I/O has completed.
@@ -812,6 +813,19 @@
 {
         if (atomic_set_buffer_clean(bh))
                 __mark_buffer_clean(bh);
+}
+
+#define atomic_set_buffer_protected(bh) test_and_set_bit(BH_Protected, &(bh)->b_state)
+
+extern inline void __mark_buffer_protected(struct buffer_head *bh)
+{
+ refile_buffer(bh);
+}
+
+extern inline void mark_buffer_protected(struct buffer_head * bh)
+{
+ if (!atomic_set_buffer_protected(bh))
+ __mark_buffer_protected(bh);
 }
 
 extern void FASTCALL(__mark_buffer_dirty(struct buffer_head *bh, int flag));

Andrea

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Sat Jan 15 2000 - 21:00:12 EST