From 8d53e9f3c6001dcb2865f6e894da5b54e1418f88 Mon Sep 17 00:00:00 2001 From: Christian Ehrhardt Date: Thu, 4 Jul 2019 10:40:06 +0200 Subject: New upstream version 18.11.2 Change-Id: I23eb4f9179abf1f9c659891f8fddb27ee68ad26b Signed-off-by: Christian Ehrhardt --- lib/librte_vhost/vhost_user.c | 54 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 44 insertions(+), 10 deletions(-) (limited to 'lib/librte_vhost/vhost_user.c') diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c index 19e04c95..5552f8bb 100644 --- a/lib/librte_vhost/vhost_user.c +++ b/lib/librte_vhost/vhost_user.c @@ -93,15 +93,47 @@ get_blk_size(int fd) return ret == -1 ? (uint64_t)-1 : (uint64_t)stat.st_blksize; } +/* + * Reclaim all the outstanding zmbufs for a virtqueue. + */ +static void +drain_zmbuf_list(struct vhost_virtqueue *vq) +{ + struct zcopy_mbuf *zmbuf, *next; + + for (zmbuf = TAILQ_FIRST(&vq->zmbuf_list); + zmbuf != NULL; zmbuf = next) { + next = TAILQ_NEXT(zmbuf, next); + + while (!mbuf_is_consumed(zmbuf->mbuf)) + usleep(1000); + + TAILQ_REMOVE(&vq->zmbuf_list, zmbuf, next); + restore_mbuf(zmbuf->mbuf); + rte_pktmbuf_free(zmbuf->mbuf); + put_zmbuf(zmbuf); + vq->nr_zmbuf -= 1; + } +} + static void free_mem_region(struct virtio_net *dev) { uint32_t i; struct rte_vhost_mem_region *reg; + struct vhost_virtqueue *vq; if (!dev || !dev->mem) return; + if (dev->dequeue_zero_copy) { + for (i = 0; i < dev->nr_vring; i++) { + vq = dev->virtqueue[i]; + if (vq) + drain_zmbuf_list(vq); + } + } + for (i = 0; i < dev->mem->nregions; i++) { reg = &dev->mem->regions[i]; if (reg->host_user_addr) { @@ -1199,8 +1231,12 @@ vhost_user_set_vring_kick(struct virtio_net **pdev, struct VhostUserMsg *msg, * the ring starts already enabled. Otherwise, it is enabled via * the SET_VRING_ENABLE message. */ - if (!(dev->features & (1ULL << VHOST_USER_F_PROTOCOL_FEATURES))) + if (!(dev->features & (1ULL << VHOST_USER_F_PROTOCOL_FEATURES))) { vq->enabled = 1; + if (dev->notify_ops->vring_state_changed) + dev->notify_ops->vring_state_changed( + dev->vid, file.index, 1); + } if (vq->kickfd >= 0) close(vq->kickfd); @@ -1212,15 +1248,7 @@ vhost_user_set_vring_kick(struct virtio_net **pdev, struct VhostUserMsg *msg, static void free_zmbufs(struct vhost_virtqueue *vq) { - struct zcopy_mbuf *zmbuf, *next; - - for (zmbuf = TAILQ_FIRST(&vq->zmbuf_list); - zmbuf != NULL; zmbuf = next) { - next = TAILQ_NEXT(zmbuf, next); - - rte_pktmbuf_free(zmbuf->mbuf); - TAILQ_REMOVE(&vq->zmbuf_list, zmbuf, next); - } + drain_zmbuf_list(vq); rte_free(vq->zmbufs); } @@ -1274,6 +1302,8 @@ vhost_user_get_vring_base(struct virtio_net **pdev, vq->callfd = VIRTIO_UNINITIALIZED_EVENTFD; + vq->signalled_used_valid = false; + if (dev->dequeue_zero_copy) free_zmbufs(vq); if (vq_is_packed(dev)) { @@ -1321,6 +1351,10 @@ vhost_user_set_vring_enable(struct virtio_net **pdev, dev->notify_ops->vring_state_changed(dev->vid, index, enable); + /* On disable, rings have to be stopped being processed. */ + if (!enable && dev->dequeue_zero_copy) + drain_zmbuf_list(dev->virtqueue[index]); + dev->virtqueue[index]->enabled = enable; return VH_RESULT_OK; -- cgit 1.2.3-korg