Commit 893c1f7e authored by Dariusz Stojaczyk's avatar Dariusz Stojaczyk Committed by Jim Harris
Browse files

rte_virtio: create call/kick fds on queue setup



This makes us open only as many descriptors as we need.

Change-Id: I2dbce218efdd37f015a0d4b250be9539373c6028
Signed-off-by: default avatarDariusz Stojaczyk <dariuszx.stojaczyk@intel.com>
Reviewed-on: https://review.gerrithub.io/379336


Tested-by: default avatarSPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarDaniel Verkamp <daniel.verkamp@intel.com>
Reviewed-by: default avatarChangpeng Liu <changpeng.liu@intel.com>
Reviewed-by: default avatarPawel Wodkowski <pawelx.wodkowski@intel.com>
parent 3adb4053
Loading
Loading
Loading
Loading
+30 −0
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/eventfd.h>

#include <linux/virtio_scsi.h>

@@ -157,6 +158,33 @@ virtio_user_setup_queue(struct virtio_dev *vdev, struct virtqueue *vq)
	struct virtio_user_dev *dev = virtio_dev_get_user_dev(vdev);
	uint16_t queue_idx = vq->vq_queue_index;
	uint64_t desc_addr, avail_addr, used_addr;
	int callfd;
	int kickfd;

	if (dev->callfds[queue_idx] != -1 || dev->kickfds[queue_idx] != -1) {
		PMD_DRV_LOG(ERR, "queue %u already exists", queue_sel);
		return -1;
	}

	/* May use invalid flag, but some backend uses kickfd and
	 * callfd as criteria to judge if dev is alive. so finally we
	 * use real event_fd.
	 */
	callfd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
	if (callfd < 0) {
		PMD_DRV_LOG(ERR, "callfd error, %s", strerror(errno));
		return -1;
	}

	kickfd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
	if (kickfd < 0) {
		PMD_DRV_LOG(ERR, "kickfd error, %s", strerror(errno));
		close(callfd);
		return -1;
	}

	dev->callfds[queue_idx] = callfd;
	dev->kickfds[queue_idx] = kickfd;

	desc_addr = (uintptr_t)vq->vq_ring_virt_mem;
	avail_addr = desc_addr + vq->vq_nentries * sizeof(struct vring_desc);
@@ -188,6 +216,8 @@ virtio_user_del_queue(struct virtio_dev *vdev, struct virtqueue *vq)

	close(dev->callfds[vq->vq_queue_index]);
	close(dev->kickfds[vq->vq_queue_index]);
	dev->callfds[vq->vq_queue_index] = -1;
	dev->kickfds[vq->vq_queue_index] = -1;
}

static void
+7 −52
Original line number Diff line number Diff line
@@ -166,65 +166,25 @@ is_vhost_user_by_type(const char *path)
	return S_ISSOCK(sb.st_mode);
}

static int
virtio_user_dev_init_notify(struct virtio_user_dev *dev)
{
	uint32_t i, j;
	int callfd;
	int kickfd;

	for (i = 0; i < VIRTIO_MAX_VIRTQUEUES; ++i) {
		if (i >= dev->vdev.max_queues) {
			dev->kickfds[i] = -1;
			dev->callfds[i] = -1;
			continue;
		}

		/* May use invalid flag, but some backend uses kickfd and
		 * callfd as criteria to judge if dev is alive. so finally we
		 * use real event_fd.
		 */
		callfd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
		if (callfd < 0) {
			PMD_DRV_LOG(ERR, "callfd error, %s", strerror(errno));
			break;
		}
		kickfd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
		if (kickfd < 0) {
			PMD_DRV_LOG(ERR, "kickfd error, %s", strerror(errno));
			break;
		}
		dev->callfds[i] = callfd;
		dev->kickfds[i] = kickfd;
	}

	if (i < VIRTIO_MAX_VIRTQUEUES) {
		for (j = 0; j <= i; ++j) {
			close(dev->callfds[j]);
			close(dev->kickfds[j]);
		}

		return -1;
	}

	return 0;
}

static int
virtio_user_dev_setup(struct virtio_user_dev *dev)
{
	uint16_t i;

	dev->vhostfd = -1;
	dev->vhostfds = NULL;
	dev->tapfds = NULL;

	for (i = 0; i < VIRTIO_MAX_VIRTQUEUES; ++i) {
		dev->callfds[i] = -1;
		dev->kickfds[i] = -1;
	}

	dev->ops = &ops_user;

	if (dev->ops->setup(dev) < 0)
		return -1;

	if (virtio_user_dev_init_notify(dev) < 0)
		return -1;

	return 0;
}

@@ -287,11 +247,6 @@ virtio_user_dev_uninit(struct virtio_user_dev *dev)

	virtio_user_stop_device(dev);

	for (i = 0; i < dev->vdev.max_queues; ++i) {
		close(dev->callfds[i]);
		close(dev->kickfds[i]);
	}

	close(dev->vhostfd);

	if (dev->vhostfds) {