From: Alex Tomas <bzzz@tmi.comex.ru>
To: linux-kernel <linux-kernel@vger.kernel.org>
Cc: ext2-devel@lists.sourceforge.net, Andrew Morton <akpm@digeo.com>,
Alex Tomas <bzzz@tmi.comex.ru>
Subject: [PATCH] concurrent block allocation for ext2 against 2.5.64
Date: 13 Mar 2003 11:55:32 +0300 [thread overview]
Message-ID: <m3el5bmyrf.fsf@lexa.home.net> (raw)
Hi!
as Andrew said, concurrent balloc for ext3 is useless because of BKL.
and I saw it in benchmarks. but it may be useful for ext2.
Results:
9/100000 9/500000 16/100000 16/500000 32/100000 32/500000
ext2: 0m9.260s 0m46.160s 0m18.133s 1m33.553s 0m35.958s 3m4.164s
ext2-ca: 0m8.578s 0m42.712s 0m17.412s 1m28.637s 0m33.736s 2m53.824s
in those benchmarks, I run 2 process, each of them writes N blocks
(9, 16, 32), truncates file and repeat these steps M times (100000, 500000).
diff -uNr linux/fs/ext2/balloc.c edited/fs/ext2/balloc.c
--- linux/fs/ext2/balloc.c Thu Feb 20 16:18:53 2003
+++ edited/fs/ext2/balloc.c Thu Mar 13 10:54:50 2003
@@ -98,9 +98,13 @@
{
struct ext2_sb_info * sbi = EXT2_SB(sb);
struct ext2_super_block * es = sbi->s_es;
- unsigned free_blocks = le32_to_cpu(es->s_free_blocks_count);
- unsigned root_blocks = le32_to_cpu(es->s_r_blocks_count);
+ unsigned free_blocks;
+ unsigned root_blocks;
+ spin_lock(&sbi->s_alloc_lock);
+
+ free_blocks = le32_to_cpu(es->s_free_blocks_count);
+ root_blocks = le32_to_cpu(es->s_r_blocks_count);
if (free_blocks < count)
count = free_blocks;
@@ -113,11 +117,16 @@
*/
if (free_blocks > root_blocks)
count = free_blocks - root_blocks;
- else
+ else {
+ spin_unlock(&sbi->s_alloc_lock);
return 0;
+ }
}
es->s_free_blocks_count = cpu_to_le32(free_blocks - count);
+
+ spin_unlock(&sbi->s_alloc_lock);
+
mark_buffer_dirty(sbi->s_sbh);
sb->s_dirt = 1;
return count;
@@ -128,35 +137,54 @@
if (count) {
struct ext2_sb_info * sbi = EXT2_SB(sb);
struct ext2_super_block * es = sbi->s_es;
- unsigned free_blocks = le32_to_cpu(es->s_free_blocks_count);
+ unsigned free_blocks;
+
+ spin_lock(&sbi->s_alloc_lock);
+ free_blocks = le32_to_cpu(es->s_free_blocks_count);
es->s_free_blocks_count = cpu_to_le32(free_blocks + count);
+ spin_unlock(&sbi->s_alloc_lock);
+
mark_buffer_dirty(sbi->s_sbh);
sb->s_dirt = 1;
}
}
-static inline int group_reserve_blocks(struct ext2_group_desc *desc,
+static inline int group_reserve_blocks(struct ext2_sb_info *sbi, struct ext2_group_desc *desc,
struct buffer_head *bh, int count)
{
unsigned free_blocks;
- if (!desc->bg_free_blocks_count)
+ spin_lock(&sbi->s_alloc_lock);
+
+ if (!desc->bg_free_blocks_count) {
+ spin_unlock(&sbi->s_alloc_lock);
return 0;
+ }
free_blocks = le16_to_cpu(desc->bg_free_blocks_count);
if (free_blocks < count)
count = free_blocks;
desc->bg_free_blocks_count = cpu_to_le16(free_blocks - count);
+
+ spin_unlock(&sbi->s_alloc_lock);
+
mark_buffer_dirty(bh);
return count;
}
-static inline void group_release_blocks(struct ext2_group_desc *desc,
+static inline void group_release_blocks(struct ext2_sb_info *sbi, struct ext2_group_desc *desc,
struct buffer_head *bh, int count)
{
if (count) {
- unsigned free_blocks = le16_to_cpu(desc->bg_free_blocks_count);
+ unsigned free_blocks;
+
+ spin_lock(&sbi->s_alloc_lock);
+
+ free_blocks = le16_to_cpu(desc->bg_free_blocks_count);
desc->bg_free_blocks_count = cpu_to_le16(free_blocks + count);
+
+ spin_unlock(&sbi->s_alloc_lock);
+
mark_buffer_dirty(bh);
}
}
@@ -176,7 +204,6 @@
struct ext2_super_block * es;
unsigned freed = 0, group_freed;
- lock_super (sb);
es = EXT2_SB(sb)->s_es;
if (block < le32_to_cpu(es->s_first_data_block) ||
block + count < block ||
@@ -224,7 +251,7 @@
block, count);
for (i = 0, group_freed = 0; i < count; i++) {
- if (!ext2_clear_bit(bit + i, bitmap_bh->b_data))
+ if (!test_and_clear_bit(bit + i, (void *) bitmap_bh->b_data))
ext2_error (sb, "ext2_free_blocks",
"bit already cleared for block %lu",
block + i);
@@ -236,7 +263,7 @@
if (sb->s_flags & MS_SYNCHRONOUS)
sync_dirty_buffer(bitmap_bh);
- group_release_blocks(desc, bh2, group_freed);
+ group_release_blocks(EXT2_SB(sb), desc, bh2, group_freed);
freed += group_freed;
if (overflow) {
@@ -247,7 +274,6 @@
error_return:
brelse(bitmap_bh);
release_blocks(sb, freed);
- unlock_super (sb);
DQUOT_FREE_BLOCK(inode, freed);
}
@@ -258,6 +284,8 @@
if (!ext2_test_bit(goal, map))
goto got_it;
+
+repeat:
if (goal) {
/*
* The goal was occupied; search forward for a free
@@ -297,7 +325,8 @@
}
return -1;
got_it:
- ext2_set_bit(goal, map);
+ if (test_and_set_bit(goal, (void *) map))
+ goto repeat;
return goal;
}
@@ -342,8 +371,6 @@
dq_alloc = prealloc_goal + 1;
- lock_super (sb);
-
es_alloc = reserve_blocks(sb, dq_alloc);
if (!es_alloc) {
*err = -ENOSPC;
@@ -360,7 +387,7 @@
if (!desc)
goto io_error;
- group_alloc = group_reserve_blocks(desc, gdp_bh, es_alloc);
+ group_alloc = group_reserve_blocks(sbi, desc, gdp_bh, es_alloc);
if (group_alloc) {
ret_block = ((goal - le32_to_cpu(es->s_first_data_block)) %
group_size);
@@ -375,7 +402,7 @@
group_size, ret_block);
if (ret_block >= 0)
goto got_block;
- group_release_blocks(desc, gdp_bh, group_alloc);
+ group_release_blocks(sbi, desc, gdp_bh, group_alloc);
group_alloc = 0;
}
@@ -393,7 +420,7 @@
desc = ext2_get_group_desc(sb, group_no, &gdp_bh);
if (!desc)
goto io_error;
- group_alloc = group_reserve_blocks(desc, gdp_bh, es_alloc);
+ group_alloc = group_reserve_blocks(sbi, desc, gdp_bh, es_alloc);
}
if (bit >= sbi->s_groups_count) {
*err = -ENOSPC;
@@ -452,7 +479,7 @@
unsigned n;
for (n = 0; n < group_alloc && ++ret_block < group_size; n++) {
- if (ext2_set_bit(ret_block, bitmap_bh->b_data))
+ if (test_and_set_bit(ret_block, (void *) bitmap_bh->b_data))
break;
}
*prealloc_block = block + 1;
@@ -471,10 +498,9 @@
*err = 0;
out_release:
- group_release_blocks(desc, gdp_bh, group_alloc);
+ group_release_blocks(sbi, desc, gdp_bh, group_alloc);
release_blocks(sb, es_alloc);
out_unlock:
- unlock_super (sb);
DQUOT_FREE_BLOCK(inode, dq_alloc);
out:
brelse(bitmap_bh);
diff -uNr linux/fs/ext2/super.c edited/fs/ext2/super.c
--- linux/fs/ext2/super.c Thu Feb 20 16:18:53 2003
+++ edited/fs/ext2/super.c Wed Mar 12 23:29:53 2003
@@ -564,6 +564,7 @@
return -ENOMEM;
sb->s_fs_info = sbi;
memset(sbi, 0, sizeof(*sbi));
+ spin_lock_init(&sbi->s_alloc_lock);
/*
* See what the current blocksize for the device is, and
diff -uNr linux/include/linux/ext2_fs_sb.h edited/include/linux/ext2_fs_sb.h
--- linux/include/linux/ext2_fs_sb.h Mon Nov 11 06:28:30 2002
+++ edited/include/linux/ext2_fs_sb.h Wed Mar 12 22:57:30 2003
@@ -45,6 +45,7 @@
u32 s_next_generation;
unsigned long s_dir_count;
u8 *s_debts;
+ spinlock_t s_alloc_lock;
};
#endif /* _LINUX_EXT2_FS_SB */
next reply other threads:[~2003-03-13 8:52 UTC|newest]
Thread overview: 39+ messages / expand[flat|nested] mbox.gz Atom feed top
2003-03-13 8:55 Alex Tomas [this message]
2003-03-13 9:58 ` [PATCH] concurrent block allocation for ext2 against 2.5.64 Andrew Morton
2003-03-13 19:17 ` Alex Tomas
2003-03-13 22:25 ` Andrew Morton
2003-03-13 23:03 ` Andreas Dilger
2003-03-13 23:10 ` Andrew Morton
2003-03-13 23:03 ` Alex Tomas
2003-03-13 23:25 ` Andrew Morton
2003-03-13 23:56 ` Andreas Dilger
2003-03-14 7:20 ` Alex Tomas
2003-03-14 20:59 ` Andreas Dilger
2003-03-14 21:14 ` Alex Tomas
2003-03-15 4:37 ` William Lee Irwin III
2003-03-15 4:54 ` Andrew Morton
2003-03-15 5:30 ` William Lee Irwin III
2003-03-15 5:43 ` Martin J. Bligh
2003-03-15 5:50 ` William Lee Irwin III
2003-03-15 5:49 ` William Lee Irwin III
2003-03-15 6:20 ` William Lee Irwin III
2003-03-15 6:44 ` Andrew Morton
2003-03-15 7:05 ` William Lee Irwin III
2003-03-15 8:24 ` William Lee Irwin III
2003-03-15 9:47 ` William Lee Irwin III
2003-03-15 11:58 ` William Lee Irwin III
2003-03-15 12:08 ` Andrew Morton
2003-03-15 12:25 ` William Lee Irwin III
2003-03-15 8:16 ` [Ext2-devel] " Alex Tomas
2003-03-15 8:29 ` William Lee Irwin III
2003-03-15 8:32 ` Alex Tomas
2003-03-15 9:23 ` William Lee Irwin III
2003-03-14 18:25 ` Martin J. Bligh
2003-03-14 19:30 ` [Ext2-devel] " Daniel Phillips
2003-03-14 19:55 ` Andrew Morton
2003-03-13 17:39 ` [Ext2-devel] " Andreas Dilger
2003-03-13 18:43 ` Alex Tomas
2003-03-13 19:09 ` Matthew Wilcox
2003-03-13 19:39 ` Andrew Morton
2003-03-13 19:23 ` Theodore Ts'o
2003-03-13 19:44 ` Andreas Dilger
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=m3el5bmyrf.fsf@lexa.home.net \
--to=bzzz@tmi.comex.ru \
--cc=akpm@digeo.com \
--cc=ext2-devel@lists.sourceforge.net \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox