]> git.proxmox.com Git - mirror_qemu.git/commit
block: Fix deadlock in bdrv_co_yield_to_drain()
authorKevin Wolf <kwolf@redhat.com>
Thu, 3 Dec 2020 17:23:11 +0000 (18:23 +0100)
committerKevin Wolf <kwolf@redhat.com>
Fri, 11 Dec 2020 16:52:40 +0000 (17:52 +0100)
commit960d5fb3e8ee09bc5f1a5c84f66dce42a6cef920
tree39067199e09a8bc788f23f6324a4a0a72d7e9a00
parent8089eab2bd5fb160b038e64e14cf7ffb3f37091e
block: Fix deadlock in bdrv_co_yield_to_drain()

If bdrv_co_yield_to_drain() is called for draining a block node that
runs in a different AioContext, it keeps that AioContext locked while it
yields and schedules a BH in the AioContext to do the actual drain.

As long as executing the BH is the very next thing that the event loop
of the node's AioContext does, this actually happens to work, but when
it tries to execute something else that wants to take the AioContext
lock, it will deadlock. (In the bug report, this other thing is a
virtio-scsi device running virtio_scsi_data_plane_handle_cmd().)

Instead, always drop the AioContext lock across the yield and reacquire
it only when the coroutine is reentered. The BH needs to unconditionally
take the lock for itself now.

This fixes the 'block_resize' QMP command on a block node that runs in
an iothread.

Cc: qemu-stable@nongnu.org
Fixes: eb94b81a94bce112e6b206df846c1551aaf6cab6
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1903511
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-Id: <20201203172311.68232-4-kwolf@redhat.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
block/io.c