The patch fixes reset_owner message handling not to clear callfd, because callfd will be valid while connection is establihed.
Signed-off-by: Tetsuya Mukawa <mukawa at igel.co.jp> --- lib/librte_vhost/virtio-net.c | 44 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/lib/librte_vhost/virtio-net.c b/lib/librte_vhost/virtio-net.c index 886c104..3907fb5 100644 --- a/lib/librte_vhost/virtio-net.c +++ b/lib/librte_vhost/virtio-net.c @@ -223,9 +223,9 @@ add_config_ll_entry(struct virtio_net_config_ll *new_ll_dev) } static void -cleanup_vq(struct vhost_virtqueue *vq) +cleanup_vq(struct vhost_virtqueue *vq, int destroy) { - if (vq->callfd >= 0) + if ((vq->callfd >= 0) && (destroy != 0)) close(vq->callfd); if (vq->kickfd >= 0) close(vq->kickfd); @@ -249,8 +249,8 @@ cleanup_device(struct virtio_net *dev) } for (i = 0; i < dev->virt_qp_nb; i++) { - cleanup_vq(dev->virtqueue[i * VIRTIO_QNUM + VIRTIO_RXQ]); - cleanup_vq(dev->virtqueue[i * VIRTIO_QNUM + VIRTIO_TXQ]); + cleanup_vq(dev->virtqueue[i * VIRTIO_QNUM + VIRTIO_RXQ], 1); + cleanup_vq(dev->virtqueue[i * VIRTIO_QNUM + VIRTIO_TXQ], 1); } } @@ -322,6 +322,25 @@ init_vring_queue_pair(struct virtio_net *dev, uint32_t qp_idx) init_vring_queue(dev->virtqueue[base_idx + VIRTIO_TXQ], qp_idx); } +static void +reset_vring_queue(struct vhost_virtqueue *vq, int qp_idx) +{ + int callfd; + + callfd = vq->callfd; + init_vring_queue(vq, qp_idx); + vq->callfd = callfd; +} + +static void +reset_vring_queue_pair(struct virtio_net *dev, uint32_t qp_idx) +{ + uint32_t base_idx = qp_idx * VIRTIO_QNUM; + + reset_vring_queue(dev->virtqueue[base_idx + VIRTIO_RXQ], qp_idx); + reset_vring_queue(dev->virtqueue[base_idx + VIRTIO_TXQ], qp_idx); +} + static int alloc_vring_queue_pair(struct virtio_net *dev, uint32_t qp_idx) { @@ -362,7 +381,7 @@ reset_device(struct virtio_net *dev) dev->flags = 0; for (i = 0; i < dev->virt_qp_nb; i++) - init_vring_queue_pair(dev, i); + reset_vring_queue_pair(dev, i); } /* @@ -467,6 +486,7 @@ static int reset_owner(struct vhost_device_ctx ctx) { struct virtio_net *dev; + uint32_t i; dev = get_device(ctx); if (dev == NULL) @@ -475,7 +495,19 @@ reset_owner(struct vhost_device_ctx ctx) if (dev->flags & VIRTIO_DEV_RUNNING) notify_destroy_device(dev); - cleanup_device(dev); + /* Unmap QEMU memory file if mapped. */ + if (dev->mem) { + munmap((void *)(uintptr_t)dev->mem->mapped_address, + (size_t)dev->mem->mapped_size); + free(dev->mem); + dev->mem = NULL; + } + + for (i = 0; i < dev->virt_qp_nb; i++) { + cleanup_vq(dev->virtqueue[i * VIRTIO_QNUM + VIRTIO_RXQ], 0); + cleanup_vq(dev->virtqueue[i * VIRTIO_QNUM + VIRTIO_TXQ], 0); + } + reset_device(dev); return 0; } -- 2.1.4