All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jianfeng Tan <jianfeng.tan@intel.com>
To: dev@dpdk.org
Cc: yuanhan.liu@linux.intel.com, ferruh.yigit@intel.com,
	cunming.liang@intel.com, Jianfeng Tan <jianfeng.tan@intel.com>
Subject: [PATCH v3 5/7] net/virtio_user: add vhost kernel support
Date: Wed,  4 Jan 2017 03:59:24 +0000	[thread overview]
Message-ID: <1483502366-140154-6-git-send-email-jianfeng.tan@intel.com> (raw)
In-Reply-To: <1483502366-140154-1-git-send-email-jianfeng.tan@intel.com>

This patch add support vhost kernel as the backend for virtio_user.
Three main hook functions are added:
  - vhost_kernel_setup() to open char device, each vq pair needs one
    vhostfd;
  - vhost_kernel_ioctl() to communicate control messages with vhost
    kernel module;
  - vhost_kernel_enable_queue_pair() to open tap device and set it
    as the backend of corresonding vhost fd (that is to say, vq pair).

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 doc/guides/rel_notes/release_17_02.rst           |  20 ++
 drivers/net/virtio/Makefile                      |   1 +
 drivers/net/virtio/virtio_user/vhost.h           |   2 +
 drivers/net/virtio/virtio_user/vhost_kernel.c    | 373 +++++++++++++++++++++++
 drivers/net/virtio/virtio_user/virtio_user_dev.c |  21 +-
 drivers/net/virtio/virtio_user/virtio_user_dev.h |   6 +
 6 files changed, 420 insertions(+), 3 deletions(-)
 create mode 100644 drivers/net/virtio/virtio_user/vhost_kernel.c

diff --git a/doc/guides/rel_notes/release_17_02.rst b/doc/guides/rel_notes/release_17_02.rst
index 180af82..7354df5 100644
--- a/doc/guides/rel_notes/release_17_02.rst
+++ b/doc/guides/rel_notes/release_17_02.rst
@@ -52,6 +52,26 @@ New Features
   See the :ref:`Generic flow API <Generic_flow_API>` documentation for more
   information.
 
+* **virtio_user with vhost-kernel as another exceptional path.**
+
+  Previously, we upstreamed a virtual device, virtio_user with vhost-user
+  as the backend, as a way for IPC (Inter-Process Communication) and user
+  space container networking.
+
+  Virtio_user with vhost-kernel as the backend is a solution for exceptional
+  path, such as KNI, which exchanges packets with kernel networking stack.
+  This solution is very promising in:
+
+  * maintenance: vhost and vhost-net (kernel) is upstreamed and extensively
+    used kernel module.
+  * features: vhost-net is born to be a networking solution, which has
+    lots of networking related featuers, like multi queue, tso, multi-seg
+    mbuf, etc.
+  * performance: similar to KNI, this solution would use one or more
+    kthreads to send/receive packets from user space DPDK applications,
+    which has little impact on user space polling thread (except that
+    it might enter into kernel space to wake up those kthreads if
+    necessary).
 
 Resolved Issues
 ---------------
diff --git a/drivers/net/virtio/Makefile b/drivers/net/virtio/Makefile
index 97972a6..faeffb2 100644
--- a/drivers/net/virtio/Makefile
+++ b/drivers/net/virtio/Makefile
@@ -60,6 +60,7 @@ endif
 
 ifeq ($(CONFIG_RTE_VIRTIO_USER),y)
 SRCS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += virtio_user/vhost_user.c
+SRCS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += virtio_user/vhost_kernel.c
 SRCS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += virtio_user/virtio_user_dev.c
 SRCS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += virtio_user_ethdev.c
 endif
diff --git a/drivers/net/virtio/virtio_user/vhost.h b/drivers/net/virtio/virtio_user/vhost.h
index 515e4fc..5c983bd 100644
--- a/drivers/net/virtio/virtio_user/vhost.h
+++ b/drivers/net/virtio/virtio_user/vhost.h
@@ -118,4 +118,6 @@ struct virtio_user_backend_ops {
 };
 
 struct virtio_user_backend_ops ops_user;
