mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-05 10:31:46 +09:00
virtio-blk: Ensure no requests in virtqueues before deleting vqs.
[ Upstream commit 4ce6e2db00de8103a0687fb0f65fd17124a51aaa ] Ensure no remaining requests in virtqueues before resetting vdev and deleting virtqueues. Otherwise these requests will never be completed. It may cause the system to become unresponsive. Function blk_mq_quiesce_queue() can ensure that requests have become in_flight status, but it cannot guarantee that requests have been processed by the device. Virtqueues should never be deleted before all requests become complete status. Function blk_mq_freeze_queue() ensure that all requests in virtqueues become complete status. And no requests can enter in virtqueues. Signed-off-by: Yi Sun <yi.sun@unisoc.com> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Link: https://lore.kernel.org/r/20240129085250.1550594-1-yi.sun@unisoc.com Signed-off-by: Jens Axboe <axboe@kernel.dk> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
0947d0d463
commit
db48acce75
@@ -1206,14 +1206,15 @@ static int virtblk_freeze(struct virtio_device *vdev)
|
|||||||
{
|
{
|
||||||
struct virtio_blk *vblk = vdev->priv;
|
struct virtio_blk *vblk = vdev->priv;
|
||||||
|
|
||||||
|
/* Ensure no requests in virtqueues before deleting vqs. */
|
||||||
|
blk_mq_freeze_queue(vblk->disk->queue);
|
||||||
|
|
||||||
/* Ensure we don't receive any more interrupts */
|
/* Ensure we don't receive any more interrupts */
|
||||||
virtio_reset_device(vdev);
|
virtio_reset_device(vdev);
|
||||||
|
|
||||||
/* Make sure no work handler is accessing the device. */
|
/* Make sure no work handler is accessing the device. */
|
||||||
flush_work(&vblk->config_work);
|
flush_work(&vblk->config_work);
|
||||||
|
|
||||||
blk_mq_quiesce_queue(vblk->disk->queue);
|
|
||||||
|
|
||||||
vdev->config->del_vqs(vdev);
|
vdev->config->del_vqs(vdev);
|
||||||
kfree(vblk->vqs);
|
kfree(vblk->vqs);
|
||||||
|
|
||||||
@@ -1231,7 +1232,7 @@ static int virtblk_restore(struct virtio_device *vdev)
|
|||||||
|
|
||||||
virtio_device_ready(vdev);
|
virtio_device_ready(vdev);
|
||||||
|
|
||||||
blk_mq_unquiesce_queue(vblk->disk->queue);
|
blk_mq_unfreeze_queue(vblk->disk->queue);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user