Skip to content

Commit f59f14e

Browse files
jeffmahoneygregkh
authored andcommitted
btrfs: fix lockdep warning with reclaim lock inversion
commit ed55b6a upstream. When encountering memory pressure, testers have run into the following lockdep warning. It was caused by __link_block_group calling kobject_add with the groups_sem held. kobject_add calls kvasprintf with GFP_KERNEL, which gets us into reclaim context. The kobject doesn't actually need to be added under the lock -- it just needs to ensure that it's only added for the first block group to be linked. ========================================================= [ INFO: possible irq lock inversion dependency detected ] 3.14.0-rc8-default #1 Not tainted --------------------------------------------------------- kswapd0/169 just changed the state of lock: (&delayed_node->mutex){+.+.-.}, at: [<ffffffffa018baea>] __btrfs_release_delayed_node+0x3a/0x200 [btrfs] but this lock took another, RECLAIM_FS-unsafe lock in the past: (&found->groups_sem){+++++.} and interrupts could create inverse lock ordering between them. other info that might help us debug this: Possible interrupt unsafe locking scenario: CPU0 CPU1 ---- ---- lock(&found->groups_sem); local_irq_disable(); lock(&delayed_node->mutex); lock(&found->groups_sem); <Interrupt> lock(&delayed_node->mutex); *** DEADLOCK *** 2 locks held by kswapd0/169: #0: (shrinker_rwsem){++++..}, at: [<ffffffff81159e8a>] shrink_slab+0x3a/0x160 #1: (&type->s_umount_key#27){++++..}, at: [<ffffffff811bac6f>] grab_super_passive+0x3f/0x90 Signed-off-by: Jeff Mahoney <[email protected]> Signed-off-by: Chris Mason <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent fe79ac2 commit f59f14e

File tree

1 file changed

+7
-3
lines changed

1 file changed

+7
-3
lines changed

fs/btrfs/extent-tree.c

+7-3
Original file line numberDiff line numberDiff line change
@@ -8344,9 +8344,15 @@ static void __link_block_group(struct btrfs_space_info *space_info,
83448344
struct btrfs_block_group_cache *cache)
83458345
{
83468346
int index = get_block_group_index(cache);
8347+
bool first = false;
83478348

83488349
down_write(&space_info->groups_sem);
8349-
if (list_empty(&space_info->block_groups[index])) {
8350+
if (list_empty(&space_info->block_groups[index]))
8351+
first = true;
8352+
list_add_tail(&cache->list, &space_info->block_groups[index]);
8353+
up_write(&space_info->groups_sem);
8354+
8355+
if (first) {
83508356
struct kobject *kobj = &space_info->block_group_kobjs[index];
83518357
int ret;
83528358

@@ -8358,8 +8364,6 @@ static void __link_block_group(struct btrfs_space_info *space_info,
83588364
kobject_put(&space_info->kobj);
83598365
}
83608366
}
8361-
list_add_tail(&cache->list, &space_info->block_groups[index]);
8362-
up_write(&space_info->groups_sem);
83638367
}
83648368

83658369
static struct btrfs_block_group_cache *

0 commit comments

Comments
 (0)