+struct virtio_user_backend_ops ops_kernel;
+
 #endif
diff --git a/drivers/net/virtio/virtio_user/vhost_kernel.c b/drivers/net/virtio/virtio_user/vhost_kernel.c
new file mode 100644
index 0000000..1e7cdef
--- /dev/null
+++ b/drivers/net/virtio/virtio_user/vhost_kernel.c
@@ -0,0 +1,373 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+#include <string.h>
+#include <errno.h>
+
+#include <rte_memory.h>
+#include <rte_eal_memconfig.h>
+
+#include "vhost.h"
+#include "virtio_user_dev.h"
+
+struct vhost_memory_kernel {
+	uint32_t nregions;
+	uint32_t padding;
+	struct vhost_memory_region regions[0];
+};
+
+/* vhost kernel ioctls */
+#define VHOST_VIRTIO 0xAF
+#define VHOST_GET_FEATURES _IOR(VHOST_VIRTIO, 0x00, __u64)
+#define VHOST_SET_FEATURES _IOW(VHOST_VIRTIO, 0x00, __u64)
+#define VHOST_SET_OWNER _IO(VHOST_VIRTIO, 0x01)
+#define VHOST_RESET_OWNER _IO(VHOST_VIRTIO, 0x02)
+#define VHOST_SET_MEM_TABLE _IOW(VHOST_VIRTIO, 0x03, struct vhost_memory_kernel)
+#define VHOST_SET_LOG_BASE _IOW(VHOST_VIRTIO, 0x04, __u64)
+#define VHOST_SET_LOG_FD _IOW(VHOST_VIRTIO, 0x07, int)
+#define VHOST_SET_VRING_NUM _IOW(VHOST_VIRTIO, 0x10, struct vhost_vring_state)
+#define VHOST_SET_VRING_ADDR _IOW(VHOST_VIRTIO, 0x11, struct vhost_vring_addr)
+#define VHOST_SET_VRING_BASE _IOW(VHOST_VIRTIO, 0x12, struct vhost_vring_state)
+#define VHOST_GET_VRING_BASE _IOWR(VHOST_VIRTIO, 0x12, struct vhost_vring_state)
+#define VHOST_SET_VRING_KICK _IOW(VHOST_VIRTIO, 0x20, struct vhost_vring_file)
+#define VHOST_SET_VRING_CALL _IOW(VHOST_VIRTIO, 0x21, struct vhost_vring_file)
+#define VHOST_SET_VRING_ERR _IOW(VHOST_VIRTIO, 0x22, struct vhost_vring_file)
+#define VHOST_NET_SET_BACKEND _IOW(VHOST_VIRTIO, 0x30, struct vhost_vring_file)
+
+/* TUN ioctls */
+#define TUNSETIFF     _IOW('T', 202, int)
+#define TUNGETFEATURES _IOR('T', 207, unsigned int)
+#define TUNSETOFFLOAD  _IOW('T', 208, unsigned int)
+#define TUNGETIFF      _IOR('T', 210, unsigned int)
+#define TUNSETSNDBUF   _IOW('T', 212, int)
+#define TUNGETVNETHDRSZ _IOR('T', 215, int)
+#define TUNSETVNETHDRSZ _IOW('T', 216, int)
+#define TUNSETQUEUE  _IOW('T', 217, int)
+#define TUNSETVNETLE _IOW('T', 220, int)
+#define TUNSETVNETBE _IOW('T', 222, int)
+
+/* TUNSETIFF ifr flags */
+#define IFF_TAP          0x0002
+#define IFF_NO_PI        0x1000
+#define IFF_ONE_QUEUE    0x2000
+#define IFF_VNET_HDR     0x4000
+#define IFF_MULTI_QUEUE  0x0100
+#define IFF_ATTACH_QUEUE 0x0200
+#define IFF_DETACH_QUEUE 0x0400
+
+/* Constants */
+#define TUN_DEF_SNDBUF	(1ull << 20)
+#define PATH_NET_TUN	"/dev/net/tun"
+#define VHOST_KERNEL_MAX_REGIONS	64
+
+static uint64_t vhost_req_user_to_kernel[] = {
+	[VHOST_USER_SET_OWNER] = VHOST_SET_OWNER,
+	[VHOST_USER_RESET_OWNER] = VHOST_RESET_OWNER,
+	[VHOST_USER_SET_FEATURES] = VHOST_SET_FEATURES,
+	[VHOST_USER_GET_FEATURES] = VHOST_GET_FEATURES,
+	[VHOST_USER_SET_VRING_CALL] = VHOST_SET_VRING_CALL,
+	[VHOST_USER_SET_VRING_NUM] = VHOST_SET_VRING_NUM,
+	[VHOST_USER_SET_VRING_BASE] = VHOST_SET_VRING_BASE,
+	[VHOST_USER_GET_VRING_BASE] = VHOST_GET_VRING_BASE,
+	[VHOST_USER_SET_VRING_ADDR] = VHOST_SET_VRING_ADDR,
+	[VHOST_USER_SET_VRING_KICK] = VHOST_SET_VRING_KICK,
+	[VHOST_USER_SET_MEM_TABLE] = VHOST_SET_MEM_TABLE,
+};
+
+/* By default, vhost kernel module allows 64 regions, but DPDK allows
+ * 256 segments. As a relief, below function merges those virtually
+ * adjacent memsegs into one region.
+ */
+static struct vhost_memory_kernel *
+prepare_vhost_memory_kernel(void)
+{
+	uint32_t i, j, k = 0;
+	struct rte_memseg *seg;
+	struct vhost_memory_region *mr;
+	struct vhost_memory_kernel *vm;
+
+	vm = malloc(sizeof(struct vhost_memory_kernel) +
+		    VHOST_KERNEL_MAX_REGIONS *
+		    sizeof(struct vhost_memory_region));
+
+	for (i = 0; i < RTE_MAX_MEMSEG; ++i) {
+		seg = &rte_eal_get_configuration()->mem_config->memseg[i];
+		if (!seg->addr)
+			break;
+
+		int new_region = 1;
+
+		for (j = 0; j < k; ++j) {
+			mr = &vm->regions[j];
+
+			if (mr->userspace_addr + mr->memory_size ==
+			    (uint64_t)(uintptr_t)seg->addr) {
+				mr->memory_size += seg->len;
+				new_region = 0;
+				break;
+			}
+
+			if ((uint64_t)(uintptr_t)seg->addr + seg->len ==
+			    mr->userspace_addr) {
+				mr->guest_phys_addr =
+					(uint64_t)(uintptr_t)seg->addr;
+				mr->userspace_addr =
+					(uint64_t)(uintptr_t)seg->addr;
+				mr->memory_size += seg->len;
+				new_region = 0;
+				break;
+			}
+		}
+
+		if (new_region == 0)
+			continue;
+
+		mr = &vm->regions[k++];
+		/* use vaddr here! */
+		mr->guest_phys_addr = (uint64_t)(uintptr_t)seg->addr;
+		mr->userspace_addr = (uint64_t)(uintptr_t)seg->addr;
+		mr->memory_size = seg->len;
+		mr->mmap_offset = 0;
+
+		if (k >= VHOST_KERNEL_MAX_REGIONS) {
+			free(vm);
+			return NULL;
+		}
+	}
+
+	vm->nregions = k;
+	vm->padding = 0;
+	return vm;
+}
+
+static int
+vhost_kernel_ioctl(struct virtio_user_dev *dev,
+		   enum vhost_user_request req,
+		   void *arg)
+{
+	int i, ret = -1;
+	uint64_t req_kernel;
+	struct vhost_memory_kernel *vm = NULL;
+
+	PMD_DRV_LOG(INFO, "%s", vhost_msg_strings[req]);
+
+	req_kernel = vhost_req_user_to_kernel[req];
+
+	if (req_kernel == VHOST_SET_MEM_TABLE) {
+		vm = prepare_vhost_memory_kernel();
+		if (!vm)
+			return -1;
+		arg = (void *)vm;
+	}
+
+	/* Does not work when VIRTIO_F_IOMMU_PLATFORM now, why? */
+	if (req_kernel == VHOST_SET_FEATURES)
+		*(uint64_t *)arg &= ~(1ULL << VIRTIO_F_IOMMU_PLATFORM);
+
+	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;
+	}
+
+	if (vm)
+		free(vm);
+
+	if (ret < 0)
+		PMD_DRV_LOG(ERR, "%s failed: %s",
+			    vhost_msg_strings[req], strerror(errno));
+
+	return ret;
+}
+
+/**
+ * Set up environment to talk with a vhost kernel backend.
+ *
+ * @return
+ *   - (-1) if fail to set up;
+ *   - (>=0) if successful.
+ */
+static int
+vhost_kernel_setup(struct virtio_user_dev *dev)
+{
+	int vhostfd;
+	uint32_t i;
+
+	for (i = 0; i < dev->max_queue_pairs; ++i) {
+		vhostfd = open(dev->path, O_RDWR);
+		if (vhostfd < 0) {
+			PMD_DRV_LOG(ERR, "fail to open %s, %s",
+				    dev->path, strerror(errno));
+			return -1;
+		}
+
+		dev->vhostfds[i] = vhostfd;
+	}
+
+	return 0;
+}
+
+static int
+vhost_kernel_set_backend(int vhostfd, int tapfd)
+{
+	struct vhost_vring_file f;
+
+	f.fd = tapfd;
+	f.index = 0;
+	if (ioctl(vhostfd, VHOST_NET_SET_BACKEND, &f) < 0) {
+		PMD_DRV_LOG(ERR, "VHOST_NET_SET_BACKEND fails, %s",
+				strerror(errno));
+		return -1;
+	}
+
+	f.index = 1;
+	if (ioctl(vhostfd, VHOST_NET_SET_BACKEND, &f) < 0) {
+		PMD_DRV_LOG(ERR, "VHOST_NET_SET_BACKEND fails, %s",
+				strerror(errno));
+		return -1;
+	}
+
+	return 0;
+}
+
+static int
+vhost_kernel_enable_queue_pair(struct virtio_user_dev *dev,
+			       uint16_t pair_idx,
+			       int enable)
+{
+	unsigned int tap_features;
+	int sndbuf = TUN_DEF_SNDBUF;
+	struct ifreq ifr;
+	int hdr_size;
+	int vhostfd;
+	int tapfd;
+
+	vhostfd = dev->vhostfds[pair_idx];
+
+	if (!enable) {
+		if (dev->tapfds[pair_idx]) {
+			close(dev->tapfds[pair_idx]);
+			dev->tapfds[pair_idx] = -1;
+		}
+		return vhost_kernel_set_backend(vhostfd, -1);
+	} else if (dev->tapfds[pair_idx] >= 0) {
+		return 0;
+	}
+
+	if ((dev->features & (1ULL << VIRTIO_NET_F_MRG_RXBUF)) ||
+	    (dev->features & (1ULL << VIRTIO_F_VERSION_1)))
+		hdr_size = sizeof(struct virtio_net_hdr_mrg_rxbuf);
+	else
+		hdr_size = sizeof(struct virtio_net_hdr);
+
+	/* TODO:
+	 * 1. verify we can get/set vnet_hdr_len, tap_probe_vnet_hdr_len
+	 * 2. get number of memory regions from vhost module parameter
+	 * max_mem_regions, supported in newer version linux kernel
+	 */
+	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;
+	}
+
+	/* Construct ifr */
+	memset(&ifr, 0, sizeof(ifr));
+	ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
+
+	if (ioctl(tapfd, TUNGETFEATURES, &tap_features) == -1) {
+		PMD_DRV_LOG(ERR, "TUNGETFEATURES failed: %s", strerror(errno));
+		goto error;
+	}
+	if (tap_features & IFF_ONE_QUEUE)
+		ifr.ifr_flags |= IFF_ONE_QUEUE;
+
+	/* Let tap instead of vhost-net handle vnet header, as the latter does
+	 * not support offloading. And in this case, we should not set feature
+	 * bit VHOST_NET_F_VIRTIO_NET_HDR.
+	 */
+	if (tap_features & IFF_VNET_HDR) {
+		ifr.ifr_flags |= IFF_VNET_HDR;
+	} else {
+		PMD_DRV_LOG(ERR, "TAP does not support IFF_VNET_HDR");
+		goto error;
+	}
+
+	if (dev->ifname)
+		strncpy(ifr.ifr_name, dev->ifname, IFNAMSIZ);
+	else
+		strncpy(ifr.ifr_name, "tap%d", IFNAMSIZ);
+	if (ioctl(tapfd, TUNSETIFF, (void *)&ifr) == -1) {
+		PMD_DRV_LOG(ERR, "TUNSETIFF failed: %s", strerror(errno));
+		goto error;
+	}
+
+	fcntl(tapfd, F_SETFL, O_NONBLOCK);
+
+	if (ioctl(tapfd, TUNSETVNETHDRSZ, &hdr_size) < 0) {
+		PMD_DRV_LOG(ERR, "TUNSETVNETHDRSZ failed: %s", strerror(errno));
+		goto error;
+	}
+
+	if (ioctl(tapfd, TUNSETSNDBUF, &sndbuf) < 0) {
+		PMD_DRV_LOG(ERR, "TUNSETSNDBUF failed: %s", strerror(errno));
+		goto error;
+	}
+
+	if (vhost_kernel_set_backend(vhostfd, tapfd) < 0)
+		goto error;
+
+	dev->tapfds[pair_idx] = tapfd;
+	if (!dev->ifname)
+		dev->ifname = strdup(ifr.ifr_name);
+
+	return 0;
+error:
+	return -1;
+}
+
+struct virtio_user_backend_ops ops_kernel = {
+	.setup = vhost_kernel_setup,
+	.send_request = vhost_kernel_ioctl,
+	.enable_qp = vhost_kernel_enable_queue_pair
+};
diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c b/drivers/net/virtio/virtio_user/virtio_user_dev.c
index 32039a1..c40b77e 100644
--- a/drivers/net/virtio/virtio_user/virtio_user_dev.c
+++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c
@@ -192,6 +192,9 @@ int virtio_user_stop_device(struct virtio_user_dev *dev)
 	for (i = 0; i < dev->max_queue_pairs; ++i)
 		dev->ops->enable_qp(dev, i, 0);
 
