Re: PATCH: WIP super lock contention mitigation in 2.4

2000-07-14 Thread Stephen C. Tweedie

Hi,

On Wed, Jul 12, 2000 at 07:12:39PM +0200, Juan J. Quintela wrote:
 
 Hi
 I have ported Stephen patch from 2.2.8 to 2.4, but now I have
 contention in the inode bitmaps.  Can I use the same trick
 there that he used in the block bitmap???

I've attached the patch I did for 2.3.99-pre7.  It uses a much simpler
trick for inodes: it just drops the lock while waiting in the
read_inode_bitmap functions and retakes it after IO.  That means that
the lock is still held for the duration of the allocation of the
inode, but that's a much rarer and also a much more lightweight
operation than block allocation, so it should work fine.

Cheers,
 Stephen


--- linux-2.3.99/fs/ext2/balloc.c.~1~   Wed Mar 29 22:35:22 2000
+++ linux-2.3.99/fs/ext2/balloc.c   Wed May  3 16:49:04 2000
@@ -9,6 +9,13 @@
  *  Enhanced block allocation by Stephen Tweedie ([EMAIL PROTECTED]), 1993
  *  Big-endian to little-endian byte-swapping/bitmaps by
  *David S. Miller ([EMAIL PROTECTED]), 1995
+ *
+ *  Dropped use of the superblock lock.
+ *  This means that we have to take extra care not to block between any
+ *  operations on the bitmap and the corresponding update to the group 
+ *  descriptors.
+ *   Stephen C. Tweedie ([EMAIL PROTECTED]), 1999
+ * 
  */
 
 #include linux/config.h
@@ -16,7 +23,6 @@
 #include linux/locks.h
 #include linux/quotaops.h
 
-
 /*
  * balloc.c contains the blocks allocation and deallocation routines
  */
@@ -70,42 +76,33 @@
 }
 
 /*
- * Read the bitmap for a given block_group, reading into the specified 
- * slot in the superblock's bitmap cache.
+ * Read the bitmap for a given block_group.
  *
- * Return =0 on success or a -ve error code.
+ * Return the buffer_head on success or NULL on IO error.
  */
 
-static int read_block_bitmap (struct super_block * sb,
-  unsigned int block_group,
-  unsigned long bitmap_nr)
+static struct buffer_head * read_block_bitmap (struct super_block * sb,
+unsigned int block_group)
 {
struct ext2_group_desc * gdp;
struct buffer_head * bh = NULL;
-   int retval = -EIO;

gdp = ext2_get_group_desc (sb, block_group, NULL);
if (!gdp)
-   goto error_out;
-   retval = 0;
+   return NULL;
+
bh = bread (sb-s_dev, le32_to_cpu(gdp-bg_block_bitmap), sb-s_blocksize);
if (!bh) {
ext2_error (sb, "read_block_bitmap",
"Cannot read block bitmap - "
"block_group = %d, block_bitmap = %lu",
block_group, (unsigned long) gdp-bg_block_bitmap);
-   retval = -EIO;
+   return NULL;
}
-   /*
-* On IO error, just leave a zero in the superblock's block pointer for
-* this group.  The IO will be retried next time.
-*/
-error_out:
-   sb-u.ext2_sb.s_block_bitmap_number[bitmap_nr] = block_group;
-   sb-u.ext2_sb.s_block_bitmap[bitmap_nr] = bh;
-   return retval;
+   return bh;
 }
 
+
 /*
  * load_block_bitmap loads the block bitmap for a blocks group
  *
@@ -122,9 +119,9 @@
 static int __load_block_bitmap (struct super_block * sb,
unsigned int block_group)
 {
-   int i, j, retval = 0;
+   int i, j;
unsigned long block_bitmap_number;
-   struct buffer_head * block_bitmap;
+   struct buffer_head * block_bitmap, *cached_bitmap = NULL;
 
if (block_group = sb-u.ext2_sb.s_groups_count)
ext2_panic (sb, "load_block_bitmap",
@@ -132,27 +129,34 @@
"block_group = %d, groups_count = %lu",
block_group, sb-u.ext2_sb.s_groups_count);
 
+ retry:
if (sb-u.ext2_sb.s_groups_count = EXT2_MAX_GROUP_LOADED) {
if (sb-u.ext2_sb.s_block_bitmap[block_group]) {
if (sb-u.ext2_sb.s_block_bitmap_number[block_group] ==
-   block_group)
+   block_group) {
+   brelse(cached_bitmap);
return block_group;
+   }
ext2_error (sb, "__load_block_bitmap",
"block_group != block_bitmap_number");
}
-   retval = read_block_bitmap (sb, block_group, block_group);
-   if (retval  0)
-   return retval;
+   if (!cached_bitmap)
+   goto load;
+   sb-u.ext2_sb.s_block_bitmap_number[block_group] = block_group;
+   sb-u.ext2_sb.s_block_bitmap[block_group] = cached_bitmap;
return block_group;
}
 
for (i = 0; i  sb-u.ext2_sb.s_loaded_block_bitmaps 
sb-u.ext2_sb.s_block_bitmap_number[i] != block_group; i++)
;
+
+   /* 

PATCH: WIP super lock contention mitigation in 2.4

2000-07-12 Thread Juan J. Quintela


Hi
I have ported Stephen patch from 2.2.8 to 2.4, but now I have
contention in the inode bitmaps.  Can I use the same trick
there that he used in the block bitmap???

Later, Juan.

diff -urN --exclude-from=/home/lfcia/quintela/work/kernel/exclude 
base/fs/ext2/balloc.c working/fs/ext2/balloc.c
--- base/fs/ext2/balloc.c   Sat May 20 20:24:56 2000
+++ working/fs/ext2/balloc.cWed Jul 12 03:55:11 2000
@@ -9,6 +9,13 @@
  *  Enhanced block allocation by Stephen Tweedie ([EMAIL PROTECTED]), 1993
  *  Big-endian to little-endian byte-swapping/bitmaps by
  *David S. Miller ([EMAIL PROTECTED]), 1995
+ *
+ *  Dropped use of the superblock lock.
+ *  This means that we have to take extra care not to block between any
+ *  operations on the bitmap and the corresponding update to the group 
+ *  descriptors.
+ *   Stephen C. Tweedie ([EMAIL PROTECTED]), 1999
+ * 
  */
 
 #include linux/config.h
