Thanks to pririty, backend is migrated before the virtio-net itself.
So we can finish the releate initialization already in .pre_load,
not postponing it to .post_load.

Fixes: bb71b1bffe58df "virtio-net: support local migration of backend"
Signed-off-by: Vladimir Sementsov-Ogievskiy <[email protected]>
---
 hw/net/virtio-net.c | 40 +++++++++++++++++-----------------------
 1 file changed, 17 insertions(+), 23 deletions(-)

diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 19f453fb7df..4794496b964 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -3250,13 +3250,28 @@ static void virtio_net_get_features(VirtIODevice *vdev, 
uint64_t *features,
     }
 }
 
+static bool virtio_net_pre_load_device(void *opaque, Error **errp)
+{
+    ERRP_GUARD();
+    VirtIONet *n = opaque;
+    VirtIODevice *vdev = VIRTIO_DEVICE(n);
+
+    if (n->peers_wait_incoming) {
+        /* MIG_PRI_BACKEND ensures the peers have already been loaded. */
+        n->peers_wait_incoming = false;
+        peer_test_vnet_hdr(n);
+        virtio_net_get_features(vdev, vdev->host_features_ex, errp);
+    }
+
+    return !*errp;
+}
+
 static int virtio_net_post_load_device(void *opaque, int version_id)
 {
     VirtIONet *n = opaque;
     VirtIODevice *vdev = VIRTIO_DEVICE(n);
     int i, link_down;
     bool has_tunnel_hdr = virtio_has_tunnel_hdr(vdev->guest_features_ex);
-    Error *local_err = NULL;
 
     trace_virtio_net_post_load_device();
     virtio_net_set_mrg_rx_bufs(n, n->mergeable_rx_bufs,
@@ -3314,20 +3329,6 @@ static int virtio_net_post_load_device(void *opaque, int 
version_id)
     }
 
     virtio_net_commit_rss_config(n);
-
-    /*
-     * If live-migration is enabled for some backend, than backend
-     * has already been migrated at higher priority (MIG_PRI_BACKEND)
-     * and virtio_net_vnet_post_load() has already called
-     * peer_test_vnet_hdr().  Recompute host_features so that virtio-net
-     * reflects the capabilities of the restored backend.
-     */
-    virtio_net_get_features(vdev, &vdev->host_features, &local_err);
-    if (local_err) {
-        error_report_err(local_err);
-        return -EINVAL;
-    }
-
     return 0;
 }
 
@@ -3478,14 +3479,6 @@ static int virtio_net_vnet_post_load(void *opaque, int 
version_id)
 {
     struct VirtIONetMigTmp *tmp = opaque;
 
-    /*
-     * If live-migration is enabled for some backend, than backend
-     * has already been migrated at higher priority (MIG_PRI_BACKEND),
-     * so n->has_vnet_hdr can be refreshed from the live backend right
-     * here.
-     */
-    peer_test_vnet_hdr(tmp->parent);
-
     if (tmp->has_vnet_hdr && !peer_has_vnet_hdr(tmp->parent)) {
         error_report("virtio-net: saved image requires vnet_hdr=on");
         return -EINVAL;
@@ -3674,6 +3667,7 @@ static const VMStateDescription vmstate_virtio_net_device 
= {
     .name = "virtio-net-device",
     .version_id = VIRTIO_NET_VM_VERSION,
     .minimum_version_id = VIRTIO_NET_VM_VERSION,
+    .pre_load_errp = virtio_net_pre_load_device,
     .post_load = virtio_net_post_load_device,
     .fields = (const VMStateField[]) {
         VMSTATE_UINT8_ARRAY(mac, VirtIONet, ETH_ALEN),
-- 
2.43.0


Reply via email to