+	free(dev->ifname);
+	dev->ifname = NULL;
+
 	return 0;
 }
 
@@ -230,7 +233,7 @@ is_vhost_user_by_type(const char *path)
 static int
 virtio_user_dev_setup(struct virtio_user_dev *dev)
 {
-	uint32_t i;
+	uint32_t i, q;
 
 	dev->vhostfd = -1;
 	for (i = 0; i < VIRTIO_MAX_VIRTQUEUES * 2 + 1; ++i) {
@@ -238,12 +241,18 @@ virtio_user_dev_setup(struct virtio_user_dev *dev)
 		dev->callfds[i] = -1;
 	}
 
+	for (q = 0; q < VHOST_KERNEL_MAX_QUEUES; ++q) {
+		dev->vhostfds[q] = -1;
+		dev->tapfds[q] = -1;
+	}
+
 	if (is_vhost_user_by_type(dev->path)) {
 		dev->ops = &ops_user;
-		return dev->ops->setup(dev);
+	} else {
+		dev->ops = &ops_kernel;
 	}
 
-	return -1;
+	return dev->ops->setup(dev);
 }
 
 int
@@ -295,7 +304,13 @@ virtio_user_dev_init(struct virtio_user_dev *dev, char *path, int queues,
 void
 virtio_user_dev_uninit(struct virtio_user_dev *dev)
 {
+	uint32_t i;
+
+	virtio_user_stop_device(dev);
+
 	close(dev->vhostfd);
+	for (i = 0; i < VHOST_KERNEL_MAX_QUEUES; ++i)
+		close(dev->vhostfds[i]);
 }
 
 static uint8_t
diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.h b/drivers/net/virtio/virtio_user/virtio_user_dev.h
index 9f2f82e..148b2e6 100644
--- a/drivers/net/virtio/virtio_user/virtio_user_dev.h
+++ b/drivers/net/virtio/virtio_user/virtio_user_dev.h
@@ -43,6 +43,12 @@ struct virtio_user_dev {
 	/* for vhost_user backend */
 	int		vhostfd;
 
+	/* for vhost_kernel backend */
+	char		*ifname;
+#define VHOST_KERNEL_MAX_QUEUES		8
+	int		vhostfds[VHOST_KERNEL_MAX_QUEUES];
+	int		tapfds[VHOST_KERNEL_MAX_QUEUES];
+
 	/* for both vhost_user and vhost_kernel */
 	int		callfds[VIRTIO_MAX_VIRTQUEUES * 2 + 1];
 	int		kickfds[VIRTIO_MAX_VIRTQUEUES * 2 + 1];
-- 
2.7.4

  parent reply	other threads:[~2017-01-04  3:58 UTC|newest]

Thread overview: 73+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-12-02 14:31 [PATCH 0/3] virtio_user as an alternative exception path Jianfeng Tan
2016-12-02 14:31 ` [PATCH 1/3] net/virtio_user: add vhost layer Jianfeng Tan
2016-12-08  7:21   ` Yuanhan Liu
2016-12-02 14:31 ` [PATCH 2/3] net/virtio_user: add vhost kernel support Jianfeng Tan
2016-12-02 14:31 ` [PATCH 3/3] net/virtio_user: fix wrongly set features Jianfeng Tan
2016-12-08  8:32   ` Yuanhan Liu
2016-12-02 14:44 ` [PATCH 0/3] virtio_user as an alternative exception path Thomas Monjalon
2016-12-23  7:14 ` [PATCH v2 0/7] " Jianfeng Tan
2016-12-23  7:14   ` [PATCH v2 1/7] net/virtio_user: fix wrongly set features Jianfeng Tan
2016-12-23  7:14   ` [PATCH v2 2/7] net/virtio_user: postpone DRIVER OK notification Jianfeng Tan
2016-12-26  6:27     ` Yuanhan Liu
2016-12-26  6:55       ` Tan, Jianfeng
2016-12-26  8:02         ` Yuanhan Liu
2016-12-26  8:26           ` Tan, Jianfeng
2016-12-23  7:14   ` [PATCH v2 3/7] net/virtio_user: move vhost user specific code Jianfeng Tan
2016-12-26  6:28     ` Yuanhan Liu
2016-12-26  6:58       ` Tan, Jianfeng
2016-12-26  7:57         ` Yuanhan Liu
2016-12-29  9:40           ` Tan, Jianfeng
2016-12-23  7:14   ` [PATCH v2 4/7] net/virtio_user: abstract virtio user backend ops Jianfeng Tan
2016-12-26  6:41     ` Yuanhan Liu
2016-12-23  7:14   ` [PATCH v2 5/7] net/virtio_user: add vhost kernel support Jianfeng Tan
2016-12-26  7:44     ` Yuanhan Liu
2017-01-04  7:22       ` Tan, Jianfeng
2017-01-04  7:46         ` Yuanhan Liu
2017-01-09  4:51         ` Jason Wang
2017-01-09  4:39     ` Jason Wang
2017-01-10  6:11       ` Tan, Jianfeng
2017-01-10  8:46         ` Thomas Monjalon
2017-01-10  9:11           ` Tan, Jianfeng
2017-01-11  2:42         ` Jason Wang
2017-01-11  3:13           ` Tan, Jianfeng
2017-01-11  3:23             ` Jason Wang
2017-01-12  9:40               ` Tan, Jianfeng
2017-01-13  2:27                 ` Jason Wang
2017-01-11  2:30       ` Tan, Jianfeng
2017-01-11  2:45         ` Jason Wang
2016-12-23  7:14   ` [PATCH v2 6/7] net/virtio_user: enable offloading Jianfeng Tan
2016-12-26  7:53     ` Yuanhan Liu
2016-12-23  7:14   ` [PATCH v2 7/7] net/virtio_user: enable multiqueue with vhost kernel Jianfeng Tan
2017-01-04  3:59 ` [PATCH v3 0/7] virtio_user as an alternative exception path Jianfeng Tan
2017-01-04  3:59   ` [PATCH v3 1/7] net/virtio_user: fix wrongly set features Jianfeng Tan
2017-01-04  3:59   ` [PATCH v3 2/7] net/virtio_user: fix not properly reset device Jianfeng Tan
2017-01-04  5:46     ` Yuanhan Liu
2017-01-04  3:59   ` [PATCH v3 3/7] net/virtio_user: move vhost user specific code Jianfeng Tan
2017-01-04  6:02     ` Yuanhan Liu
2017-01-04  6:46       ` Tan, Jianfeng
2017-01-04  7:08         ` Yuanhan Liu
2017-01-04  3:59   ` [PATCH v3 4/7] net/virtio_user: abstract virtio user backend ops Jianfeng Tan
2017-01-04  6:11     ` Yuanhan Liu
2017-01-04  3:59   ` Jianfeng Tan [this message]
2017-01-04  6:13     ` [PATCH v3 5/7] net/virtio_user: add vhost kernel support Yuanhan Liu
2017-01-04  3:59   ` [PATCH v3 6/7] net/virtio_user: enable offloading Jianfeng Tan
2017-01-04  3:59   ` [PATCH v3 7/7] net/virtio_user: enable multiqueue with vhost kernel Jianfeng Tan
2017-01-09 14:06   ` [PATCH v3 0/7] virtio_user as an alternative exception path Bruce Richardson
2017-01-10  8:46     ` Tan, Jianfeng
2017-01-13 12:18 ` [PATCH v4 0/8] " Jianfeng Tan
2017-01-13 12:18   ` [PATCH v4 1/8] net/virtio_user: fix wrongly get/set features Jianfeng Tan
2017-01-13 12:18   ` [PATCH v4 2/8] net/virtio_user: fix not properly reset device Jianfeng Tan
2017-01-13 12:18   ` [PATCH v4 3/8] net/virtio_user: move vhost user specific code Jianfeng Tan
2017-01-13 12:18   ` [PATCH v4 4/8] net/virtio_user: abstract virtio user backend ops Jianfeng Tan
2017-01-13 12:18   ` [PATCH v4 5/8] net/virtio_user: add vhost kernel support Jianfeng Tan
2017-01-13 12:18   ` [PATCH v4 6/8] net/virtio_user: enable offloading Jianfeng Tan
2017-01-13 12:18   ` [PATCH v4 7/8] net/virtio_user: enable multiqueue with vhost kernel Jianfeng Tan
2017-01-13 12:18   ` [PATCH v4 8/8] doc: add guide to use virtio_user as exceptional path Jianfeng Tan
2017-01-16  6:00     ` Yuanhan Liu
2017-01-16  6:04       ` Yuanhan Liu
2017-01-16  9:44       ` Thomas Monjalon
2017-01-16  9:49         ` Yuanhan Liu
2017-01-16 14:45           ` Thomas Monjalon
2017-01-22  0:46     ` Aws Ismail
2017-01-22  7:16       ` Tan, Jianfeng
2017-01-16 15:05   ` [PATCH v4 0/8] virtio_user as an alternative exception path Yuanhan Liu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1483502366-140154-6-git-send-email-jianfeng.tan@intel.com \
    --to=jianfeng.tan@intel.com \
    --cc=cunming.liang@intel.com \
    --cc=dev@dpdk.org \
    --cc=ferruh.yigit@intel.com \
    --cc=yuanhan.liu@linux.intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.