@@ -232,6 +232,8 @@ int virtio_queue_ready(VirtQueue *vq);
int virtio_queue_empty(VirtQueue *vq);
+bool virtio_queue_full(const VirtQueue *vq);
+
/* Host binding interface. */
uint32_t virtio_config_readb(VirtIODevice *vdev, uint32_t addr);
@@ -670,6 +670,20 @@ int virtio_queue_empty(VirtQueue *vq)
}
}
+/*
+ * virtio_queue_full:
+ * @vq The #VirtQueue
+ *
+ * Check if all descriptors of the queue are available. In other words, is the
+ * complete opposite of virtio_queue_empty: If the queue is full, the driver
+ * cannot transfer more buffers to the device until the latter make some as
+ * used.
+ */
+bool virtio_queue_full(const VirtQueue *vq)
+{
+ return vq->inuse >= vq->vring.num;
+}
+
static void virtqueue_unmap_sg(VirtQueue *vq, const VirtQueueElement *elem,
unsigned int len)
{
@@ -1439,7 +1453,7 @@ static void *virtqueue_split_pop(VirtQueue *vq, size_t sz)
max = vq->vring.num;
- if (vq->inuse >= vq->vring.num) {
+ if (unlikely(virtio_queue_full(vq))) {
virtio_error(vdev, "Virtqueue size exceeded");
goto done;
}
@@ -1574,7 +1588,7 @@ static void *virtqueue_packed_pop(VirtQueue *vq, size_t sz)
max = vq->vring.num;
- if (vq->inuse >= vq->vring.num) {
+ if (unlikely(virtio_queue_full(vq))) {
virtio_error(vdev, "Virtqueue size exceeded");
goto done;
}
Check if all descriptors of the queue are available. In other words, is the complete opposite of virtio_queue_empty: If the queue is full, the driver cannot transfer more buffers to the device until the latter make some as used. In Shadow vq this situation happens with the correct guest network driver, since the rx queue is filled for the device to write. Since Shadow Virtqueue forward the available ones blindly, it will call the driver forever for them, reaching the point where no more descriptors are available. While a straightforward solution is to keep the count of them in SVQ, this specific issue is the only need for that counter. Exposing this check helps to keep the SVQ simpler storing as little status as possible. Signed-off-by: Eugenio PĂ©rez <eperezma@redhat.com> --- include/hw/virtio/virtio.h | 2 ++ hw/virtio/virtio.c | 18 ++++++++++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-)