]> www.infradead.org Git - users/dwmw2/qemu.git/commitdiff
virtio-net: purge outstanding packets when starting vhost
authorMichael S. Tsirkin <mst@redhat.com>
Thu, 4 Sep 2014 08:39:17 +0000 (11:39 +0300)
committerStefan Hajnoczi <stefanha@redhat.com>
Thu, 4 Sep 2014 16:19:09 +0000 (17:19 +0100)
whenever we start vhost, virtio could have outstanding packets
queued, when they complete later we'll modify the ring
while vhost is processing it.

To prevent this, purge outstanding packets on vhost start.

Cc: qemu-stable@nongnu.org
Cc: Jason Wang <jasowang@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
hw/net/virtio-net.c

index 365e266b7486d6e4d765a6b665d0596cb625ed41..826a2a5fca919a3fc959563f9611c9aa321b0a30 100644 (file)
@@ -125,10 +125,23 @@ static void virtio_net_vhost_status(VirtIONet *n, uint8_t status)
         return;
     }
     if (!n->vhost_started) {
-        int r;
+        int r, i;
+
         if (!vhost_net_query(get_vhost_net(nc->peer), vdev)) {
             return;
         }
+
+        /* Any packets outstanding? Purge them to avoid touching rings
+         * when vhost is running.
+         */
+        for (i = 0;  i < queues; i++) {
+            NetClientState *qnc = qemu_get_subqueue(n->nic, i);
+
+            /* Purge both directions: TX and RX. */
+            qemu_net_queue_purge(qnc->peer->incoming_queue, qnc);
+            qemu_net_queue_purge(qnc->incoming_queue, qnc->peer);
+        }
+
         n->vhost_started = 1;
         r = vhost_net_start(vdev, n->nic->ncs, queues);
         if (r < 0) {