@@ -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);