From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46266) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XPZJ2-00048V-BD for qemu-devel@nongnu.org; Thu, 04 Sep 2014 11:50:45 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1XPZIx-0006hO-3U for qemu-devel@nongnu.org; Thu, 04 Sep 2014 11:50:40 -0400 From: Stefan Hajnoczi Date: Thu, 4 Sep 2014 16:50:11 +0100 Message-Id: <1409845811-27943-8-git-send-email-stefanha@redhat.com> In-Reply-To: <1409845811-27943-1-git-send-email-stefanha@redhat.com> References: <1409845811-27943-1-git-send-email-stefanha@redhat.com> Subject: [Qemu-devel] [PULL 7/7] virtio-net: purge outstanding packets when starting vhost List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Peter Maydell , Jason Wang , qemu-stable@nongnu.org, Stefan Hajnoczi , "Michael S. Tsirkin" From: "Michael S. Tsirkin" 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 --- 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 365e266..826a2a5 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) { -- 1.9.3