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: Dariusz Stojaczyk <dariuszx.stojaczyk@intel.com>
Reviewed-on: https://review.gerrithub.io/379336
Tested-by: SPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com>
Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Pawel Wodkowski <pawelx.wodkowski@intel.com>
This commit is contained in:
Dariusz Stojaczyk 2017-09-20 17:50:08 +02:00 committed by Jim Harris
parent 3adb4053af
commit 893c1f7e25
2 changed files with 37 additions and 52 deletions

View File

@ -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

View File

@ -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) {