Initializes vhost-net support for iterative live migration by avoiding the assertion that vhost needs to be stopped before proceeding with sending the initial VMStateDescription for virtio-net.
This should be okay to do since we only care about the static device state and not the dynamic ring states for the initial sending of the device state. After the iterative migration portion is finished and the source is stopped, we still assert that vhost is also stopped. Signed-off-by: Jonah Palmer <jonah.pal...@oracle.com> --- hw/net/virtio-net.c | 23 ++++++++++++++++++++++- include/hw/virtio/virtio.h | 1 + 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index b7ac5e8278..07941f991e 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -3753,6 +3753,19 @@ static bool failover_hide_primary_device(DeviceListener *listener, static int virtio_net_pre_save(void *opaque) { VirtIONet *n = opaque; + VirtIODevice *vdev = VIRTIO_DEVICE(n); + + /* + * During iterative migration, vhost will still be active. However, + * this shouldn't be an issue since we don't care about the dynamic + * ring states at this point. + * + * The final migration at the end will still occur with vhost stopped + * and any inconsistencies will be overwritten. + */ + if (vdev->migration && !vdev->migration->iterative_vmstate_sent) { + return 0; + } /* At this point, backend must be stopped, otherwise * it might keep writing to memory. */ @@ -3809,11 +3822,16 @@ static bool virtio_net_is_active(void *opaque) static int virtio_net_save_setup(QEMUFile *f, void *opaque, Error **errp) { VirtIONet *n = opaque; + VirtIODevice *vdev = VIRTIO_DEVICE(n); + vdev->migration = g_new0(VirtIODevMigration, 1); + vdev->migration->iterative_vmstate_sent = false; qemu_put_be64(f, VNET_MIG_F_INIT_STATE); vmstate_save_state(f, &vmstate_virtio_net, n, NULL); qemu_put_be64(f, VNET_MIG_F_END_DATA); + vdev->migration->iterative_vmstate_sent = true; + return 0; } @@ -3838,7 +3856,10 @@ static int virtio_net_save_live_complete_precopy(QEMUFile *f, void *opaque) static void virtio_net_save_cleanup(void *opaque) { - + VirtIONet *n = opaque; + VirtIODevice *vdev = VIRTIO_DEVICE(n); + g_free(vdev->migration); + vdev->migration = NULL; } static int virtio_net_load_setup(QEMUFile *f, void *opaque, Error **errp) diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h index 06b6e6ba65..aa3f60cb7b 100644 --- a/include/hw/virtio/virtio.h +++ b/include/hw/virtio/virtio.h @@ -101,6 +101,7 @@ enum virtio_device_endian { /* VirtIODevice iterative live migration data structure */ typedef struct VirtIODevMigration { bool iterative_vmstate_loaded; + bool iterative_vmstate_sent; } VirtIODevMigration; /** -- 2.47.1