@@ -70,42 +77,33 @@
 }
 
 /*
- * Read the bitmap for a given block_group, reading into the specified 
- * slot in the superblock's bitmap cache.
+ * Read the bitmap for a given block_group.
  *
- * Return =0 on success or a -ve error code.
+ * Return the buffer_head on success or NULL on IO error.
  */
 
-static int read_block_bitmap (struct super_block * sb,
-  unsigned int block_group,
-  unsigned long bitmap_nr)
+static struct buffer_head * read_block_bitmap (struct super_block * sb,
+unsigned int block_group)
 {
struct ext2_group_desc * gdp;
struct buffer_head * bh = NULL;
-   int retval = -EIO;

gdp = ext2_get_group_desc (sb, block_group, NULL);
if (!gdp)
-   goto error_out;
-   retval = 0;
+   return NULL;
+
bh = bread (sb-s_dev, le32_to_cpu(gdp-bg_block_bitmap), sb-s_blocksize);
if (!bh) {
ext2_error (sb, "read_block_bitmap",
"Cannot read block bitmap - "
"block_group = %d, block_bitmap = %lu",
block_group, (unsigned long) gdp-bg_block_bitmap);
-   retval = -EIO;
+   return NULL;
}
-   /*
-* On IO error, just leave a zero in the superblock's block pointer for
-* this group.  The IO will be retried next time.
-*/
-error_out:
-   sb-u.ext2_sb.s_block_bitmap_number[bitmap_nr] = block_group;
-   sb-u.ext2_sb.s_block_bitmap[bitmap_nr] = bh;
-   return retval;
+   return bh;
 }
 
+
 /*
  * load_block_bitmap loads the block bitmap for a blocks group
  *
@@ -122,9 +120,9 @@
 static int __load_block_bitmap (struct super_block * sb,
unsigned int block_group)
 {
-   int i, j, retval = 0;
+   int i, j;
unsigned long block_bitmap_number;
-   struct buffer_head * block_bitmap;
+   struct buffer_head * block_bitmap, *cached_bitmap = NULL;
 
if (block_group = sb-u.ext2_sb.s_groups_count)
ext2_panic (sb, "load_block_bitmap",
@@ -132,27 +130,34 @@
"block_group = %d, groups_count = %lu",
block_group, sb-u.ext2_sb.s_groups_count);
 
+retry:
if (sb-u.ext2_sb.s_groups_count = EXT2_MAX_GROUP_LOADED) {
if (sb-u.ext2_sb.s_block_bitmap[block_group]) {
if (sb-u.ext2_sb.s_block_bitmap_number[block_group] ==
-   block_group)
+   block_group) {
+   brelse(cached_bitmap);
return block_group;
+   }
ext2_error (sb, "__load_block_bitmap",
"block_group != block_bitmap_number");
}
-   retval = read_block_bitmap (sb, block_group, block_group);
-   if (retval  0)
-   return retval;
+   if (!cached_bitmap)
+   goto load;
+   sb-u.ext2_sb.s_block_bitmap_number[block_group] = block_group;
+   sb-u.ext2_sb.s_block_bitmap[block_group] = cached_bitmap;
return block_group;
}
 
for (i = 0; i  sb-u.ext2_sb.s_loaded_block_bitmaps 
sb-u.ext2_sb.s_block_bitmap_number[i] != block_group; i++)
;
+
+   /* already cached? */
if (i  sb-u.ext2_sb.s_loaded_block_bitmaps 
sb-u.ext2_sb.s_block_bitmap_number[i] == block_group) {
block_bitmap_number = sb-u.ext2_sb.s_block_bitmap_number[i];
block_bitmap = sb-u.ext2_sb.s_block_bitmap[i];
+
for (j = i; j  0; j--) {
sb-u.ext2_sb.s_block_bitmap_number[j] =
sb-u.ext2_sb.s_block_bitmap_number[j - 1];
@@ -161,28 +166,36 @@
}