Use skip_drain on GET_VRING_BASE to suspend in-flight I/O requests, and then migrate them throught inflight subsection.
Signed-off-by: Alexandr Moshkov <[email protected]> --- hw/block/vhost-user-blk.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c index 3421145f23..4e606fd0fc 100644 --- a/hw/block/vhost-user-blk.c +++ b/hw/block/vhost-user-blk.c @@ -130,6 +130,17 @@ const VhostDevConfigOps blk_ops = { .vhost_dev_config_notifier = vhost_user_blk_handle_config_change, }; +static bool vhost_user_blk_inflight_needed(void *opaque) +{ + struct VHostUserBlk *s = opaque; + + bool inflight_migration = virtio_has_feature(s->dev.protocol_features, + VHOST_USER_PROTOCOL_F_GET_VRING_BASE_INFLIGHT); + + return inflight_migration && s->inflight_migration; +} + + static int vhost_user_blk_start(VirtIODevice *vdev, Error **errp) { VHostUserBlk *s = VHOST_USER_BLK(vdev); @@ -221,11 +232,13 @@ static int vhost_user_blk_stop(VirtIODevice *vdev) return 0; } + bool skip_drain = vhost_user_blk_inflight_needed(s); + force_stop = s->skip_get_vring_base_on_force_shutdown && qemu_force_shutdown_requested(); ret = force_stop ? vhost_dev_force_stop(&s->dev, vdev, true) : - vhost_dev_stop(&s->dev, vdev, true, false); + vhost_dev_stop(&s->dev, vdev, true, skip_drain); if (k->set_guest_notifiers(qbus->parent, s->dev.nvqs, false) < 0) { error_report("vhost guest notifier cleanup failed: %d", ret); @@ -568,16 +581,6 @@ static struct vhost_dev *vhost_user_blk_get_vhost(VirtIODevice *vdev) return &s->dev; } -static bool vhost_user_blk_inflight_needed(void *opaque) -{ - struct VHostUserBlk *s = opaque; - - bool inflight_migration = virtio_has_feature(s->dev.protocol_features, - VHOST_USER_PROTOCOL_F_GET_VRING_BASE_INFLIGHT); - - return inflight_migration; -} - static const VMStateDescription vmstate_vhost_user_blk_inflight = { .name = "vhost-user-blk/inflight", .version_id = 1, -- 2.34.1
