From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by dpdk.org (Postfix) with ESMTP id E403F10DE9 for ; Fri, 23 Dec 2016 08:13:58 +0100 (CET) Received: from orsmga005.jf.intel.com ([10.7.209.41]) by orsmga102.jf.intel.com with ESMTP; 22 Dec 2016 23:13:58 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.33,392,1477983600"; d="scan'208";a="45730696" Received: from dpdk06.sh.intel.com ([10.239.129.195]) by orsmga005.jf.intel.com with ESMTP; 22 Dec 2016 23:13:56 -0800 From: Jianfeng Tan To: dev@dpdk.org Cc: yuanhan.liu@linux.intel.com, ferruh.yigit@intel.com, cunming.liang@intel.com, Jianfeng Tan Date: Fri, 23 Dec 2016 07:14:26 +0000 Message-Id: <1482477266-39199-8-git-send-email-jianfeng.tan@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1482477266-39199-1-git-send-email-jianfeng.tan@intel.com> References: <1480689075-66977-1-git-send-email-jianfeng.tan@intel.com> <1482477266-39199-1-git-send-email-jianfeng.tan@intel.com> Subject: [dpdk-dev] [PATCH v2 7/7] net/virtio_user: enable multiqueue with vhost kernel X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 23 Dec 2016 07:13:59 -0000 With vhost kernel, to enable multiqueue, we need backend device in kernel support multiqueue feature. Specifically, with tap as the backend, as linux/Documentation/networking/tuntap.txt shows, we check if tap supports IFF_MULTI_QUEUE feature. And for vhost kernel, each queue pair has a vhost fd, and with a tap fd binding this vhost fd. All tap fds are set with the same tap interface name. Signed-off-by: Jianfeng Tan --- drivers/net/virtio/virtio_user/vhost_kernel.c | 67 +++++++++++++++++++++--- drivers/net/virtio/virtio_user/virtio_user_dev.c | 1 + 2 files changed, 62 insertions(+), 6 deletions(-) diff --git a/drivers/net/virtio/virtio_user/vhost_kernel.c b/drivers/net/virtio/virtio_user/vhost_kernel.c index fb3c454..67b382e 100644 --- a/drivers/net/virtio/virtio_user/vhost_kernel.c +++ b/drivers/net/virtio/virtio_user/vhost_kernel.c @@ -203,6 +203,29 @@ static const uint64_t host_offloads_mask = (1ULL << VIRTIO_NET_F_HOST_TSO6); static int +tap_supporte_mq(void) +{ + int tapfd; + unsigned int tap_features; + + tapfd = open(PATH_NET_TUN, O_RDWR); + if (tapfd < 0) { + PMD_DRV_LOG(ERR, "fail to open %s: %s", + PATH_NET_TUN, strerror(errno)); + return -1; + } + + if (ioctl(tapfd, TUNGETFEATURES, &tap_features) == -1) { + PMD_DRV_LOG(ERR, "TUNGETFEATURES failed: %s", strerror(errno)); + close(tapfd); + return -1; + } + + close(tapfd); + return tap_features & IFF_MULTI_QUEUE; +} + +static int vhost_kernel_ioctl(struct virtio_user_dev *dev, enum vhost_user_request req, void *arg) @@ -210,6 +233,8 @@ vhost_kernel_ioctl(struct virtio_user_dev *dev, int i, ret = -1; uint64_t req_kernel; struct vhost_memory_kernel *vm = NULL; + int vhostfd; + unsigned int queue_sel; req_kernel = vhost_req_user_to_kernel[req]; @@ -229,13 +254,33 @@ vhost_kernel_ioctl(struct virtio_user_dev *dev, *(uint64_t *)arg &= ~host_offloads_mask; } - for (i = 0; i < VHOST_KERNEL_MAX_QUEUES; ++i) { - if (dev->vhostfds[i] < 0) - continue; + switch (req_kernel) { + case VHOST_SET_VRING_NUM: + case VHOST_SET_VRING_ADDR: + case VHOST_SET_VRING_BASE: + case VHOST_GET_VRING_BASE: + case VHOST_SET_VRING_KICK: + case VHOST_SET_VRING_CALL: + queue_sel = *(unsigned int *)arg; + vhostfd = dev->vhostfds[queue_sel / 2]; + *(unsigned int *)arg = queue_sel % 2; + PMD_DRV_LOG(DEBUG, "vhostfd=%d, index=%u", + vhostfd, *(unsigned int *)arg); + break; + default: + vhostfd = -1; + } + if (vhostfd == -1) { + for (i = 0; i < VHOST_KERNEL_MAX_QUEUES; ++i) { + if (dev->vhostfds[i] < 0) + continue; - ret = ioctl(dev->vhostfds[i], req_kernel, arg); - if (ret < 0) - break; + ret = ioctl(dev->vhostfds[i], req_kernel, arg); + if (ret < 0) + break; + } + } else { + ret = ioctl(vhostfd, req_kernel, arg); } if (!ret && req_kernel == VHOST_GET_FEATURES) { @@ -245,6 +290,12 @@ vhost_kernel_ioctl(struct virtio_user_dev *dev, */ *((uint64_t *)arg) |= guest_offloads_mask; *((uint64_t *)arg) |= host_offloads_mask; + + /* vhost_kernel will not declare this feature, but it does + * support multi-queue. + */ + if (tap_supporte_mq()) + *(uint64_t *)arg |= (1ull << VIRTIO_NET_F_MQ); } if (vm) @@ -320,6 +371,7 @@ vhost_kernel_enable_queue_pair(struct virtio_user_dev *dev, TUN_F_TSO6 | TUN_F_TSO_ECN | TUN_F_UFO; + int req_mq = (dev->max_queue_pairs > 1); vhostfd = dev->vhostfds[pair_idx]; @@ -373,6 +425,9 @@ vhost_kernel_enable_queue_pair(struct virtio_user_dev *dev, goto error; } + if (req_mq) + ifr.ifr_flags |= IFF_MULTI_QUEUE; + if (dev->ifname) strncpy(ifr.ifr_name, dev->ifname, IFNAMSIZ); else diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c b/drivers/net/virtio/virtio_user/virtio_user_dev.c index c718b85..241f5bb 100644 --- a/drivers/net/virtio/virtio_user/virtio_user_dev.c +++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c @@ -93,6 +93,7 @@ virtio_user_kick_queue(struct virtio_user_dev *dev, uint32_t queue_sel) state.num = vring->num; dev->ops->send_request(dev, VHOST_USER_SET_VRING_NUM, &state); + state.index = queue_sel; state.num = 0; /* no reservation */ dev->ops->send_request(dev, VHOST_USER_SET_VRING_BASE, &state); -- 2.7.4