diff options
author | Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> | 2009-02-24 12:14:52 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-03-16 17:53:06 -0700 |
commit | 9be67f0451236e7fe8cd0b75b610c37a736891d1 (patch) | |
tree | f363c392a0814c84e57c162ad5683056a2c664ea | |
parent | 88798d5547218277d2c293c0d9da3edaddba6e66 (diff) | |
download | lwn-9be67f0451236e7fe8cd0b75b610c37a736891d1.tar.gz lwn-9be67f0451236e7fe8cd0b75b610c37a736891d1.zip |
ext4: Fix lockdep warning
(cherry picked from commit ba4439165f0f0d25b2fe065cf0c1ff8130b802eb)
We should not call ext4_mb_add_n_trim while holding alloc_semp.
=============================================
[ INFO: possible recursive locking detected ]
2.6.29-rc4-git1-dirty #124
---------------------------------------------
ffsb/3116 is trying to acquire lock:
(&meta_group_info[i]->alloc_sem){----}, at: [<ffffffff8035a6e8>]
ext4_mb_load_buddy+0xd2/0x343
but task is already holding lock:
(&meta_group_info[i]->alloc_sem){----}, at: [<ffffffff8035a6e8>]
ext4_mb_load_buddy+0xd2/0x343
http://bugzilla.kernel.org/show_bug.cgi?id=12672
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | fs/ext4/mballoc.c | 29 |
1 files changed, 16 insertions, 13 deletions
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index dbf6c0e52d43..adb23f9fc1ba 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -4569,23 +4569,26 @@ static int ext4_mb_release_context(struct ext4_allocation_context *ac) pa->pa_free -= ac->ac_b_ex.fe_len; pa->pa_len -= ac->ac_b_ex.fe_len; spin_unlock(&pa->pa_lock); - /* - * We want to add the pa to the right bucket. - * Remove it from the list and while adding - * make sure the list to which we are adding - * doesn't grow big. - */ - if (likely(pa->pa_free)) { - spin_lock(pa->pa_obj_lock); - list_del_rcu(&pa->pa_inode_list); - spin_unlock(pa->pa_obj_lock); - ext4_mb_add_n_trim(ac); - } } - ext4_mb_put_pa(ac, ac->ac_sb, pa); } if (ac->alloc_semp) up_read(ac->alloc_semp); + if (pa) { + /* + * We want to add the pa to the right bucket. + * Remove it from the list and while adding + * make sure the list to which we are adding + * doesn't grow big. We need to release + * alloc_semp before calling ext4_mb_add_n_trim() + */ + if (pa->pa_linear && likely(pa->pa_free)) { + spin_lock(pa->pa_obj_lock); + list_del_rcu(&pa->pa_inode_list); + spin_unlock(pa->pa_obj_lock); + ext4_mb_add_n_trim(ac); + } + ext4_mb_put_pa(ac, ac->ac_sb, pa); + } if (ac->ac_bitmap_page) page_cache_release(ac->ac_bitmap_page); if (ac->ac_buddy_page) |