From e8bcf842001739765b8dcc1996d86a0ffd2054d5 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Tue, 2 Sep 2014 17:26:12 +0300 Subject: virtio-net: don't run bh on vm stopped commit 783e7706937fe15523b609b545587a028a2bdd03 virtio-net: stop/start bh when appropriate is incomplete: BH might execute within the same main loop iteration but after vmstop, so in theory, we might trigger an assertion. I was unable to reproduce this in practice, but it seems clear enough that the potential is there, so worth fixing. Cc: qemu-stable@nongnu.org Reported-by: Stefan Hajnoczi Signed-off-by: Michael S. Tsirkin Signed-off-by: Stefan Hajnoczi --- hw/net/virtio-net.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'hw/net/virtio-net.c') diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index 268eff9..365e266 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -1224,7 +1224,12 @@ static void virtio_net_tx_timer(void *opaque) VirtIONetQueue *q = opaque; VirtIONet *n = q->n; VirtIODevice *vdev = VIRTIO_DEVICE(n); - assert(vdev->vm_running); + /* This happens when device was stopped but BH wasn't. */ + if (!vdev->vm_running) { + /* Make sure tx waiting is set, so we'll run when restarted. */ + assert(q->tx_waiting); + return; + } q->tx_waiting = 0; @@ -1244,7 +1249,12 @@ static void virtio_net_tx_bh(void *opaque) VirtIODevice *vdev = VIRTIO_DEVICE(n); int32_t ret; - assert(vdev->vm_running); + /* This happens when device was stopped but BH wasn't. */ + if (!vdev->vm_running) { + /* Make sure tx waiting is set, so we'll run when restarted. */ + assert(q->tx_waiting); + return; + } q->tx_waiting = 0; -- cgit v1.1 From 086abc1ccd0fa5103345adda819e6c6436949579 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Thu, 4 Sep 2014 11:39:17 +0300 Subject: 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 --- hw/net/virtio-net.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'hw/net/virtio-net.c') 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) { -- cgit v1.1