In case of migration of QEMU from the new version (where the inflight-migration parameter is present), to the old one (where it is absent) there is no way to disable this feature on the backend during runtime. Now inflight-migration param can be turned on and off, so this logic will work correctly.
Now when inflight-migration is enabled and the device is stopping due to live migration, send GET_VRING_BASE_SKIP_DRAIN message to the back-end, allowing back-end to suspend inflight I/O immediately instead of completing them. In case if inflight-migration is disabled, use default GET_VRING_BASE message with back-end. Also now QEMU will always try to setup VHOST_USER_PROTOCOL_F_GET_VRING_BASE_INFLIGHT protocol feature with backend. This will allow to use GET_VRING_BASE_SKIP_DRAIN message. Signed-off-by: Alexandr Moshkov <[email protected]> --- hw/block/vhost-user-blk.c | 30 ++++++++++++++++++++++++------ hw/virtio/vhost-user.c | 3 +-- include/hw/virtio/vhost-user.h | 1 - 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c index 156ed6de30..cd0a443b26 100644 --- a/hw/block/vhost-user-blk.c +++ b/hw/block/vhost-user-blk.c @@ -135,10 +135,7 @@ 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; + return s->inflight_migration; } @@ -239,11 +236,14 @@ static int vhost_user_blk_stop(VirtIODevice *vdev) return 0; } + bool skip_drain = vhost_user_blk_inflight_needed(s) && + runstate_check(RUN_STATE_FINISH_MIGRATE); + 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); err = k->set_guest_notifiers(qbus->parent, s->dev.nvqs, false); if (err < 0) { @@ -375,7 +375,6 @@ static int vhost_user_blk_connect(DeviceState *dev, Error **errp) vhost_dev_set_config_notifier(&s->dev, &blk_ops); s->vhost_user.supports_config = true; - s->vhost_user.supports_inflight_migration = s->inflight_migration; ret = vhost_dev_init(&s->dev, &s->vhost_user, VHOST_BACKEND_TYPE_USER, 0, errp); if (ret < 0) { @@ -598,10 +597,29 @@ static struct vhost_dev *vhost_user_blk_get_vhost(VirtIODevice *vdev) return &s->dev; } +static bool vhost_user_blk_pre_save(void *opaque, Error **errp) +{ + VHostUserBlk *s = VHOST_USER_BLK(opaque); + + bool inflight_migration_enabled = vhost_user_has_protocol_feature(&s->dev, + VHOST_USER_PROTOCOL_F_GET_VRING_BASE_INFLIGHT); + + if (vhost_user_blk_inflight_needed(s) && !inflight_migration_enabled) { + error_setg(errp, "can't migrate vhost-user-blk device: " + "backend doesn't support " + "VHOST_USER_PROTOCOL_F_GET_VRING_BASE_INFLIGHT " + "protocol feature"); + return false; + } + + return true; +} + static const VMStateDescription vmstate_vhost_user_blk_inflight = { .name = "vhost-user-blk/inflight", .version_id = 1, .needed = vhost_user_blk_inflight_needed, + .pre_save_errp = vhost_user_blk_pre_save, .fields = (const VMStateField[]) { VMSTATE_VHOST_INFLIGHT_REGION(inflight, VHostUserBlk), VMSTATE_END_OF_LIST() diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c index 2f71ede599..e3e0164707 100644 --- a/hw/virtio/vhost-user.c +++ b/hw/virtio/vhost-user.c @@ -2570,8 +2570,7 @@ static int vhost_user_backend_init(struct vhost_dev *dev, void *opaque, } } - if (!u->user->supports_inflight_migration || - !virtio_has_feature(protocol_features, + if (!virtio_has_feature(protocol_features, VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD)) { protocol_features &= ~(1ULL << VHOST_USER_PROTOCOL_F_GET_VRING_BASE_INFLIGHT); diff --git a/include/hw/virtio/vhost-user.h b/include/hw/virtio/vhost-user.h index 06c360af18..1ded2c2d27 100644 --- a/include/hw/virtio/vhost-user.h +++ b/include/hw/virtio/vhost-user.h @@ -72,7 +72,6 @@ typedef struct VhostUserState { GPtrArray *notifiers; int memory_slots; bool supports_config; - bool supports_inflight_migration; } VhostUserState; /** -- 2.34.1
