summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael S. Tsirkin <mst@redhat.com>2014-09-04 11:39:17 +0300
committerMichael Roth <mdroth@linux.vnet.ibm.com>2014-09-10 09:30:58 -0500
commitcf29a8839115c99eb4050cea31d71ee1cb96ad2a (patch)
tree77eed3f32d84f7675c76a86ccafd03829ad2cdc1
parent08743db463e52a2d1d789200dba5bfaa3221adc2 (diff)
downloadqemu-cf29a8839115c99eb4050cea31d71ee1cb96ad2a.tar.gz
virtio-net: purge outstanding packets when starting vhost
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> (cherry picked from commit 086abc1ccd0fa5103345adda819e6c6436949579) Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
-rw-r--r--hw/net/virtio-net.c15
1 files changed, 14 insertions, 1 deletions
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 365e266b74..826a2a5fca 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -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) {