diff mbox series

btrfs: zoned: fix possible deadlock on log sync

Message ID ba64e01fa8f13d10daebe1d8e24ad1a20de9b231.1613545566.git.johannes.thumshirn@wdc.com (mailing list archive)
State New, archived
Headers show
Series btrfs: zoned: fix possible deadlock on log sync | expand

Commit Message

Johannes Thumshirn Feb. 17, 2021, 7:06 a.m. UTC
Lockdep with fstests test-case btrfs/041 detected a unsafe locking
scenario when we allocate the log node on a zoned filesystem.

btrfs/041
 ============================================
 WARNING: possible recursive locking detected
 5.11.0-rc7+ #939 Not tainted
 --------------------------------------------
 xfs_io/698 is trying to acquire lock:
 ffff88810cd673a0 (&root->log_mutex){+.+.}-{3:3}, at: btrfs_sync_log+0x3d1/0xee0 [btrfs]

 but task is already holding lock:
 ffff88810b0fc3a0 (&root->log_mutex){+.+.}-{3:3}, at: btrfs_sync_log+0x313/0xee0 [btrfs]

 other info that might help us debug this:
  Possible unsafe locking scenario:

        CPU0
        ----
   lock(&root->log_mutex);
   lock(&root->log_mutex);

  *** DEADLOCK ***

  May be due to missing lock nesting notation

 2 locks held by xfs_io/698:
  #0: ffff88810cd66620 (sb_internal){.+.+}-{0:0}, at: btrfs_sync_file+0x2c3/0x570 [btrfs]
  #1: ffff88810b0fc3a0 (&root->log_mutex){+.+.}-{3:3}, at: btrfs_sync_log+0x313/0xee0 [btrfs]

 stack backtrace:
 CPU: 0 PID: 698 Comm: xfs_io Not tainted 5.11.0-rc7+ #939
 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.13.0-0-gf21b5a4-rebuilt.opensuse.org 04/01/2014
 Call Trace:
  dump_stack+0x77/0x97
  __lock_acquire.cold+0xb9/0x32a
  lock_acquire+0xb5/0x400
  ? btrfs_sync_log+0x3d1/0xee0 [btrfs]
  __mutex_lock+0x7b/0x8d0
  ? btrfs_sync_log+0x3d1/0xee0 [btrfs]
  ? btrfs_sync_log+0x3d1/0xee0 [btrfs]
  ? find_first_extent_bit+0x9f/0x100 [btrfs]
  ? __mutex_unlock_slowpath+0x35/0x270
  btrfs_sync_log+0x3d1/0xee0 [btrfs]
  btrfs_sync_file+0x3a8/0x570 [btrfs]
  __x64_sys_fsync+0x34/0x60
  do_syscall_64+0x33/0x40
  entry_SYSCALL_64_after_hwframe+0x44/0xa9
 RIP: 0033:0x7f1e856b8ecb
 Code: 0f 05 48 3d 00 f0 ff ff 77 45 c3 0f 1f 40 00 48 83 ec 18 89 7c 24 0c e8 b3 f6 ff ff 8b 7c 24 0c 41 89 c0 b8 4a 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 35 44 89 c7 89 44 24 0c e8 11 f7 ff ff 8b 44
 RSP: 002b:00007ffde89011b0 EFLAGS: 00000293 ORIG_RAX: 000000000000004a
 RAX: ffffffffffffffda RBX: 0000557ef97886c0 RCX: 00007f1e856b8ecb
 RDX: 0000000000000002 RSI: 0000557ef97886e0 RDI: 0000000000000003
 RBP: 0000557ef97886e0 R08: 0000000000000000 R09: 0000000000000003
 R10: fffffffffffff50e R11: 0000000000000293 R12: 0000000000000001
 R13: 0000557ef97886c0 R14: 0000000000000001 R15: 0000557ef976e2a0

This happens, because we are taking the ->log_mutex albeit it has already
been locked.

Also while at it, fix the bogus unlock of the tree_log_mutex in the error
handling.

Fixes: 3ddebf27fcd3 ("btrfs: zoned: reorder log node allocation on zoned filesystem")
Cc: Filipe Manana <fdmanana@suse.com>
Cc: Naohiro Aota <naohiro.aota@wdc.com>
Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
---
 fs/btrfs/tree-log.c | 3 ---
 1 file changed, 3 deletions(-)

Comments

