hw/virtio/vring/event_idx: fix the vring_avail_event error
authorBin Wu <wu.wubin@huawei.com>
Fri, 31 Oct 2014 00:40:16 +0000 (00:40 +0000)
committerMichael S. Tsirkin <mst@redhat.com>
Sun, 2 Nov 2014 11:44:12 +0000 (13:44 +0200)
The event idx in virtio is an effective way to reduce the number of
interrupts and exits of the guest. When the guest puts an request
into the virtio ring, it doesn't exit immediately to inform the
backend. Instead, the guest checks the "avail" event idx to determine
the notification.

In virtqueue_pop, when a request is poped, the current avail event
idx should be set to the number of vq->last_avail_idx.

Signed-off-by: Bin Wu <wu.wubin@huawei.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
hw/virtio/dataplane/vring.c
hw/virtio/virtio.c

index 372706a234e53462ae3aab85ac0f56b452df0567..61f6d83686edd013ab2e4fd9fdcbf7cb6c97358e 100644 (file)
@@ -352,10 +352,6 @@ int vring_pop(VirtIODevice *vdev, Vring *vring,
         goto out;
     }
 
-    if (vdev->guest_features & (1 << VIRTIO_RING_F_EVENT_IDX)) {
-        vring_avail_event(&vring->vr) = vring->vr.avail->idx;
-    }
-
     i = head;
     do {
         if (unlikely(i >= num)) {
@@ -392,6 +388,10 @@ int vring_pop(VirtIODevice *vdev, Vring *vring,
 
     /* On success, increment avail index. */
     vring->last_avail_idx++;
+    if (vdev->guest_features & (1 << VIRTIO_RING_F_EVENT_IDX)) {
+        vring_avail_event(&vring->vr) = vring->last_avail_idx;
+    }
+
     return head;
 
 out:
index 2c236bf271bcf1790960fa982e40c5c62d8d10bd..013979a6b82fd0501f274bcc9fd6be86a5b96b05 100644 (file)
@@ -469,7 +469,7 @@ int virtqueue_pop(VirtQueue *vq, VirtQueueElement *elem)
 
     i = head = virtqueue_get_head(vq, vq->last_avail_idx++);
     if (vdev->guest_features & (1 << VIRTIO_RING_F_EVENT_IDX)) {
-        vring_avail_event(vq, vring_avail_idx(vq));
+        vring_avail_event(vq, vq->last_avail_idx);
     }
 
     if (vring_desc_flags(vdev, desc_pa, i) & VRING_DESC_F_INDIRECT) {