To restore the device at the destination of a live migration we send the commands through control virtqueue. For a device to read CVQ it must have received the DRIVER_OK status bit.
However this opens a window where the device could start receiving packets in rx queue 0 before it receives the RSS configuration. To avoid that, we will not send vring_enable until all configuration is used by the device. As a first step, run vhost_set_vring_ready for all vhost_net backend after all of them are started (with DRIVER_OK). This code should not affect vdpa. Signed-off-by: Eugenio Pérez <epere...@redhat.com> --- hw/net/vhost_net.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c index c4eecc6f36..3900599465 100644 --- a/hw/net/vhost_net.c +++ b/hw/net/vhost_net.c @@ -399,6 +399,18 @@ int vhost_net_start(VirtIODevice *dev, NetClientState *ncs, } else { peer = qemu_get_peer(ncs, n->max_queue_pairs); } + r = vhost_net_start_one(get_vhost_net(peer), dev); + if (r < 0) { + goto err_start; + } + } + + for (int j = 0; j < nvhosts; j++) { + if (j < data_queue_pairs) { + peer = qemu_get_peer(ncs, j); + } else { + peer = qemu_get_peer(ncs, n->max_queue_pairs); + } if (peer->vring_enable) { /* restore vring enable state */ @@ -408,11 +420,6 @@ int vhost_net_start(VirtIODevice *dev, NetClientState *ncs, goto err_start; } } - - r = vhost_net_start_one(get_vhost_net(peer), dev); - if (r < 0) { - goto err_start; - } } return 0; -- 2.31.1