During inter-host migration, waiting for disk requests to be drained in the vhost-user backend can incur significant downtime.
This can be avoided if QEMU migrates the inflight region in vhost-user-blk. Thus, during the qemu migration, the vhost-user backend can cancel all inflight requests and then, after migration, they will be executed on another host. In vhost_user_blk_stop() on incoming inter-host migration make force_stop = true, so GET_VRING_BASE will not be executed. Signed-off-by: Alexandr Moshkov <[email protected]> --- hw/block/vhost-user-blk.c | 29 +++++++++++++++++++++++++++++ include/hw/virtio/vhost-user-blk.h | 1 + 2 files changed, 30 insertions(+) diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c index a8fd90480a..2d9b398de6 100644 --- a/hw/block/vhost-user-blk.c +++ b/hw/block/vhost-user-blk.c @@ -139,6 +139,14 @@ 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; + + return s->skip_get_vring_base_inflight_migration && + !migrate_local_vhost_user_blk(); +} + static int vhost_user_blk_start(VirtIODevice *vdev, Error **errp) { VHostUserBlk *s = VHOST_USER_BLK(vdev); @@ -242,6 +250,11 @@ static int vhost_user_blk_stop(VirtIODevice *vdev) force_stop = s->skip_get_vring_base_on_force_shutdown && qemu_force_shutdown_requested(); + if (vhost_user_blk_inflight_needed(s) && + runstate_check(RUN_STATE_FINISH_MIGRATE)) { + force_stop = true; + } + s->dev.backend_transfer = s->dev.backend_transfer || (runstate_check(RUN_STATE_FINISH_MIGRATE) && migrate_local_vhost_user_blk()); @@ -656,6 +669,16 @@ static struct vhost_dev *vhost_user_blk_get_vhost(VirtIODevice *vdev) return &s->dev; } +static const VMStateDescription vmstate_vhost_user_blk_inflight = { + .name = "vhost-user-blk/inflight", + .version_id = 1, + .needed = vhost_user_blk_inflight_needed, + .fields = (const VMStateField[]) { + VMSTATE_VHOST_INFLIGHT_REGION(inflight, VHostUserBlk), + VMSTATE_END_OF_LIST() + }, +}; + static bool vhost_user_blk_pre_incoming(void *opaque, Error **errp) { VHostUserBlk *s = VHOST_USER_BLK(opaque); @@ -678,6 +701,10 @@ static const VMStateDescription vmstate_vhost_user_blk = { VMSTATE_VIRTIO_DEVICE, VMSTATE_END_OF_LIST() }, + .subsections = (const VMStateDescription * const []) { + &vmstate_vhost_user_blk_inflight, + NULL + } }; static bool vhost_user_needed(void *opaque) @@ -751,6 +778,8 @@ static const Property vhost_user_blk_properties[] = { VIRTIO_BLK_F_WRITE_ZEROES, true), DEFINE_PROP_BOOL("skip-get-vring-base-on-force-shutdown", VHostUserBlk, skip_get_vring_base_on_force_shutdown, false), + DEFINE_PROP_BOOL("skip-get-vring-base-inflight-migration", VHostUserBlk, + skip_get_vring_base_inflight_migration, false), }; static void vhost_user_blk_class_init(ObjectClass *klass, const void *data) diff --git a/include/hw/virtio/vhost-user-blk.h b/include/hw/virtio/vhost-user-blk.h index b06f55fd6f..859fb96956 100644 --- a/include/hw/virtio/vhost-user-blk.h +++ b/include/hw/virtio/vhost-user-blk.h @@ -52,6 +52,7 @@ struct VHostUserBlk { bool started_vu; bool skip_get_vring_base_on_force_shutdown; + bool skip_get_vring_base_inflight_migration; bool incoming_backend; }; -- 2.34.1
