[Devel] [PATCH rh7] ploop: release plo->ctl_mutex for thaw_bdev in PLOOP_IOC_THAW handler

Vladimir Davydov vdavydov at virtuozzo.com
Fri Jul 15 01:10:48 PDT 2016


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 <pborzenkov at virtuozzo.com>
Signed-off-by: Vladimir Davydov <vdavydov at virtuozzo.com>
Cc: Maxim Patlasov <mpatlasov at virtuozzo.com>
---
 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



More information about the Devel mailing list