diff mbox

[06/19] virtio: update last_avail_idx when inuse is decreased.

Message ID AANLkTi=7bS=W+FZihBya-pRXR2asQ6BgSTBPcPewgHBF@mail.gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Yoshiaki Tamura Dec. 24, 2010, 11:22 a.m. UTC
None
diff mbox

Patch

diff --git a/hw/virtio.c b/hw/virtio.c
index 07dbf86..b1586da 100644
--- a/hw/virtio.c
+++ b/hw/virtio.c
@@ -198,7 +198,7 @@  int virtio_queue_ready(VirtQueue *vq)

 int virtio_queue_empty(VirtQueue *vq)
 {
-    return vring_avail_idx(vq) == vq->last_avail_idx;
+    return vring_avail_idx(vq) == vq->last_avail_idx + vq->inuse;
 }

 void virtqueue_fill(VirtQueue *vq, const VirtQueueElement *elem,
@@ -238,6 +238,7 @@  void virtqueue_flush(VirtQueue *vq, unsigned int count)
     wmb();
     trace_virtqueue_flush(vq, count);
     vring_used_idx_increment(vq, count);
+    vq->last_avail_idx += count;
     vq->inuse -= count;
 }

@@ -306,7 +307,7 @@  int virtqueue_avail_bytes(VirtQueue *vq, int in_bytes, int o
     unsigned int idx;
     int total_bufs, in_total, out_total;

-    idx = vq->last_avail_idx;
+    idx = vq->last_avail_idx + vq->inuse;

     total_bufs = in_total = out_total = 0;
     while (virtqueue_num_heads(vq, idx)) {
@@ -386,7 +387,7 @@  int virtqueue_pop(VirtQueue *vq, VirtQueueElement *elem)
     unsigned int i, head, max;
     target_phys_addr_t desc_pa = vq->vring.desc;

-    if (!virtqueue_num_heads(vq, vq->last_avail_idx))
+    if (!virtqueue_num_heads(vq, vq->last_avail_idx + vq->inuse))
         return 0;

     /* When we start there are none of either input nor output. */
@@ -394,7 +395,7 @@  int virtqueue_pop(VirtQueue *vq, VirtQueueElement *elem)

     max = vq->vring.num;

-    i = head = virtqueue_get_head(vq, vq->last_avail_idx++);
+    i = head = virtqueue_get_head(vq, vq->last_avail_idx + vq->inuse);

     if (vring_desc_flags(desc_pa, i) & VRING_DESC_F_INDIRECT) {
         if (vring_desc_len(desc_pa, i) % sizeof(VRingDesc)) {
@@ -626,7 +627,7 @@  void virtio_notify(VirtIODevice *vdev, VirtQueue *vq)
     /* Always notify when queue is empty (when feature acknowledge) */
     if ((vring_avail_flags(vq) & VRING_AVAIL_F_NO_INTERRUPT) &&
         (!(vdev->guest_features & (1 << VIRTIO_F_NOTIFY_ON_EMPTY)) ||
-         (vq->inuse || vring_avail_idx(vq) != vq->last_avail_idx)))
+         (vq->inuse || vring_avail_idx(vq) != vq->last_avail_idx + vq->inuse)))
         return;

     trace_virtio_notify(vdev, vq);