Skip to content

Commit ed55b6a

Browse files
jeffmahoneymasoncl
authored andcommitted
btrfs: fix lockdep warning with reclaim lock inversion
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 alexander-zimmermann#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 alexander-zimmermann#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]>
1 parent 3f8a18c commit ed55b6a

File tree

1 file changed

+7
-3
lines changed

1 file changed

+7
-3
lines changed

fs/btrfs/extent-tree.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8337,9 +8337,15 @@ static void __link_block_group(struct btrfs_space_info *space_info,
83378337
struct btrfs_block_group_cache *cache)
83388338
{
83398339
int index = get_block_group_index(cache);
8340+
bool first = false;
83408341

83418342
down_write(&space_info->groups_sem);
8342-
if (list_empty(&space_info->block_groups[index])) {
8343+
if (list_empty(&space_info->block_groups[index]))
8344+
first = true;
8345+
list_add_tail(&cache->list, &space_info->block_groups[index]);
8346+
up_write(&space_info->groups_sem);
8347+
8348+
if (first) {
83438349
struct kobject *kobj = &space_info->block_group_kobjs[index];
83448350
int ret;
83458351

@@ -8351,8 +8357,6 @@ static void __link_block_group(struct btrfs_space_info *space_info,
83518357
kobject_put(&space_info->kobj);
83528358
}
83538359
}
8354-
list_add_tail(&cache->list, &space_info->block_groups[index]);
8355-
up_write(&space_info->groups_sem);
83568360
}
83578361

83588362
static struct btrfs_block_group_cache *

0 commit comments

Comments
 (0)