From 8b94174a4ebc6aab81c4d171343ca989ea05764a Mon Sep 17 00:00:00 2001 From: Dariusz Stojaczyk Date: Wed, 3 Jan 2018 12:16:04 +0100 Subject: [PATCH] virtio: fix full-virtqueue handling Distinguish between "not enough descriptors available" and "iovcnt > queue depth". This patch brings back I/O re-queueing for virtio bdev module. It was temporarily disabled by 451de7e1 [1]. [1] 451de7e1: "virtio: switch to the new virtqueue API" Change-Id: I4c4f6a6d9d91373ee647ea7cafd53ad999aa6aa2 Signed-off-by: Pawel Wodkowski Signed-off-by: Dariusz Stojaczyk Reviewed-on: https://review.gerrithub.io/393447 Tested-by: SPDK Automated Test System Reviewed-by: Ben Walker Reviewed-by: Jim Harris --- include/spdk_internal/virtio.h | 7 ++++--- lib/virtio/virtio.c | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/include/spdk_internal/virtio.h b/include/spdk_internal/virtio.h index 69416d500..67b81eaff 100644 --- a/include/spdk_internal/virtio.h +++ b/include/spdk_internal/virtio.h @@ -209,9 +209,10 @@ uint16_t virtio_recv_pkts(struct virtqueue *vq, void **io, uint32_t *len, uint16 * is sent, processed and a response is received, the same object will be * returned to the user calling the virtio poll API. * \param iovcnt number of required iovectors for the request. This can be - * higher than than the actual number of descriptors to be added. - * \return 0 on success or negative errno otherwise. If not enough iovectors - * are available, -ENOSPC is returned. + * higher than than the actual number of iovectors to be added. + * \return 0 on success or negative errno otherwise. If the `iovcnt` is + * greater than virtqueue depth, -EINVAL is returned. If simply not enough + * iovectors are available, -ENOMEM is returned. */ int virtqueue_req_start(struct virtqueue *vq, void *cookie, int iovcnt); diff --git a/lib/virtio/virtio.c b/lib/virtio/virtio.c index 3e22d9efc..a4f0fc6d1 100644 --- a/lib/virtio/virtio.c +++ b/lib/virtio/virtio.c @@ -448,7 +448,7 @@ virtqueue_req_start(struct virtqueue *vq, void *cookie, int iovcnt) assert(virtio_dev_get_status(vq->vdev) & VIRTIO_CONFIG_S_DRIVER_OK); if (iovcnt > vq->vq_free_cnt) { - return -ENOSPC; + return iovcnt > vq->vq_nentries ? -EINVAL : -ENOMEM; } if (vq->req_start != VQ_RING_DESC_CHAIN_END) {