The increase/decrease of bio counter is on the I/O path, so we should
use io_schedule() instead of schedule(), or the deadlock might be
triggered by the pending I/O in the plug list. io_schedule() can help
us because it will flush all the pending I/O before the task is going
to sleep.

Signed-off-by: Miao Xie <mi...@cn.fujitsu.com>
---
Changelog v2 -> v3:
- New patch to fix possible deadlock caused by the pending bios in the
  plug list when the io submitters were going to sleep.

Changelog v1 -> v2:
- None.
---
 fs/btrfs/dev-replace.c | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/fs/btrfs/dev-replace.c b/fs/btrfs/dev-replace.c
index fa27b4e..894796a 100644
--- a/fs/btrfs/dev-replace.c
+++ b/fs/btrfs/dev-replace.c
@@ -928,16 +928,23 @@ void btrfs_bio_counter_sub(struct btrfs_fs_info *fs_info, 
s64 amount)
                wake_up(&fs_info->replace_wait);
 }
 
+#define btrfs_wait_event_io(wq, condition)                             \
+do {                                                                   \
+       if (condition)                                                  \
+               break;                                                  \
+       (void)___wait_event(wq, condition, TASK_UNINTERRUPTIBLE, 0, 0,  \
+                           io_schedule());                             \
+} while (0)
+
 void btrfs_bio_counter_inc_blocked(struct btrfs_fs_info *fs_info)
 {
-       DEFINE_WAIT(wait);
 again:
        percpu_counter_inc(&fs_info->bio_counter);
        if (test_bit(BTRFS_FS_STATE_DEV_REPLACING, &fs_info->fs_state)) {
                btrfs_bio_counter_dec(fs_info);
-               wait_event(fs_info->replace_wait,
-                          !test_bit(BTRFS_FS_STATE_DEV_REPLACING,
-                                    &fs_info->fs_state));
+               btrfs_wait_event_io(fs_info->replace_wait,
+                                   !test_bit(BTRFS_FS_STATE_DEV_REPLACING,
+                                             &fs_info->fs_state));
                goto again;
        }
 
-- 
1.9.3

--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to