* [PATCH 0/7] kill-the-bkl/reiserfs performances updates
@ 2009-05-08 18:35 Frederic Weisbecker
2009-05-08 18:35 ` [PATCH 1/7] kill-the-BKL/reiserfs: add reiserfs_cond_resched() Frederic Weisbecker
` (6 more replies)
0 siblings, 7 replies; 8+ messages in thread
From: Frederic Weisbecker @ 2009-05-08 18:35 UTC (permalink / raw)
To: Al Viro
Cc: LKML, Frederic Weisbecker, Ingo Molnar, Jeff Mahoney,
Alexander Beregalov, Chris Mason
Hi Al, everyone,
This patchset is the result of some lock tracing and analysis.
After doing a dbench test on SMP (2 CPUS) with 100 procs during
about 300 secs, I get the following throughput:
With the bkl:
40 MB/s
With the write lock before this patchset:
31 MB/s
With the write lock after this patchset:
36 MB/s
There is still some work to do but it's a good progress.
It seems to depend on the remaining disk space, sometimes I reach
almost the same performances, sometimes it's lower.
For those who want to test it against -rc4, you can pull on the tree
described below, it's a migration of the reiserfs work that was done
in Ingo's tip:core/kill-the-bkl + this patchset.
Thanks,
Frederic.
The following changes since commit e26767ea29f0eb3271e03ba5355c645e2b39939f:
Frederic Weisbecker (1):
kill-the-BKL/reiserfs: release the write lock on flush_commit_list()
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/frederic/random-tracing.git
reiserfs/kill-the-bkl
Frederic Weisbecker (7):
kill-the-BKL/reiserfs: add reiserfs_cond_resched()
kill-the-bkl/reiserfs: conditionaly release the write lock on fs_changed()
kill-the-bkl/reiserfs: lock only once on reiserfs_get_block()
kill-the-bkl/reiserfs: don't hold the write recursively in reiserfs_lookup()
kill-the-bkl/reiserfs: reduce number of contentions in search_by_key()
kill-the-bkl/reiserfs: factorize the locking in reiserfs_write_end()
kill-the-bkl/reiserfs: use mutex_lock in reiserfs_mutex_lock_safe
fs/reiserfs/inode.c | 44 +++++++++++++++++++++++++-----------------
fs/reiserfs/journal.c | 8 ++----
fs/reiserfs/namei.c | 15 ++++++++++---
fs/reiserfs/stree.c | 12 ++++++++++-
include/linux/reiserfs_fs.h | 17 +++++++++++++--
5 files changed, 65 insertions(+), 31 deletions(-)
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 1/7] kill-the-BKL/reiserfs: add reiserfs_cond_resched()
2009-05-08 18:35 [PATCH 0/7] kill-the-bkl/reiserfs performances updates Frederic Weisbecker
@ 2009-05-08 18:35 ` Frederic Weisbecker
2009-05-08 18:35 ` [PATCH 2/7] kill-the-bkl/reiserfs: conditionaly release the write lock on fs_changed() Frederic Weisbecker
` (5 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Frederic Weisbecker @ 2009-05-08 18:35 UTC (permalink / raw)
To: Al Viro
Cc: LKML, Frederic Weisbecker, Jeff Mahoney, Chris Mason,
Ingo Molnar, Alexander Beregalov
Usually, when we call cond_resched(), we want the write lock
to be released and then reacquired once we return from scheduling.
Not only does it follow the previous bkl based locking scheme, but
it also let other waiters to get the lock.
But if we aren't going to reschedule(), such as in !TIF_NEED_RESCHED
case, it's useless to release the lock. Worse, if we release and reacquire
the lock whereas it is not needed, we create useless contentions. Also
if someone takes the lock while we are modifying or reading the tree,
there are good chances we'll have to retry our operation, eg if the
block we were seeeking has moved.
So this patch introduces a helper which only unlock the write lock
if we are going to schedule.
[ Impact: prepare to inject less lock contention and less tree operation attempts ]
Reported-by: Andi Kleen <andi@firstfloor.org>
Cc: Jeff Mahoney <jeffm@suse.com>
Cc: Chris Mason <chris.mason@oracle.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Alexander Beregalov <a.beregalov@gmail.com>
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
---
include/linux/reiserfs_fs.h | 13 +++++++++++++
1 files changed, 13 insertions(+), 0 deletions(-)
diff --git a/include/linux/reiserfs_fs.h b/include/linux/reiserfs_fs.h
index 397d281..995bdf9 100644
--- a/include/linux/reiserfs_fs.h
+++ b/include/linux/reiserfs_fs.h
@@ -62,6 +62,19 @@ void reiserfs_write_unlock(struct super_block *s);
int reiserfs_write_lock_once(struct super_block *s);
void reiserfs_write_unlock_once(struct super_block *s, int lock_depth);
+/*
+ * When we schedule, we usually want to also release the write lock,
+ * according to the previous bkl based locking scheme of reiserfs.
+ */
+static inline void reiserfs_cond_resched(struct super_block *s)
+{
+ if (need_resched()) {
+ reiserfs_write_unlock(s);
+ schedule();
+ reiserfs_write_lock(s);
+ }
+}
+
struct fid;
/* in reading the #defines, it may help to understand that they employ
--
1.6.2.3
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 2/7] kill-the-bkl/reiserfs: conditionaly release the write lock on fs_changed()
2009-05-08 18:35 [PATCH 0/7] kill-the-bkl/reiserfs performances updates Frederic Weisbecker
2009-05-08 18:35 ` [PATCH 1/7] kill-the-BKL/reiserfs: add reiserfs_cond_resched() Frederic Weisbecker
@ 2009-05-08 18:35 ` Frederic Weisbecker
2009-05-08 18:35 ` [PATCH 3/7] kill-the-bkl/reiserfs: lock only once on reiserfs_get_block() Frederic Weisbecker
` (4 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Frederic Weisbecker @ 2009-05-08 18:35 UTC (permalink / raw)
To: Al Viro
Cc: LKML, Frederic Weisbecker, Jeff Mahoney, Chris Mason,
Ingo Molnar, Alexander Beregalov
The goal of fs_changed() is to check whether the tree changed during a
schedule(). This is a BKL legacy.
A recent patch added an explicit unconditional release/reacquire of the
write lock around the cond_resched() called inside fs_changed.
But it's wasteful to unconditionally do that, we are creating superfluous
lock contention in !TIF_NEED_RESCHED case.
This patch manage that by calling reiserfs_cond_resched() from fs_changed()
which only releases the lock if we are going to reschedule.
[ Impact: inject less lock contention and tree job retries ]
Cc: Jeff Mahoney <jeffm@suse.com>
Cc: Chris Mason <chris.mason@oracle.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Alexander Beregalov <a.beregalov@gmail.com>
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
---
include/linux/reiserfs_fs.h | 4 +---
1 files changed, 1 insertions(+), 3 deletions(-)
diff --git a/include/linux/reiserfs_fs.h b/include/linux/reiserfs_fs.h
index 995bdf9..39bd4ea 100644
--- a/include/linux/reiserfs_fs.h
+++ b/include/linux/reiserfs_fs.h
@@ -1317,9 +1317,7 @@ static inline loff_t max_reiserfs_offset(struct inode *inode)
#define __fs_changed(gen,s) (gen != get_generation (s))
#define fs_changed(gen,s) \
({ \
- reiserfs_write_unlock(s); \
- cond_resched(); \
- reiserfs_write_lock(s); \
+ reiserfs_cond_resched(s); \
__fs_changed(gen, s); \
})
--
1.6.2.3
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 3/7] kill-the-bkl/reiserfs: lock only once on reiserfs_get_block()
2009-05-08 18:35 [PATCH 0/7] kill-the-bkl/reiserfs performances updates Frederic Weisbecker
2009-05-08 18:35 ` [PATCH 1/7] kill-the-BKL/reiserfs: add reiserfs_cond_resched() Frederic Weisbecker
2009-05-08 18:35 ` [PATCH 2/7] kill-the-bkl/reiserfs: conditionaly release the write lock on fs_changed() Frederic Weisbecker
@ 2009-05-08 18:35 ` Frederic Weisbecker
2009-05-08 18:35 ` [PATCH 4/7] kill-the-bkl/reiserfs: don't hold the write recursively in reiserfs_lookup() Frederic Weisbecker
` (3 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Frederic Weisbecker @ 2009-05-08 18:35 UTC (permalink / raw)
To: Al Viro
Cc: LKML, Frederic Weisbecker, Jeff Mahoney, Chris Mason,
Ingo Molnar, Alexander Beregalov
reiserfs_get_block() is one of these sites where the write lock might
be acquired recursively.
It's a particular problem because this function is called very often.
It's a hot spot which needs to reschedule() periodically while converting
direct items to indirect ones because it can take some time.
Then if we are applying the write lock release/reacquire pattern on
schedule() here, it may not produce the desired effect since we may have
locked in more than one depth.
The solution is to use reiserfs_write_lock_once() which won't try
to reacquire the lock recursively. Then the lock will be *really*
released before schedule().
Also, we only release the lock if TIF_NEED_RESCHED is set to not
create wasteful numerous contentions.
[ Impact: fix a too long holded lock case in reiserfs_get_block() ]
Cc: Jeff Mahoney <jeffm@suse.com>
Cc: Chris Mason <chris.mason@oracle.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Alexander Beregalov <a.beregalov@gmail.com>
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
---
fs/reiserfs/inode.c | 19 +++++++++++--------
1 files changed, 11 insertions(+), 8 deletions(-)
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
index 153668e..a5f69ef 100644
--- a/fs/reiserfs/inode.c
+++ b/fs/reiserfs/inode.c
@@ -605,6 +605,7 @@ int reiserfs_get_block(struct inode *inode, sector_t block,
__le32 *item;
int done;
int fs_gen;
+ int lock_depth;
struct reiserfs_transaction_handle *th = NULL;
/* space reserved in transaction batch:
. 3 balancings in direct->indirect conversion
@@ -620,11 +621,11 @@ int reiserfs_get_block(struct inode *inode, sector_t block,
loff_t new_offset =
(((loff_t) block) << inode->i_sb->s_blocksize_bits) + 1;
- reiserfs_write_lock(inode->i_sb);
+ lock_depth = reiserfs_write_lock_once(inode->i_sb);
version = get_inode_item_key_version(inode);
if (!file_capable(inode, block)) {
- reiserfs_write_unlock(inode->i_sb);
+ reiserfs_write_unlock_once(inode->i_sb, lock_depth);
return -EFBIG;
}
@@ -636,7 +637,7 @@ int reiserfs_get_block(struct inode *inode, sector_t block,
/* find number of block-th logical block of the file */
ret = _get_block_create_0(inode, block, bh_result,
create | GET_BLOCK_READ_DIRECT);
- reiserfs_write_unlock(inode->i_sb);
+ reiserfs_write_unlock_once(inode->i_sb, lock_depth);
return ret;
}
/*
@@ -754,7 +755,7 @@ int reiserfs_get_block(struct inode *inode, sector_t block,
if (!dangle && th)
retval = reiserfs_end_persistent_transaction(th);
- reiserfs_write_unlock(inode->i_sb);
+ reiserfs_write_unlock_once(inode->i_sb, lock_depth);
/* the item was found, so new blocks were not added to the file
** there is no need to make sure the inode is updated with this
@@ -1005,9 +1006,11 @@ int reiserfs_get_block(struct inode *inode, sector_t block,
* long time. reschedule if needed and also release the write
* lock for others.
*/
- reiserfs_write_unlock(inode->i_sb);
- cond_resched();
- reiserfs_write_lock(inode->i_sb);
+ if (need_resched()) {
+ reiserfs_write_unlock_once(inode->i_sb, lock_depth);
+ schedule();
+ lock_depth = reiserfs_write_lock_once(inode->i_sb);
+ }
retval = search_for_position_by_key(inode->i_sb, &key, &path);
if (retval == IO_ERROR) {
@@ -1042,7 +1045,7 @@ int reiserfs_get_block(struct inode *inode, sector_t block,
retval = err;
}
- reiserfs_write_unlock(inode->i_sb);
+ reiserfs_write_unlock_once(inode->i_sb, lock_depth);
reiserfs_check_path(&path);
return retval;
}
--
1.6.2.3
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 4/7] kill-the-bkl/reiserfs: don't hold the write recursively in reiserfs_lookup()
2009-05-08 18:35 [PATCH 0/7] kill-the-bkl/reiserfs performances updates Frederic Weisbecker
` (2 preceding siblings ...)
2009-05-08 18:35 ` [PATCH 3/7] kill-the-bkl/reiserfs: lock only once on reiserfs_get_block() Frederic Weisbecker
@ 2009-05-08 18:35 ` Frederic Weisbecker
2009-05-08 18:35 ` [PATCH 5/7] kill-the-bkl/reiserfs: reduce number of contentions in search_by_key() Frederic Weisbecker
` (2 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Frederic Weisbecker @ 2009-05-08 18:35 UTC (permalink / raw)
To: Al Viro
Cc: LKML, Frederic Weisbecker, Jeff Mahoney, Chris Mason,
Ingo Molnar, Alexander Beregalov
The write lock can be acquired recursively in reiserfs_lookup(). But we may
want to *really* release the lock before possible rescheduling from a
reiserfs_lookup() callee.
Hence we want to only acquire the lock once (ie: not recursively).
[ Impact: prevent from possible false unreleased write lock on sleeping ]
Cc: Jeff Mahoney <jeffm@suse.com>
Cc: Chris Mason <chris.mason@oracle.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Alexander Beregalov <a.beregalov@gmail.com>
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
---
fs/reiserfs/namei.c | 15 +++++++++++----
1 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c
index efd4d72..bed3827 100644
--- a/fs/reiserfs/namei.c
+++ b/fs/reiserfs/namei.c
@@ -324,6 +324,7 @@ static struct dentry *reiserfs_lookup(struct inode *dir, struct dentry *dentry,
struct nameidata *nd)
{
int retval;
+ int lock_depth;
struct inode *inode = NULL;
struct reiserfs_dir_entry de;
INITIALIZE_PATH(path_to_entry);
@@ -331,7 +332,13 @@ static struct dentry *reiserfs_lookup(struct inode *dir, struct dentry *dentry,
if (REISERFS_MAX_NAME(dir->i_sb->s_blocksize) < dentry->d_name.len)
return ERR_PTR(-ENAMETOOLONG);
- reiserfs_write_lock(dir->i_sb);
+ /*
+ * Might be called with or without the write lock, must be careful
+ * to not recursively hold it in case we want to release the lock
+ * before rescheduling.
+ */
+ lock_depth = reiserfs_write_lock_once(dir->i_sb);
+
de.de_gen_number_bit_string = NULL;
retval =
reiserfs_find_entry(dir, dentry->d_name.name, dentry->d_name.len,
@@ -347,14 +354,14 @@ static struct dentry *reiserfs_lookup(struct inode *dir, struct dentry *dentry,
le32_to_cpu(INODE_PKEY
(REISERFS_SB(dir->i_sb)->priv_root->d_inode)->
k_objectid)) {
- reiserfs_write_unlock(dir->i_sb);
+ reiserfs_write_unlock_once(dir->i_sb, lock_depth);
return ERR_PTR(-EACCES);
}
inode =
reiserfs_iget(dir->i_sb, (struct cpu_key *)&(de.de_dir_id));
if (!inode || IS_ERR(inode)) {
- reiserfs_write_unlock(dir->i_sb);
+ reiserfs_write_unlock_once(dir->i_sb, lock_depth);
return ERR_PTR(-EACCES);
}
@@ -363,7 +370,7 @@ static struct dentry *reiserfs_lookup(struct inode *dir, struct dentry *dentry,
if (IS_PRIVATE(dir))
inode->i_flags |= S_PRIVATE;
}
- reiserfs_write_unlock(dir->i_sb);
+ reiserfs_write_unlock_once(dir->i_sb, lock_depth);
if (retval == IO_ERROR) {
return ERR_PTR(-EIO);
}
--
1.6.2.3
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 5/7] kill-the-bkl/reiserfs: reduce number of contentions in search_by_key()
2009-05-08 18:35 [PATCH 0/7] kill-the-bkl/reiserfs performances updates Frederic Weisbecker
` (3 preceding siblings ...)
2009-05-08 18:35 ` [PATCH 4/7] kill-the-bkl/reiserfs: don't hold the write recursively in reiserfs_lookup() Frederic Weisbecker
@ 2009-05-08 18:35 ` Frederic Weisbecker
2009-05-08 18:35 ` [PATCH 6/7] kill-the-bkl/reiserfs: factorize the locking in reiserfs_write_end() Frederic Weisbecker
2009-05-08 18:35 ` [PATCH 7/7] kill-the-bkl/reiserfs: use mutex_lock in reiserfs_mutex_lock_safe Frederic Weisbecker
6 siblings, 0 replies; 8+ messages in thread
From: Frederic Weisbecker @ 2009-05-08 18:35 UTC (permalink / raw)
To: Al Viro
Cc: LKML, Frederic Weisbecker, Jeff Mahoney, Chris Mason,
Ingo Molnar, Alexander Beregalov
search_by_key() is a central function in reiserfs which searches
the patch in the fs tree from the root to a node given its key.
It is the function that is most requesting the write lock
because it's a path very often used.
Also we forget to release the lock while reading the next tree node,
making us holding the lock in a wasteful way.
Then we release the lock while reading the current node and its childs,
all-in-one. It should be safe because we have a reference to these
blocks and even if we read a block that will be concurrently changed,
we have an fs_changed check later that will make us retry the path from
the root.
[ Impact: release the write lock while unused in a hot path ]
Cc: Jeff Mahoney <jeffm@suse.com>
Cc: Chris Mason <chris.mason@oracle.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Alexander Beregalov <a.beregalov@gmail.com>
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
---
fs/reiserfs/stree.c | 12 +++++++++++-
1 files changed, 11 insertions(+), 1 deletions(-)
diff --git a/fs/reiserfs/stree.c b/fs/reiserfs/stree.c
index 6ddcecb..960c911 100644
--- a/fs/reiserfs/stree.c
+++ b/fs/reiserfs/stree.c
@@ -529,6 +529,14 @@ static void search_by_key_reada(struct super_block *s,
for (i = 0; i < num; i++) {
bh[i] = sb_getblk(s, b[i]);
}
+ /*
+ * We are going to read some blocks on which we
+ * have a reference. It's safe, though we might be
+ * reading blocks concurrently changed if we release
+ * the lock. But it's still fine because we check later
+ * if the tree changed
+ */
+ reiserfs_write_unlock(s);
for (j = 0; j < i; j++) {
/*
* note, this needs attention if we are getting rid of the BKL
@@ -626,10 +634,12 @@ int search_by_key(struct super_block *sb, const struct cpu_key *key, /* Key to s
if ((bh = last_element->pe_buffer =
sb_getblk(sb, block_number))) {
if (!buffer_uptodate(bh) && reada_count > 1)
+ /* will unlock the write lock */
search_by_key_reada(sb, reada_bh,
reada_blocks, reada_count);
+ else
+ reiserfs_write_unlock(sb);
ll_rw_block(READ, 1, &bh);
- reiserfs_write_unlock(sb);
wait_on_buffer(bh);
reiserfs_write_lock(sb);
if (!buffer_uptodate(bh))
--
1.6.2.3
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 6/7] kill-the-bkl/reiserfs: factorize the locking in reiserfs_write_end()
2009-05-08 18:35 [PATCH 0/7] kill-the-bkl/reiserfs performances updates Frederic Weisbecker
` (4 preceding siblings ...)
2009-05-08 18:35 ` [PATCH 5/7] kill-the-bkl/reiserfs: reduce number of contentions in search_by_key() Frederic Weisbecker
@ 2009-05-08 18:35 ` Frederic Weisbecker
2009-05-08 18:35 ` [PATCH 7/7] kill-the-bkl/reiserfs: use mutex_lock in reiserfs_mutex_lock_safe Frederic Weisbecker
6 siblings, 0 replies; 8+ messages in thread
From: Frederic Weisbecker @ 2009-05-08 18:35 UTC (permalink / raw)
To: Al Viro
Cc: LKML, Frederic Weisbecker, Jeff Mahoney, Chris Mason,
Ingo Molnar, Alexander Beregalov
reiserfs_write_end() is a hot path in reiserfs.
We have two wasteful write lock lock/release inside that can be gathered
without changing the code logic.
This patch factorizes them out in a single protected section, reducing the
number of contentions inside.
[ Impact: reduce lock contention in a reiserfs hotpath ]
Cc: Jeff Mahoney <jeffm@suse.com>
Cc: Chris Mason <chris.mason@oracle.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Alexander Beregalov <a.beregalov@gmail.com>
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
---
fs/reiserfs/inode.c | 25 +++++++++++++++----------
1 files changed, 15 insertions(+), 10 deletions(-)
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
index a5f69ef..cd65176 100644
--- a/fs/reiserfs/inode.c
+++ b/fs/reiserfs/inode.c
@@ -2685,6 +2685,8 @@ static int reiserfs_write_end(struct file *file, struct address_space *mapping,
int update_sd = 0;
struct reiserfs_transaction_handle *th;
unsigned start;
+ int lock_depth = 0;
+ bool locked = false;
if ((unsigned long)fsdata & AOP_FLAG_CONT_EXPAND)
pos ++;
@@ -2711,9 +2713,11 @@ static int reiserfs_write_end(struct file *file, struct address_space *mapping,
** to do the i_size updates here.
*/
pos += copied;
+
if (pos > inode->i_size) {
struct reiserfs_transaction_handle myth;
- reiserfs_write_lock(inode->i_sb);
+ lock_depth = reiserfs_write_lock_once(inode->i_sb);
+ locked = true;
/* If the file have grown beyond the border where it
can have a tail, unmark it as needing a tail
packing */
@@ -2724,10 +2728,9 @@ static int reiserfs_write_end(struct file *file, struct address_space *mapping,
REISERFS_I(inode)->i_flags &= ~i_pack_on_close_mask;
ret = journal_begin(&myth, inode->i_sb, 1);
- if (ret) {
- reiserfs_write_unlock(inode->i_sb);
+ if (ret)
goto journal_error;
- }
+
reiserfs_update_inode_transaction(inode);
inode->i_size = pos;
/*
@@ -2739,34 +2742,36 @@ static int reiserfs_write_end(struct file *file, struct address_space *mapping,
reiserfs_update_sd(&myth, inode);
update_sd = 1;
ret = journal_end(&myth, inode->i_sb, 1);
- reiserfs_write_unlock(inode->i_sb);
if (ret)
goto journal_error;
}
if (th) {
- reiserfs_write_lock(inode->i_sb);
+ if (!locked) {
+ lock_depth = reiserfs_write_lock_once(inode->i_sb);
+ locked = true;
+ }
if (!update_sd)
mark_inode_dirty(inode);
ret = reiserfs_end_persistent_transaction(th);
- reiserfs_write_unlock(inode->i_sb);
if (ret)
goto out;
}
out:
+ if (locked)
+ reiserfs_write_unlock_once(inode->i_sb, lock_depth);
unlock_page(page);
page_cache_release(page);
return ret == 0 ? copied : ret;
journal_error:
+ reiserfs_write_unlock_once(inode->i_sb, lock_depth);
+ locked = false;
if (th) {
- reiserfs_write_lock(inode->i_sb);
if (!update_sd)
reiserfs_update_sd(th, inode);
ret = reiserfs_end_persistent_transaction(th);
- reiserfs_write_unlock(inode->i_sb);
}
-
goto out;
}
--
1.6.2.3
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 7/7] kill-the-bkl/reiserfs: use mutex_lock in reiserfs_mutex_lock_safe
2009-05-08 18:35 [PATCH 0/7] kill-the-bkl/reiserfs performances updates Frederic Weisbecker
` (5 preceding siblings ...)
2009-05-08 18:35 ` [PATCH 6/7] kill-the-bkl/reiserfs: factorize the locking in reiserfs_write_end() Frederic Weisbecker
@ 2009-05-08 18:35 ` Frederic Weisbecker
6 siblings, 0 replies; 8+ messages in thread
From: Frederic Weisbecker @ 2009-05-08 18:35 UTC (permalink / raw)
To: Al Viro
Cc: LKML, Frederic Weisbecker, Jeff Mahoney, Chris Mason,
Ingo Molnar, Alexander Beregalov
reiserfs_mutex_lock_safe() is a hack to avoid any dependency between
an internal reiserfs mutex and the write lock, it has been proposed
to follow the old bkl logic.
The code does the following:
while (!mutex_trylock(m)) {
reiserfs_write_unlock(s);
schedule();
reiserfs_write_lock(s);
}
It then imitate the implicit behaviour of the lock when it was
a Bkl and hadn't such dependency:
mutex_lock(m) {
if (fastpath)
let's go
else {
wait_for_mutex() {
schedule() {
unlock_kernel()
reacquire_lock_kernel()
}
}
}
}
The problem is that by using such explicit schedule(), we don't
benefit of the adaptive mutex spinning on owner.
The logic in use now is:
reiserfs_write_unlock(s);
mutex_lock(m); // -> possible adaptive spinning
reiserfs_write_lock(s);
[ Impact: restore the use of adaptive spinning mutexes in reiserfs ]
Cc: Jeff Mahoney <jeffm@suse.com>
Cc: Chris Mason <chris.mason@oracle.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Alexander Beregalov <a.beregalov@gmail.com>
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
---
fs/reiserfs/journal.c | 8 +++-----
1 files changed, 3 insertions(+), 5 deletions(-)
diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c
index b1ebd5a..3c3e00d 100644
--- a/fs/reiserfs/journal.c
+++ b/fs/reiserfs/journal.c
@@ -566,11 +566,9 @@ static inline void insert_journal_hash(struct reiserfs_journal_cnode **table,
static inline void reiserfs_mutex_lock_safe(struct mutex *m,
struct super_block *s)
{
- while (!mutex_trylock(m)) {
- reiserfs_write_unlock(s);
- schedule();
- reiserfs_write_lock(s);
- }
+ reiserfs_write_unlock(s);
+ mutex_lock(m);
+ reiserfs_write_lock(s);
}
/* lock the current transaction */
--
1.6.2.3
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2009-05-08 18:38 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-05-08 18:35 [PATCH 0/7] kill-the-bkl/reiserfs performances updates Frederic Weisbecker
2009-05-08 18:35 ` [PATCH 1/7] kill-the-BKL/reiserfs: add reiserfs_cond_resched() Frederic Weisbecker
2009-05-08 18:35 ` [PATCH 2/7] kill-the-bkl/reiserfs: conditionaly release the write lock on fs_changed() Frederic Weisbecker
2009-05-08 18:35 ` [PATCH 3/7] kill-the-bkl/reiserfs: lock only once on reiserfs_get_block() Frederic Weisbecker
2009-05-08 18:35 ` [PATCH 4/7] kill-the-bkl/reiserfs: don't hold the write recursively in reiserfs_lookup() Frederic Weisbecker
2009-05-08 18:35 ` [PATCH 5/7] kill-the-bkl/reiserfs: reduce number of contentions in search_by_key() Frederic Weisbecker
2009-05-08 18:35 ` [PATCH 6/7] kill-the-bkl/reiserfs: factorize the locking in reiserfs_write_end() Frederic Weisbecker
2009-05-08 18:35 ` [PATCH 7/7] kill-the-bkl/reiserfs: use mutex_lock in reiserfs_mutex_lock_safe Frederic Weisbecker
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Powered by JetHome