Filipe Manana Feb. 17, 2021, 10:55 a.m. UTC | #1
On Wed, Feb 17, 2021 at 7:38 AM Johannes Thumshirn
<johannes.thumshirn@wdc.com> wrote:
>
> Lockdep with fstests test-case btrfs/041 detected a unsafe locking
> scenario when we allocate the log node on a zoned filesystem.
>
> btrfs/041
>  ============================================
>  WARNING: possible recursive locking detected
>  5.11.0-rc7+ #939 Not tainted
>  --------------------------------------------
>  xfs_io/698 is trying to acquire lock:
>  ffff88810cd673a0 (&root->log_mutex){+.+.}-{3:3}, at: btrfs_sync_log+0x3d1/0xee0 [btrfs]
>
>  but task is already holding lock:
>  ffff88810b0fc3a0 (&root->log_mutex){+.+.}-{3:3}, at: btrfs_sync_log+0x313/0xee0 [btrfs]
>
>  other info that might help us debug this:
>   Possible unsafe locking scenario:
>
>         CPU0
>         ----
>    lock(&root->log_mutex);
>    lock(&root->log_mutex);
>
>   *** DEADLOCK ***
>
>   May be due to missing lock nesting notation
>
>  2 locks held by xfs_io/698:
>   #0: ffff88810cd66620 (sb_internal){.+.+}-{0:0}, at: btrfs_sync_file+0x2c3/0x570 [btrfs]
>   #1: ffff88810b0fc3a0 (&root->log_mutex){+.+.}-{3:3}, at: btrfs_sync_log+0x313/0xee0 [btrfs]
>
>  stack backtrace:
>  CPU: 0 PID: 698 Comm: xfs_io Not tainted 5.11.0-rc7+ #939
>  Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.13.0-0-gf21b5a4-rebuilt.opensuse.org 04/01/2014
>  Call Trace:
>   dump_stack+0x77/0x97
>   __lock_acquire.cold+0xb9/0x32a
>   lock_acquire+0xb5/0x400
>   ? btrfs_sync_log+0x3d1/0xee0 [btrfs]
>   __mutex_lock+0x7b/0x8d0
>   ? btrfs_sync_log+0x3d1/0xee0 [btrfs]
>   ? btrfs_sync_log+0x3d1/0xee0 [btrfs]
>   ? find_first_extent_bit+0x9f/0x100 [btrfs]
>   ? __mutex_unlock_slowpath+0x35/0x270
>   btrfs_sync_log+0x3d1/0xee0 [btrfs]
>   btrfs_sync_file+0x3a8/0x570 [btrfs]
>   __x64_sys_fsync+0x34/0x60
>   do_syscall_64+0x33/0x40
>   entry_SYSCALL_64_after_hwframe+0x44/0xa9
>  RIP: 0033:0x7f1e856b8ecb
>  Code: 0f 05 48 3d 00 f0 ff ff 77 45 c3 0f 1f 40 00 48 83 ec 18 89 7c 24 0c e8 b3 f6 ff ff 8b 7c 24 0c 41 89 c0 b8 4a 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 35 44 89 c7 89 44 24 0c e8 11 f7 ff ff 8b 44
>  RSP: 002b:00007ffde89011b0 EFLAGS: 00000293 ORIG_RAX: 000000000000004a
>  RAX: ffffffffffffffda RBX: 0000557ef97886c0 RCX: 00007f1e856b8ecb
>  RDX: 0000000000000002 RSI: 0000557ef97886e0 RDI: 0000000000000003
>  RBP: 0000557ef97886e0 R08: 0000000000000000 R09: 0000000000000003
>  R10: fffffffffffff50e R11: 0000000000000293 R12: 0000000000000001
>  R13: 0000557ef97886c0 R14: 0000000000000001 R15: 0000557ef976e2a0
>
> This happens, because we are taking the ->log_mutex albeit it has already
> been locked.
>
> Also while at it, fix the bogus unlock of the tree_log_mutex in the error
> handling.
>
> Fixes: 3ddebf27fcd3 ("btrfs: zoned: reorder log node allocation on zoned filesystem")
> Cc: Filipe Manana <fdmanana@suse.com>
> Cc: Naohiro Aota <naohiro.aota@wdc.com>
> Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>

Reviewed-by: Filipe Manana <fdmanana@suse.com>

Looks good, and actually this is a guaranteed deadlock rather than a
possible deadlock (as the subject says).

Thanks.

