From b8ec917c284572380d4f14477760ee78aa9d1076 Mon Sep 17 00:00:00 2001
From: Marcelo Tosatti <mtosatti@redhat.com>
Date: Mon, 1 Mar 2010 20:52:14 -0300
Subject: [PATCH 11/20] virtio-net: fix network stall under load

RH-Author: Marcelo Tosatti <mtosatti@redhat.com>
Message-id: <c2ccb114ed0e574ef1d58ec3689b784bcd64a0ae.1267476474.git.mtosatti@redhat.com>
Patchwork-id: 7359
O-Subject: [PATCH 12/21] virtio-net: fix network stall under load
Bugzilla: 569613
RH-Acked-by: Gleb Natapov <gleb@redhat.com>
RH-Acked-by: Rik van Riel <riel@redhat.com>
RH-Acked-by: Juan Quintela <quintela@redhat.com>

From: Tom Lendacky <tahm@linux.vnet.ibm.com>

Fix a race condition where qemu finds that there are not enough virtio
ring buffers available and the guest make more buffers available before
qemu can enable notifications.

Signed-off-by: Tom Lendacky <toml@us.ibm.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 06b1297017415ae6a07a0e97ad7d8e90b2d95823)
(cherry picked from commit 7ebc79037c5f426bfb08cc506670bf7dd3912430)
---
 hw/virtio-net.c |   10 +++++++++-
 1 files changed, 9 insertions(+), 1 deletions(-)

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 hw/virtio-net.c |   10 +++++++++-
 1 files changed, 9 insertions(+), 1 deletions(-)

diff --git a/hw/virtio-net.c b/hw/virtio-net.c
index 0d68fa3..d57c616 100644
--- a/hw/virtio-net.c
+++ b/hw/virtio-net.c
@@ -393,7 +393,15 @@ static int virtio_net_has_buffers(VirtIONet *n, int bufsize)
         (n->mergeable_rx_bufs &&
          !virtqueue_avail_bytes(n->rx_vq, bufsize, 0))) {
         virtio_queue_set_notification(n->rx_vq, 1);
-        return 0;
+
+        /* To avoid a race condition where the guest has made some buffers
+         * available after the above check but before notification was
+         * enabled, check for available buffers again.
+         */
+        if (virtio_queue_empty(n->rx_vq) ||
+            (n->mergeable_rx_bufs &&
+             !virtqueue_avail_bytes(n->rx_vq, bufsize, 0)))
+            return 0;
     }
 
     virtio_queue_set_notification(n->rx_vq, 0);
-- 
1.7.0.3

