From 0f09781df215086f095e40b42662dd2f3378ca7f Mon Sep 17 00:00:00 2001 From: Steve Sistare Date: Tue, 20 Aug 2024 05:48:08 -0700 Subject: [PATCH 2/2] vhost cpr-transfer support For cpr-transfer mode, a vhost device must be reset before CPR state is sent to new QEMU, because after state is sent, new QEMU initializes the device and calls set_owner. Install a cpr-setup notifier to do so. This still works for cpr-exec mode. Signed-off-by: Steve Sistare --- hw/virtio/vhost.c | 17 +++++++++++++++-- include/hw/virtio/vhost.h | 1 + 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c index 54c5ec7..31c72d1 100644 --- a/hw/virtio/vhost.c +++ b/hw/virtio/vhost.c @@ -1513,16 +1513,24 @@ static int vhost_cpr_notifier(NotifierWithReturn *notifier, struct vhost_dev *dev; int r; - dev = container_of(notifier, struct vhost_dev, cpr_exec_notifier); + dev = (migrate_mode() == MIG_MODE_CPR_EXEC) ? + container_of(notifier, struct vhost_dev, cpr_exec_notifier) : + container_of(notifier, struct vhost_dev, cpr_transfer_notifier); + if (dev->vhost_ops->backend_type != VHOST_BACKEND_TYPE_KERNEL) { return 0; } - if (e->type == MIG_EVENT_PRECOPY_DONE) { + if (e->type == MIG_EVENT_PRECOPY_CPR_SETUP) { r = dev->vhost_ops->vhost_reset_device(dev); if (r < 0) { VHOST_OPS_DEBUG(r, "vhost_reset_device failed"); } + } else if (e->type == MIG_EVENT_PRECOPY_FAILED) { + r = dev->vhost_ops->vhost_set_owner(dev); + if (r < 0) { + VHOST_OPS_DEBUG(r, "vhost_set_owner failed"); + } } return 0; } @@ -1538,6 +1546,7 @@ int vhost_dev_init(struct vhost_dev *hdev, void *opaque, hdev->vdev = NULL; hdev->migration_blocker = NULL; hdev->cpr_exec_notifier.notify = NULL; + hdev->cpr_transfer_notifier.notify = NULL; r = vhost_set_backend_type(hdev, backend_type); assert(r >= 0); @@ -1641,6 +1650,9 @@ int vhost_dev_init(struct vhost_dev *hdev, void *opaque, migration_add_notifier_mode(&hdev->cpr_exec_notifier, vhost_cpr_notifier, MIG_MODE_CPR_EXEC); + migration_add_notifier_mode(&hdev->cpr_transfer_notifier, + vhost_cpr_notifier, + MIG_MODE_CPR_TRANSFER); QLIST_INSERT_HEAD(&vhost_devices, hdev, entry); /* @@ -1698,6 +1710,7 @@ void vhost_dev_cleanup(struct vhost_dev *hdev) } migrate_del_blocker(&hdev->migration_blocker); migration_remove_notifier(&hdev->cpr_exec_notifier); + migration_remove_notifier(&hdev->cpr_transfer_notifier); g_free(hdev->mem); g_free(hdev->mem_sections); if (hdev->vhost_ops) { diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h index e9aca11..ab7e874 100644 --- a/include/hw/virtio/vhost.h +++ b/include/hw/virtio/vhost.h @@ -133,6 +133,7 @@ struct vhost_dev { QLIST_HEAD(, vhost_iommu) iommu_list; IOMMUNotifier n; NotifierWithReturn cpr_exec_notifier; + NotifierWithReturn cpr_transfer_notifier; const VhostDevConfigOps *config_ops; }; -- 1.8.3.1