Recent patch to ploop 91a74e3b91a ("ploop: add PLOOP_IOC_FREEZE and
PLOOP_IOC_THAW ioctls") introduced the follwing deadlock:Thread 1: [<ffffffff8122dc1e>] sleep_on_buffer+0xe/0x20 [<ffffffff8122fd78>] __sync_dirty_buffer+0xb8/0xe0 [<ffffffff8122fdb3>] sync_dirty_buffer+0x13/0x20 [<ffffffffa01dc930>] ext4_commit_super+0x1b0/0x240 [ext4] [<ffffffffa01dc9ed>] ext4_unfreeze+0x2d/0x40 [ext4] [<ffffffff811fc63f>] thaw_super+0x3f/0xb0 [<ffffffff812357d5>] thaw_bdev+0x65/0x80 [<ffffffffa0380140>] ploop_ioctl+0x6d0/0x29f0 [ploop] [<ffffffff812d3d3f>] blkdev_ioctl+0x2df/0x770 [<ffffffff81236131>] block_ioctl+0x41/0x50 [<ffffffff8120d0c5>] do_vfs_ioctl+0x255/0x4f0 [<ffffffff8120d3b4>] SyS_ioctl+0x54/0xa0 [<ffffffff81642d09>] system_call_fastpath+0x16/0x1b [<ffffffffffffffff>] 0xffffffffffffffff Thread 2: [<ffffffffa038a4c3>] ploop_pb_get_pending+0x163/0x290 [ploop] [<ffffffffa03791a1>] ploop_push_backup_io_get.isra.26+0x81/0x1b0 [ploop] [<ffffffffa037a75b>] ploop_push_backup_io+0x15b/0x260 [ploop] [<ffffffffa0380906>] ploop_ioctl+0xe96/0x29f0 [ploop] [<ffffffff812d3d3f>] blkdev_ioctl+0x2df/0x770 [<ffffffff81236131>] block_ioctl+0x41/0x50 [<ffffffff8120d0c5>] do_vfs_ioctl+0x255/0x4f0 [<ffffffff8120d3b4>] SyS_ioctl+0x54/0xa0 [<ffffffff81642d09>] system_call_fastpath+0x16/0x1b [<ffffffffffffffff>] 0xffffffffffffffff E.g. thread 1 is thawing ploop with PLOOP_IOC_THAW ioctl which holds plo->ctl_mutex during its work. To thaw itself, ext4 has to commit some data. This commit triggers push backup out-of-order request which must be processed and acked by userspace to be completed. But userspace can't process it, because ploop_pb_get_pending() wants the same mutext. Thus, deadlock. Fix the deadlock by releasing the mutex before calling thaw_bdev and reaquiring it after thaw_bdev is done. https://jira.sw.ru/browse/PSBM-49699 Reported-by: Pavel Borzenkov <[email protected]> Signed-off-by: Vladimir Davydov <[email protected]> Cc: Maxim Patlasov <[email protected]> --- drivers/block/ploop/dev.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/block/ploop/dev.c b/drivers/block/ploop/dev.c index d52975eaaa36..3dc94ca5c393 100644 --- a/drivers/block/ploop/dev.c +++ b/drivers/block/ploop/dev.c @@ -4839,11 +4839,12 @@ static int ploop_thaw(struct ploop_device *plo, struct block_device *bdev) if (!test_bit(PLOOP_S_FROZEN, &plo->state)) return 0; + plo->sb = NULL; + clear_bit(PLOOP_S_FROZEN, &plo->state); + + mutex_unlock(&plo->ctl_mutex); err = thaw_bdev(bdev, sb); - if (!err) { - plo->sb = NULL; - clear_bit(PLOOP_S_FROZEN, &plo->state); - } + mutex_lock(&plo->ctl_mutex); return err; } -- 2.1.4 _______________________________________________ Devel mailing list [email protected] https://lists.openvz.org/mailman/listinfo/devel
