From cf29a8839115c99eb4050cea31d71ee1cb96ad2a Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Thu, 4 Sep 2014 11:39:17 +0300 Subject: [PATCH] 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 Signed-off-by: Michael S. Tsirkin Signed-off-by: Stefan Hajnoczi (cherry picked from commit 086abc1ccd0fa5103345adda819e6c6436949579) Signed-off-by: Michael Roth --- hw/net/virtio-net.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index 365e266b748..826a2a5fca9 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) { -- 2.39.5