> ---
>  fs/btrfs/tree-log.c | 3 ---
>  1 file changed, 3 deletions(-)
>
> diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
> index d90695c1ab6c..2f1acc9aea9e 100644
> --- a/fs/btrfs/tree-log.c
> +++ b/fs/btrfs/tree-log.c
> @@ -3174,16 +3174,13 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
>         root_log_ctx.log_transid = log_root_tree->log_transid;
>
>         if (btrfs_is_zoned(fs_info)) {
> -               mutex_lock(&fs_info->tree_root->log_mutex);
>                 if (!log_root_tree->node) {
>                         ret = btrfs_alloc_log_tree_node(trans, log_root_tree);
>                         if (ret) {
> -                               mutex_unlock(&fs_info->tree_log_mutex);
>                                 mutex_unlock(&log_root_tree->log_mutex);
>                                 goto out;
>                         }
>                 }
> -               mutex_unlock(&fs_info->tree_root->log_mutex);
>         }
>
>         /*
> --
> 2.30.0
>
David Sterba Feb. 17, 2021, 5:33 p.m. UTC | #2
On Wed, Feb 17, 2021 at 04:06:18PM +0900, Johannes Thumshirn wrote:
> Lockdep with fstests test-case btrfs/041 detected a unsafe locking
> scenario when we allocate the log node on a zoned filesystem.
> 
> btrfs/041
>  ============================================
>  WARNING: possible recursive locking detected
>  5.11.0-rc7+ #939 Not tainted
>  --------------------------------------------
>  xfs_io/698 is trying to acquire lock:
>  ffff88810cd673a0 (&root->log_mutex){+.+.}-{3:3}, at: btrfs_sync_log+0x3d1/0xee0 [btrfs]
> 
>  but task is already holding lock:
>  ffff88810b0fc3a0 (&root->log_mutex){+.+.}-{3:3}, at: btrfs_sync_log+0x313/0xee0 [btrfs]
> 
>  other info that might help us debug this:
>   Possible unsafe locking scenario:
> 
>         CPU0
>         ----
>    lock(&root->log_mutex);
>    lock(&root->log_mutex);
> 
>   *** DEADLOCK ***
> 
>   May be due to missing lock nesting notation
> 
>  2 locks held by xfs_io/698:
>   #0: ffff88810cd66620 (sb_internal){.+.+}-{0:0}, at: btrfs_sync_file+0x2c3/0x570 [btrfs]
>   #1: ffff88810b0fc3a0 (&root->log_mutex){+.+.}-{3:3}, at: btrfs_sync_log+0x313/0xee0 [btrfs]
> 
>  stack backtrace:
>  CPU: 0 PID: 698 Comm: xfs_io Not tainted 5.11.0-rc7+ #939
>  Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.13.0-0-gf21b5a4-rebuilt.opensuse.org 04/01/2014
>  Call Trace:
>   dump_stack+0x77/0x97
>   __lock_acquire.cold+0xb9/0x32a
>   lock_acquire+0xb5/0x400
>   ? btrfs_sync_log+0x3d1/0xee0 [btrfs]
>   __mutex_lock+0x7b/0x8d0
>   ? btrfs_sync_log+0x3d1/0xee0 [btrfs]
>   ? btrfs_sync_log+0x3d1/0xee0 [btrfs]
>   ? find_first_extent_bit+0x9f/0x100 [btrfs]
>   ? __mutex_unlock_slowpath+0x35/0x270
>   btrfs_sync_log+0x3d1/0xee0 [btrfs]
>   btrfs_sync_file+0x3a8/0x570 [btrfs]
>   __x64_sys_fsync+0x34/0x60
>   do_syscall_64+0x33/0x40
>   entry_SYSCALL_64_after_hwframe+0x44/0xa9
>  RIP: 0033:0x7f1e856b8ecb
>  Code: 0f 05 48 3d 00 f0 ff ff 77 45 c3 0f 1f 40 00 48 83 ec 18 89 7c 24 0c e8 b3 f6 ff ff 8b 7c 24 0c 41 89 c0 b8 4a 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 35 44 89 c7 89 44 24 0c e8 11 f7 ff ff 8b 44

This line should be deleted from the stacktraces.

>  RSP: 002b:00007ffde89011b0 EFLAGS: 00000293 ORIG_RAX: 000000000000004a
>  RAX: ffffffffffffffda RBX: 0000557ef97886c0 RCX: 00007f1e856b8ecb
>  RDX: 0000000000000002 RSI: 0000557ef97886e0 RDI: 0000000000000003
>  RBP: 0000557ef97886e0 R08: 0000000000000000 R09: 0000000000000003
>  R10: fffffffffffff50e R11: 0000000000000293 R12: 0000000000000001
>  R13: 0000557ef97886c0 R14: 0000000000000001 R15: 0000557ef976e2a0
> 
> This happens, because we are taking the ->log_mutex albeit it has already
> been locked.
> 
> Also while at it, fix the bogus unlock of the tree_log_mutex in the error
> handling.
> 
> Fixes: 3ddebf27fcd3 ("btrfs: zoned: reorder log node allocation on zoned filesystem")
> Cc: Filipe Manana <fdmanana@suse.com>
> Cc: Naohiro Aota <naohiro.aota@wdc.com>
> Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>

With updated subject adde to misc-next, thanks.
diff mbox series

Patch

diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index d90695c1ab6c..2f1acc9aea9e 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -3174,16 +3174,13 @@  int btrfs_sync_log(struct btrfs_trans_handle *trans,
 	root_log_ctx.log_transid = log_root_tree->log_transid;
 
 	if (btrfs_is_zoned(fs_info)) {
-		mutex_lock(&fs_info->tree_root->log_mutex);
 		if (!log_root_tree->node) {
 			ret = btrfs_alloc_log_tree_node(trans, log_root_tree);
 			if (ret) {
-				mutex_unlock(&fs_info->tree_log_mutex);
 				mutex_unlock(&log_root_tree->log_mutex);
 				goto out;
 			}
 		}
-		mutex_unlock(&fs_info->tree_root->log_mutex);
 	}
 
 	/*