All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/7] vhost: support selective datapath
@ 2018-02-02 23:28 Zhihong Wang
  2018-02-02 23:28 ` [PATCH 1/7] vhost: make capabilities configurable Zhihong Wang
                   ` (10 more replies)
  0 siblings, 11 replies; 67+ messages in thread
From: Zhihong Wang @ 2018-02-02 23:28 UTC (permalink / raw)
  To: dev
  Cc: jianfeng.tan, tiwei.bie, maxime.coquelin, yliu, cunming.liang,
	xiao.w.wang, dan.daly, Zhihong Wang

This patch set introduces support for selective datapath in DPDK vhost-user
lib. vDPA stands for vhost Data Path Acceleration. The idea is to enable
various types of virtio-compatible devices to do data transfer with virtio
driver directly to enable acceleration.

The default datapath is the existing software implementation, more options
will be available when new engines are added.

Design details
====

An engine is a group of virtio-compatible devices. The definition of engine
is as follows:

struct rte_vdpa_eng_addr {
	union {
		uint8_t __dummy[64];

		struct {
			struct rte_pci_addr pci_addr;
		};
	};
};

struct rte_vdpa_eng_info {
	char name[MAX_VDPA_NAME_LEN];
	struct rte_vdpa_eng_addr *addr;
};

struct rte_vdpa_dev_ops {
	vdpa_dev_conf_t        dev_conf;
	vdpa_dev_close_t       dev_close;
	vdpa_vring_state_set_t vring_state_set;
	vdpa_feature_set_t     feature_set;
	vdpa_migration_done_t  migration_done;
};

struct rte_vdpa_eng_ops {
	vdpa_eng_init_t   eng_init;
	vdpa_eng_uninit_t eng_uninit;
	vdpa_info_query_t info_query;
};

struct rte_vdpa_eng_driver {
	const char *name;
	struct rte_vdpa_eng_ops eng_ops;
	struct rte_vdpa_dev_ops dev_ops;
} __rte_cache_aligned;

struct rte_vdpa_engine {
	struct rte_vdpa_eng_info    eng_info;
	struct rte_vdpa_eng_driver *eng_drv;
} __rte_cache_aligned;

A set of engine ops is defined in rte_vdpa_eng_ops for engine init, uninit,
and attributes reporting. The attributes are defined as follows:

struct rte_vdpa_eng_attr {
	uint64_t features;
	uint64_t protocol_features;
	uint32_t queue_num;
	uint32_t dev_num;
};

A set of device ops is defined in rte_vdpa_dev_ops for each virtio device
in the engine to do device specific operations.

Changes to the current vhost-user lib are:
====

 1. Make vhost device capabilities configurable to adopt various engines.
    Such capabilities include supported features, protocol features, queue
    number. APIs are introduced to let app configure these capabilities.

 2. In addition to the existing vhost framework, a set of callbacks is
    added for vhost to call the driver for device operations at the right
    time:

     a. dev_conf: Called to configure the actual device when the virtio
        device becomes ready.

     b. dev_close: Called to close the actual device when the virtio device
        is stopped.

     c. vring_state_set: Called to change the state of the vring in the
        actual device when vring state changes.

     d. feature_set: Called to set the negotiated features to device.

     e. migration_done: Called to allow the device to response to RARP
        sending.

 3. To make vhost aware of its own type, an engine id (eid) and a device
    id (did) are added into the vhost data structure to identify the actual
    device. APIs are introduced to let app configure them. When the default
    software datapath is used, eid and did are set to -1. When alternative
    datapath is used, eid and did are set by app to specify which device to
    use. Each vhost-user socket can have only 1 connection in this case.

Working process:
====

 1. Register driver during DPDK initialization.

 2. Register engine with driver name and address.

 3. Get engine attributes.

 4. For vhost device creation:

      a. Register vhost-user socket.

      b. Set eid and did of the vhost-user socket.

      c. Set attributes of the vhost-user socket.

      d. Register vhost-user callbacks.

      e. Start to wait for connection.

 4. When connection comes and virtio device data structure is negotiated,
    configure the device with all needed info.

Zhihong Wang (7):
  vhost: make capabilities configurable
  vhost: expose vhost feature definitions
  vhost: support selective datapath
  vhost: add apis for datapath configuration
  vhost: adapt vhost lib for selective datapath
  vhost: get callfd before device setup
  vhost: expose new apis

 lib/librte_vhost/Makefile              |   4 +-
 lib/librte_vhost/rte_vdpa.h            | 119 +++++++++++++++++++++++++++
 lib/librte_vhost/rte_vhost.h           | 136 +++++++++++++++++++++++++++++++
 lib/librte_vhost/rte_vhost_version.map |  18 ++++
 lib/librte_vhost/socket.c              | 145 +++++++++++++++++++++++++++++++++
 lib/librte_vhost/vdpa.c                | 125 ++++++++++++++++++++++++++++
 lib/librte_vhost/vhost.c               |  49 +++++++++++
 lib/librte_vhost/vhost.h               |  14 +++-
 lib/librte_vhost/vhost_user.c          | 108 +++++++++++++++++++-----
 lib/librte_vhost/vhost_user.h          |  20 ++---
 10 files changed, 700 insertions(+), 38 deletions(-)
 create mode 100644 lib/librte_vhost/rte_vdpa.h
 create mode 100644 lib/librte_vhost/vdpa.c

-- 
2.7.5

^ permalink raw reply	[flat|nested] 67+ messages in thread

* [PATCH 1/7] vhost: make capabilities configurable
  2018-02-02 23:28 [PATCH 0/7] vhost: support selective datapath Zhihong Wang
@ 2018-02-02 23:28 ` Zhihong Wang
  2018-02-06 10:19   ` Maxime Coquelin
  2018-02-02 23:28 ` [PATCH 2/7] vhost: export vhost feature definitions Zhihong Wang
                   ` (9 subsequent siblings)
  10 siblings, 1 reply; 67+ messages in thread
From: Zhihong Wang @ 2018-02-02 23:28 UTC (permalink / raw)
  To: dev
  Cc: jianfeng.tan, tiwei.bie, maxime.coquelin, yliu, cunming.liang,
	xiao.w.wang, dan.daly, Zhihong Wang

This patch makes vhost device capabilities configurable to adopt new
devices, since different devices may have different capabilities, like
different combinations of supported features, or different number of
queues. APIs are introduced to let app configure these capabilities.

Signed-off-by: Zhihong Wang <zhihong.wang@intel.com>
---
 lib/librte_vhost/rte_vhost.h  | 50 ++++++++++++++++++++++++++++
 lib/librte_vhost/socket.c     | 77 +++++++++++++++++++++++++++++++++++++++++++
 lib/librte_vhost/vhost_user.c | 48 ++++++++++++++++++++-------
 3 files changed, 164 insertions(+), 11 deletions(-)

diff --git a/lib/librte_vhost/rte_vhost.h b/lib/librte_vhost/rte_vhost.h
index d332069..12cf48f 100644
--- a/lib/librte_vhost/rte_vhost.h
+++ b/lib/librte_vhost/rte_vhost.h
@@ -182,6 +182,56 @@ int rte_vhost_driver_unregister(const char *path);
 int rte_vhost_driver_set_features(const char *path, uint64_t features);
 
 /**
+ * Get the protocol feature bits.
+ *
+ * @param path
+ *  The vhost-user socket file path
+ * @param protocol_features
+ *  A pointer to store the queried protocol feature bits
+ * @return
+ *  0 on success, -1 on failure
+ */
+int rte_vhost_driver_get_protocol_features(const char *path,
+		uint64_t *protocol_features);
+
+/**
+ * Set the protocol feature bits the vhost-user driver supports.
+ *
+ * @param path
+ *  The vhost-user socket file path
+ * @param protocol_features
+ *  Supported protocol features
+ * @return
+ *  0 on success, -1 on failure
+ */
+int rte_vhost_driver_set_protocol_features(const char *path,
+		uint64_t protocol_features);
+
+/**
+ * Get the queue number.
+ *
+ * @param path
+ *  The vhost-user socket file path
+ * @param queue_num
+ *  A pointer to store the queried queue number
+ * @return
+ *  0 on success, -1 on failure
+ */
+int rte_vhost_driver_get_queue_num(const char *path, uint16_t *queue_num);
+
+/**
+ * Set the queue number the vhost-user driver supports.
+ *
+ * @param path
+ *  The vhost-user socket file path
+ * @param queue_num
+ *  Supported queue number
+ * @return
+ *  0 on success, -1 on failure
+ */
+int rte_vhost_driver_set_queue_num(const char *path, uint16_t queue_num);
+
+/**
  * Enable vhost-user driver features.
  *
  * Note that
diff --git a/lib/librte_vhost/socket.c b/lib/librte_vhost/socket.c
index 6e3857e..e1d0036 100644
--- a/lib/librte_vhost/socket.c
+++ b/lib/librte_vhost/socket.c
@@ -49,7 +49,10 @@ struct vhost_user_socket {
 	 * features negotiation.
 	 */
 	uint64_t supported_features;
+	uint64_t supported_protocol_features;
 	uint64_t features;
+	uint64_t protocol_features;
+	uint16_t queue_num;
 
 	struct vhost_device_ops const *notify_ops;
 };
@@ -593,6 +596,75 @@ rte_vhost_driver_get_features(const char *path, uint64_t *features)
 	}
 }
 
+int rte_vhost_driver_set_protocol_features(const char *path,
+		uint64_t protocol_features)
+{
+	struct vhost_user_socket *vsocket;
+
+	pthread_mutex_lock(&vhost_user.mutex);
+	vsocket = find_vhost_user_socket(path);
+	if (vsocket) {
+		vsocket->supported_protocol_features = protocol_features;
+		vsocket->protocol_features = protocol_features;
+	}
+	pthread_mutex_unlock(&vhost_user.mutex);
+
+	return vsocket ? 0 : -1;
+}
+
+int
+rte_vhost_driver_get_protocol_features(const char *path,
+		uint64_t *protocol_features)
+{
+	struct vhost_user_socket *vsocket;
+
+	pthread_mutex_lock(&vhost_user.mutex);
+	vsocket = find_vhost_user_socket(path);
+	if (vsocket)
+		*protocol_features = vsocket->protocol_features;
+	pthread_mutex_unlock(&vhost_user.mutex);
+
+	if (!vsocket) {
+		RTE_LOG(ERR, VHOST_CONFIG,
+			"socket file %s is not registered yet.\n", path);
+		return -1;
+	} else {
+		return 0;
+	}
+}
+
+int rte_vhost_driver_set_queue_num(const char *path, uint16_t queue_num)
+{
+	struct vhost_user_socket *vsocket;
+
+	pthread_mutex_lock(&vhost_user.mutex);
+	vsocket = find_vhost_user_socket(path);
+	if (vsocket)
+		vsocket->queue_num = queue_num;
+	pthread_mutex_unlock(&vhost_user.mutex);
+
+	return vsocket ? 0 : -1;
+}
+
+int rte_vhost_driver_get_queue_num(const char *path, uint16_t *queue_num)
+{
+	struct vhost_user_socket *vsocket;
+
+	pthread_mutex_lock(&vhost_user.mutex);
+	vsocket = find_vhost_user_socket(path);
+	if (vsocket)
+		*queue_num = vsocket->queue_num;
+	pthread_mutex_unlock(&vhost_user.mutex);
+
+	if (!vsocket) {
+		RTE_LOG(ERR, VHOST_CONFIG,
+			"socket file %s is not registered yet.\n", path);
+		return -1;
+	} else {
+		return 0;
+	}
+}
+
 /*
  * Register a new vhost-user socket; here we could act as server
  * (the default case), or client (when RTE_VHOST_USER_CLIENT) flag
@@ -655,6 +727,11 @@ rte_vhost_driver_register(const char *path, uint64_t flags)
 		vsocket->features &= ~(1ULL << VIRTIO_F_IOMMU_PLATFORM);
 	}
 
+	vsocket->supported_protocol_features = VHOST_USER_PROTOCOL_FEATURES;
+	vsocket->protocol_features           = VHOST_USER_PROTOCOL_FEATURES;
+
+	vsocket->queue_num = VHOST_MAX_QUEUE_PAIRS;
+
 	if ((flags & RTE_VHOST_USER_CLIENT) != 0) {
 		vsocket->reconnect = !(flags & RTE_VHOST_USER_NO_RECONNECT);
 		if (vsocket->reconnect && reconn_tid == 0) {
diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c
index 1dd1a61..87ba267 100644
--- a/lib/librte_vhost/vhost_user.c
+++ b/lib/librte_vhost/vhost_user.c
@@ -127,6 +127,18 @@ vhost_user_reset_owner(struct virtio_net *dev)
 }
 
 /*
+ * The supported queue num.
+ */
+static uint16_t
+vhost_user_get_queue_num(struct virtio_net *dev)
+{
+	uint16_t queue_num = 0;
+
+	rte_vhost_driver_get_queue_num(dev->ifname, &queue_num);
+	return queue_num;
+}
+
+/*
  * The features that we support are requested.
  */
 static uint64_t
@@ -930,13 +942,17 @@ vhost_user_set_vring_enable(struct virtio_net *dev,
 	return 0;
 }
 
-static void
-vhost_user_get_protocol_features(struct virtio_net *dev,
-				 struct VhostUserMsg *msg)
+/*
+ * The protocol features that we support are requested.
+ */
+
+static uint64_t
+vhost_user_get_protocol_features(struct virtio_net *dev)
 {
-	uint64_t features, protocol_features = VHOST_USER_PROTOCOL_FEATURES;
+	uint64_t features, protocol_features;
 
 	rte_vhost_driver_get_features(dev->ifname, &features);
+	rte_vhost_driver_get_protocol_features(dev->ifname, &protocol_features);
 
 	/*
 	 * REPLY_ACK protocol feature is only mandatory for now
@@ -947,18 +963,27 @@ vhost_user_get_protocol_features(struct virtio_net *dev,
 	if (!(features & (1ULL << VIRTIO_F_IOMMU_PLATFORM)))
 		protocol_features &= ~(1ULL << VHOST_USER_PROTOCOL_F_REPLY_ACK);
 
-	msg->payload.u64 = protocol_features;
-	msg->size = sizeof(msg->payload.u64);
+	return protocol_features;
 }
 
-static void
+static int
 vhost_user_set_protocol_features(struct virtio_net *dev,
 				 uint64_t protocol_features)
 {
-	if (protocol_features & ~VHOST_USER_PROTOCOL_FEATURES)
-		return;
+	uint64_t vhost_protocol_features = 0;
+
+	rte_vhost_driver_get_protocol_features(dev->ifname,
+			&vhost_protocol_features);
+	if (protocol_features & ~vhost_protocol_features) {
+		RTE_LOG(ERR, VHOST_CONFIG,
+			"(%d) received invalid negotiated protocol_features.\n",
+			dev->vid);
+		return -1;
+	}
 
 	dev->protocol_features = protocol_features;
+
+	return 0;
 }
 
 static int
@@ -1391,7 +1416,8 @@ vhost_user_msg_handler(int vid, int fd)
 		break;
 
 	case VHOST_USER_GET_PROTOCOL_FEATURES:
-		vhost_user_get_protocol_features(dev, &msg);
+		msg.payload.u64 = vhost_user_get_protocol_features(dev);
+		msg.size = sizeof(msg.payload.u64);
 		send_vhost_reply(fd, &msg);
 		break;
 	case VHOST_USER_SET_PROTOCOL_FEATURES:
@@ -1451,7 +1477,7 @@ vhost_user_msg_handler(int vid, int fd)
 		break;
 
 	case VHOST_USER_GET_QUEUE_NUM:
-		msg.payload.u64 = VHOST_MAX_QUEUE_PAIRS;
+		msg.payload.u64 = vhost_user_get_queue_num(dev);
 		msg.size = sizeof(msg.payload.u64);
 		send_vhost_reply(fd, &msg);
 		break;
-- 
2.7.5

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH 2/7] vhost: export vhost feature definitions
  2018-02-02 23:28 [PATCH 0/7] vhost: support selective datapath Zhihong Wang
  2018-02-02 23:28 ` [PATCH 1/7] vhost: make capabilities configurable Zhihong Wang
@ 2018-02-02 23:28 ` Zhihong Wang
  2018-02-02 23:28 ` [PATCH 3/7] vhost: support selective datapath Zhihong Wang
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 67+ messages in thread
From: Zhihong Wang @ 2018-02-02 23:28 UTC (permalink / raw)
  To: dev
  Cc: jianfeng.tan, tiwei.bie, maxime.coquelin, yliu, cunming.liang,
	xiao.w.wang, dan.daly, Zhihong Wang

This patch exports vhost-user protocol features to support device driver
development.

Signed-off-by: Zhihong Wang <zhihong.wang@intel.com>
---
 lib/librte_vhost/rte_vhost.h  |  8 ++++++++
 lib/librte_vhost/vhost.h      |  4 +---
 lib/librte_vhost/vhost_user.c |  9 +++++----
 lib/librte_vhost/vhost_user.h | 20 +++++++-------------
 4 files changed, 21 insertions(+), 20 deletions(-)

diff --git a/lib/librte_vhost/rte_vhost.h b/lib/librte_vhost/rte_vhost.h
index 12cf48f..6c92580 100644
--- a/lib/librte_vhost/rte_vhost.h
+++ b/lib/librte_vhost/rte_vhost.h
@@ -29,6 +29,14 @@ extern "C" {
 #define RTE_VHOST_USER_DEQUEUE_ZERO_COPY	(1ULL << 2)
 #define RTE_VHOST_USER_IOMMU_SUPPORT	(1ULL << 3)
 
+#define RTE_VHOST_USER_PROTOCOL_F_MQ		0
+#define RTE_VHOST_USER_PROTOCOL_F_LOG_SHMFD	1
+#define RTE_VHOST_USER_PROTOCOL_F_RARP		2
+#define RTE_VHOST_USER_PROTOCOL_F_REPLY_ACK	3
+#define RTE_VHOST_USER_PROTOCOL_F_NET_MTU	4
+#define RTE_VHOST_USER_PROTOCOL_F_SLAVE_REQ	5
+#define RTE_VHOST_USER_F_PROTOCOL_FEATURES	30
+
 /**
  * Information relating to memory regions including offsets to
  * addresses in QEMUs memory file.
diff --git a/lib/librte_vhost/vhost.h b/lib/librte_vhost/vhost.h
index 646aad3..09a745d 100644
--- a/lib/librte_vhost/vhost.h
+++ b/lib/librte_vhost/vhost.h
@@ -172,8 +172,6 @@ struct vhost_msg {
  #define VIRTIO_F_VERSION_1 32
 #endif
 
-#define VHOST_USER_F_PROTOCOL_FEATURES	30
-
 /* Features supported by this builtin vhost-user net driver. */
 #define VIRTIO_NET_SUPPORTED_FEATURES ((1ULL << VIRTIO_NET_F_MRG_RXBUF) | \
 				(1ULL << VIRTIO_F_ANY_LAYOUT) | \
@@ -183,7 +181,7 @@ struct vhost_msg {
 				(1ULL << VIRTIO_NET_F_MQ)      | \
 				(1ULL << VIRTIO_F_VERSION_1)   | \
 				(1ULL << VHOST_F_LOG_ALL)      | \
-				(1ULL << VHOST_USER_F_PROTOCOL_FEATURES) | \
+				(1ULL << RTE_VHOST_USER_F_PROTOCOL_FEATURES) | \
 				(1ULL << VIRTIO_NET_F_GSO) | \
 				(1ULL << VIRTIO_NET_F_HOST_TSO4) | \
 				(1ULL << VIRTIO_NET_F_HOST_TSO6) | \
diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c
index 87ba267..b1762e6 100644
--- a/lib/librte_vhost/vhost_user.c
+++ b/lib/librte_vhost/vhost_user.c
@@ -510,7 +510,7 @@ vhost_user_set_vring_addr(struct virtio_net **pdev, VhostUserMsg *msg)
 	vring_invalidate(dev, vq);
 
 	if (vq->enabled && (dev->features &
-				(1ULL << VHOST_USER_F_PROTOCOL_FEATURES))) {
+				(1ULL << RTE_VHOST_USER_F_PROTOCOL_FEATURES))) {
 		dev = translate_ring_addresses(dev, msg->payload.state.index);
 		if (!dev)
 			return -1;
@@ -847,11 +847,11 @@ vhost_user_set_vring_kick(struct virtio_net **pdev, struct VhostUserMsg *pmsg)
 	vq = dev->virtqueue[file.index];
 
 	/*
-	 * When VHOST_USER_F_PROTOCOL_FEATURES is not negotiated,
+	 * When RTE_VHOST_USER_F_PROTOCOL_FEATURES is not negotiated,
 	 * the ring starts already enabled. Otherwise, it is enabled via
 	 * the SET_VRING_ENABLE message.
 	 */
-	if (!(dev->features & (1ULL << VHOST_USER_F_PROTOCOL_FEATURES)))
+	if (!(dev->features & (1ULL << RTE_VHOST_USER_F_PROTOCOL_FEATURES)))
 		vq->enabled = 1;
 
 	if (vq->kickfd >= 0)
@@ -961,7 +961,8 @@ vhost_user_get_protocol_features(struct virtio_net *dev)
 	 * Qemu versions (from v2.7.0 to v2.9.0).
 	 */
 	if (!(features & (1ULL << VIRTIO_F_IOMMU_PLATFORM)))
-		protocol_features &= ~(1ULL << VHOST_USER_PROTOCOL_F_REPLY_ACK);
+		protocol_features &=
+			~(1ULL << RTE_VHOST_USER_PROTOCOL_F_REPLY_ACK);
 
 	return protocol_features;
 }
diff --git a/lib/librte_vhost/vhost_user.h b/lib/librte_vhost/vhost_user.h
index d4bd604..58e475d 100644
--- a/lib/librte_vhost/vhost_user.h
+++ b/lib/librte_vhost/vhost_user.h
@@ -14,19 +14,13 @@
 
 #define VHOST_MEMORY_MAX_NREGIONS 8
 
-#define VHOST_USER_PROTOCOL_F_MQ	0
-#define VHOST_USER_PROTOCOL_F_LOG_SHMFD	1
-#define VHOST_USER_PROTOCOL_F_RARP	2
-#define VHOST_USER_PROTOCOL_F_REPLY_ACK	3
-#define VHOST_USER_PROTOCOL_F_NET_MTU 4
-#define VHOST_USER_PROTOCOL_F_SLAVE_REQ 5
-
-#define VHOST_USER_PROTOCOL_FEATURES	((1ULL << VHOST_USER_PROTOCOL_F_MQ) | \
-					 (1ULL << VHOST_USER_PROTOCOL_F_LOG_SHMFD) |\
-					 (1ULL << VHOST_USER_PROTOCOL_F_RARP) | \
-					 (1ULL << VHOST_USER_PROTOCOL_F_REPLY_ACK) | \
-					 (1ULL << VHOST_USER_PROTOCOL_F_NET_MTU) | \
-					 (1ULL << VHOST_USER_PROTOCOL_F_SLAVE_REQ))
+#define VHOST_USER_PROTOCOL_FEATURES \
+			((1ULL << RTE_VHOST_USER_PROTOCOL_F_MQ) | \
+			 (1ULL << RTE_VHOST_USER_PROTOCOL_F_LOG_SHMFD) |\
+			 (1ULL << RTE_VHOST_USER_PROTOCOL_F_RARP) | \
+			 (1ULL << RTE_VHOST_USER_PROTOCOL_F_REPLY_ACK) | \
+			 (1ULL << RTE_VHOST_USER_PROTOCOL_F_NET_MTU) | \
+			 (1ULL << RTE_VHOST_USER_PROTOCOL_F_SLAVE_REQ))
 
 typedef enum VhostUserRequest {
 	VHOST_USER_NONE = 0,
-- 
2.7.5

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH 3/7] vhost: support selective datapath
  2018-02-02 23:28 [PATCH 0/7] vhost: support selective datapath Zhihong Wang
  2018-02-02 23:28 ` [PATCH 1/7] vhost: make capabilities configurable Zhihong Wang
  2018-02-02 23:28 ` [PATCH 2/7] vhost: export vhost feature definitions Zhihong Wang
@ 2018-02-02 23:28 ` Zhihong Wang
  2018-02-02 23:28 ` [PATCH 4/7] vhost: add apis for datapath configuration Zhihong Wang
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 67+ messages in thread
From: Zhihong Wang @ 2018-02-02 23:28 UTC (permalink / raw)
  To: dev
  Cc: jianfeng.tan, tiwei.bie, maxime.coquelin, yliu, cunming.liang,
	xiao.w.wang, dan.daly, Zhihong Wang

This patch introduces support for selective datapath in DPDK vhost-user lib
to enable various types of virtio-compatible devices to do data transfer
with virtio driver directly to enable acceleration. The default datapath is
the existing software implementation, more options will be available when
new engines are registered.

An engine is a group of virtio-compatible devices under a single address.
The engine driver includes:

 1. A set of engine ops is defined in rte_vdpa_eng_ops to perform engine
    init, uninit, and attributes reporting.
    
 2. A set of device ops is defined in rte_vdpa_dev_ops for virtio devices
    in the engine to do device specific operations:

     a. dev_conf: Called to configure the actual device when the virtio
        device becomes ready.

     b. dev_close: Called to close the actual device when the virtio device
        is stopped.

     c. vring_state_set: Called to change the state of the vring in the
        actual device when vring state changes.

     d. feature_set: Called to set the negotiated features to device.

     e. migration_done: Called to allow the device to response to RARP
        sending.

Signed-off-by: Zhihong Wang <zhihong.wang@intel.com>
---
 lib/librte_vhost/Makefile   |   4 +-
 lib/librte_vhost/rte_vdpa.h | 113 +++++++++++++++++++++++++++++++++++++++
 lib/librte_vhost/vdpa.c     | 125 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 240 insertions(+), 2 deletions(-)
 create mode 100644 lib/librte_vhost/rte_vdpa.h
 create mode 100644 lib/librte_vhost/vdpa.c

diff --git a/lib/librte_vhost/Makefile b/lib/librte_vhost/Makefile
index 5d6c6ab..37044ac 100644
--- a/lib/librte_vhost/Makefile
+++ b/lib/librte_vhost/Makefile
@@ -22,9 +22,9 @@ LDLIBS += -lrte_eal -lrte_mempool -lrte_mbuf -lrte_ethdev -lrte_net
 
 # all source are stored in SRCS-y
 SRCS-$(CONFIG_RTE_LIBRTE_VHOST) := fd_man.c iotlb.c socket.c vhost.c \
-					vhost_user.c virtio_net.c
+					vhost_user.c virtio_net.c vdpa.c
 
 # install includes
-SYMLINK-$(CONFIG_RTE_LIBRTE_VHOST)-include += rte_vhost.h
+SYMLINK-$(CONFIG_RTE_LIBRTE_VHOST)-include += rte_vhost.h rte_vdpa.h
 
 include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/lib/librte_vhost/rte_vdpa.h b/lib/librte_vhost/rte_vdpa.h
new file mode 100644
index 0000000..729849b
--- /dev/null
+++ b/lib/librte_vhost/rte_vdpa.h
@@ -0,0 +1,113 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Intel Corporation
+ */
+
+#ifndef _RTE_VDPA_H_
+#define _RTE_VDPA_H_
+
+/**
+ * @file
+ *
+ * Device specific vhost lib
+ */
+
+#include <rte_memory.h>
+#include <rte_pci.h>
+#include "rte_vhost.h"
+
+#define MAX_VDPA_ENGINE_NUM 128
+#define MAX_VDPA_NAME_LEN 128
+
+
+struct rte_vdpa_eng_addr {
+	union {
+		uint8_t __dummy[64];
+
+		struct {
+			struct rte_pci_addr pci_addr;
+		};
+	};
+};
+
+struct rte_vdpa_eng_info {
+	char name[MAX_VDPA_NAME_LEN];
+	struct rte_vdpa_eng_addr *addr;
+};
+
+struct rte_vdpa_eng_attr {
+	uint64_t features;
+	uint64_t protocol_features;
+	uint32_t queue_num;
+	uint32_t dev_num;
+};
+
+/* register/remove engine */
+typedef int (*vdpa_eng_init_t)(int eid, struct rte_vdpa_eng_addr *addr);
+typedef int (*vdpa_eng_uninit_t)(int eid);
+
+/* query info of this engine */
+typedef int (*vdpa_info_query_t)(int eid,
+		struct rte_vdpa_eng_attr *attr);
+
+/* driver configure/close the port based on connection */
+typedef int (*vdpa_dev_conf_t)(int vid);
+typedef int (*vdpa_dev_close_t)(int vid);
+
+/* enable/disable this vring */
+typedef int (*vdpa_vring_state_set_t)(int vid, int vring, int state);
+
+/* set features when changed */
+typedef int (*vdpa_feature_set_t)(int vid);
+
+/* destination operations when migration done, e.g. send rarp */
+typedef int (*vdpa_migration_done_t)(int vid);
+
+/* device ops */
+struct rte_vdpa_dev_ops {
+	vdpa_dev_conf_t        dev_conf;
+	vdpa_dev_close_t       dev_close;
+	vdpa_vring_state_set_t vring_state_set;
+	vdpa_feature_set_t     feature_set;
+	vdpa_migration_done_t  migration_done;
+};
+
+/* engine ops */
+struct rte_vdpa_eng_ops {
+	vdpa_eng_init_t eng_init;
+	vdpa_eng_uninit_t eng_uninit;
+	vdpa_info_query_t info_query;
+};
+
+struct rte_vdpa_eng_driver {
+	const char *name;
+	struct rte_vdpa_eng_ops eng_ops;
+	struct rte_vdpa_dev_ops dev_ops;
+} __rte_cache_aligned;
+
+struct rte_vdpa_engine {
+	struct rte_vdpa_eng_info eng_info;
+	struct rte_vdpa_eng_driver *eng_drv;
+} __rte_cache_aligned;
+
+extern struct rte_vdpa_engine *vdpa_engines[];
+extern uint32_t vdpa_engine_num;
+
+/* engine management */
+int rte_vdpa_register_engine(const char *name, struct rte_vdpa_eng_addr *addr);
+int rte_vdpa_unregister_engine(int eid);
+
+int rte_vdpa_find_engine_id(struct rte_vdpa_eng_addr *addr);
+
+int rte_vdpa_info_query(int eid, struct rte_vdpa_eng_attr *attr);
+
+/* driver register api */
+void rte_vdpa_register_driver(struct rte_vdpa_eng_driver *drv);
+
+#define RTE_VDPA_REGISTER_DRIVER(nm, drv) \
+RTE_INIT(vdpainitfn_ ##nm); \
+static void vdpainitfn_ ##nm(void) \
+{ \
+	rte_vdpa_register_driver(&drv); \
+} \
+
+#endif /* _RTE_VDPA_H_ */
diff --git a/lib/librte_vhost/vdpa.c b/lib/librte_vhost/vdpa.c
new file mode 100644
index 0000000..1fc2d0b
--- /dev/null
+++ b/lib/librte_vhost/vdpa.c
@@ -0,0 +1,125 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Intel Corporation
+ */
+
+/**
+ * @file
+ *
+ * Device specific vhost lib
+ */
+
+#include <rte_malloc.h>
+#include "rte_vdpa.h"
+#include "vhost.h"
+
+static struct rte_vdpa_eng_driver *vdpa_drivers[MAX_VDPA_ENGINE_NUM];
+static uint32_t vdpa_driver_num;
+
+struct rte_vdpa_engine *vdpa_engines[MAX_VDPA_ENGINE_NUM];
+uint32_t vdpa_engine_num;
+
+static int is_same_eng(struct rte_vdpa_eng_addr *a, struct rte_vdpa_eng_addr *b)
+{
+	if (a->pci_addr.domain != b->pci_addr.domain
+			|| a->pci_addr.bus != b->pci_addr.bus
+			|| a->pci_addr.devid != b->pci_addr.devid
+			|| a->pci_addr.function != b->pci_addr.function)
+		return -1;
+
+	return 0;
+}
+
+void rte_vdpa_register_driver(struct rte_vdpa_eng_driver *driver)
+{
+	if (vdpa_driver_num >= MAX_VDPA_ENGINE_NUM)
+		return;
+
+	vdpa_drivers[vdpa_driver_num] = driver;
+	vdpa_driver_num++;
+}
+
+int rte_vdpa_register_engine(const char *name, struct rte_vdpa_eng_addr *addr)
+{
+	static int engine_idx;
+
+	struct rte_vdpa_engine *eng;
+	struct rte_vdpa_eng_driver *cur;
+	char engine_name[MAX_VDPA_NAME_LEN];
+	int i;
+
+	for (i = 0; i < MAX_VDPA_ENGINE_NUM; ++i) {
+		eng = vdpa_engines[i];
+		if (eng && is_same_eng(eng->eng_info.addr, addr) == 0)
+			return i;
+	}
+
+	sprintf(engine_name, "vdpa-%s-%d", name, engine_idx++);
+	eng = rte_zmalloc(engine_name, sizeof(struct rte_vdpa_engine),
+			RTE_CACHE_LINE_SIZE);
+	if (!eng)
+		return -1;
+
+	for (i = 0; i < MAX_VDPA_ENGINE_NUM; ++i) {
+		cur = vdpa_drivers[i];
+		if (cur && 0 == strncmp(name, cur->name,
+					MAX_VDPA_NAME_LEN)) {
+			eng->eng_drv = cur;
+			strcpy(eng->eng_info.name, name);
+			eng->eng_info.addr = addr;
+			for (i = 0; i < MAX_VDPA_ENGINE_NUM; ++i) {
+				if (vdpa_engines[i])
+					continue;
+				vdpa_engines[i] = eng;
+				if (eng->eng_drv->eng_ops.eng_init)
+					eng->eng_drv->eng_ops.eng_init(i, addr);
+				vdpa_engine_num++;
+				return i;
+			}
+		}
+	}
+
+	return -1;
+}
+
+int rte_vdpa_unregister_engine(int eid)
+{
+	if (eid < 0 || eid >= MAX_VDPA_ENGINE_NUM || vdpa_engines[eid]
+			== NULL)
+		return -1;
+
+	if (vdpa_engines[eid]->eng_drv->eng_ops.eng_uninit)
+		vdpa_engines[eid]->eng_drv->eng_ops.eng_uninit(eid);
+
+	rte_free(vdpa_engines[eid]);
+	vdpa_engines[eid] = NULL;
+	vdpa_engine_num--;
+
+	return eid;
+}
+
+int rte_vdpa_find_engine_id(struct rte_vdpa_eng_addr *addr)
+{
+	struct rte_vdpa_engine *eng;
+	int i;
+
+	for (i = 0; i < MAX_VDPA_ENGINE_NUM; ++i) {
+		eng = vdpa_engines[i];
+		if (eng && is_same_eng(eng->eng_info.addr, addr) == 0)
+			return i;
+	}
+
+	return -1;
+}
+
+int rte_vdpa_info_query(int eid, struct rte_vdpa_eng_attr *attr)
+{
+	if (eid < 0 || eid >= MAX_VDPA_ENGINE_NUM || vdpa_engines[eid]
+			== NULL)
+		return -1;
+
+	if (vdpa_engines[eid]->eng_drv->eng_ops.info_query == NULL)
+		return -1;
+
+	return vdpa_engines[eid]->eng_drv->eng_ops.info_query(eid, attr);
+
+}
-- 
2.7.5

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH 4/7] vhost: add apis for datapath configuration
  2018-02-02 23:28 [PATCH 0/7] vhost: support selective datapath Zhihong Wang
                   ` (2 preceding siblings ...)
  2018-02-02 23:28 ` [PATCH 3/7] vhost: support selective datapath Zhihong Wang
@ 2018-02-02 23:28 ` Zhihong Wang
  2018-02-02 23:28 ` [PATCH 5/7] vhost: adapt vhost lib for selective datapath Zhihong Wang
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 67+ messages in thread
From: Zhihong Wang @ 2018-02-02 23:28 UTC (permalink / raw)
  To: dev
  Cc: jianfeng.tan, tiwei.bie, maxime.coquelin, yliu, cunming.liang,
	xiao.w.wang, dan.daly, Zhihong Wang

This patch adds APIs for datapath configuration. The eid and did of the
vhost-user socket can be configured to identify the actual device.

When the default software datapath is used, eid and did are set to -1.
When alternative datapath is used, eid and did are set by app to specify
which device to use. Each vhost-user socket can have only 1 connection in
this case.

Signed-off-by: Zhihong Wang <zhihong.wang@intel.com>
---
 lib/librte_vhost/rte_vhost.h | 68 ++++++++++++++++++++++++++++++++++++++++++++
 lib/librte_vhost/socket.c    | 65 ++++++++++++++++++++++++++++++++++++++++++
 lib/librte_vhost/vhost.c     | 44 ++++++++++++++++++++++++++++
 lib/librte_vhost/vhost.h     | 10 +++++++
 4 files changed, 187 insertions(+)

diff --git a/lib/librte_vhost/rte_vhost.h b/lib/librte_vhost/rte_vhost.h
index 6c92580..03f4ed1 100644
--- a/lib/librte_vhost/rte_vhost.h
+++ b/lib/librte_vhost/rte_vhost.h
@@ -178,6 +178,50 @@ int rte_vhost_driver_register(const char *path, uint64_t flags);
 int rte_vhost_driver_unregister(const char *path);
 
 /**
+ * Set the engine id, enforce single connection per socket
+ *
+ * @param path
+ *  The vhost-user socket file path
+ * @param eid
+ *  Engine id
+ * @return
+ *  0 on success, -1 on failure
+ */
+int rte_vhost_driver_set_vdpa_eid(const char *path, int eid);
+
+/**
+ * Set the device id, enforce single connection per socket
+ *
+ * @param path
+ *  The vhost-user socket file path
+ * @param did
+ *  Device id
+ * @return
+ *  0 on success, -1 on failure
+ */
+int rte_vhost_driver_set_vdpa_did(const char *path, int did);
+
+/**
+ * Get the engine id
+ *
+ * @param path
+ *  The vhost-user socket file path
+ * @return
+ *  Engine id, -1 on failure
+ */
+int rte_vhost_driver_get_vdpa_eid(const char *path);
+
+/**
+ * Get the device id
+ *
+ * @param path
+ *  The vhost-user socket file path
+ * @return
+ *  Device id, -1 on failure
+ */
+int rte_vhost_driver_get_vdpa_did(const char *path);
+
+/**
  * Set the feature bits the vhost-user driver supports.
  *
  * @param path
@@ -492,6 +536,30 @@ int rte_vhost_vring_call(int vid, uint16_t vring_idx);
  */
 uint32_t rte_vhost_rx_queue_count(int vid, uint16_t qid);
 
+/**
+ * Get vdpa engine id for vhost device.
+ *
+ * @param vid
+ *  vhost device ID
+ * @param eid
+ *  engine id
+ * @return
+ *  engine id
+ */
+int rte_vhost_get_vdpa_eid(int vid);
+
+/**
+ * Get vdpa device id for vhost device.
+ *
+ * @param vid
+ *  vhost device ID
+ * @param did
+ *  device id
+ * @return
+ *  device id
+ */
+int rte_vhost_get_vdpa_did(int vid);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/librte_vhost/socket.c b/lib/librte_vhost/socket.c
index e1d0036..c4f90af 100644
--- a/lib/librte_vhost/socket.c
+++ b/lib/librte_vhost/socket.c
@@ -54,6 +54,13 @@ struct vhost_user_socket {
 	uint64_t protocol_features;
 	uint16_t queue_num;
 
+	/* engine and device id to identify a certain port on a specific
+	 * backend, both are set to -1 for sw. when used, one socket can
+	 * have 1 connection only.
+	 */
+	int eid;
+	int did;
+
 	struct vhost_device_ops const *notify_ops;
 };
 
@@ -524,6 +531,64 @@ find_vhost_user_socket(const char *path)
 }
 
 int
+rte_vhost_driver_set_vdpa_eid(const char *path, int eid)
+{
+	struct vhost_user_socket *vsocket;
+
+	pthread_mutex_lock(&vhost_user.mutex);
+	vsocket = find_vhost_user_socket(path);
+	if (vsocket)
+		vsocket->eid = eid;
+	pthread_mutex_unlock(&vhost_user.mutex);
+
+	return vsocket ? 0 : -1;
+}
+
+int
+rte_vhost_driver_set_vdpa_did(const char *path, int did)
+{
+	struct vhost_user_socket *vsocket;
+
+	pthread_mutex_lock(&vhost_user.mutex);
+	vsocket = find_vhost_user_socket(path);
+	if (vsocket)
+		vsocket->did = did;
+	pthread_mutex_unlock(&vhost_user.mutex);
+
+	return vsocket ? 0 : -1;
+}
+
+int
+rte_vhost_driver_get_vdpa_eid(const char *path)
+{
+	struct vhost_user_socket *vsocket;
+	int eid = -1;
+
+	pthread_mutex_lock(&vhost_user.mutex);
+	vsocket = find_vhost_user_socket(path);
+	if (vsocket)
+		eid = vsocket->eid;
+	pthread_mutex_unlock(&vhost_user.mutex);
+
+	return eid;
+}
+
+int
+rte_vhost_driver_get_vdpa_did(const char *path)
+{
+	struct vhost_user_socket *vsocket;
+	int did = -1;
+
+	pthread_mutex_lock(&vhost_user.mutex);
+	vsocket = find_vhost_user_socket(path);
+	if (vsocket)
+		did = vsocket->did;
+	pthread_mutex_unlock(&vhost_user.mutex);
+
+	return did;
+}
+
+int
 rte_vhost_driver_disable_features(const char *path, uint64_t features)
 {
 	struct vhost_user_socket *vsocket;
diff --git a/lib/librte_vhost/vhost.c b/lib/librte_vhost/vhost.c
index 1dd9adb..2dff199 100644
--- a/lib/librte_vhost/vhost.c
+++ b/lib/librte_vhost/vhost.c
@@ -288,6 +288,8 @@ vhost_new_device(void)
 	vhost_devices[i] = dev;
 	dev->vid = i;
 	dev->slave_req_fd = -1;
+	dev->eid = -1;
+	dev->did = -1;
 
 	return i;
 }
@@ -316,6 +318,28 @@ vhost_destroy_device(int vid)
 }
 
 void
+vhost_set_vdpa_eid(int vid, int eid)
+{
+	struct virtio_net *dev = get_device(vid);
+
+	if (dev == NULL)
+		return;
+
+	dev->eid = eid;
+}
+
+void
+vhost_set_vdpa_did(int vid, int did)
+{
+	struct virtio_net *dev = get_device(vid);
+
+	if (dev == NULL)
+		return;
+
+	dev->did = did;
+}
+
+void
 vhost_set_ifname(int vid, const char *if_name, unsigned int if_len)
 {
 	struct virtio_net *dev;
@@ -605,3 +629,23 @@ rte_vhost_rx_queue_count(int vid, uint16_t qid)
 
 	return *((volatile uint16_t *)&vq->avail->idx) - vq->last_avail_idx;
 }
+
+int rte_vhost_get_vdpa_eid(int vid)
+{
+	struct virtio_net *dev = get_device(vid);
+
+	if (dev == NULL)
+		return -1;
+
+	return dev->eid;
+}
+
+int rte_vhost_get_vdpa_did(int vid)
+{
+	struct virtio_net *dev = get_device(vid);
+
+	if (dev == NULL)
+		return -1;
+
+	return dev->did;
+}
diff --git a/lib/librte_vhost/vhost.h b/lib/librte_vhost/vhost.h
index 09a745d..23d9060 100644
--- a/lib/librte_vhost/vhost.h
+++ b/lib/librte_vhost/vhost.h
@@ -19,6 +19,7 @@
 #include <rte_rwlock.h>
 
 #include "rte_vhost.h"
+#include "rte_vdpa.h"
 
 /* Used to indicate that the device is running on a data core */
 #define VIRTIO_DEV_RUNNING 1
@@ -237,6 +238,12 @@ struct virtio_net {
 	struct guest_page       *guest_pages;
 
 	int			slave_req_fd;
+
+	/* engine and device id to identify a certain port on a specific
+	 * backend, both are set to -1 for sw.
+	 */
+	int			eid;
+	int			did;
 } __rte_cache_aligned;
 
 
@@ -353,6 +360,9 @@ void free_vq(struct vhost_virtqueue *vq);
 
 int alloc_vring_queue(struct virtio_net *dev, uint32_t vring_idx);
 
+void vhost_set_vdpa_eid(int vid, int eid);
+void vhost_set_vdpa_did(int vid, int did);
+
 void vhost_set_ifname(int, const char *if_name, unsigned int if_len);
 void vhost_enable_dequeue_zero_copy(int vid);
 
-- 
2.7.5

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH 5/7] vhost: adapt vhost lib for selective datapath
  2018-02-02 23:28 [PATCH 0/7] vhost: support selective datapath Zhihong Wang
                   ` (3 preceding siblings ...)
  2018-02-02 23:28 ` [PATCH 4/7] vhost: add apis for datapath configuration Zhihong Wang
@ 2018-02-02 23:28 ` Zhihong Wang
  2018-02-02 23:28 ` [PATCH 6/7] vhost: get callfd before device setup Zhihong Wang
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 67+ messages in thread
From: Zhihong Wang @ 2018-02-02 23:28 UTC (permalink / raw)
  To: dev
  Cc: jianfeng.tan, tiwei.bie, maxime.coquelin, yliu, cunming.liang,
	xiao.w.wang, dan.daly, Zhihong Wang

This patch adapts vhost lib for selective datapath by calling device ops
at the corresponding stage.

Signed-off-by: Zhihong Wang <zhihong.wang@intel.com>
---
 lib/librte_vhost/socket.c     |  3 +++
 lib/librte_vhost/vhost.c      |  5 +++++
 lib/librte_vhost/vhost_user.c | 48 +++++++++++++++++++++++++++++++++++++++----
 3 files changed, 52 insertions(+), 4 deletions(-)

diff --git a/lib/librte_vhost/socket.c b/lib/librte_vhost/socket.c
index c4f90af..8296e4b 100644
--- a/lib/librte_vhost/socket.c
+++ b/lib/librte_vhost/socket.c
@@ -205,6 +205,9 @@ vhost_user_add_connection(int fd, struct vhost_user_socket *vsocket)
 	size = strnlen(vsocket->path, PATH_MAX);
 	vhost_set_ifname(vid, vsocket->path, size);
 
+	vhost_set_vdpa_eid(vid, vsocket->eid);
+	vhost_set_vdpa_did(vid, vsocket->did);
+
 	if (vsocket->dequeue_zero_copy)
 		vhost_enable_dequeue_zero_copy(vid);
 
diff --git a/lib/librte_vhost/vhost.c b/lib/librte_vhost/vhost.c
index 2dff199..1a3ddd5 100644
--- a/lib/librte_vhost/vhost.c
+++ b/lib/librte_vhost/vhost.c
@@ -302,11 +302,16 @@ void
 vhost_destroy_device(int vid)
 {
 	struct virtio_net *dev = get_device(vid);
+	int eid = dev->eid;
 
 	if (dev == NULL)
 		return;
 
 	if (dev->flags & VIRTIO_DEV_RUNNING) {
+		if (eid >= 0 && vdpa_engines[eid] &&
+				vdpa_engines[eid]->eng_drv &&
+				vdpa_engines[eid]->eng_drv->dev_ops.dev_close)
+			vdpa_engines[eid]->eng_drv->dev_ops.dev_close(dev->vid);
 		dev->flags &= ~VIRTIO_DEV_RUNNING;
 		dev->notify_ops->destroy_device(vid);
 	}
diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c
index b1762e6..05b53fa 100644
--- a/lib/librte_vhost/vhost_user.c
+++ b/lib/librte_vhost/vhost_user.c
@@ -116,7 +116,13 @@ vhost_user_set_owner(void)
 static int
 vhost_user_reset_owner(struct virtio_net *dev)
 {
+	int eid = dev->eid;
+
 	if (dev->flags & VIRTIO_DEV_RUNNING) {
+		if (eid >= 0 && vdpa_engines[eid] &&
+				vdpa_engines[eid]->eng_drv &&
+				vdpa_engines[eid]->eng_drv->dev_ops.dev_close)
+			vdpa_engines[eid]->eng_drv->dev_ops.dev_close(dev->vid);
 		dev->flags &= ~VIRTIO_DEV_RUNNING;
 		dev->notify_ops->destroy_device(dev->vid);
 	}
@@ -157,6 +163,7 @@ static int
 vhost_user_set_features(struct virtio_net *dev, uint64_t features)
 {
 	uint64_t vhost_features = 0;
+	int eid = dev->eid;
 
 	rte_vhost_driver_get_features(dev->ifname, &vhost_features);
 	if (features & ~vhost_features) {
@@ -186,6 +193,11 @@ vhost_user_set_features(struct virtio_net *dev, uint64_t features)
 			dev->notify_ops->features_changed(dev->vid, features);
 	}
 
+	if (eid >= 0 && vdpa_engines[eid] &&
+			vdpa_engines[eid]->eng_drv &&
+			vdpa_engines[eid]->eng_drv->dev_ops.feature_set)
+		vdpa_engines[eid]->eng_drv->dev_ops.feature_set(dev->vid);
+
 	dev->features = features;
 	if (dev->features &
 		((1 << VIRTIO_NET_F_MRG_RXBUF) | (1ULL << VIRTIO_F_VERSION_1))) {
@@ -883,9 +895,14 @@ vhost_user_get_vring_base(struct virtio_net *dev,
 			  VhostUserMsg *msg)
 {
 	struct vhost_virtqueue *vq = dev->virtqueue[msg->payload.state.index];
+	int eid = dev->eid;
 
 	/* We have to stop the queue (virtio) if it is running. */
 	if (dev->flags & VIRTIO_DEV_RUNNING) {
+		if (eid >= 0 && vdpa_engines[eid] &&
+				vdpa_engines[eid]->eng_drv &&
+				vdpa_engines[eid]->eng_drv->dev_ops.dev_close)
+			vdpa_engines[eid]->eng_drv->dev_ops.dev_close(dev->vid);
 		dev->flags &= ~VIRTIO_DEV_RUNNING;
 		dev->notify_ops->destroy_device(dev->vid);
 	}
@@ -928,16 +945,24 @@ vhost_user_set_vring_enable(struct virtio_net *dev,
 			    VhostUserMsg *msg)
 {
 	int enable = (int)msg->payload.state.num;
+	int index = (int)msg->payload.state.index;
+	int eid = dev->eid;
 
 	RTE_LOG(INFO, VHOST_CONFIG,
 		"set queue enable: %d to qp idx: %d\n",
-		enable, msg->payload.state.index);
+		enable, index);
+
+	if (eid >= 0 && vdpa_engines[eid] &&
+			vdpa_engines[eid]->eng_drv &&
+			vdpa_engines[eid]->eng_drv->dev_ops.vring_state_set)
+		vdpa_engines[eid]->eng_drv->dev_ops.vring_state_set(dev->vid,
+				index, enable);
 
 	if (dev->notify_ops->vring_state_changed)
 		dev->notify_ops->vring_state_changed(dev->vid,
-				msg->payload.state.index, enable);
+				index, enable);
 
-	dev->virtqueue[msg->payload.state.index]->enabled = enable;
+	dev->virtqueue[index]->enabled = enable;
 
 	return 0;
 }
@@ -1049,6 +1074,7 @@ static int
 vhost_user_send_rarp(struct virtio_net *dev, struct VhostUserMsg *msg)
 {
 	uint8_t *mac = (uint8_t *)&msg->payload.u64;
+	int eid = dev->eid;
 
 	RTE_LOG(DEBUG, VHOST_CONFIG,
 		":: mac: %02x:%02x:%02x:%02x:%02x:%02x\n",
@@ -1064,6 +1090,10 @@ vhost_user_send_rarp(struct virtio_net *dev, struct VhostUserMsg *msg)
 	 */
 	rte_smp_wmb();
 	rte_atomic16_set(&dev->broadcast_rarp, 1);
+	if (eid >= 0 && vdpa_engines[eid] &&
+			vdpa_engines[eid]->eng_drv &&
+			vdpa_engines[eid]->eng_drv->dev_ops.migration_done)
+		vdpa_engines[eid]->eng_drv->dev_ops.migration_done(dev->vid);
 
 	return 0;
 }
@@ -1526,8 +1556,18 @@ vhost_user_msg_handler(int vid, int fd)
 						"dequeue zero copy is enabled\n");
 			}
 
-			if (dev->notify_ops->new_device(dev->vid) == 0)
+			if (dev->notify_ops->new_device(vid) == 0)
 				dev->flags |= VIRTIO_DEV_RUNNING;
+
+			struct rte_vdpa_engine *eng;
+			int eid = dev->eid;
+
+			if (eid >= 0) {
+				eng = vdpa_engines[eid];
+				if (eng && eng->eng_drv &&
+						eng->eng_drv->dev_ops.dev_conf)
+					eng->eng_drv->dev_ops.dev_conf(vid);
+			}
 		}
 	}
 
-- 
2.7.5

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH 6/7] vhost: get callfd before device setup
  2018-02-02 23:28 [PATCH 0/7] vhost: support selective datapath Zhihong Wang
                   ` (4 preceding siblings ...)
  2018-02-02 23:28 ` [PATCH 5/7] vhost: adapt vhost lib for selective datapath Zhihong Wang
@ 2018-02-02 23:28 ` Zhihong Wang
  2018-02-02 23:28 ` [PATCH 7/7] vhost: export new apis Zhihong Wang
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 67+ messages in thread
From: Zhihong Wang @ 2018-02-02 23:28 UTC (permalink / raw)
  To: dev
  Cc: jianfeng.tan, tiwei.bie, maxime.coquelin, yliu, cunming.liang,
	xiao.w.wang, dan.daly

From: Xiao Wang <xiao.w.wang@intel.com>

This patch is to make sure device is configured with all needed guest
info. According to QEMU vhost message sequence, the real callfd comes
just before SET_VRING_ENABLE.

Signed-off-by: Xiao Wang <xiao.w.wang@intel.com>
---
 lib/librte_vhost/vhost_user.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c
index 05b53fa..3fe1b3d 100644
--- a/lib/librte_vhost/vhost_user.c
+++ b/lib/librte_vhost/vhost_user.c
@@ -1547,7 +1547,8 @@ vhost_user_msg_handler(int vid, int fd)
 		send_vhost_reply(fd, &msg);
 	}
 
-	if (!(dev->flags & VIRTIO_DEV_RUNNING) && virtio_is_ready(dev)) {
+	if (!(dev->flags & VIRTIO_DEV_RUNNING) && virtio_is_ready(dev)
+			&& msg.request.master == VHOST_USER_SET_VRING_ENABLE) {
 		dev->flags |= VIRTIO_DEV_READY;
 
 		if (!(dev->flags & VIRTIO_DEV_RUNNING)) {
-- 
2.7.5

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH 7/7] vhost: export new apis
  2018-02-02 23:28 [PATCH 0/7] vhost: support selective datapath Zhihong Wang
                   ` (5 preceding siblings ...)
  2018-02-02 23:28 ` [PATCH 6/7] vhost: get callfd before device setup Zhihong Wang
@ 2018-02-02 23:28 ` Zhihong Wang
  2018-02-13  9:21 ` [PATCH v2 0/6] vhost: support selective datapath Zhihong Wang
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 67+ messages in thread
From: Zhihong Wang @ 2018-02-02 23:28 UTC (permalink / raw)
  To: dev
  Cc: jianfeng.tan, tiwei.bie, maxime.coquelin, yliu, cunming.liang,
	xiao.w.wang, dan.daly, Zhihong Wang

This patch exports new APIs as experimental.

Signed-off-by: Zhihong Wang <zhihong.wang@intel.com>
---
 lib/librte_vhost/rte_vdpa.h            | 16 +++++++++++-----
 lib/librte_vhost/rte_vhost.h           | 30 ++++++++++++++++++++----------
 lib/librte_vhost/rte_vhost_version.map | 18 ++++++++++++++++++
 3 files changed, 49 insertions(+), 15 deletions(-)

diff --git a/lib/librte_vhost/rte_vdpa.h b/lib/librte_vhost/rte_vdpa.h
index 729849b..f6f6d0a 100644
--- a/lib/librte_vhost/rte_vdpa.h
+++ b/lib/librte_vhost/rte_vdpa.h
@@ -93,15 +93,21 @@ extern struct rte_vdpa_engine *vdpa_engines[];
 extern uint32_t vdpa_engine_num;
 
 /* engine management */
-int rte_vdpa_register_engine(const char *name, struct rte_vdpa_eng_addr *addr);
-int rte_vdpa_unregister_engine(int eid);
+int __rte_experimental
+rte_vdpa_register_engine(const char *name, struct rte_vdpa_eng_addr *addr);
 
-int rte_vdpa_find_engine_id(struct rte_vdpa_eng_addr *addr);
+int __rte_experimental
+rte_vdpa_unregister_engine(int eid);
 
-int rte_vdpa_info_query(int eid, struct rte_vdpa_eng_attr *attr);
+int __rte_experimental
+rte_vdpa_find_engine_id(struct rte_vdpa_eng_addr *addr);
+
+int __rte_experimental
+rte_vdpa_info_query(int eid, struct rte_vdpa_eng_attr *attr);
 
 /* driver register api */
-void rte_vdpa_register_driver(struct rte_vdpa_eng_driver *drv);
+void __rte_experimental
+rte_vdpa_register_driver(struct rte_vdpa_eng_driver *drv);
 
 #define RTE_VDPA_REGISTER_DRIVER(nm, drv) \
 RTE_INIT(vdpainitfn_ ##nm); \
diff --git a/lib/librte_vhost/rte_vhost.h b/lib/librte_vhost/rte_vhost.h
index 03f4ed1..dc38566 100644
--- a/lib/librte_vhost/rte_vhost.h
+++ b/lib/librte_vhost/rte_vhost.h
@@ -187,7 +187,8 @@ int rte_vhost_driver_unregister(const char *path);
  * @return
  *  0 on success, -1 on failure
  */
-int rte_vhost_driver_set_vdpa_eid(const char *path, int eid);
+int __rte_experimental
+rte_vhost_driver_set_vdpa_eid(const char *path, int eid);
 
 /**
  * Set the device id, enforce single connection per socket
@@ -199,7 +200,8 @@ int rte_vhost_driver_set_vdpa_eid(const char *path, int eid);
  * @return
  *  0 on success, -1 on failure
  */
-int rte_vhost_driver_set_vdpa_did(const char *path, int did);
+int __rte_experimental
+rte_vhost_driver_set_vdpa_did(const char *path, int did);
 
 /**
  * Get the engine id
@@ -209,7 +211,8 @@ int rte_vhost_driver_set_vdpa_did(const char *path, int did);
  * @return
  *  Engine id, -1 on failure
  */
-int rte_vhost_driver_get_vdpa_eid(const char *path);
+int __rte_experimental
+rte_vhost_driver_get_vdpa_eid(const char *path);
 
 /**
  * Get the device id
@@ -219,7 +222,8 @@ int rte_vhost_driver_get_vdpa_eid(const char *path);
  * @return
  *  Device id, -1 on failure
  */
-int rte_vhost_driver_get_vdpa_did(const char *path);
+int __rte_experimental
+rte_vhost_driver_get_vdpa_did(const char *path);
 
 /**
  * Set the feature bits the vhost-user driver supports.
@@ -243,7 +247,8 @@ int rte_vhost_driver_set_features(const char *path, uint64_t features);
  * @return
  *  0 on success, -1 on failure
  */
-int rte_vhost_driver_get_protocol_features(const char *path,
+int __rte_experimental
+rte_vhost_driver_get_protocol_features(const char *path,
 		uint64_t *protocol_features);
 
 /**
@@ -256,7 +261,8 @@ int rte_vhost_driver_get_protocol_features(const char *path,
  * @return
  *  0 on success, -1 on failure
  */
-int rte_vhost_driver_set_protocol_features(const char *path,
+int __rte_experimental
+rte_vhost_driver_set_protocol_features(const char *path,
 		uint64_t protocol_features);
 
 /**
@@ -269,7 +275,8 @@ int rte_vhost_driver_set_protocol_features(const char *path,
  * @return
  *  0 on success, -1 on failure
  */
-int rte_vhost_driver_get_queue_num(const char *path, uint16_t *queue_num);
+int __rte_experimental
+rte_vhost_driver_get_queue_num(const char *path, uint16_t *queue_num);
 
 /**
  * Set the queue number the vhost-user driver supports.
@@ -281,7 +288,8 @@ int rte_vhost_driver_get_queue_num(const char *path, uint16_t *queue_num);
  * @return
  *  0 on success, -1 on failure
  */
-int rte_vhost_driver_set_queue_num(const char *path, uint16_t queue_num);
+int __rte_experimental
+rte_vhost_driver_set_queue_num(const char *path, uint16_t queue_num);
 
 /**
  * Enable vhost-user driver features.
@@ -546,7 +554,8 @@ uint32_t rte_vhost_rx_queue_count(int vid, uint16_t qid);
  * @return
  *  engine id
  */
-int rte_vhost_get_vdpa_eid(int vid);
+int __rte_experimental
+rte_vhost_get_vdpa_eid(int vid);
 
 /**
  * Get vdpa device id for vhost device.
@@ -558,7 +567,8 @@ int rte_vhost_get_vdpa_eid(int vid);
  * @return
  *  device id
  */
-int rte_vhost_get_vdpa_did(int vid);
+int __rte_experimental
+rte_vhost_get_vdpa_did(int vid);
 
 #ifdef __cplusplus
 }
diff --git a/lib/librte_vhost/rte_vhost_version.map b/lib/librte_vhost/rte_vhost_version.map
index df01031..de585df 100644
--- a/lib/librte_vhost/rte_vhost_version.map
+++ b/lib/librte_vhost/rte_vhost_version.map
@@ -59,3 +59,21 @@ DPDK_18.02 {
 	rte_vhost_vring_call;
 
 } DPDK_17.08;
+
+EXPERIMENTAL {
+	rte_vhost_driver_set_vdpa_eid;
+	rte_vhost_driver_set_vdpa_did;
+	rte_vhost_driver_get_vdpa_eid;
+	rte_vhost_driver_get_vdpa_did;
+	rte_vhost_driver_get_protocol_features;
+	rte_vhost_driver_set_protocol_features;
+	rte_vhost_driver_get_queue_num;
+	rte_vhost_driver_set_queue_num;
+	rte_vhost_get_vdpa_eid;
+	rte_vhost_get_vdpa_did;
+	rte_vdpa_register_engine;
+	rte_vdpa_unregister_engine;
+	rte_vdpa_find_engine_id;
+	rte_vdpa_info_query;
+	rte_vdpa_register_driver;
+} DPDK_18.02;
-- 
2.7.5

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* Re: [PATCH 1/7] vhost: make capabilities configurable
  2018-02-02 23:28 ` [PATCH 1/7] vhost: make capabilities configurable Zhihong Wang
@ 2018-02-06 10:19   ` Maxime Coquelin
  2018-02-08  3:03     ` Wang, Zhihong
  0 siblings, 1 reply; 67+ messages in thread
From: Maxime Coquelin @ 2018-02-06 10:19 UTC (permalink / raw)
  To: Zhihong Wang, dev
  Cc: jianfeng.tan, tiwei.bie, yliu, cunming.liang, xiao.w.wang, dan.daly

Hi Zhihong,

On 02/03/2018 12:28 AM, Zhihong Wang wrote:
> This patch makes vhost device capabilities configurable to adopt new
> devices, since different devices may have different capabilities, like
> different combinations of supported features, or different number of
> queues. APIs are introduced to let app configure these capabilities.
> 
> Signed-off-by: Zhihong Wang <zhihong.wang@intel.com>
> ---
>   lib/librte_vhost/rte_vhost.h  | 50 ++++++++++++++++++++++++++++
>   lib/librte_vhost/socket.c     | 77 +++++++++++++++++++++++++++++++++++++++++++
>   lib/librte_vhost/vhost_user.c | 48 ++++++++++++++++++++-------
>   3 files changed, 164 insertions(+), 11 deletions(-)
> 
...

> diff --git a/lib/librte_vhost/socket.c b/lib/librte_vhost/socket.c
> index 6e3857e..e1d0036 100644
> --- a/lib/librte_vhost/socket.c
> +++ b/lib/librte_vhost/socket.c
> @@ -49,7 +49,10 @@ struct vhost_user_socket {
>   	 * features negotiation.
>   	 */
>   	uint64_t supported_features;
> +	uint64_t supported_protocol_features;
>   	uint64_t features;
> +	uint64_t protocol_features;
> +	uint16_t queue_num;
>   
>   	struct vhost_device_ops const *notify_ops;
>   };
> @@ -593,6 +596,75 @@ rte_vhost_driver_get_features(const char *path, uint64_t *features)
>   	}
>   }
>   
> +int rte_vhost_driver_set_protocol_features(const char *path,
> +		uint64_t protocol_features)
> +{
> +	struct vhost_user_socket *vsocket;
> +
> +	pthread_mutex_lock(&vhost_user.mutex);
> +	vsocket = find_vhost_user_socket(path);
> +	if (vsocket) {
> +		vsocket->supported_protocol_features = protocol_features;
> +		vsocket->protocol_features = protocol_features;
> +	}
> +	pthread_mutex_unlock(&vhost_user.mutex);
> +
> +	return vsocket ? 0 : -1;
> +}
> +
> +int
> +rte_vhost_driver_get_protocol_features(const char *path,
> +		uint64_t *protocol_features)
> +{
> +	struct vhost_user_socket *vsocket;
> +
> +	pthread_mutex_lock(&vhost_user.mutex);
> +	vsocket = find_vhost_user_socket(path);
> +	if (vsocket)
> +		*protocol_features = vsocket->protocol_features;
> +	pthread_mutex_unlock(&vhost_user.mutex);
> +
> +	if (!vsocket) {
> +		RTE_LOG(ERR, VHOST_CONFIG,
> +			"socket file %s is not registered yet.\n", path);
> +		return -1;
> +	} else {
> +		return 0;
> +	}
> +}
> +
> +int rte_vhost_driver_set_queue_num(const char *path, uint16_t queue_num)
> +{
> +	struct vhost_user_socket *vsocket;
> +
> +	pthread_mutex_lock(&vhost_user.mutex);
> +	vsocket = find_vhost_user_socket(path);
> +	if (vsocket)
> +		vsocket->queue_num = queue_num;

Shouldn't be MIN(queue_num, VHOST_MAX_QUEUE_PAIRS) to be sure you can
switch from HW offload to SW processing?

> +	pthread_mutex_unlock(&vhost_user.mutex);
> +
> +	return vsocket ? 0 : -1;
> +}
> +
> +int rte_vhost_driver_get_queue_num(const char *path, uint16_t *queue_num)
> +{
> +	struct vhost_user_socket *vsocket;
> +
> +	pthread_mutex_lock(&vhost_user.mutex);
> +	vsocket = find_vhost_user_socket(path);
> +	if (vsocket)
> +		*queue_num = vsocket->queue_num;
> +	pthread_mutex_unlock(&vhost_user.mutex);
> +
> +	if (!vsocket) {
> +		RTE_LOG(ERR, VHOST_CONFIG,
> +			"socket file %s is not registered yet.\n", path);
> +		return -1;
> +	} else {
> +		return 0;
> +	}
> +}
> +
>   /*
>    * Register a new vhost-user socket; here we could act as server
>    * (the default case), or client (when RTE_VHOST_USER_CLIENT) flag
> @@ -655,6 +727,11 @@ rte_vhost_driver_register(const char *path, uint64_t flags)
>   		vsocket->features &= ~(1ULL << VIRTIO_F_IOMMU_PLATFORM);
>   	}
>   
> +	vsocket->supported_protocol_features = VHOST_USER_PROTOCOL_FEATURES;
> +	vsocket->protocol_features           = VHOST_USER_PROTOCOL_FEATURES;
> +
> +	vsocket->queue_num = VHOST_MAX_QUEUE_PAIRS;
> +
>   	if ((flags & RTE_VHOST_USER_CLIENT) != 0) {
>   		vsocket->reconnect = !(flags & RTE_VHOST_USER_NO_RECONNECT);
>   		if (vsocket->reconnect && reconn_tid == 0) {
> diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c
> index 1dd1a61..87ba267 100644
> --- a/lib/librte_vhost/vhost_user.c
> +++ b/lib/librte_vhost/vhost_user.c
> @@ -127,6 +127,18 @@ vhost_user_reset_owner(struct virtio_net *dev)
>   }
>   
>   /*
> + * The supported queue num.
> + */
> +static uint16_t
> +vhost_user_get_queue_num(struct virtio_net *dev)
> +{
> +	uint16_t queue_num = 0;
> +
> +	rte_vhost_driver_get_queue_num(dev->ifname, &queue_num);
> +	return queue_num;
> +}
> +
> +/*
>    * The features that we support are requested.
>    */
>   static uint64_t
> @@ -930,13 +942,17 @@ vhost_user_set_vring_enable(struct virtio_net *dev,
>   	return 0;
>   }
>   
> -static void
> -vhost_user_get_protocol_features(struct virtio_net *dev,
> -				 struct VhostUserMsg *msg)
> +/*
> + * The protocol features that we support are requested.
> + */
> +
> +static uint64_t
> +vhost_user_get_protocol_features(struct virtio_net *dev)
>   {
> -	uint64_t features, protocol_features = VHOST_USER_PROTOCOL_FEATURES;
> +	uint64_t features, protocol_features;
>   
>   	rte_vhost_driver_get_features(dev->ifname, &features);
> +	rte_vhost_driver_get_protocol_features(dev->ifname, &protocol_features);
>   
>   	/*
>   	 * REPLY_ACK protocol feature is only mandatory for now
> @@ -947,18 +963,27 @@ vhost_user_get_protocol_features(struct virtio_net *dev,
>   	if (!(features & (1ULL << VIRTIO_F_IOMMU_PLATFORM)))
>   		protocol_features &= ~(1ULL << VHOST_USER_PROTOCOL_F_REPLY_ACK);
>   
> -	msg->payload.u64 = protocol_features;
> -	msg->size = sizeof(msg->payload.u64);
> +	return protocol_features;
>   }
>   
> -static void
> +static int
>   vhost_user_set_protocol_features(struct virtio_net *dev,
>   				 uint64_t protocol_features)
>   {
> -	if (protocol_features & ~VHOST_USER_PROTOCOL_FEATURES)

I think the above check is still necessary, or it should be checked
in rte_vhost_driver_set_protocol_features().

Indeed, the application shouldn't set a protocol feature bit that isn't
supported by the libvhost-user library.

> -		return;
> +	uint64_t vhost_protocol_features = 0;
> +
> +	rte_vhost_driver_get_protocol_features(dev->ifname,
> +			&vhost_protocol_features);
> +	if (protocol_features & ~vhost_protocol_features) {
> +		RTE_LOG(ERR, VHOST_CONFIG,
> +			"(%d) received invalid negotiated protocol_features.\n",
> +			dev->vid);
> +		return -1;
> +	}
>   
>   	dev->protocol_features = protocol_features;
> +
> +	return 0;
>   }
>   
>   static int
> @@ -1391,7 +1416,8 @@ vhost_user_msg_handler(int vid, int fd)
>   		break;
>   
>   	case VHOST_USER_GET_PROTOCOL_FEATURES:
> -		vhost_user_get_protocol_features(dev, &msg);
> +		msg.payload.u64 = vhost_user_get_protocol_features(dev);
> +		msg.size = sizeof(msg.payload.u64);
>   		send_vhost_reply(fd, &msg);
>   		break;
>   	case VHOST_USER_SET_PROTOCOL_FEATURES:
> @@ -1451,7 +1477,7 @@ vhost_user_msg_handler(int vid, int fd)
>   		break;
>   
>   	case VHOST_USER_GET_QUEUE_NUM:
> -		msg.payload.u64 = VHOST_MAX_QUEUE_PAIRS;
> +		msg.payload.u64 = vhost_user_get_queue_num(dev);
>   		msg.size = sizeof(msg.payload.u64);
>   		send_vhost_reply(fd, &msg);
>   		break;
> 

Maxime

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH 1/7] vhost: make capabilities configurable
  2018-02-06 10:19   ` Maxime Coquelin
@ 2018-02-08  3:03     ` Wang, Zhihong
  0 siblings, 0 replies; 67+ messages in thread
From: Wang, Zhihong @ 2018-02-08  3:03 UTC (permalink / raw)
  To: Maxime Coquelin, dev
  Cc: Tan, Jianfeng, Bie, Tiwei, yliu, Liang, Cunming, Wang, Xiao W, Daly, Dan

Hi Maxime,

> -----Original Message-----
> From: Maxime Coquelin [mailto:maxime.coquelin@redhat.com]
> Sent: Tuesday, February 6, 2018 6:19 PM
> To: Wang, Zhihong <zhihong.wang@intel.com>; dev@dpdk.org
> Cc: Tan, Jianfeng <jianfeng.tan@intel.com>; Bie, Tiwei
> <tiwei.bie@intel.com>; yliu@fridaylinux.org; Liang, Cunming
> <cunming.liang@intel.com>; Wang, Xiao W <xiao.w.wang@intel.com>; Daly,
> Dan <dan.daly@intel.com>
> Subject: Re: [PATCH 1/7] vhost: make capabilities configurable
> 
> Hi Zhihong,
> 
...
> > +int rte_vhost_driver_set_queue_num(const char *path, uint16_t
> queue_num)
> > +{
> > +	struct vhost_user_socket *vsocket;
> > +
> > +	pthread_mutex_lock(&vhost_user.mutex);
> > +	vsocket = find_vhost_user_socket(path);
> > +	if (vsocket)
> > +		vsocket->queue_num = queue_num;
> 
> Shouldn't be MIN(queue_num, VHOST_MAX_QUEUE_PAIRS) to be sure you
> can
> switch from HW offload to SW processing?

Yes, the check is necessary.

> 
> > +	pthread_mutex_unlock(&vhost_user.mutex);
> > +
> > +	return vsocket ? 0 : -1;
> > +}
...
> > -static void
> > +static int
> >   vhost_user_set_protocol_features(struct virtio_net *dev,
> >   				 uint64_t protocol_features)
> >   {
> > -	if (protocol_features & ~VHOST_USER_PROTOCOL_FEATURES)
> 
> I think the above check is still necessary, or it should be checked
> in rte_vhost_driver_set_protocol_features().

Thanks. Yes I think all set capabilities should be contained in the
capabilities of the vhost-user lib.

Will update rte_vhost_driver_set_*().

-Zhihong

> 
> Indeed, the application shouldn't set a protocol feature bit that isn't
> supported by the libvhost-user library.
> 
> > -		return;
> > +	uint64_t vhost_protocol_features = 0;
> > +
> > +	rte_vhost_driver_get_protocol_features(dev->ifname,
> > +			&vhost_protocol_features);
> > +	if (protocol_features & ~vhost_protocol_features) {
> > +		RTE_LOG(ERR, VHOST_CONFIG,
> > +			"(%d) received invalid negotiated
> protocol_features.\n",
> > +			dev->vid);
> > +		return -1;
> > +	}
> >
> >   	dev->protocol_features = protocol_features;
> > +
> > +	return 0;
> >   }
> >
> >   static int
> > @@ -1391,7 +1416,8 @@ vhost_user_msg_handler(int vid, int fd)
> >   		break;
> >
> >   	case VHOST_USER_GET_PROTOCOL_FEATURES:
> > -		vhost_user_get_protocol_features(dev, &msg);
> > +		msg.payload.u64 = vhost_user_get_protocol_features(dev);
> > +		msg.size = sizeof(msg.payload.u64);
> >   		send_vhost_reply(fd, &msg);
> >   		break;
> >   	case VHOST_USER_SET_PROTOCOL_FEATURES:
> > @@ -1451,7 +1477,7 @@ vhost_user_msg_handler(int vid, int fd)
> >   		break;
> >
> >   	case VHOST_USER_GET_QUEUE_NUM:
> > -		msg.payload.u64 = VHOST_MAX_QUEUE_PAIRS;
> > +		msg.payload.u64 = vhost_user_get_queue_num(dev);
> >   		msg.size = sizeof(msg.payload.u64);
> >   		send_vhost_reply(fd, &msg);
> >   		break;
> >
> 
> Maxime

^ permalink raw reply	[flat|nested] 67+ messages in thread

* [PATCH v2 0/6] vhost: support selective datapath
  2018-02-02 23:28 [PATCH 0/7] vhost: support selective datapath Zhihong Wang
                   ` (6 preceding siblings ...)
  2018-02-02 23:28 ` [PATCH 7/7] vhost: export new apis Zhihong Wang
@ 2018-02-13  9:21 ` Zhihong Wang
  2018-02-13  9:21   ` [PATCH v2 1/6] vhost: export vhost feature definitions Zhihong Wang
                     ` (5 more replies)
  2018-02-27 10:13 ` [PATCH v3 0/5] vhost: support selective datapath Zhihong Wang
                   ` (2 subsequent siblings)
  10 siblings, 6 replies; 67+ messages in thread
From: Zhihong Wang @ 2018-02-13  9:21 UTC (permalink / raw)
  To: dev
  Cc: jianfeng.tan, tiwei.bie, maxime.coquelin, yliu, cunming.liang,
	xiao.w.wang, dan.daly, Zhihong Wang

This patch set introduces support for selective datapath in DPDK vhost-user
lib. vDPA stands for vhost Data Path Acceleration. The idea is to enable
various types of virtio-compatible devices to do data transfer with virtio
driver directly to enable acceleration.

The default datapath is the existing software implementation, more options
will be available when new engines are added.

Design details
====

An engine is a group of virtio-compatible devices. The definition of engine
is as follows:

struct rte_vdpa_eng_addr {
	union {
		uint8_t __dummy[64];
		struct rte_pci_addr pci_addr;
	};
};

struct rte_vdpa_eng_info {
	char name[MAX_VDPA_NAME_LEN];
	struct rte_vdpa_eng_addr *addr;
};

struct rte_vdpa_dev_ops {
	vdpa_dev_conf_t        dev_conf;
	vdpa_dev_close_t       dev_close;
	vdpa_vring_state_set_t vring_state_set;
	vdpa_feature_set_t     feature_set;
	vdpa_migration_done_t  migration_done;
	vdpa_get_vfio_group_fd_t  get_vfio_group_fd;
	vdpa_get_vfio_device_fd_t get_vfio_device_fd;
	vdpa_get_notify_area_t    get_notify_area;
};

struct rte_vdpa_eng_ops {
	vdpa_eng_init_t   eng_init;
	vdpa_eng_uninit_t eng_uninit;
	vdpa_info_query_t info_query;
};

struct rte_vdpa_eng_driver {
	const char *name;
	struct rte_vdpa_eng_ops eng_ops;
	struct rte_vdpa_dev_ops dev_ops;
} __rte_cache_aligned;

struct rte_vdpa_engine {
	struct rte_vdpa_eng_info    eng_info;
	struct rte_vdpa_eng_driver *eng_drv;
} __rte_cache_aligned;

A set of engine ops is defined in rte_vdpa_eng_ops for engine init, uninit,
and attributes reporting. The attributes are defined as follows:

struct rte_vdpa_eng_attr {
	uint64_t features;
	uint64_t protocol_features;
	uint32_t queue_num;
	uint32_t dev_num;
};

A set of device ops is defined in rte_vdpa_dev_ops for each virtio device
in the engine to do device specific operations.

Changes to the current vhost-user lib are:
====

 1. Make vhost device capabilities configurable to adopt various engines.
    Such capabilities include supported features, protocol features, queue
    number. APIs are introduced to let app configure these capabilities.

 2. In addition to the existing vhost framework, a set of callbacks is
    added for vhost to call the driver for device operations at the right
    time:

     a. dev_conf: Called to configure the actual device when the virtio
        device becomes ready.

     b. dev_close: Called to close the actual device when the virtio device
        is stopped.

     c. vring_state_set: Called to change the state of the vring in the
        actual device when vring state changes.

     d. feature_set: Called to set the negotiated features to device.

     e. migration_done: Called to allow the device to response to RARP
        sending.

     f. get_vfio_group_fd: Called to get the VFIO group fd of the device.

     g. get_vfio_device_fd: Called to get the VFIO device fd of the device.

     h. get_notify_area: Called to get the notify area info of the queue.

 3. To make vhost aware of its own type, an engine id (eid) and a device
    id (did) are added into the vhost data structure to identify the actual
    device. APIs are introduced to let app configure them. When the default
    software datapath is used, eid and did are set to -1. When alternative
    datapath is used, eid and did are set by app to specify which device to
    use. Each vhost-user socket can have only 1 connection in this case.

Working process:
====

 1. Register driver during DPDK initialization.

 2. Register engine with driver name and address.

 3. Get engine attributes.

 4. For vhost device creation:

      a. Register vhost-user socket.

      b. Set eid and did of the vhost-user socket.

      c. Register vhost-user callbacks.

      d. Start to wait for connection.

 4. When connection comes and virtio device data structure is negotiated,
    the device will be configured with all needed info.

---
Changes in v2:

 1. Ensure negotiated capabilities are supported in vhost-user lib.

 2. Add APIs for live migration.

 3. Configure the data path at the right time.

 4. Add VFIO related vDPA device ops.

 5. Rebase on dpdk-next-virtio.

Zhihong Wang (6):
  vhost: export vhost feature definitions
  vhost: support selective datapath
  vhost: add apis for datapath configuration
  vhost: adapt vhost lib for selective datapath
  vhost: add apis for live migration
  vhost: export new apis

 lib/librte_vhost/Makefile              |   4 +-
 lib/librte_vhost/rte_vdpa.h            | 126 ++++++++++++++++++++++++++
 lib/librte_vhost/rte_vhost.h           | 157 +++++++++++++++++++++++++++++++++
 lib/librte_vhost/rte_vhost_version.map |  19 ++++
 lib/librte_vhost/socket.c              | 141 ++++++++++++++++++++++++++++-
 lib/librte_vhost/vdpa.c                | 124 ++++++++++++++++++++++++++
 lib/librte_vhost/vhost.c               | 116 ++++++++++++++++++++++++
 lib/librte_vhost/vhost.h               |  16 +++-
 lib/librte_vhost/vhost_user.c          |  65 +++++++++++---
 lib/librte_vhost/vhost_user.h          |  20 ++---
 10 files changed, 758 insertions(+), 30 deletions(-)
 create mode 100644 lib/librte_vhost/rte_vdpa.h
 create mode 100644 lib/librte_vhost/vdpa.c

-- 
2.13.6

^ permalink raw reply	[flat|nested] 67+ messages in thread

* [PATCH v2 1/6] vhost: export vhost feature definitions
  2018-02-13  9:21 ` [PATCH v2 0/6] vhost: support selective datapath Zhihong Wang
@ 2018-02-13  9:21   ` Zhihong Wang
  2018-03-06  9:37     ` Tan, Jianfeng
  2018-02-13  9:21   ` [PATCH v2 2/6] vhost: support selective datapath Zhihong Wang
                     ` (4 subsequent siblings)
  5 siblings, 1 reply; 67+ messages in thread
From: Zhihong Wang @ 2018-02-13  9:21 UTC (permalink / raw)
  To: dev
  Cc: jianfeng.tan, tiwei.bie, maxime.coquelin, yliu, cunming.liang,
	xiao.w.wang, dan.daly, Zhihong Wang

This patch exports vhost-user protocol features to support device driver
development.

Signed-off-by: Zhihong Wang <zhihong.wang@intel.com>
---
 lib/librte_vhost/rte_vhost.h  |  8 ++++++++
 lib/librte_vhost/vhost.h      |  4 +---
 lib/librte_vhost/vhost_user.c |  9 +++++----
 lib/librte_vhost/vhost_user.h | 20 +++++++-------------
 4 files changed, 21 insertions(+), 20 deletions(-)

diff --git a/lib/librte_vhost/rte_vhost.h b/lib/librte_vhost/rte_vhost.h
index d33206997..b05162366 100644
--- a/lib/librte_vhost/rte_vhost.h
+++ b/lib/librte_vhost/rte_vhost.h
@@ -29,6 +29,14 @@ extern "C" {
 #define RTE_VHOST_USER_DEQUEUE_ZERO_COPY	(1ULL << 2)
 #define RTE_VHOST_USER_IOMMU_SUPPORT	(1ULL << 3)
 
+#define RTE_VHOST_USER_PROTOCOL_F_MQ		0
+#define RTE_VHOST_USER_PROTOCOL_F_LOG_SHMFD	1
+#define RTE_VHOST_USER_PROTOCOL_F_RARP		2
+#define RTE_VHOST_USER_PROTOCOL_F_REPLY_ACK	3
+#define RTE_VHOST_USER_PROTOCOL_F_NET_MTU	4
+#define RTE_VHOST_USER_PROTOCOL_F_SLAVE_REQ	5
+#define RTE_VHOST_USER_F_PROTOCOL_FEATURES	30
+
 /**
  * Information relating to memory regions including offsets to
  * addresses in QEMUs memory file.
diff --git a/lib/librte_vhost/vhost.h b/lib/librte_vhost/vhost.h
index 58aec2e0d..a0b0520e2 100644
--- a/lib/librte_vhost/vhost.h
+++ b/lib/librte_vhost/vhost.h
@@ -174,8 +174,6 @@ struct vhost_msg {
  #define VIRTIO_F_VERSION_1 32
 #endif
 
-#define VHOST_USER_F_PROTOCOL_FEATURES	30
-
 /* Features supported by this builtin vhost-user net driver. */
 #define VIRTIO_NET_SUPPORTED_FEATURES ((1ULL << VIRTIO_NET_F_MRG_RXBUF) | \
 				(1ULL << VIRTIO_F_ANY_LAYOUT) | \
@@ -185,7 +183,7 @@ struct vhost_msg {
 				(1ULL << VIRTIO_NET_F_MQ)      | \
 				(1ULL << VIRTIO_F_VERSION_1)   | \
 				(1ULL << VHOST_F_LOG_ALL)      | \
-				(1ULL << VHOST_USER_F_PROTOCOL_FEATURES) | \
+				(1ULL << RTE_VHOST_USER_F_PROTOCOL_FEATURES) | \
 				(1ULL << VIRTIO_NET_F_GSO) | \
 				(1ULL << VIRTIO_NET_F_HOST_TSO4) | \
 				(1ULL << VIRTIO_NET_F_HOST_TSO6) | \
diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c
index 5c5361066..c93e48e4d 100644
--- a/lib/librte_vhost/vhost_user.c
+++ b/lib/librte_vhost/vhost_user.c
@@ -527,7 +527,7 @@ vhost_user_set_vring_addr(struct virtio_net **pdev, VhostUserMsg *msg)
 	vring_invalidate(dev, vq);
 
 	if (vq->enabled && (dev->features &
-				(1ULL << VHOST_USER_F_PROTOCOL_FEATURES))) {
+				(1ULL << RTE_VHOST_USER_F_PROTOCOL_FEATURES))) {
 		dev = translate_ring_addresses(dev, msg->payload.addr.index);
 		if (!dev)
 			return -1;
@@ -897,11 +897,11 @@ vhost_user_set_vring_kick(struct virtio_net **pdev, struct VhostUserMsg *pmsg)
 	vq = dev->virtqueue[file.index];
 
 	/*
-	 * When VHOST_USER_F_PROTOCOL_FEATURES is not negotiated,
+	 * When RTE_VHOST_USER_F_PROTOCOL_FEATURES is not negotiated,
 	 * the ring starts already enabled. Otherwise, it is enabled via
 	 * the SET_VRING_ENABLE message.
 	 */
-	if (!(dev->features & (1ULL << VHOST_USER_F_PROTOCOL_FEATURES)))
+	if (!(dev->features & (1ULL << RTE_VHOST_USER_F_PROTOCOL_FEATURES)))
 		vq->enabled = 1;
 
 	if (vq->kickfd >= 0)
@@ -1012,7 +1012,8 @@ vhost_user_get_protocol_features(struct virtio_net *dev,
 	 * Qemu versions (from v2.7.0 to v2.9.0).
 	 */
 	if (!(features & (1ULL << VIRTIO_F_IOMMU_PLATFORM)))
-		protocol_features &= ~(1ULL << VHOST_USER_PROTOCOL_F_REPLY_ACK);
+		protocol_features &=
+			~(1ULL << RTE_VHOST_USER_PROTOCOL_F_REPLY_ACK);
 
 	msg->payload.u64 = protocol_features;
 	msg->size = sizeof(msg->payload.u64);
diff --git a/lib/librte_vhost/vhost_user.h b/lib/librte_vhost/vhost_user.h
index 0fafbe6e0..066e772dd 100644
--- a/lib/librte_vhost/vhost_user.h
+++ b/lib/librte_vhost/vhost_user.h
@@ -14,19 +14,13 @@
 
 #define VHOST_MEMORY_MAX_NREGIONS 8
 
-#define VHOST_USER_PROTOCOL_F_MQ	0
-#define VHOST_USER_PROTOCOL_F_LOG_SHMFD	1
-#define VHOST_USER_PROTOCOL_F_RARP	2
-#define VHOST_USER_PROTOCOL_F_REPLY_ACK	3
-#define VHOST_USER_PROTOCOL_F_NET_MTU 4
-#define VHOST_USER_PROTOCOL_F_SLAVE_REQ 5
-
-#define VHOST_USER_PROTOCOL_FEATURES	((1ULL << VHOST_USER_PROTOCOL_F_MQ) | \
-					 (1ULL << VHOST_USER_PROTOCOL_F_LOG_SHMFD) |\
-					 (1ULL << VHOST_USER_PROTOCOL_F_RARP) | \
-					 (1ULL << VHOST_USER_PROTOCOL_F_REPLY_ACK) | \
-					 (1ULL << VHOST_USER_PROTOCOL_F_NET_MTU) | \
-					 (1ULL << VHOST_USER_PROTOCOL_F_SLAVE_REQ))
+#define VHOST_USER_PROTOCOL_FEATURES \
+			((1ULL << RTE_VHOST_USER_PROTOCOL_F_MQ) | \
+			 (1ULL << RTE_VHOST_USER_PROTOCOL_F_LOG_SHMFD) |\
+			 (1ULL << RTE_VHOST_USER_PROTOCOL_F_RARP) | \
+			 (1ULL << RTE_VHOST_USER_PROTOCOL_F_REPLY_ACK) | \
+			 (1ULL << RTE_VHOST_USER_PROTOCOL_F_NET_MTU) | \
+			 (1ULL << RTE_VHOST_USER_PROTOCOL_F_SLAVE_REQ))
 
 typedef enum VhostUserRequest {
 	VHOST_USER_NONE = 0,
-- 
2.13.6

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v2 2/6] vhost: support selective datapath
  2018-02-13  9:21 ` [PATCH v2 0/6] vhost: support selective datapath Zhihong Wang
  2018-02-13  9:21   ` [PATCH v2 1/6] vhost: export vhost feature definitions Zhihong Wang
@ 2018-02-13  9:21   ` Zhihong Wang
  2018-02-13  9:21   ` [PATCH v2 3/6] vhost: add apis for datapath configuration Zhihong Wang
                     ` (3 subsequent siblings)
  5 siblings, 0 replies; 67+ messages in thread
From: Zhihong Wang @ 2018-02-13  9:21 UTC (permalink / raw)
  To: dev
  Cc: jianfeng.tan, tiwei.bie, maxime.coquelin, yliu, cunming.liang,
	xiao.w.wang, dan.daly, Zhihong Wang

This patch introduces support for selective datapath in DPDK vhost-user lib
to enable various types of virtio-compatible devices to do data transfer
with virtio driver directly to enable acceleration. The default datapath is
the existing software implementation, more options will be available when
new engines are registered.

An engine is a group of virtio-compatible devices under a single address.
The engine driver includes:

 1. A set of engine ops is defined in rte_vdpa_eng_ops to perform engine
    init, uninit, and attributes reporting.
    
 2. A set of device ops is defined in rte_vdpa_dev_ops for virtio devices
    in the engine to do device specific operations:

     a. dev_conf: Called to configure the actual device when the virtio
        device becomes ready.

     b. dev_close: Called to close the actual device when the virtio device
        is stopped.

     c. vring_state_set: Called to change the state of the vring in the
        actual device when vring state changes.

     d. feature_set: Called to set the negotiated features to device.

     e. migration_done: Called to allow the device to response to RARP
        sending.

     f. get_vfio_group_fd: Called to get the VFIO group fd of the device.

     g. get_vfio_device_fd: Called to get the VFIO device fd of the device.

     h. get_notify_area: Called to get the notify area info of the queue.

Signed-off-by: Zhihong Wang <zhihong.wang@intel.com>
---
Changes in v2:

 1. Add VFIO related vDPA device ops.

 lib/librte_vhost/Makefile   |   4 +-
 lib/librte_vhost/rte_vdpa.h | 120 ++++++++++++++++++++++++++++++++++++++++++
 lib/librte_vhost/vdpa.c     | 124 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 246 insertions(+), 2 deletions(-)
 create mode 100644 lib/librte_vhost/rte_vdpa.h
 create mode 100644 lib/librte_vhost/vdpa.c

diff --git a/lib/librte_vhost/Makefile b/lib/librte_vhost/Makefile
index 5d6c6abae..37044ac03 100644
--- a/lib/librte_vhost/Makefile
+++ b/lib/librte_vhost/Makefile
@@ -22,9 +22,9 @@ LDLIBS += -lrte_eal -lrte_mempool -lrte_mbuf -lrte_ethdev -lrte_net
 
 # all source are stored in SRCS-y
 SRCS-$(CONFIG_RTE_LIBRTE_VHOST) := fd_man.c iotlb.c socket.c vhost.c \
-					vhost_user.c virtio_net.c
+					vhost_user.c virtio_net.c vdpa.c
 
 # install includes
-SYMLINK-$(CONFIG_RTE_LIBRTE_VHOST)-include += rte_vhost.h
+SYMLINK-$(CONFIG_RTE_LIBRTE_VHOST)-include += rte_vhost.h rte_vdpa.h
 
 include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/lib/librte_vhost/rte_vdpa.h b/lib/librte_vhost/rte_vdpa.h
new file mode 100644
index 000000000..1bde36f7f
--- /dev/null
+++ b/lib/librte_vhost/rte_vdpa.h
@@ -0,0 +1,120 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Intel Corporation
+ */
+
+#ifndef _RTE_VDPA_H_
+#define _RTE_VDPA_H_
+
+/**
+ * @file
+ *
+ * Device specific vhost lib
+ */
+
+#include <rte_pci.h>
+#include "rte_vhost.h"
+
+#define MAX_VDPA_ENGINE_NUM 128
+#define MAX_VDPA_NAME_LEN 128
+
+struct rte_vdpa_eng_addr {
+	union {
+		uint8_t __dummy[64];
+		struct rte_pci_addr pci_addr;
+	};
+};
+
+struct rte_vdpa_eng_info {
+	struct rte_vdpa_eng_addr *addr;
+	char name[MAX_VDPA_NAME_LEN];
+};
+
+struct rte_vdpa_eng_attr {
+	uint64_t features;
+	uint64_t protocol_features;
+	uint32_t queue_num;
+	uint32_t dev_num;
+};
+
+/* register/remove engine */
+typedef int (*vdpa_eng_init_t)(int eid, struct rte_vdpa_eng_addr *addr);
+typedef int (*vdpa_eng_uninit_t)(int eid);
+
+/* query info of this engine */
+typedef int (*vdpa_info_query_t)(int eid,
+		struct rte_vdpa_eng_attr *attr);
+
+/* driver configure/close the port based on connection */
+typedef int (*vdpa_dev_conf_t)(int vid);
+typedef int (*vdpa_dev_close_t)(int vid);
+
+/* enable/disable this vring */
+typedef int (*vdpa_vring_state_set_t)(int vid, int vring, int state);
+
+/* set features when changed */
+typedef int (*vdpa_feature_set_t)(int vid);
+
+/* destination operations when migration done, e.g. send rarp */
+typedef int (*vdpa_migration_done_t)(int vid);
+
+/* get the vfio group fd */
+typedef int (*vdpa_get_vfio_group_fd_t)(int vid);
+
+/* get the vfio device fd */
+typedef int (*vdpa_get_vfio_device_fd_t)(int vid);
+
+/* get the notify area info of the queue */
+typedef int (*vdpa_get_notify_area_t)(int vid, int qid, uint64_t *offset,
+		uint64_t *size);
+/* device ops */
+struct rte_vdpa_dev_ops {
+	vdpa_dev_conf_t           dev_conf;
+	vdpa_dev_close_t          dev_close;
+	vdpa_vring_state_set_t    vring_state_set;
+	vdpa_feature_set_t        feature_set;
+	vdpa_migration_done_t     migration_done;
+	vdpa_get_vfio_group_fd_t  get_vfio_group_fd;
+	vdpa_get_vfio_device_fd_t get_vfio_device_fd;
+	vdpa_get_notify_area_t    get_notify_area;
+};
+
+/* engine ops */
+struct rte_vdpa_eng_ops {
+	vdpa_eng_init_t eng_init;
+	vdpa_eng_uninit_t eng_uninit;
+	vdpa_info_query_t info_query;
+};
+
+struct rte_vdpa_eng_driver {
+	struct rte_vdpa_eng_ops eng_ops;
+	struct rte_vdpa_dev_ops dev_ops;
+	const char *name;
+} __rte_cache_aligned;
+
+struct rte_vdpa_engine {
+	struct rte_vdpa_eng_info eng_info;
+	struct rte_vdpa_eng_driver *eng_drv;
+} __rte_cache_aligned;
+
+extern struct rte_vdpa_engine *vdpa_engines[];
+extern uint32_t vdpa_engine_num;
+
+/* engine management */
+int rte_vdpa_register_engine(const char *name, struct rte_vdpa_eng_addr *addr);
+int rte_vdpa_unregister_engine(int eid);
+
+int rte_vdpa_find_engine_id(struct rte_vdpa_eng_addr *addr);
+
+int rte_vdpa_info_query(int eid, struct rte_vdpa_eng_attr *attr);
+
+/* driver register api */
+void rte_vdpa_register_driver(struct rte_vdpa_eng_driver *drv);
+
+#define RTE_VDPA_REGISTER_DRIVER(nm, drv) \
+RTE_INIT(vdpainitfn_ ##nm); \
+static void vdpainitfn_ ##nm(void) \
+{ \
+	rte_vdpa_register_driver(&drv); \
+} \
+
+#endif /* _RTE_VDPA_H_ */
diff --git a/lib/librte_vhost/vdpa.c b/lib/librte_vhost/vdpa.c
new file mode 100644
index 000000000..5d5ffe147
--- /dev/null
+++ b/lib/librte_vhost/vdpa.c
@@ -0,0 +1,124 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Intel Corporation
+ */
+
+/**
+ * @file
+ *
+ * Device specific vhost lib
+ */
+
+#include <stdbool.h>
+
+#include <rte_malloc.h>
+#include "rte_vdpa.h"
+#include "vhost.h"
+
+static struct rte_vdpa_eng_driver *vdpa_drivers[MAX_VDPA_ENGINE_NUM];
+static uint32_t vdpa_driver_num;
+
+struct rte_vdpa_engine *vdpa_engines[MAX_VDPA_ENGINE_NUM];
+uint32_t vdpa_engine_num;
+
+static int is_same_eng(struct rte_vdpa_eng_addr *a, struct rte_vdpa_eng_addr *b)
+{
+	if (a->pci_addr.domain != b->pci_addr.domain ||
+			a->pci_addr.bus != b->pci_addr.bus ||
+			a->pci_addr.devid != b->pci_addr.devid ||
+			a->pci_addr.function != b->pci_addr.function)
+		return -1;
+
+	return 0;
+}
+
+void rte_vdpa_register_driver(struct rte_vdpa_eng_driver *driver)
+{
+	if (vdpa_driver_num >= MAX_VDPA_ENGINE_NUM)
+		return;
+
+	vdpa_drivers[vdpa_driver_num] = driver;
+	vdpa_driver_num++;
+}
+
+int rte_vdpa_register_engine(const char *name, struct rte_vdpa_eng_addr *addr)
+{
+	static int engine_idx;
+
+	struct rte_vdpa_engine *eng;
+	struct rte_vdpa_eng_driver *cur;
+	char engine_name[MAX_VDPA_NAME_LEN];
+	int i;
+
+	for (i = 0; i < MAX_VDPA_ENGINE_NUM; ++i) {
+		eng = vdpa_engines[i];
+		if (eng && is_same_eng(eng->eng_info.addr, addr) == 0)
+			return i;
+	}
+
+	sprintf(engine_name, "vdpa-%s-%d", name, engine_idx++);
+	eng = rte_zmalloc(engine_name, sizeof(struct rte_vdpa_engine),
+			RTE_CACHE_LINE_SIZE);
+	if (!eng)
+		return -1;
+
+	for (i = 0; i < MAX_VDPA_ENGINE_NUM; ++i) {
+		cur = vdpa_drivers[i];
+		if (cur && 0 == strncmp(name, cur->name,
+					MAX_VDPA_NAME_LEN)) {
+			eng->eng_drv = cur;
+			strcpy(eng->eng_info.name, name);
+			eng->eng_info.addr = addr;
+			for (i = 0; i < MAX_VDPA_ENGINE_NUM; ++i) {
+				if (vdpa_engines[i])
+					continue;
+				vdpa_engines[i] = eng;
+				if (eng->eng_drv->eng_ops.eng_init)
+					eng->eng_drv->eng_ops.eng_init(i, addr);
+				vdpa_engine_num++;
+				return i;
+			}
+		}
+	}
+
+	return -1;
+}
+
+int rte_vdpa_unregister_engine(int eid)
+{
+	if (eid < 0 || eid >= MAX_VDPA_ENGINE_NUM || vdpa_engines[eid]
+			== NULL)
+		return -1;
+
+	if (vdpa_engines[eid]->eng_drv->eng_ops.eng_uninit)
+		vdpa_engines[eid]->eng_drv->eng_ops.eng_uninit(eid);
+
+	rte_free(vdpa_engines[eid]);
+	vdpa_engines[eid] = NULL;
+	vdpa_engine_num--;
+
+	return eid;
+}
+
+int rte_vdpa_find_engine_id(struct rte_vdpa_eng_addr *addr)
+{
+	struct rte_vdpa_engine *eng;
+	int i;
+
+	for (i = 0; i < MAX_VDPA_ENGINE_NUM; ++i) {
+		eng = vdpa_engines[i];
+		if (eng && is_same_eng(eng->eng_info.addr, addr) == 0)
+			return i;
+	}
+
+	return -1;
+}
+
+int rte_vdpa_info_query(int eid, struct rte_vdpa_eng_attr *attr)
+{
+	if (eid < 0 || eid >= MAX_VDPA_ENGINE_NUM ||
+			vdpa_engines[eid] == NULL ||
+			vdpa_engines[eid]->eng_drv->eng_ops.info_query == NULL)
+		return -1;
+
+	return vdpa_engines[eid]->eng_drv->eng_ops.info_query(eid, attr);
+}
-- 
2.13.6

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v2 3/6] vhost: add apis for datapath configuration
  2018-02-13  9:21 ` [PATCH v2 0/6] vhost: support selective datapath Zhihong Wang
  2018-02-13  9:21   ` [PATCH v2 1/6] vhost: export vhost feature definitions Zhihong Wang
  2018-02-13  9:21   ` [PATCH v2 2/6] vhost: support selective datapath Zhihong Wang
@ 2018-02-13  9:21   ` Zhihong Wang
  2018-02-13  9:21   ` [PATCH v2 4/6] vhost: adapt vhost lib for selective datapath Zhihong Wang
                     ` (2 subsequent siblings)
  5 siblings, 0 replies; 67+ messages in thread
From: Zhihong Wang @ 2018-02-13  9:21 UTC (permalink / raw)
  To: dev
  Cc: jianfeng.tan, tiwei.bie, maxime.coquelin, yliu, cunming.liang,
	xiao.w.wang, dan.daly, Zhihong Wang

This patch adds APIs for datapath configuration. The eid and did of the
vhost-user socket can be configured to identify the actual device.

When the default software datapath is used, eid and did are set to -1.
When alternative datapath is used, eid and did are set by app to specify
which device to use. Each vhost-user socket can have only 1 connection in
this case.

Signed-off-by: Zhihong Wang <zhihong.wang@intel.com>
---
 lib/librte_vhost/rte_vhost.h | 64 +++++++++++++++++++++++++++++++++++++++++++
 lib/librte_vhost/socket.c    | 65 ++++++++++++++++++++++++++++++++++++++++++++
 lib/librte_vhost/vhost.c     | 50 ++++++++++++++++++++++++++++++++++
 lib/librte_vhost/vhost.h     | 10 +++++++
 4 files changed, 189 insertions(+)

diff --git a/lib/librte_vhost/rte_vhost.h b/lib/librte_vhost/rte_vhost.h
index b05162366..a76acea6b 100644
--- a/lib/librte_vhost/rte_vhost.h
+++ b/lib/librte_vhost/rte_vhost.h
@@ -178,6 +178,50 @@ int rte_vhost_driver_register(const char *path, uint64_t flags);
 int rte_vhost_driver_unregister(const char *path);
 
 /**
+ * Set the engine id, enforce single connection per socket
+ *
+ * @param path
+ *  The vhost-user socket file path
+ * @param eid
+ *  Engine id
+ * @return
+ *  0 on success, -1 on failure
+ */
+int rte_vhost_driver_set_vdpa_eid(const char *path, int eid);
+
+/**
+ * Set the device id, enforce single connection per socket
+ *
+ * @param path
+ *  The vhost-user socket file path
+ * @param did
+ *  Device id
+ * @return
+ *  0 on success, -1 on failure
+ */
+int rte_vhost_driver_set_vdpa_did(const char *path, int did);
+
+/**
+ * Get the engine id
+ *
+ * @param path
+ *  The vhost-user socket file path
+ * @return
+ *  Engine id, -1 on failure
+ */
+int rte_vhost_driver_get_vdpa_eid(const char *path);
+
+/**
+ * Get the device id
+ *
+ * @param path
+ *  The vhost-user socket file path
+ * @return
+ *  Device id, -1 on failure
+ */
+int rte_vhost_driver_get_vdpa_did(const char *path);
+
+/**
  * Set the feature bits the vhost-user driver supports.
  *
  * @param path
@@ -442,6 +486,26 @@ int rte_vhost_vring_call(int vid, uint16_t vring_idx);
  */
 uint32_t rte_vhost_rx_queue_count(int vid, uint16_t qid);
 
+/**
+ * Get vdpa engine id for vhost device.
+ *
+ * @param vid
+ *  vhost device ID
+ * @return
+ *  engine id
+ */
+int rte_vhost_get_vdpa_eid(int vid);
+
+/**
+ * Get vdpa device id for vhost device.
+ *
+ * @param vid
+ *  vhost device ID
+ * @return
+ *  device id
+ */
+int rte_vhost_get_vdpa_did(int vid);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/librte_vhost/socket.c b/lib/librte_vhost/socket.c
index 6ba60f5dc..5367ba771 100644
--- a/lib/librte_vhost/socket.c
+++ b/lib/librte_vhost/socket.c
@@ -52,6 +52,13 @@ struct vhost_user_socket {
 	uint64_t supported_features;
 	uint64_t features;
 
+	/* engine and device id to identify a certain port on a specific
+	 * backend, both are set to -1 for sw. when used, one socket can
+	 * have 1 connection only.
+	 */
+	int eid;
+	int did;
+
 	struct vhost_device_ops const *notify_ops;
 };
 
@@ -535,6 +542,64 @@ find_vhost_user_socket(const char *path)
 }
 
 int
+rte_vhost_driver_set_vdpa_eid(const char *path, int eid)
+{
+	struct vhost_user_socket *vsocket;
+
+	pthread_mutex_lock(&vhost_user.mutex);
+	vsocket = find_vhost_user_socket(path);
+	if (vsocket)
+		vsocket->eid = eid;
+	pthread_mutex_unlock(&vhost_user.mutex);
+
+	return vsocket ? 0 : -1;
+}
+
+int
+rte_vhost_driver_set_vdpa_did(const char *path, int did)
+{
+	struct vhost_user_socket *vsocket;
+
+	pthread_mutex_lock(&vhost_user.mutex);
+	vsocket = find_vhost_user_socket(path);
+	if (vsocket)
+		vsocket->did = did;
+	pthread_mutex_unlock(&vhost_user.mutex);
+
+	return vsocket ? 0 : -1;
+}
+
+int
+rte_vhost_driver_get_vdpa_eid(const char *path)
+{
+	struct vhost_user_socket *vsocket;
+	int eid = -1;
+
+	pthread_mutex_lock(&vhost_user.mutex);
+	vsocket = find_vhost_user_socket(path);
+	if (vsocket)
+		eid = vsocket->eid;
+	pthread_mutex_unlock(&vhost_user.mutex);
+
+	return eid;
+}
+
+int
+rte_vhost_driver_get_vdpa_did(const char *path)
+{
+	struct vhost_user_socket *vsocket;
+	int did = -1;
+
+	pthread_mutex_lock(&vhost_user.mutex);
+	vsocket = find_vhost_user_socket(path);
+	if (vsocket)
+		did = vsocket->did;
+	pthread_mutex_unlock(&vhost_user.mutex);
+
+	return did;
+}
+
+int
 rte_vhost_driver_disable_features(const char *path, uint64_t features)
 {
 	struct vhost_user_socket *vsocket;
diff --git a/lib/librte_vhost/vhost.c b/lib/librte_vhost/vhost.c
index f6f12a03b..45cf90f99 100644
--- a/lib/librte_vhost/vhost.c
+++ b/lib/librte_vhost/vhost.c
@@ -283,6 +283,8 @@ vhost_new_device(void)
 	dev->vid = i;
 	dev->flags = VIRTIO_DEV_BUILTIN_VIRTIO_NET;
 	dev->slave_req_fd = -1;
+	dev->eid = -1;
+	dev->did = -1;
 
 	return i;
 }
@@ -311,6 +313,34 @@ vhost_destroy_device(int vid)
 }
 
 void
+vhost_set_vdpa_eid(int vid, int eid)
+{
+	struct virtio_net *dev = get_device(vid);
+
+	if (eid < 0 || eid >= MAX_VDPA_ENGINE_NUM || vdpa_engines[eid] == NULL)
+		return;
+
+	if (dev == NULL)
+		return;
+
+	dev->eid = eid;
+}
+
+void
+vhost_set_vdpa_did(int vid, int did)
+{
+	struct virtio_net *dev = get_device(vid);
+
+	if (did < 0)
+		return;
+
+	if (dev == NULL)
+		return;
+
+	dev->did = did;
+}
+
+void
 vhost_set_ifname(int vid, const char *if_name, unsigned int if_len)
 {
 	struct virtio_net *dev;
@@ -614,3 +644,23 @@ rte_vhost_rx_queue_count(int vid, uint16_t qid)
 
 	return *((volatile uint16_t *)&vq->avail->idx) - vq->last_avail_idx;
 }
+
+int rte_vhost_get_vdpa_eid(int vid)
+{
+	struct virtio_net *dev = get_device(vid);
+
+	if (dev == NULL)
+		return -1;
+
+	return dev->eid;
+}
+
+int rte_vhost_get_vdpa_did(int vid)
+{
+	struct virtio_net *dev = get_device(vid);
+
+	if (dev == NULL)
+		return -1;
+
+	return dev->did;
+}
diff --git a/lib/librte_vhost/vhost.h b/lib/librte_vhost/vhost.h
index a0b0520e2..b3fa6da03 100644
--- a/lib/librte_vhost/vhost.h
+++ b/lib/librte_vhost/vhost.h
@@ -19,6 +19,7 @@
 #include <rte_rwlock.h>
 
 #include "rte_vhost.h"
+#include "rte_vdpa.h"
 
 /* Used to indicate that the device is running on a data core */
 #define VIRTIO_DEV_RUNNING 1
@@ -239,6 +240,12 @@ struct virtio_net {
 	struct guest_page       *guest_pages;
 
 	int			slave_req_fd;
+
+	/* engine and device id to identify a certain port on a specific
+	 * backend, both are set to -1 for sw.
+	 */
+	int			eid;
+	int			did;
 } __rte_cache_aligned;
 
 
@@ -365,6 +372,9 @@ void free_vq(struct vhost_virtqueue *vq);
 
 int alloc_vring_queue(struct virtio_net *dev, uint32_t vring_idx);
 
+void vhost_set_vdpa_eid(int vid, int eid);
+void vhost_set_vdpa_did(int vid, int did);
+
 void vhost_set_ifname(int, const char *if_name, unsigned int if_len);
 void vhost_enable_dequeue_zero_copy(int vid);
 void vhost_set_builtin_virtio_net(int vid, bool enable);
-- 
2.13.6

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v2 4/6] vhost: adapt vhost lib for selective datapath
  2018-02-13  9:21 ` [PATCH v2 0/6] vhost: support selective datapath Zhihong Wang
                     ` (2 preceding siblings ...)
  2018-02-13  9:21   ` [PATCH v2 3/6] vhost: add apis for datapath configuration Zhihong Wang
@ 2018-02-13  9:21   ` Zhihong Wang
  2018-02-13  9:21   ` [PATCH v2 5/6] vhost: add apis for live migration Zhihong Wang
  2018-02-13  9:21   ` [PATCH v2 6/6] vhost: export new apis Zhihong Wang
  5 siblings, 0 replies; 67+ messages in thread
From: Zhihong Wang @ 2018-02-13  9:21 UTC (permalink / raw)
  To: dev
  Cc: jianfeng.tan, tiwei.bie, maxime.coquelin, yliu, cunming.liang,
	xiao.w.wang, dan.daly, Zhihong Wang

This patch adapts vhost lib for selective datapath by calling device ops
at the corresponding stage.

Signed-off-by: Zhihong Wang <zhihong.wang@intel.com>
---
Changes in v2:

 1. Ensure negotiated capabilities are supported in vhost-user lib.

 2. Configure the data path at the right time.

 lib/librte_vhost/rte_vhost.h  | 25 ++++++++++++++
 lib/librte_vhost/socket.c     | 76 +++++++++++++++++++++++++++++++++++++++++--
 lib/librte_vhost/vhost.c      |  3 ++
 lib/librte_vhost/vhost.h      |  2 ++
 lib/librte_vhost/vhost_user.c | 56 +++++++++++++++++++++++++++----
 5 files changed, 154 insertions(+), 8 deletions(-)

diff --git a/lib/librte_vhost/rte_vhost.h b/lib/librte_vhost/rte_vhost.h
index a76acea6b..9bec36756 100644
--- a/lib/librte_vhost/rte_vhost.h
+++ b/lib/librte_vhost/rte_vhost.h
@@ -277,6 +277,31 @@ int rte_vhost_driver_disable_features(const char *path, uint64_t features);
 int rte_vhost_driver_get_features(const char *path, uint64_t *features);
 
 /**
+ * Get the protocol feature bits before feature negotiation.
+ *
+ * @param path
+ *  The vhost-user socket file path
+ * @param protocol_features
+ *  A pointer to store the queried protocol feature bits
+ * @return
+ *  0 on success, -1 on failure
+ */
+int rte_vhost_driver_get_protocol_features(const char *path,
+		uint64_t *protocol_features);
+
+/**
+ * Get the queue number bits before feature negotiation.
+ *
+ * @param path
+ *  The vhost-user socket file path
+ * @param queue_num
+ *  A pointer to store the queried queue number bits
+ * @return
+ *  0 on success, -1 on failure
+ */
+int rte_vhost_driver_get_queue_num(const char *path, uint32_t *queue_num);
+
+/**
  * Get the feature bits after negotiation
  *
  * @param vid
diff --git a/lib/librte_vhost/socket.c b/lib/librte_vhost/socket.c
index 5367ba771..0354740fa 100644
--- a/lib/librte_vhost/socket.c
+++ b/lib/librte_vhost/socket.c
@@ -216,6 +216,9 @@ vhost_user_add_connection(int fd, struct vhost_user_socket *vsocket)
 
 	vhost_set_builtin_virtio_net(vid, vsocket->use_builtin_virtio_net);
 
+	vhost_set_vdpa_eid(vid, vsocket->eid);
+	vhost_set_vdpa_did(vid, vsocket->did);
+
 	if (vsocket->dequeue_zero_copy)
 		vhost_enable_dequeue_zero_copy(vid);
 
@@ -667,11 +670,80 @@ int
 rte_vhost_driver_get_features(const char *path, uint64_t *features)
 {
 	struct vhost_user_socket *vsocket;
+	struct rte_vdpa_eng_attr attr;
+	int eid = -1;
 
 	pthread_mutex_lock(&vhost_user.mutex);
 	vsocket = find_vhost_user_socket(path);
-	if (vsocket)
-		*features = vsocket->features;
+	if (vsocket) {
+		eid = vsocket->eid;
+		if (rte_vdpa_info_query(eid, &attr) < 0)
+			*features = vsocket->features;
+		else
+			*features = vsocket->features & attr.features;
+
+	}
+	pthread_mutex_unlock(&vhost_user.mutex);
+
+	if (!vsocket) {
+		RTE_LOG(ERR, VHOST_CONFIG,
+			"socket file %s is not registered yet.\n", path);
+		return -1;
+	} else {
+		return 0;
+	}
+}
+
+int
+rte_vhost_driver_get_protocol_features(const char *path,
+		uint64_t *protocol_features)
+{
+	struct vhost_user_socket *vsocket;
+	struct rte_vdpa_eng_attr attr;
+	int eid = -1;
+
+	pthread_mutex_lock(&vhost_user.mutex);
+	vsocket = find_vhost_user_socket(path);
+	if (vsocket) {
+		eid = vsocket->eid;
+		if (rte_vdpa_info_query(eid, &attr) < 0)
+			*protocol_features = VHOST_USER_PROTOCOL_FEATURES;
+		else
+			*protocol_features = VHOST_USER_PROTOCOL_FEATURES
+				& attr.protocol_features;
+
+	}
+	pthread_mutex_unlock(&vhost_user.mutex);
+
+	if (!vsocket) {
+		RTE_LOG(ERR, VHOST_CONFIG,
+			"socket file %s is not registered yet.\n", path);
+		return -1;
+	} else {
+		return 0;
+	}
+}
+
+int
+rte_vhost_driver_get_queue_num(const char *path,
+		uint32_t *queue_num)
+{
+	struct vhost_user_socket *vsocket;
+	struct rte_vdpa_eng_attr attr;
+	int eid = -1;
+
+	pthread_mutex_lock(&vhost_user.mutex);
+	vsocket = find_vhost_user_socket(path);
+	if (vsocket) {
+		eid = vsocket->eid;
+		if (rte_vdpa_info_query(eid, &attr) < 0)
+			*queue_num = VHOST_MAX_QUEUE_PAIRS;
+		else if (attr.queue_num > VHOST_MAX_QUEUE_PAIRS)
+			*queue_num = VHOST_MAX_QUEUE_PAIRS;
+		else
+			*queue_num = attr.queue_num;
+
+	}
 	pthread_mutex_unlock(&vhost_user.mutex);
 
 	if (!vsocket) {
diff --git a/lib/librte_vhost/vhost.c b/lib/librte_vhost/vhost.c
index 45cf90f99..f8a5a1c42 100644
--- a/lib/librte_vhost/vhost.c
+++ b/lib/librte_vhost/vhost.c
@@ -297,11 +297,14 @@ void
 vhost_destroy_device(int vid)
 {
 	struct virtio_net *dev = get_device(vid);
+	int eid = dev->eid;
 
 	if (dev == NULL)
 		return;
 
 	if (dev->flags & VIRTIO_DEV_RUNNING) {
+		if (eid >= 0 && vdpa_engines[eid]->eng_drv->dev_ops.dev_close)
+			vdpa_engines[eid]->eng_drv->dev_ops.dev_close(dev->vid);
 		dev->flags &= ~VIRTIO_DEV_RUNNING;
 		dev->notify_ops->destroy_device(vid);
 	}
diff --git a/lib/librte_vhost/vhost.h b/lib/librte_vhost/vhost.h
index b3fa6da03..e11b27842 100644
--- a/lib/librte_vhost/vhost.h
+++ b/lib/librte_vhost/vhost.h
@@ -27,6 +27,8 @@
 #define VIRTIO_DEV_READY 2
 /* Used to indicate that the built-in vhost net device backend is enabled */
 #define VIRTIO_DEV_BUILTIN_VIRTIO_NET 4
+/* Used to indicate that the device has its own data path and configured */
+#define VIRTIO_DEV_VDPA_CONFIGURED 8
 
 /* Backend value set by guest. */
 #define VIRTIO_DEV_STOPPED -1
diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c
index c93e48e4d..8b07b6c43 100644
--- a/lib/librte_vhost/vhost_user.c
+++ b/lib/librte_vhost/vhost_user.c
@@ -133,7 +133,11 @@ vhost_user_set_owner(void)
 static int
 vhost_user_reset_owner(struct virtio_net *dev)
 {
+	int eid = dev->eid;
+
 	if (dev->flags & VIRTIO_DEV_RUNNING) {
+		if (eid >= 0 && vdpa_engines[eid]->eng_drv->dev_ops.dev_close)
+			vdpa_engines[eid]->eng_drv->dev_ops.dev_close(dev->vid);
 		dev->flags &= ~VIRTIO_DEV_RUNNING;
 		dev->notify_ops->destroy_device(dev->vid);
 	}
@@ -156,12 +160,25 @@ vhost_user_get_features(struct virtio_net *dev)
 }
 
 /*
+ * The queue number that we support are requested.
+ */
+static uint32_t
+vhost_user_get_queue_num(struct virtio_net *dev)
+{
+	uint32_t queue_num = 0;
+
+	rte_vhost_driver_get_queue_num(dev->ifname, &queue_num);
+	return (uint64_t)queue_num;
+}
+
+/*
  * We receive the negotiated features supported by us and the virtio device.
  */
 static int
 vhost_user_set_features(struct virtio_net *dev, uint64_t features)
 {
 	uint64_t vhost_features = 0;
+	int eid = dev->eid;
 
 	rte_vhost_driver_get_features(dev->ifname, &vhost_features);
 	if (features & ~vhost_features) {
@@ -191,6 +208,9 @@ vhost_user_set_features(struct virtio_net *dev, uint64_t features)
 			dev->notify_ops->features_changed(dev->vid, features);
 	}
 
+	if (eid >= 0 && vdpa_engines[eid]->eng_drv->dev_ops.feature_set)
+		vdpa_engines[eid]->eng_drv->dev_ops.feature_set(dev->vid);
+
 	dev->features = features;
 	if (dev->features &
 		((1 << VIRTIO_NET_F_MRG_RXBUF) | (1ULL << VIRTIO_F_VERSION_1))) {
@@ -933,9 +953,12 @@ vhost_user_get_vring_base(struct virtio_net *dev,
 			  VhostUserMsg *msg)
 {
 	struct vhost_virtqueue *vq = dev->virtqueue[msg->payload.state.index];
+	int eid = dev->eid;
 
 	/* We have to stop the queue (virtio) if it is running. */
 	if (dev->flags & VIRTIO_DEV_RUNNING) {
+		if (eid >= 0 && vdpa_engines[eid]->eng_drv->dev_ops.dev_close)
+			vdpa_engines[eid]->eng_drv->dev_ops.dev_close(dev->vid);
 		dev->flags &= ~VIRTIO_DEV_RUNNING;
 		dev->notify_ops->destroy_device(dev->vid);
 	}
@@ -983,16 +1006,22 @@ vhost_user_set_vring_enable(struct virtio_net *dev,
 			    VhostUserMsg *msg)
 {
 	int enable = (int)msg->payload.state.num;
+	int index = (int)msg->payload.state.index;
+	int eid = dev->eid;
 
 	RTE_LOG(INFO, VHOST_CONFIG,
 		"set queue enable: %d to qp idx: %d\n",
-		enable, msg->payload.state.index);
+		enable, index);
+
+	if (eid >= 0 && vdpa_engines[eid]->eng_drv->dev_ops.vring_state_set)
+		vdpa_engines[eid]->eng_drv->dev_ops.vring_state_set(dev->vid,
+				index, enable);
 
 	if (dev->notify_ops->vring_state_changed)
 		dev->notify_ops->vring_state_changed(dev->vid,
-				msg->payload.state.index, enable);
+				index, enable);
 
-	dev->virtqueue[msg->payload.state.index]->enabled = enable;
+	dev->virtqueue[index]->enabled = enable;
 
 	return 0;
 }
@@ -1001,9 +1030,10 @@ static void
 vhost_user_get_protocol_features(struct virtio_net *dev,
 				 struct VhostUserMsg *msg)
 {
-	uint64_t features, protocol_features = VHOST_USER_PROTOCOL_FEATURES;
+	uint64_t features, protocol_features;
 
 	rte_vhost_driver_get_features(dev->ifname, &features);
+	rte_vhost_driver_get_protocol_features(dev->ifname, &protocol_features);
 
 	/*
 	 * REPLY_ACK protocol feature is only mandatory for now
@@ -1015,7 +1045,6 @@ vhost_user_get_protocol_features(struct virtio_net *dev,
 		protocol_features &=
 			~(1ULL << RTE_VHOST_USER_PROTOCOL_F_REPLY_ACK);
 
-	msg->payload.u64 = protocol_features;
 	msg->size = sizeof(msg->payload.u64);
 }
 
@@ -1100,6 +1129,7 @@ static int
 vhost_user_send_rarp(struct virtio_net *dev, struct VhostUserMsg *msg)
 {
 	uint8_t *mac = (uint8_t *)&msg->payload.u64;
+	int eid = dev->eid;
 
 	RTE_LOG(DEBUG, VHOST_CONFIG,
 		":: mac: %02x:%02x:%02x:%02x:%02x:%02x\n",
@@ -1115,6 +1145,8 @@ vhost_user_send_rarp(struct virtio_net *dev, struct VhostUserMsg *msg)
 	 */
 	rte_smp_wmb();
 	rte_atomic16_set(&dev->broadcast_rarp, 1);
+	if (eid >= 0 && vdpa_engines[eid]->eng_drv->dev_ops.migration_done)
+		vdpa_engines[eid]->eng_drv->dev_ops.migration_done(dev->vid);
 
 	return 0;
 }
@@ -1376,6 +1408,8 @@ vhost_user_msg_handler(int vid, int fd)
 {
 	struct virtio_net *dev;
 	struct VhostUserMsg msg;
+	struct rte_vdpa_engine *eng;
+	int eid;
 	int ret;
 	int unlock_required = 0;
 
@@ -1528,7 +1562,7 @@ vhost_user_msg_handler(int vid, int fd)
 		break;
 
 	case VHOST_USER_GET_QUEUE_NUM:
-		msg.payload.u64 = VHOST_MAX_QUEUE_PAIRS;
+		msg.payload.u64 = (uint64_t)vhost_user_get_queue_num(dev);
 		msg.size = sizeof(msg.payload.u64);
 		send_vhost_reply(fd, &msg);
 		break;
@@ -1581,6 +1615,16 @@ vhost_user_msg_handler(int vid, int fd)
 		}
 	}
 
+	eid = dev->eid;
+	if (eid >= 0 && virtio_is_ready(dev) &&
+			!(dev->flags & VIRTIO_DEV_VDPA_CONFIGURED) &&
+			msg.request.master == VHOST_USER_SET_VRING_ENABLE) {
+		eng = vdpa_engines[eid];
+		if (eng->eng_drv->dev_ops.dev_conf)
+			eng->eng_drv->dev_ops.dev_conf(vid);
+		dev->flags |= VIRTIO_DEV_VDPA_CONFIGURED;
+	}
+
 	return 0;
 }
 
-- 
2.13.6

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v2 5/6] vhost: add apis for live migration
  2018-02-13  9:21 ` [PATCH v2 0/6] vhost: support selective datapath Zhihong Wang
                     ` (3 preceding siblings ...)
  2018-02-13  9:21   ` [PATCH v2 4/6] vhost: adapt vhost lib for selective datapath Zhihong Wang
@ 2018-02-13  9:21   ` Zhihong Wang
  2018-02-13  9:21   ` [PATCH v2 6/6] vhost: export new apis Zhihong Wang
  5 siblings, 0 replies; 67+ messages in thread
From: Zhihong Wang @ 2018-02-13  9:21 UTC (permalink / raw)
  To: dev
  Cc: jianfeng.tan, tiwei.bie, maxime.coquelin, yliu, cunming.liang,
	xiao.w.wang, dan.daly, Zhihong Wang

This patch adds APIs to enable live migration for non-builtin data paths.

At src side, last_avail/used_idx from the device need to be set into the
virtio_net structure, and the log_base and log_size from the virtio_net
structure need to be set into the device.

At dst side, last_avail/used_idx need to be read from the virtio_net
structure and set into the device.

Signed-off-by: Zhihong Wang <zhihong.wang@intel.com>
---
 lib/librte_vhost/rte_vhost.h | 49 ++++++++++++++++++++++++++++++++++
 lib/librte_vhost/vhost.c     | 63 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 112 insertions(+)

diff --git a/lib/librte_vhost/rte_vhost.h b/lib/librte_vhost/rte_vhost.h
index 9bec36756..48005d9ff 100644
--- a/lib/librte_vhost/rte_vhost.h
+++ b/lib/librte_vhost/rte_vhost.h
@@ -512,6 +512,55 @@ int rte_vhost_vring_call(int vid, uint16_t vring_idx);
 uint32_t rte_vhost_rx_queue_count(int vid, uint16_t qid);
 
 /**
+ * Get log base and log size of the vhost device
+ *
+ * @param vid
+ *  vhost device ID
+ * @param log_base
+ *  vhost log base
+ * @param log_size
+ *  vhost log size
+ * @return
+ *  0 on success, -1 on failure
+ */
+int rte_vhost_get_log_base(int vid, uint64_t *log_base,
+		uint64_t *log_size);
+
+/**
+ * Get last_avail/used_idx of the vhost virtqueue
+ *
+ * @param vid
+ *  vhost device ID
+ * @param queue_id
+ *  vhost queue index
+ * @param last_avail_idx
+ *  vhost last_avail_idx to get
+ * @param last_used_idx
+ *  vhost last_used_idx to get
+ * @return
+ *  0 on success, -1 on failure
+ */
+int rte_vhost_get_vring_base(int vid, uint16_t queue_id,
+		uint16_t *last_avail_idx, uint16_t *last_used_idx);
+
+/**
+ * Set last_avail/used_idx of the vhost virtqueue
+ *
+ * @param vid
+ *  vhost device ID
+ * @param queue_id
+ *  vhost queue index
+ * @param last_avail_idx
+ *  last_avail_idx to set
+ * @param last_used_idx
+ *  last_used_idx to set
+ * @return
+ *  0 on success, -1 on failure
+ */
+int rte_vhost_set_vring_base(int vid, uint16_t queue_id,
+		uint16_t last_avail_idx, uint16_t last_used_idx);
+
+/**
  * Get vdpa engine id for vhost device.
  *
  * @param vid
diff --git a/lib/librte_vhost/vhost.c b/lib/librte_vhost/vhost.c
index f8a5a1c42..c7332c557 100644
--- a/lib/librte_vhost/vhost.c
+++ b/lib/librte_vhost/vhost.c
@@ -667,3 +667,66 @@ int rte_vhost_get_vdpa_did(int vid)
 
 	return dev->did;
 }
+
+int rte_vhost_get_log_base(int vid, uint64_t *log_base,
+		uint64_t *log_size)
+{
+	struct virtio_net *dev = get_device(vid);
+
+	if (!dev)
+		return -1;
+
+	if (unlikely(!(dev->flags & VIRTIO_DEV_BUILTIN_VIRTIO_NET))) {
+		RTE_LOG(ERR, VHOST_DATA,
+			"(%d) %s: built-in vhost net backend is disabled.\n",
+			dev->vid, __func__);
+		return -1;
+	}
+
+	*log_base = dev->log_base;
+	*log_size = dev->log_size;
+
+	return 0;
+}
+
+int rte_vhost_get_vring_base(int vid, uint16_t queue_id,
+		uint16_t *last_avail_idx, uint16_t *last_used_idx)
+{
+	struct virtio_net *dev = get_device(vid);
+
+	if (!dev)
+		return -1;
+
+	if (unlikely(!(dev->flags & VIRTIO_DEV_BUILTIN_VIRTIO_NET))) {
+		RTE_LOG(ERR, VHOST_DATA,
+			"(%d) %s: built-in vhost net backend is disabled.\n",
+			dev->vid, __func__);
+		return -1;
+	}
+
+	*last_avail_idx = dev->virtqueue[queue_id]->last_avail_idx;
+	*last_used_idx = dev->virtqueue[queue_id]->last_used_idx;
+
+	return 0;
+}
+
+int rte_vhost_set_vring_base(int vid, uint16_t queue_id,
+		uint16_t last_avail_idx, uint16_t last_used_idx)
+{
+	struct virtio_net *dev = get_device(vid);
+
+	if (!dev)
+		return -1;
+
+	if (unlikely(!(dev->flags & VIRTIO_DEV_BUILTIN_VIRTIO_NET))) {
+		RTE_LOG(ERR, VHOST_DATA,
+			"(%d) %s: built-in vhost net backend is disabled.\n",
+			dev->vid, __func__);
+		return -1;
+	}
+
+	dev->virtqueue[queue_id]->last_avail_idx = last_avail_idx;
+	dev->virtqueue[queue_id]->last_used_idx = last_used_idx;
+
+	return 0;
+}
-- 
2.13.6

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v2 6/6] vhost: export new apis
  2018-02-13  9:21 ` [PATCH v2 0/6] vhost: support selective datapath Zhihong Wang
                     ` (4 preceding siblings ...)
  2018-02-13  9:21   ` [PATCH v2 5/6] vhost: add apis for live migration Zhihong Wang
@ 2018-02-13  9:21   ` Zhihong Wang
  2018-03-06  9:51     ` Tan, Jianfeng
  5 siblings, 1 reply; 67+ messages in thread
From: Zhihong Wang @ 2018-02-13  9:21 UTC (permalink / raw)
  To: dev
  Cc: jianfeng.tan, tiwei.bie, maxime.coquelin, yliu, cunming.liang,
	xiao.w.wang, dan.daly, Zhihong Wang

This patch exports new APIs as experimental.

Signed-off-by: Zhihong Wang <zhihong.wang@intel.com>
---
 lib/librte_vhost/rte_vdpa.h            | 16 +++++++++++-----
 lib/librte_vhost/rte_vhost.h           | 33 ++++++++++++++++++++++-----------
 lib/librte_vhost/rte_vhost_version.map | 19 +++++++++++++++++++
 3 files changed, 52 insertions(+), 16 deletions(-)

diff --git a/lib/librte_vhost/rte_vdpa.h b/lib/librte_vhost/rte_vdpa.h
index 1bde36f7f..23fb471be 100644
--- a/lib/librte_vhost/rte_vdpa.h
+++ b/lib/librte_vhost/rte_vdpa.h
@@ -100,15 +100,21 @@ extern struct rte_vdpa_engine *vdpa_engines[];
 extern uint32_t vdpa_engine_num;
 
 /* engine management */
-int rte_vdpa_register_engine(const char *name, struct rte_vdpa_eng_addr *addr);
-int rte_vdpa_unregister_engine(int eid);
+int __rte_experimental
+rte_vdpa_register_engine(const char *name, struct rte_vdpa_eng_addr *addr);
 
-int rte_vdpa_find_engine_id(struct rte_vdpa_eng_addr *addr);
+int __rte_experimental
+rte_vdpa_unregister_engine(int eid);
 
-int rte_vdpa_info_query(int eid, struct rte_vdpa_eng_attr *attr);
+int __rte_experimental
+rte_vdpa_find_engine_id(struct rte_vdpa_eng_addr *addr);
+
+int __rte_experimental
+rte_vdpa_info_query(int eid, struct rte_vdpa_eng_attr *attr);
 
 /* driver register api */
-void rte_vdpa_register_driver(struct rte_vdpa_eng_driver *drv);
+void __rte_experimental
+rte_vdpa_register_driver(struct rte_vdpa_eng_driver *drv);
 
 #define RTE_VDPA_REGISTER_DRIVER(nm, drv) \
 RTE_INIT(vdpainitfn_ ##nm); \
diff --git a/lib/librte_vhost/rte_vhost.h b/lib/librte_vhost/rte_vhost.h
index 48005d9ff..d5589c543 100644
--- a/lib/librte_vhost/rte_vhost.h
+++ b/lib/librte_vhost/rte_vhost.h
@@ -187,7 +187,8 @@ int rte_vhost_driver_unregister(const char *path);
  * @return
  *  0 on success, -1 on failure
  */
-int rte_vhost_driver_set_vdpa_eid(const char *path, int eid);
+int __rte_experimental
+rte_vhost_driver_set_vdpa_eid(const char *path, int eid);
 
 /**
  * Set the device id, enforce single connection per socket
@@ -199,7 +200,8 @@ int rte_vhost_driver_set_vdpa_eid(const char *path, int eid);
  * @return
  *  0 on success, -1 on failure
  */
-int rte_vhost_driver_set_vdpa_did(const char *path, int did);
+int __rte_experimental
+rte_vhost_driver_set_vdpa_did(const char *path, int did);
 
 /**
  * Get the engine id
@@ -209,7 +211,8 @@ int rte_vhost_driver_set_vdpa_did(const char *path, int did);
  * @return
  *  Engine id, -1 on failure
  */
-int rte_vhost_driver_get_vdpa_eid(const char *path);
+int __rte_experimental
+rte_vhost_driver_get_vdpa_eid(const char *path);
 
 /**
  * Get the device id
@@ -219,7 +222,8 @@ int rte_vhost_driver_get_vdpa_eid(const char *path);
  * @return
  *  Device id, -1 on failure
  */
-int rte_vhost_driver_get_vdpa_did(const char *path);
+int __rte_experimental
+rte_vhost_driver_get_vdpa_did(const char *path);
 
 /**
  * Set the feature bits the vhost-user driver supports.
@@ -286,7 +290,8 @@ int rte_vhost_driver_get_features(const char *path, uint64_t *features);
  * @return
  *  0 on success, -1 on failure
  */
-int rte_vhost_driver_get_protocol_features(const char *path,
+int __rte_experimental
+rte_vhost_driver_get_protocol_features(const char *path,
 		uint64_t *protocol_features);
 
 /**
@@ -299,7 +304,8 @@ int rte_vhost_driver_get_protocol_features(const char *path,
  * @return
  *  0 on success, -1 on failure
  */
-int rte_vhost_driver_get_queue_num(const char *path, uint32_t *queue_num);
+int __rte_experimental
+rte_vhost_driver_get_queue_num(const char *path, uint32_t *queue_num);
 
 /**
  * Get the feature bits after negotiation
@@ -523,7 +529,8 @@ uint32_t rte_vhost_rx_queue_count(int vid, uint16_t qid);
  * @return
  *  0 on success, -1 on failure
  */
-int rte_vhost_get_log_base(int vid, uint64_t *log_base,
+int __rte_experimental
+rte_vhost_get_log_base(int vid, uint64_t *log_base,
 		uint64_t *log_size);
 
 /**
@@ -540,7 +547,8 @@ int rte_vhost_get_log_base(int vid, uint64_t *log_base,
  * @return
  *  0 on success, -1 on failure
  */
-int rte_vhost_get_vring_base(int vid, uint16_t queue_id,
+int __rte_experimental
+rte_vhost_get_vring_base(int vid, uint16_t queue_id,
 		uint16_t *last_avail_idx, uint16_t *last_used_idx);
 
 /**
@@ -557,7 +565,8 @@ int rte_vhost_get_vring_base(int vid, uint16_t queue_id,
  * @return
  *  0 on success, -1 on failure
  */
-int rte_vhost_set_vring_base(int vid, uint16_t queue_id,
+int __rte_experimental
+rte_vhost_set_vring_base(int vid, uint16_t queue_id,
 		uint16_t last_avail_idx, uint16_t last_used_idx);
 
 /**
@@ -568,7 +577,8 @@ int rte_vhost_set_vring_base(int vid, uint16_t queue_id,
  * @return
  *  engine id
  */
-int rte_vhost_get_vdpa_eid(int vid);
+int __rte_experimental
+rte_vhost_get_vdpa_eid(int vid);
 
 /**
  * Get vdpa device id for vhost device.
@@ -578,7 +588,8 @@ int rte_vhost_get_vdpa_eid(int vid);
  * @return
  *  device id
  */
-int rte_vhost_get_vdpa_did(int vid);
+int __rte_experimental
+rte_vhost_get_vdpa_did(int vid);
 
 #ifdef __cplusplus
 }
diff --git a/lib/librte_vhost/rte_vhost_version.map b/lib/librte_vhost/rte_vhost_version.map
index df0103129..36257e51b 100644
--- a/lib/librte_vhost/rte_vhost_version.map
+++ b/lib/librte_vhost/rte_vhost_version.map
@@ -59,3 +59,22 @@ DPDK_18.02 {
 	rte_vhost_vring_call;
 
 } DPDK_17.08;
+
+EXPERIMENTAL {
+	rte_vhost_driver_set_vdpa_eid;
+	rte_vhost_driver_set_vdpa_did;
+	rte_vhost_driver_get_vdpa_eid;
+	rte_vhost_driver_get_vdpa_did;
+	rte_vhost_driver_get_protocol_features;
+	rte_vhost_driver_get_queue_num;
+	rte_vhost_get_log_base;
+	rte_vhost_get_vring_base;
+	rte_vhost_set_vring_base;
+	rte_vhost_get_vdpa_eid;
+	rte_vhost_get_vdpa_did;
+	rte_vdpa_register_engine;
+	rte_vdpa_unregister_engine;
+	rte_vdpa_find_engine_id;
+	rte_vdpa_info_query;
+	rte_vdpa_register_driver;
+} DPDK_18.02;
-- 
2.13.6

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v3 0/5] vhost: support selective datapath
  2018-02-02 23:28 [PATCH 0/7] vhost: support selective datapath Zhihong Wang
                   ` (7 preceding siblings ...)
  2018-02-13  9:21 ` [PATCH v2 0/6] vhost: support selective datapath Zhihong Wang
@ 2018-02-27 10:13 ` Zhihong Wang
  2018-02-27 10:13   ` [PATCH v3 1/5] vhost: export vhost feature definitions Zhihong Wang
                     ` (5 more replies)
  2018-03-10 10:01 ` [PATCH v4 " Zhihong Wang
  2018-04-02 11:46 ` [PATCH v5 0/5] vhost: support selective datapath Zhihong Wang
  10 siblings, 6 replies; 67+ messages in thread
From: Zhihong Wang @ 2018-02-27 10:13 UTC (permalink / raw)
  To: dev
  Cc: jianfeng.tan, tiwei.bie, maxime.coquelin, yliu, cunming.liang,
	xiao.w.wang, dan.daly, Zhihong Wang

This patch set introduces support for selective datapath in DPDK vhost-user
lib. vDPA stands for vhost Data Path Acceleration. The idea is to enable
various types of virtio-compatible devices to do data transfer with virtio
driver directly to enable acceleration.

The default datapath is the existing software implementation, more options
will be available when new engines are added.

Design details
====

An engine is a group of virtio-compatible devices. The definition of engine
is as follows:

struct rte_vdpa_eng_addr {
	union {
		uint8_t __dummy[64];
		struct rte_pci_addr pci_addr;
	};
};

struct rte_vdpa_eng_info {
	char name[MAX_VDPA_NAME_LEN];
	struct rte_vdpa_eng_addr *addr;
};

struct rte_vdpa_dev_ops {
	vdpa_dev_conf_t        dev_conf;
	vdpa_dev_close_t       dev_close;
	vdpa_vring_state_set_t vring_state_set;
	vdpa_feature_set_t     feature_set;
	vdpa_migration_done_t  migration_done;
	vdpa_get_vfio_group_fd_t  get_vfio_group_fd;
	vdpa_get_vfio_device_fd_t get_vfio_device_fd;
	vdpa_get_notify_area_t    get_notify_area;
};

struct rte_vdpa_eng_ops {
	vdpa_eng_init_t   eng_init;
	vdpa_eng_uninit_t eng_uninit;
	vdpa_info_query_t info_query;
};

struct rte_vdpa_eng_driver {
	const char *name;
	struct rte_vdpa_eng_ops eng_ops;
	struct rte_vdpa_dev_ops dev_ops;
} __rte_cache_aligned;

struct rte_vdpa_engine {
	struct rte_vdpa_eng_info    eng_info;
	struct rte_vdpa_eng_driver *eng_drv;
} __rte_cache_aligned;

A set of engine ops is defined in rte_vdpa_eng_ops for engine init, uninit,
and attributes reporting. The attributes are defined as follows:

struct rte_vdpa_eng_attr {
	uint64_t features;
	uint64_t protocol_features;
	uint32_t queue_num;
	uint32_t dev_num;
};

A set of device ops is defined in rte_vdpa_dev_ops for each virtio device
in the engine to do device specific operations.

Changes to the current vhost-user lib are:
====

 1. Make vhost device capabilities configurable to adopt various engines.
    Such capabilities include supported features, protocol features, queue
    number. APIs are introduced to let app configure these capabilities.

 2. In addition to the existing vhost framework, a set of callbacks is
    added for vhost to call the driver for device operations at the right
    time:

     a. dev_conf: Called to configure the actual device when the virtio
        device becomes ready.

     b. dev_close: Called to close the actual device when the virtio device
        is stopped.

     c. vring_state_set: Called to change the state of the vring in the
        actual device when vring state changes.

     d. feature_set: Called to set the negotiated features to device.

     e. migration_done: Called to allow the device to response to RARP
        sending.

     f. get_vfio_group_fd: Called to get the VFIO group fd of the device.

     g. get_vfio_device_fd: Called to get the VFIO device fd of the device.

     h. get_notify_area: Called to get the notify area info of the queue.

 3. To make vhost aware of its own type, an engine id (eid) and a device
    id (did) are added into the vhost data structure to identify the actual
    device. APIs are introduced to let app configure them. When the default
    software datapath is used, eid and did are set to -1. When alternative
    datapath is used, eid and did are set by app to specify which device to
    use. Each vhost-user socket can have only 1 connection in this case.

Working process:
====

 1. Register driver during DPDK initialization.

 2. Register engine with driver name and address.

 3. Get engine attributes.

 4. For vhost device creation:

      a. Register vhost-user socket.

      b. Set eid and did of the vhost-user socket.

      c. Register vhost-user callbacks.

      d. Start to wait for connection.

 4. When connection comes and virtio device data structure is negotiated,
    the device will be configured with all needed info.

---
Changes in v3:

 1. Keep macro names the same as in the spec.

 2. Export new APIs where they're introduced.

---
Changes in v2:

 1. Ensure negotiated capabilities are supported in vhost-user lib.

 2. Add APIs for live migration.

 3. Configure the data path at the right time.

 4. Add VFIO related vDPA device ops.

 5. Rebase on dpdk-next-virtio.

Zhihong Wang (5):
  vhost: export vhost feature definitions
  vhost: support selective datapath
  vhost: add apis for datapath configuration
  vhost: adapt vhost lib for selective datapath
  vhost: add apis for live migration

 lib/librte_vhost/Makefile              |   4 +-
 lib/librte_vhost/rte_vdpa.h            | 126 +++++++++++++++++++++++
 lib/librte_vhost/rte_vhost.h           | 178 +++++++++++++++++++++++++++++++++
 lib/librte_vhost/rte_vhost_version.map |  19 ++++
 lib/librte_vhost/socket.c              | 141 +++++++++++++++++++++++++-
 lib/librte_vhost/vdpa.c                | 124 +++++++++++++++++++++++
 lib/librte_vhost/vhost.c               | 116 +++++++++++++++++++++
 lib/librte_vhost/vhost.h               |  14 ++-
 lib/librte_vhost/vhost_user.c          |  56 +++++++++--
 lib/librte_vhost/vhost_user.h          |   7 --
 10 files changed, 766 insertions(+), 19 deletions(-)
 create mode 100644 lib/librte_vhost/rte_vdpa.h
 create mode 100644 lib/librte_vhost/vdpa.c

-- 
2.13.6

^ permalink raw reply	[flat|nested] 67+ messages in thread

* [PATCH v3 1/5] vhost: export vhost feature definitions
  2018-02-27 10:13 ` [PATCH v3 0/5] vhost: support selective datapath Zhihong Wang
@ 2018-02-27 10:13   ` Zhihong Wang
  2018-02-27 10:13   ` [PATCH v3 2/5] vhost: support selective datapath Zhihong Wang
                     ` (4 subsequent siblings)
  5 siblings, 0 replies; 67+ messages in thread
From: Zhihong Wang @ 2018-02-27 10:13 UTC (permalink / raw)
  To: dev
  Cc: jianfeng.tan, tiwei.bie, maxime.coquelin, yliu, cunming.liang,
	xiao.w.wang, dan.daly, Zhihong Wang

This patch exports vhost-user protocol features to support device driver
development.

Signed-off-by: Zhihong Wang <zhihong.wang@intel.com>
---
Changes in v3:

 1. Keep macro names the same as in the spec.

 lib/librte_vhost/rte_vhost.h  | 30 ++++++++++++++++++++++++++++++
 lib/librte_vhost/vhost.h      |  2 --
 lib/librte_vhost/vhost_user.h |  7 -------
 3 files changed, 30 insertions(+), 9 deletions(-)

diff --git a/lib/librte_vhost/rte_vhost.h b/lib/librte_vhost/rte_vhost.h
index d33206997..671ea5053 100644
--- a/lib/librte_vhost/rte_vhost.h
+++ b/lib/librte_vhost/rte_vhost.h
@@ -29,6 +29,36 @@ extern "C" {
 #define RTE_VHOST_USER_DEQUEUE_ZERO_COPY	(1ULL << 2)
 #define RTE_VHOST_USER_IOMMU_SUPPORT	(1ULL << 3)
 
+/** Protocol features. */
+#ifndef VHOST_USER_PROTOCOL_F_MQ
+#define VHOST_USER_PROTOCOL_F_MQ	0
+#endif
+
+#ifndef VHOST_USER_PROTOCOL_F_LOG_SHMFD
+#define VHOST_USER_PROTOCOL_F_LOG_SHMFD	1
+#endif
+
+#ifndef VHOST_USER_PROTOCOL_F_RARP
+#define VHOST_USER_PROTOCOL_F_RARP	2
+#endif
+
+#ifndef VHOST_USER_PROTOCOL_F_REPLY_ACK
+#define VHOST_USER_PROTOCOL_F_REPLY_ACK	3
+#endif
+
+#ifndef VHOST_USER_PROTOCOL_F_NET_MTU
+#define VHOST_USER_PROTOCOL_F_NET_MTU	4
+#endif
+
+#ifndef VHOST_USER_PROTOCOL_F_SLAVE_REQ
+#define VHOST_USER_PROTOCOL_F_SLAVE_REQ	5
+#endif
+
+/** Indicate whether protocol features negotiation is supported. */
+#ifndef VHOST_USER_F_PROTOCOL_FEATURES
+#define VHOST_USER_F_PROTOCOL_FEATURES	30
+#endif
+
 /**
  * Information relating to memory regions including offsets to
  * addresses in QEMUs memory file.
diff --git a/lib/librte_vhost/vhost.h b/lib/librte_vhost/vhost.h
index 58aec2e0d..2e28e4026 100644
--- a/lib/librte_vhost/vhost.h
+++ b/lib/librte_vhost/vhost.h
@@ -174,8 +174,6 @@ struct vhost_msg {
  #define VIRTIO_F_VERSION_1 32
 #endif
 
-#define VHOST_USER_F_PROTOCOL_FEATURES	30
-
 /* Features supported by this builtin vhost-user net driver. */
 #define VIRTIO_NET_SUPPORTED_FEATURES ((1ULL << VIRTIO_NET_F_MRG_RXBUF) | \
 				(1ULL << VIRTIO_F_ANY_LAYOUT) | \
diff --git a/lib/librte_vhost/vhost_user.h b/lib/librte_vhost/vhost_user.h
index 0fafbe6e0..97afabc47 100644
--- a/lib/librte_vhost/vhost_user.h
+++ b/lib/librte_vhost/vhost_user.h
@@ -14,13 +14,6 @@
 
 #define VHOST_MEMORY_MAX_NREGIONS 8
 
-#define VHOST_USER_PROTOCOL_F_MQ	0
-#define VHOST_USER_PROTOCOL_F_LOG_SHMFD	1
-#define VHOST_USER_PROTOCOL_F_RARP	2
-#define VHOST_USER_PROTOCOL_F_REPLY_ACK	3
-#define VHOST_USER_PROTOCOL_F_NET_MTU 4
-#define VHOST_USER_PROTOCOL_F_SLAVE_REQ 5
-
 #define VHOST_USER_PROTOCOL_FEATURES	((1ULL << VHOST_USER_PROTOCOL_F_MQ) | \
 					 (1ULL << VHOST_USER_PROTOCOL_F_LOG_SHMFD) |\
 					 (1ULL << VHOST_USER_PROTOCOL_F_RARP) | \
-- 
2.13.6

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v3 2/5] vhost: support selective datapath
  2018-02-27 10:13 ` [PATCH v3 0/5] vhost: support selective datapath Zhihong Wang
  2018-02-27 10:13   ` [PATCH v3 1/5] vhost: export vhost feature definitions Zhihong Wang
@ 2018-02-27 10:13   ` Zhihong Wang
  2018-03-21 21:05     ` Maxime Coquelin
  2018-02-27 10:13   ` [PATCH v3 3/5] vhost: add apis for datapath configuration Zhihong Wang
                     ` (3 subsequent siblings)
  5 siblings, 1 reply; 67+ messages in thread
From: Zhihong Wang @ 2018-02-27 10:13 UTC (permalink / raw)
  To: dev
  Cc: jianfeng.tan, tiwei.bie, maxime.coquelin, yliu, cunming.liang,
	xiao.w.wang, dan.daly, Zhihong Wang

This patch introduces support for selective datapath in DPDK vhost-user lib
to enable various types of virtio-compatible devices to do data transfer
with virtio driver directly to enable acceleration. The default datapath is
the existing software implementation, more options will be available when
new engines are registered.

An engine is a group of virtio-compatible devices under a single address.
The engine driver includes:

 1. A set of engine ops is defined in rte_vdpa_eng_ops to perform engine
    init, uninit, and attributes reporting.
    
 2. A set of device ops is defined in rte_vdpa_dev_ops for virtio devices
    in the engine to do device specific operations:

     a. dev_conf: Called to configure the actual device when the virtio
        device becomes ready.

     b. dev_close: Called to close the actual device when the virtio device
        is stopped.

     c. vring_state_set: Called to change the state of the vring in the
        actual device when vring state changes.

     d. feature_set: Called to set the negotiated features to device.

     e. migration_done: Called to allow the device to response to RARP
        sending.

     f. get_vfio_group_fd: Called to get the VFIO group fd of the device.

     g. get_vfio_device_fd: Called to get the VFIO device fd of the device.

     h. get_notify_area: Called to get the notify area info of the queue.

Signed-off-by: Zhihong Wang <zhihong.wang@intel.com>
---
Changes in v2:

 1. Add VFIO related vDPA device ops.

 lib/librte_vhost/Makefile              |   4 +-
 lib/librte_vhost/rte_vdpa.h            | 126 +++++++++++++++++++++++++++++++++
 lib/librte_vhost/rte_vhost_version.map |   8 +++
 lib/librte_vhost/vdpa.c                | 124 ++++++++++++++++++++++++++++++++
 4 files changed, 260 insertions(+), 2 deletions(-)
 create mode 100644 lib/librte_vhost/rte_vdpa.h
 create mode 100644 lib/librte_vhost/vdpa.c

diff --git a/lib/librte_vhost/Makefile b/lib/librte_vhost/Makefile
index 5d6c6abae..37044ac03 100644
--- a/lib/librte_vhost/Makefile
+++ b/lib/librte_vhost/Makefile
@@ -22,9 +22,9 @@ LDLIBS += -lrte_eal -lrte_mempool -lrte_mbuf -lrte_ethdev -lrte_net
 
 # all source are stored in SRCS-y
 SRCS-$(CONFIG_RTE_LIBRTE_VHOST) := fd_man.c iotlb.c socket.c vhost.c \
-					vhost_user.c virtio_net.c
+					vhost_user.c virtio_net.c vdpa.c
 
 # install includes
-SYMLINK-$(CONFIG_RTE_LIBRTE_VHOST)-include += rte_vhost.h
+SYMLINK-$(CONFIG_RTE_LIBRTE_VHOST)-include += rte_vhost.h rte_vdpa.h
 
 include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/lib/librte_vhost/rte_vdpa.h b/lib/librte_vhost/rte_vdpa.h
new file mode 100644
index 000000000..23fb471be
--- /dev/null
+++ b/lib/librte_vhost/rte_vdpa.h
@@ -0,0 +1,126 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Intel Corporation
+ */
+
+#ifndef _RTE_VDPA_H_
+#define _RTE_VDPA_H_
+
+/**
+ * @file
+ *
+ * Device specific vhost lib
+ */
+
+#include <rte_pci.h>
+#include "rte_vhost.h"
+
+#define MAX_VDPA_ENGINE_NUM 128
+#define MAX_VDPA_NAME_LEN 128
+
+struct rte_vdpa_eng_addr {
+	union {
+		uint8_t __dummy[64];
+		struct rte_pci_addr pci_addr;
+	};
+};
+
+struct rte_vdpa_eng_info {
+	struct rte_vdpa_eng_addr *addr;
+	char name[MAX_VDPA_NAME_LEN];
+};
+
+struct rte_vdpa_eng_attr {
+	uint64_t features;
+	uint64_t protocol_features;
+	uint32_t queue_num;
+	uint32_t dev_num;
+};
+
+/* register/remove engine */
+typedef int (*vdpa_eng_init_t)(int eid, struct rte_vdpa_eng_addr *addr);
+typedef int (*vdpa_eng_uninit_t)(int eid);
+
+/* query info of this engine */
+typedef int (*vdpa_info_query_t)(int eid,
+		struct rte_vdpa_eng_attr *attr);
+
+/* driver configure/close the port based on connection */
+typedef int (*vdpa_dev_conf_t)(int vid);
+typedef int (*vdpa_dev_close_t)(int vid);
+
+/* enable/disable this vring */
+typedef int (*vdpa_vring_state_set_t)(int vid, int vring, int state);
+
+/* set features when changed */
+typedef int (*vdpa_feature_set_t)(int vid);
+
+/* destination operations when migration done, e.g. send rarp */
+typedef int (*vdpa_migration_done_t)(int vid);
+
+/* get the vfio group fd */
+typedef int (*vdpa_get_vfio_group_fd_t)(int vid);
+
+/* get the vfio device fd */
+typedef int (*vdpa_get_vfio_device_fd_t)(int vid);
+
+/* get the notify area info of the queue */
+typedef int (*vdpa_get_notify_area_t)(int vid, int qid, uint64_t *offset,
+		uint64_t *size);
+/* device ops */
+struct rte_vdpa_dev_ops {
+	vdpa_dev_conf_t           dev_conf;
+	vdpa_dev_close_t          dev_close;
+	vdpa_vring_state_set_t    vring_state_set;
+	vdpa_feature_set_t        feature_set;
+	vdpa_migration_done_t     migration_done;
+	vdpa_get_vfio_group_fd_t  get_vfio_group_fd;
+	vdpa_get_vfio_device_fd_t get_vfio_device_fd;
+	vdpa_get_notify_area_t    get_notify_area;
+};
+
+/* engine ops */
+struct rte_vdpa_eng_ops {
+	vdpa_eng_init_t eng_init;
+	vdpa_eng_uninit_t eng_uninit;
+	vdpa_info_query_t info_query;
+};
+
+struct rte_vdpa_eng_driver {
+	struct rte_vdpa_eng_ops eng_ops;
+	struct rte_vdpa_dev_ops dev_ops;
+	const char *name;
+} __rte_cache_aligned;
+
+struct rte_vdpa_engine {
+	struct rte_vdpa_eng_info eng_info;
+	struct rte_vdpa_eng_driver *eng_drv;
+} __rte_cache_aligned;
+
+extern struct rte_vdpa_engine *vdpa_engines[];
+extern uint32_t vdpa_engine_num;
+
+/* engine management */
+int __rte_experimental
+rte_vdpa_register_engine(const char *name, struct rte_vdpa_eng_addr *addr);
+
+int __rte_experimental
+rte_vdpa_unregister_engine(int eid);
+
+int __rte_experimental
+rte_vdpa_find_engine_id(struct rte_vdpa_eng_addr *addr);
+
+int __rte_experimental
+rte_vdpa_info_query(int eid, struct rte_vdpa_eng_attr *attr);
+
+/* driver register api */
+void __rte_experimental
+rte_vdpa_register_driver(struct rte_vdpa_eng_driver *drv);
+
+#define RTE_VDPA_REGISTER_DRIVER(nm, drv) \
+RTE_INIT(vdpainitfn_ ##nm); \
+static void vdpainitfn_ ##nm(void) \
+{ \
+	rte_vdpa_register_driver(&drv); \
+} \
+
+#endif /* _RTE_VDPA_H_ */
diff --git a/lib/librte_vhost/rte_vhost_version.map b/lib/librte_vhost/rte_vhost_version.map
index df0103129..57a3edd01 100644
--- a/lib/librte_vhost/rte_vhost_version.map
+++ b/lib/librte_vhost/rte_vhost_version.map
@@ -59,3 +59,11 @@ DPDK_18.02 {
 	rte_vhost_vring_call;
 
 } DPDK_17.08;
+
+EXPERIMENTAL {
+	rte_vdpa_register_engine;
+	rte_vdpa_unregister_engine;
+	rte_vdpa_find_engine_id;
+	rte_vdpa_info_query;
+	rte_vdpa_register_driver;
+} DPDK_18.02;
diff --git a/lib/librte_vhost/vdpa.c b/lib/librte_vhost/vdpa.c
new file mode 100644
index 000000000..5d5ffe147
--- /dev/null
+++ b/lib/librte_vhost/vdpa.c
@@ -0,0 +1,124 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Intel Corporation
+ */
+
+/**
+ * @file
+ *
+ * Device specific vhost lib
+ */
+
+#include <stdbool.h>
+
+#include <rte_malloc.h>
+#include "rte_vdpa.h"
+#include "vhost.h"
+
+static struct rte_vdpa_eng_driver *vdpa_drivers[MAX_VDPA_ENGINE_NUM];
+static uint32_t vdpa_driver_num;
+
+struct rte_vdpa_engine *vdpa_engines[MAX_VDPA_ENGINE_NUM];
+uint32_t vdpa_engine_num;
+
+static int is_same_eng(struct rte_vdpa_eng_addr *a, struct rte_vdpa_eng_addr *b)
+{
+	if (a->pci_addr.domain != b->pci_addr.domain ||
+			a->pci_addr.bus != b->pci_addr.bus ||
+			a->pci_addr.devid != b->pci_addr.devid ||
+			a->pci_addr.function != b->pci_addr.function)
+		return -1;
+
+	return 0;
+}
+
+void rte_vdpa_register_driver(struct rte_vdpa_eng_driver *driver)
+{
+	if (vdpa_driver_num >= MAX_VDPA_ENGINE_NUM)
+		return;
+
+	vdpa_drivers[vdpa_driver_num] = driver;
+	vdpa_driver_num++;
+}
+
+int rte_vdpa_register_engine(const char *name, struct rte_vdpa_eng_addr *addr)
+{
+	static int engine_idx;
+
+	struct rte_vdpa_engine *eng;
+	struct rte_vdpa_eng_driver *cur;
+	char engine_name[MAX_VDPA_NAME_LEN];
+	int i;
+
+	for (i = 0; i < MAX_VDPA_ENGINE_NUM; ++i) {
+		eng = vdpa_engines[i];
+		if (eng && is_same_eng(eng->eng_info.addr, addr) == 0)
+			return i;
+	}
+
+	sprintf(engine_name, "vdpa-%s-%d", name, engine_idx++);
+	eng = rte_zmalloc(engine_name, sizeof(struct rte_vdpa_engine),
+			RTE_CACHE_LINE_SIZE);
+	if (!eng)
+		return -1;
+
+	for (i = 0; i < MAX_VDPA_ENGINE_NUM; ++i) {
+		cur = vdpa_drivers[i];
+		if (cur && 0 == strncmp(name, cur->name,
+					MAX_VDPA_NAME_LEN)) {
+			eng->eng_drv = cur;
+			strcpy(eng->eng_info.name, name);
+			eng->eng_info.addr = addr;
+			for (i = 0; i < MAX_VDPA_ENGINE_NUM; ++i) {
+				if (vdpa_engines[i])
+					continue;
+				vdpa_engines[i] = eng;
+				if (eng->eng_drv->eng_ops.eng_init)
+					eng->eng_drv->eng_ops.eng_init(i, addr);
+				vdpa_engine_num++;
+				return i;
+			}
+		}
+	}
+
+	return -1;
+}
+
+int rte_vdpa_unregister_engine(int eid)
+{
+	if (eid < 0 || eid >= MAX_VDPA_ENGINE_NUM || vdpa_engines[eid]
+			== NULL)
+		return -1;
+
+	if (vdpa_engines[eid]->eng_drv->eng_ops.eng_uninit)
+		vdpa_engines[eid]->eng_drv->eng_ops.eng_uninit(eid);
+
+	rte_free(vdpa_engines[eid]);
+	vdpa_engines[eid] = NULL;
+	vdpa_engine_num--;
+
+	return eid;
+}
+
+int rte_vdpa_find_engine_id(struct rte_vdpa_eng_addr *addr)
+{
+	struct rte_vdpa_engine *eng;
+	int i;
+
+	for (i = 0; i < MAX_VDPA_ENGINE_NUM; ++i) {
+		eng = vdpa_engines[i];
+		if (eng && is_same_eng(eng->eng_info.addr, addr) == 0)
+			return i;
+	}
+
+	return -1;
+}
+
+int rte_vdpa_info_query(int eid, struct rte_vdpa_eng_attr *attr)
+{
+	if (eid < 0 || eid >= MAX_VDPA_ENGINE_NUM ||
+			vdpa_engines[eid] == NULL ||
+			vdpa_engines[eid]->eng_drv->eng_ops.info_query == NULL)
+		return -1;
+
+	return vdpa_engines[eid]->eng_drv->eng_ops.info_query(eid, attr);
+}
-- 
2.13.6

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v3 3/5] vhost: add apis for datapath configuration
  2018-02-27 10:13 ` [PATCH v3 0/5] vhost: support selective datapath Zhihong Wang
  2018-02-27 10:13   ` [PATCH v3 1/5] vhost: export vhost feature definitions Zhihong Wang
  2018-02-27 10:13   ` [PATCH v3 2/5] vhost: support selective datapath Zhihong Wang
@ 2018-02-27 10:13   ` Zhihong Wang
  2018-03-21 21:08     ` Maxime Coquelin
  2018-02-27 10:13   ` [PATCH v3 4/5] vhost: adapt vhost lib for selective datapath Zhihong Wang
                     ` (2 subsequent siblings)
  5 siblings, 1 reply; 67+ messages in thread
From: Zhihong Wang @ 2018-02-27 10:13 UTC (permalink / raw)
  To: dev
  Cc: jianfeng.tan, tiwei.bie, maxime.coquelin, yliu, cunming.liang,
	xiao.w.wang, dan.daly, Zhihong Wang

This patch adds APIs for datapath configuration. The eid and did of the
vhost-user socket can be configured to identify the actual device.

When the default software datapath is used, eid and did are set to -1.
When alternative datapath is used, eid and did are set by app to specify
which device to use. Each vhost-user socket can have only 1 connection in
this case.

Signed-off-by: Zhihong Wang <zhihong.wang@intel.com>
---
 lib/librte_vhost/rte_vhost.h           | 70 ++++++++++++++++++++++++++++++++++
 lib/librte_vhost/rte_vhost_version.map |  6 +++
 lib/librte_vhost/socket.c              | 65 +++++++++++++++++++++++++++++++
 lib/librte_vhost/vhost.c               | 50 ++++++++++++++++++++++++
 lib/librte_vhost/vhost.h               | 10 +++++
 5 files changed, 201 insertions(+)

diff --git a/lib/librte_vhost/rte_vhost.h b/lib/librte_vhost/rte_vhost.h
index 671ea5053..7aa57ca87 100644
--- a/lib/librte_vhost/rte_vhost.h
+++ b/lib/librte_vhost/rte_vhost.h
@@ -200,6 +200,54 @@ int rte_vhost_driver_register(const char *path, uint64_t flags);
 int rte_vhost_driver_unregister(const char *path);
 
 /**
+ * Set the engine id, enforce single connection per socket
+ *
+ * @param path
+ *  The vhost-user socket file path
+ * @param eid
+ *  Engine id
+ * @return
+ *  0 on success, -1 on failure
+ */
+int __rte_experimental
+rte_vhost_driver_set_vdpa_eid(const char *path, int eid);
+
+/**
+ * Set the device id, enforce single connection per socket
+ *
+ * @param path
+ *  The vhost-user socket file path
+ * @param did
+ *  Device id
+ * @return
+ *  0 on success, -1 on failure
+ */
+int __rte_experimental
+rte_vhost_driver_set_vdpa_did(const char *path, int did);
+
+/**
+ * Get the engine id
+ *
+ * @param path
+ *  The vhost-user socket file path
+ * @return
+ *  Engine id, -1 on failure
+ */
+int __rte_experimental
+rte_vhost_driver_get_vdpa_eid(const char *path);
+
+/**
+ * Get the device id
+ *
+ * @param path
+ *  The vhost-user socket file path
+ * @return
+ *  Device id, -1 on failure
+ */
+int __rte_experimental
+rte_vhost_driver_get_vdpa_did(const char *path);
+
+/**
  * Set the feature bits the vhost-user driver supports.
  *
  * @param path
@@ -464,6 +512,28 @@ int rte_vhost_vring_call(int vid, uint16_t vring_idx);
  */
 uint32_t rte_vhost_rx_queue_count(int vid, uint16_t qid);
 
+/**
+ * Get vdpa engine id for vhost device.
+ *
+ * @param vid
+ *  vhost device ID
+ * @return
+ *  engine id
+ */
+int __rte_experimental
+rte_vhost_get_vdpa_eid(int vid);
+
+/**
+ * Get vdpa device id for vhost device.
+ *
+ * @param vid
+ *  vhost device ID
+ * @return
+ *  device id
+ */
+int __rte_experimental
+rte_vhost_get_vdpa_did(int vid);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/librte_vhost/rte_vhost_version.map b/lib/librte_vhost/rte_vhost_version.map
index 57a3edd01..c505596c5 100644
--- a/lib/librte_vhost/rte_vhost_version.map
+++ b/lib/librte_vhost/rte_vhost_version.map
@@ -66,4 +66,10 @@ EXPERIMENTAL {
 	rte_vdpa_find_engine_id;
 	rte_vdpa_info_query;
 	rte_vdpa_register_driver;
+	rte_vhost_driver_set_vdpa_eid;
+	rte_vhost_driver_set_vdpa_did;
+	rte_vhost_driver_get_vdpa_eid;
+	rte_vhost_driver_get_vdpa_did;
+	rte_vhost_get_vdpa_eid;
+	rte_vhost_get_vdpa_did;
 } DPDK_18.02;
diff --git a/lib/librte_vhost/socket.c b/lib/librte_vhost/socket.c
index cfc31e179..8551eb58c 100644
--- a/lib/librte_vhost/socket.c
+++ b/lib/librte_vhost/socket.c
@@ -52,6 +52,13 @@ struct vhost_user_socket {
 	uint64_t supported_features;
 	uint64_t features;
 
+	/* engine and device id to identify a certain port on a specific
+	 * backend, both are set to -1 for sw. when used, one socket can
+	 * have 1 connection only.
+	 */
+	int eid;
+	int did;
+
 	struct vhost_device_ops const *notify_ops;
 };
 
@@ -545,6 +552,64 @@ find_vhost_user_socket(const char *path)
 }
 
 int
+rte_vhost_driver_set_vdpa_eid(const char *path, int eid)
+{
+	struct vhost_user_socket *vsocket;
+
+	pthread_mutex_lock(&vhost_user.mutex);
+	vsocket = find_vhost_user_socket(path);
+	if (vsocket)
+		vsocket->eid = eid;
+	pthread_mutex_unlock(&vhost_user.mutex);
+
+	return vsocket ? 0 : -1;
+}
+
+int
+rte_vhost_driver_set_vdpa_did(const char *path, int did)
+{
+	struct vhost_user_socket *vsocket;
+
+	pthread_mutex_lock(&vhost_user.mutex);
+	vsocket = find_vhost_user_socket(path);
+	if (vsocket)
+		vsocket->did = did;
+	pthread_mutex_unlock(&vhost_user.mutex);
+
+	return vsocket ? 0 : -1;
+}
+
+int
+rte_vhost_driver_get_vdpa_eid(const char *path)
+{
+	struct vhost_user_socket *vsocket;
+	int eid = -1;
+
+	pthread_mutex_lock(&vhost_user.mutex);
+	vsocket = find_vhost_user_socket(path);
+	if (vsocket)
+		eid = vsocket->eid;
+	pthread_mutex_unlock(&vhost_user.mutex);
+
+	return eid;
+}
+
+int
+rte_vhost_driver_get_vdpa_did(const char *path)
+{
+	struct vhost_user_socket *vsocket;
+	int did = -1;
+
+	pthread_mutex_lock(&vhost_user.mutex);
+	vsocket = find_vhost_user_socket(path);
+	if (vsocket)
+		did = vsocket->did;
+	pthread_mutex_unlock(&vhost_user.mutex);
+
+	return did;
+}
+
+int
 rte_vhost_driver_disable_features(const char *path, uint64_t features)
 {
 	struct vhost_user_socket *vsocket;
diff --git a/lib/librte_vhost/vhost.c b/lib/librte_vhost/vhost.c
index f6f12a03b..45cf90f99 100644
--- a/lib/librte_vhost/vhost.c
+++ b/lib/librte_vhost/vhost.c
@@ -283,6 +283,8 @@ vhost_new_device(void)
 	dev->vid = i;
 	dev->flags = VIRTIO_DEV_BUILTIN_VIRTIO_NET;
 	dev->slave_req_fd = -1;
+	dev->eid = -1;
+	dev->did = -1;
 
 	return i;
 }
@@ -311,6 +313,34 @@ vhost_destroy_device(int vid)
 }
 
 void
+vhost_set_vdpa_eid(int vid, int eid)
+{
+	struct virtio_net *dev = get_device(vid);
+
+	if (eid < 0 || eid >= MAX_VDPA_ENGINE_NUM || vdpa_engines[eid] == NULL)
+		return;
+
+	if (dev == NULL)
+		return;
+
+	dev->eid = eid;
+}
+
+void
+vhost_set_vdpa_did(int vid, int did)
+{
+	struct virtio_net *dev = get_device(vid);
+
+	if (did < 0)
+		return;
+
+	if (dev == NULL)
+		return;
+
+	dev->did = did;
+}
+
+void
 vhost_set_ifname(int vid, const char *if_name, unsigned int if_len)
 {
 	struct virtio_net *dev;
@@ -614,3 +644,23 @@ rte_vhost_rx_queue_count(int vid, uint16_t qid)
 
 	return *((volatile uint16_t *)&vq->avail->idx) - vq->last_avail_idx;
 }
+
+int rte_vhost_get_vdpa_eid(int vid)
+{
+	struct virtio_net *dev = get_device(vid);
+
+	if (dev == NULL)
+		return -1;
+
+	return dev->eid;
+}
+
+int rte_vhost_get_vdpa_did(int vid)
+{
+	struct virtio_net *dev = get_device(vid);
+
+	if (dev == NULL)
+		return -1;
+
+	return dev->did;
+}
diff --git a/lib/librte_vhost/vhost.h b/lib/librte_vhost/vhost.h
index 2e28e4026..e06d789fa 100644
--- a/lib/librte_vhost/vhost.h
+++ b/lib/librte_vhost/vhost.h
@@ -19,6 +19,7 @@
 #include <rte_rwlock.h>
 
 #include "rte_vhost.h"
+#include "rte_vdpa.h"
 
 /* Used to indicate that the device is running on a data core */
 #define VIRTIO_DEV_RUNNING 1
@@ -239,6 +240,12 @@ struct virtio_net {
 	struct guest_page       *guest_pages;
 
 	int			slave_req_fd;
+
+	/* engine and device id to identify a certain port on a specific
+	 * backend, both are set to -1 for sw.
+	 */
+	int			eid;
+	int			did;
 } __rte_cache_aligned;
 
 
@@ -365,6 +372,9 @@ void free_vq(struct vhost_virtqueue *vq);
 
 int alloc_vring_queue(struct virtio_net *dev, uint32_t vring_idx);
 
+void vhost_set_vdpa_eid(int vid, int eid);
+void vhost_set_vdpa_did(int vid, int did);
+
 void vhost_set_ifname(int, const char *if_name, unsigned int if_len);
 void vhost_enable_dequeue_zero_copy(int vid);
 void vhost_set_builtin_virtio_net(int vid, bool enable);
-- 
2.13.6

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v3 4/5] vhost: adapt vhost lib for selective datapath
  2018-02-27 10:13 ` [PATCH v3 0/5] vhost: support selective datapath Zhihong Wang
                     ` (2 preceding siblings ...)
  2018-02-27 10:13   ` [PATCH v3 3/5] vhost: add apis for datapath configuration Zhihong Wang
@ 2018-02-27 10:13   ` Zhihong Wang
  2018-02-27 10:13   ` [PATCH v3 5/5] vhost: add apis for live migration Zhihong Wang
  2018-03-29 12:15   ` [PATCH v3 0/5] vhost: support selective datapath Wodkowski, PawelX
  5 siblings, 0 replies; 67+ messages in thread
From: Zhihong Wang @ 2018-02-27 10:13 UTC (permalink / raw)
  To: dev
  Cc: jianfeng.tan, tiwei.bie, maxime.coquelin, yliu, cunming.liang,
	xiao.w.wang, dan.daly, Zhihong Wang

This patch adapts vhost lib for selective datapath by calling device ops
at the corresponding stage.

Signed-off-by: Zhihong Wang <zhihong.wang@intel.com>
---
Changes in v2:

 1. Ensure negotiated capabilities are supported in vhost-user lib.

 2. Configure the data path at the right time.

 lib/librte_vhost/rte_vhost.h           | 27 ++++++++++++
 lib/librte_vhost/rte_vhost_version.map |  2 +
 lib/librte_vhost/socket.c              | 76 +++++++++++++++++++++++++++++++++-
 lib/librte_vhost/vhost.c               |  3 ++
 lib/librte_vhost/vhost.h               |  2 +
 lib/librte_vhost/vhost_user.c          | 56 ++++++++++++++++++++++---
 6 files changed, 158 insertions(+), 8 deletions(-)

diff --git a/lib/librte_vhost/rte_vhost.h b/lib/librte_vhost/rte_vhost.h
index 7aa57ca87..77c2a1a8b 100644
--- a/lib/librte_vhost/rte_vhost.h
+++ b/lib/librte_vhost/rte_vhost.h
@@ -303,6 +303,33 @@ int rte_vhost_driver_disable_features(const char *path, uint64_t features);
 int rte_vhost_driver_get_features(const char *path, uint64_t *features);
 
 /**
+ * Get the protocol feature bits before feature negotiation.
+ *
+ * @param path
+ *  The vhost-user socket file path
+ * @param protocol_features
+ *  A pointer to store the queried protocol feature bits
+ * @return
+ *  0 on success, -1 on failure
+ */
+int __rte_experimental
+rte_vhost_driver_get_protocol_features(const char *path,
+		uint64_t *protocol_features);
+
+/**
+ * Get the queue number bits before feature negotiation.
+ *
+ * @param path
+ *  The vhost-user socket file path
+ * @param queue_num
+ *  A pointer to store the queried queue number bits
+ * @return
+ *  0 on success, -1 on failure
+ */
+int __rte_experimental
+rte_vhost_driver_get_queue_num(const char *path, uint32_t *queue_num);
+
+/**
  * Get the feature bits after negotiation
  *
  * @param vid
diff --git a/lib/librte_vhost/rte_vhost_version.map b/lib/librte_vhost/rte_vhost_version.map
index c505596c5..8ef2a396c 100644
--- a/lib/librte_vhost/rte_vhost_version.map
+++ b/lib/librte_vhost/rte_vhost_version.map
@@ -72,4 +72,6 @@ EXPERIMENTAL {
 	rte_vhost_driver_get_vdpa_did;
 	rte_vhost_get_vdpa_eid;
 	rte_vhost_get_vdpa_did;
+	rte_vhost_driver_get_protocol_features;
+	rte_vhost_driver_get_queue_num;
 } DPDK_18.02;
diff --git a/lib/librte_vhost/socket.c b/lib/librte_vhost/socket.c
index 8551eb58c..14dce2a73 100644
--- a/lib/librte_vhost/socket.c
+++ b/lib/librte_vhost/socket.c
@@ -216,6 +216,9 @@ vhost_user_add_connection(int fd, struct vhost_user_socket *vsocket)
 
 	vhost_set_builtin_virtio_net(vid, vsocket->use_builtin_virtio_net);
 
+	vhost_set_vdpa_eid(vid, vsocket->eid);
+	vhost_set_vdpa_did(vid, vsocket->did);
+
 	if (vsocket->dequeue_zero_copy)
 		vhost_enable_dequeue_zero_copy(vid);
 
@@ -677,11 +680,80 @@ int
 rte_vhost_driver_get_features(const char *path, uint64_t *features)
 {
 	struct vhost_user_socket *vsocket;
+	struct rte_vdpa_eng_attr attr;
+	int eid = -1;
 
 	pthread_mutex_lock(&vhost_user.mutex);
 	vsocket = find_vhost_user_socket(path);
-	if (vsocket)
-		*features = vsocket->features;
+	if (vsocket) {
+		eid = vsocket->eid;
+		if (rte_vdpa_info_query(eid, &attr) < 0)
+			*features = vsocket->features;
+		else
+			*features = vsocket->features & attr.features;
+
+	}
+	pthread_mutex_unlock(&vhost_user.mutex);
+
+	if (!vsocket) {
+		RTE_LOG(ERR, VHOST_CONFIG,
+			"socket file %s is not registered yet.\n", path);
+		return -1;
+	} else {
+		return 0;
+	}
+}
+
+int
+rte_vhost_driver_get_protocol_features(const char *path,
+		uint64_t *protocol_features)
+{
+	struct vhost_user_socket *vsocket;
+	struct rte_vdpa_eng_attr attr;
+	int eid = -1;
+
+	pthread_mutex_lock(&vhost_user.mutex);
+	vsocket = find_vhost_user_socket(path);
+	if (vsocket) {
+		eid = vsocket->eid;
+		if (rte_vdpa_info_query(eid, &attr) < 0)
+			*protocol_features = VHOST_USER_PROTOCOL_FEATURES;
+		else
+			*protocol_features = VHOST_USER_PROTOCOL_FEATURES
+				& attr.protocol_features;
+
+	}
+	pthread_mutex_unlock(&vhost_user.mutex);
+
+	if (!vsocket) {
+		RTE_LOG(ERR, VHOST_CONFIG,
+			"socket file %s is not registered yet.\n", path);
+		return -1;
+	} else {
+		return 0;
+	}
+}
+
+int
+rte_vhost_driver_get_queue_num(const char *path,
+		uint32_t *queue_num)
+{
+	struct vhost_user_socket *vsocket;
+	struct rte_vdpa_eng_attr attr;
+	int eid = -1;
+
+	pthread_mutex_lock(&vhost_user.mutex);
+	vsocket = find_vhost_user_socket(path);
+	if (vsocket) {
+		eid = vsocket->eid;
+		if (rte_vdpa_info_query(eid, &attr) < 0)
+			*queue_num = VHOST_MAX_QUEUE_PAIRS;
+		else if (attr.queue_num > VHOST_MAX_QUEUE_PAIRS)
+			*queue_num = VHOST_MAX_QUEUE_PAIRS;
+		else
+			*queue_num = attr.queue_num;
+
+	}
 	pthread_mutex_unlock(&vhost_user.mutex);
 
 	if (!vsocket) {
diff --git a/lib/librte_vhost/vhost.c b/lib/librte_vhost/vhost.c
index 45cf90f99..f8a5a1c42 100644
--- a/lib/librte_vhost/vhost.c
+++ b/lib/librte_vhost/vhost.c
@@ -297,11 +297,14 @@ void
 vhost_destroy_device(int vid)
 {
 	struct virtio_net *dev = get_device(vid);
+	int eid = dev->eid;
 
 	if (dev == NULL)
 		return;
 
 	if (dev->flags & VIRTIO_DEV_RUNNING) {
+		if (eid >= 0 && vdpa_engines[eid]->eng_drv->dev_ops.dev_close)
+			vdpa_engines[eid]->eng_drv->dev_ops.dev_close(dev->vid);
 		dev->flags &= ~VIRTIO_DEV_RUNNING;
 		dev->notify_ops->destroy_device(vid);
 	}
diff --git a/lib/librte_vhost/vhost.h b/lib/librte_vhost/vhost.h
index e06d789fa..53fd76e92 100644
--- a/lib/librte_vhost/vhost.h
+++ b/lib/librte_vhost/vhost.h
@@ -27,6 +27,8 @@
 #define VIRTIO_DEV_READY 2
 /* Used to indicate that the built-in vhost net device backend is enabled */
 #define VIRTIO_DEV_BUILTIN_VIRTIO_NET 4
+/* Used to indicate that the device has its own data path and configured */
+#define VIRTIO_DEV_VDPA_CONFIGURED 8
 
 /* Backend value set by guest. */
 #define VIRTIO_DEV_STOPPED -1
diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c
index 5c5361066..d4e0c9c62 100644
--- a/lib/librte_vhost/vhost_user.c
+++ b/lib/librte_vhost/vhost_user.c
@@ -133,7 +133,11 @@ vhost_user_set_owner(void)
 static int
 vhost_user_reset_owner(struct virtio_net *dev)
 {
+	int eid = dev->eid;
+
 	if (dev->flags & VIRTIO_DEV_RUNNING) {
+		if (eid >= 0 && vdpa_engines[eid]->eng_drv->dev_ops.dev_close)
+			vdpa_engines[eid]->eng_drv->dev_ops.dev_close(dev->vid);
 		dev->flags &= ~VIRTIO_DEV_RUNNING;
 		dev->notify_ops->destroy_device(dev->vid);
 	}
@@ -156,12 +160,25 @@ vhost_user_get_features(struct virtio_net *dev)
 }
 
 /*
+ * The queue number that we support are requested.
+ */
+static uint32_t
+vhost_user_get_queue_num(struct virtio_net *dev)
+{
+	uint32_t queue_num = 0;
+
+	rte_vhost_driver_get_queue_num(dev->ifname, &queue_num);
+	return (uint64_t)queue_num;
+}
+
+/*
  * We receive the negotiated features supported by us and the virtio device.
  */
 static int
 vhost_user_set_features(struct virtio_net *dev, uint64_t features)
 {
 	uint64_t vhost_features = 0;
+	int eid = dev->eid;
 
 	rte_vhost_driver_get_features(dev->ifname, &vhost_features);
 	if (features & ~vhost_features) {
@@ -191,6 +208,9 @@ vhost_user_set_features(struct virtio_net *dev, uint64_t features)
 			dev->notify_ops->features_changed(dev->vid, features);
 	}
 
+	if (eid >= 0 && vdpa_engines[eid]->eng_drv->dev_ops.feature_set)
+		vdpa_engines[eid]->eng_drv->dev_ops.feature_set(dev->vid);
+
 	dev->features = features;
 	if (dev->features &
 		((1 << VIRTIO_NET_F_MRG_RXBUF) | (1ULL << VIRTIO_F_VERSION_1))) {
@@ -933,9 +953,12 @@ vhost_user_get_vring_base(struct virtio_net *dev,
 			  VhostUserMsg *msg)
 {
 	struct vhost_virtqueue *vq = dev->virtqueue[msg->payload.state.index];
+	int eid = dev->eid;
 
 	/* We have to stop the queue (virtio) if it is running. */
 	if (dev->flags & VIRTIO_DEV_RUNNING) {
+		if (eid >= 0 && vdpa_engines[eid]->eng_drv->dev_ops.dev_close)
+			vdpa_engines[eid]->eng_drv->dev_ops.dev_close(dev->vid);
 		dev->flags &= ~VIRTIO_DEV_RUNNING;
 		dev->notify_ops->destroy_device(dev->vid);
 	}
@@ -983,16 +1006,22 @@ vhost_user_set_vring_enable(struct virtio_net *dev,
 			    VhostUserMsg *msg)
 {
 	int enable = (int)msg->payload.state.num;
+	int index = (int)msg->payload.state.index;
+	int eid = dev->eid;
 
 	RTE_LOG(INFO, VHOST_CONFIG,
 		"set queue enable: %d to qp idx: %d\n",
-		enable, msg->payload.state.index);
+		enable, index);
+
+	if (eid >= 0 && vdpa_engines[eid]->eng_drv->dev_ops.vring_state_set)
+		vdpa_engines[eid]->eng_drv->dev_ops.vring_state_set(dev->vid,
+				index, enable);
 
 	if (dev->notify_ops->vring_state_changed)
 		dev->notify_ops->vring_state_changed(dev->vid,
-				msg->payload.state.index, enable);
+				index, enable);
 
-	dev->virtqueue[msg->payload.state.index]->enabled = enable;
+	dev->virtqueue[index]->enabled = enable;
 
 	return 0;
 }
@@ -1001,9 +1030,10 @@ static void
 vhost_user_get_protocol_features(struct virtio_net *dev,
 				 struct VhostUserMsg *msg)
 {
-	uint64_t features, protocol_features = VHOST_USER_PROTOCOL_FEATURES;
+	uint64_t features, protocol_features;
 
 	rte_vhost_driver_get_features(dev->ifname, &features);
+	rte_vhost_driver_get_protocol_features(dev->ifname, &protocol_features);
 
 	/*
 	 * REPLY_ACK protocol feature is only mandatory for now
@@ -1014,7 +1044,6 @@ vhost_user_get_protocol_features(struct virtio_net *dev,
 	if (!(features & (1ULL << VIRTIO_F_IOMMU_PLATFORM)))
 		protocol_features &= ~(1ULL << VHOST_USER_PROTOCOL_F_REPLY_ACK);
 
-	msg->payload.u64 = protocol_features;
 	msg->size = sizeof(msg->payload.u64);
 }
 
@@ -1099,6 +1128,7 @@ static int
 vhost_user_send_rarp(struct virtio_net *dev, struct VhostUserMsg *msg)
 {
 	uint8_t *mac = (uint8_t *)&msg->payload.u64;
+	int eid = dev->eid;
 
 	RTE_LOG(DEBUG, VHOST_CONFIG,
 		":: mac: %02x:%02x:%02x:%02x:%02x:%02x\n",
@@ -1114,6 +1144,8 @@ vhost_user_send_rarp(struct virtio_net *dev, struct VhostUserMsg *msg)
 	 */
 	rte_smp_wmb();
 	rte_atomic16_set(&dev->broadcast_rarp, 1);
+	if (eid >= 0 && vdpa_engines[eid]->eng_drv->dev_ops.migration_done)
+		vdpa_engines[eid]->eng_drv->dev_ops.migration_done(dev->vid);
 
 	return 0;
 }
@@ -1375,6 +1407,8 @@ vhost_user_msg_handler(int vid, int fd)
 {
 	struct virtio_net *dev;
 	struct VhostUserMsg msg;
+	struct rte_vdpa_engine *eng;
+	int eid;
 	int ret;
 	int unlock_required = 0;
 
@@ -1527,7 +1561,7 @@ vhost_user_msg_handler(int vid, int fd)
 		break;
 
 	case VHOST_USER_GET_QUEUE_NUM:
-		msg.payload.u64 = VHOST_MAX_QUEUE_PAIRS;
+		msg.payload.u64 = (uint64_t)vhost_user_get_queue_num(dev);
 		msg.size = sizeof(msg.payload.u64);
 		send_vhost_reply(fd, &msg);
 		break;
@@ -1580,6 +1614,16 @@ vhost_user_msg_handler(int vid, int fd)
 		}
 	}
 
+	eid = dev->eid;
+	if (eid >= 0 && virtio_is_ready(dev) &&
+			!(dev->flags & VIRTIO_DEV_VDPA_CONFIGURED) &&
+			msg.request.master == VHOST_USER_SET_VRING_ENABLE) {
+		eng = vdpa_engines[eid];
+		if (eng->eng_drv->dev_ops.dev_conf)
+			eng->eng_drv->dev_ops.dev_conf(vid);
+		dev->flags |= VIRTIO_DEV_VDPA_CONFIGURED;
+	}
+
 	return 0;
 }
 
-- 
2.13.6

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v3 5/5] vhost: add apis for live migration
  2018-02-27 10:13 ` [PATCH v3 0/5] vhost: support selective datapath Zhihong Wang
                     ` (3 preceding siblings ...)
  2018-02-27 10:13   ` [PATCH v3 4/5] vhost: adapt vhost lib for selective datapath Zhihong Wang
@ 2018-02-27 10:13   ` Zhihong Wang
  2018-03-29 12:15   ` [PATCH v3 0/5] vhost: support selective datapath Wodkowski, PawelX
  5 siblings, 0 replies; 67+ messages in thread
From: Zhihong Wang @ 2018-02-27 10:13 UTC (permalink / raw)
  To: dev
  Cc: jianfeng.tan, tiwei.bie, maxime.coquelin, yliu, cunming.liang,
	xiao.w.wang, dan.daly, Zhihong Wang

This patch adds APIs to enable live migration for non-builtin data paths.

At src side, last_avail/used_idx from the device need to be set into the
virtio_net structure, and the log_base and log_size from the virtio_net
structure need to be set into the device.

At dst side, last_avail/used_idx need to be read from the virtio_net
structure and set into the device.

Signed-off-by: Zhihong Wang <zhihong.wang@intel.com>
---
 lib/librte_vhost/rte_vhost.h           | 51 +++++++++++++++++++++++++++
 lib/librte_vhost/rte_vhost_version.map |  3 ++
 lib/librte_vhost/vhost.c               | 63 ++++++++++++++++++++++++++++++++++
 3 files changed, 117 insertions(+)

diff --git a/lib/librte_vhost/rte_vhost.h b/lib/librte_vhost/rte_vhost.h
index 77c2a1a8b..0f9303949 100644
--- a/lib/librte_vhost/rte_vhost.h
+++ b/lib/librte_vhost/rte_vhost.h
@@ -540,6 +540,57 @@ int rte_vhost_vring_call(int vid, uint16_t vring_idx);
 uint32_t rte_vhost_rx_queue_count(int vid, uint16_t qid);
 
 /**
+ * Get log base and log size of the vhost device
+ *
+ * @param vid
+ *  vhost device ID
+ * @param log_base
+ *  vhost log base
+ * @param log_size
+ *  vhost log size
+ * @return
+ *  0 on success, -1 on failure
+ */
+int __rte_experimental
+rte_vhost_get_log_base(int vid, uint64_t *log_base, uint64_t *log_size);
+
+/**
+ * Get last_avail/used_idx of the vhost virtqueue
+ *
+ * @param vid
+ *  vhost device ID
+ * @param queue_id
+ *  vhost queue index
+ * @param last_avail_idx
+ *  vhost last_avail_idx to get
+ * @param last_used_idx
+ *  vhost last_used_idx to get
+ * @return
+ *  0 on success, -1 on failure
+ */
+int __rte_experimental
+rte_vhost_get_vring_base(int vid, uint16_t queue_id,
+		uint16_t *last_avail_idx, uint16_t *last_used_idx);
+
+/**
+ * Set last_avail/used_idx of the vhost virtqueue
+ *
+ * @param vid
+ *  vhost device ID
+ * @param queue_id
+ *  vhost queue index
+ * @param last_avail_idx
+ *  last_avail_idx to set
+ * @param last_used_idx
+ *  last_used_idx to set
+ * @return
+ *  0 on success, -1 on failure
+ */
+int __rte_experimental
+rte_vhost_set_vring_base(int vid, uint16_t queue_id,
+		uint16_t last_avail_idx, uint16_t last_used_idx);
+
+/**
  * Get vdpa engine id for vhost device.
  *
  * @param vid
diff --git a/lib/librte_vhost/rte_vhost_version.map b/lib/librte_vhost/rte_vhost_version.map
index 8ef2a396c..88bf6cb54 100644
--- a/lib/librte_vhost/rte_vhost_version.map
+++ b/lib/librte_vhost/rte_vhost_version.map
@@ -74,4 +74,7 @@ EXPERIMENTAL {
 	rte_vhost_get_vdpa_did;
 	rte_vhost_driver_get_protocol_features;
 	rte_vhost_driver_get_queue_num;
+	rte_vhost_get_log_base;
+	rte_vhost_get_vring_base;
+	rte_vhost_set_vring_base;
 } DPDK_18.02;
diff --git a/lib/librte_vhost/vhost.c b/lib/librte_vhost/vhost.c
index f8a5a1c42..c7332c557 100644
--- a/lib/librte_vhost/vhost.c
+++ b/lib/librte_vhost/vhost.c
@@ -667,3 +667,66 @@ int rte_vhost_get_vdpa_did(int vid)
 
 	return dev->did;
 }
+
+int rte_vhost_get_log_base(int vid, uint64_t *log_base,
+		uint64_t *log_size)
+{
+	struct virtio_net *dev = get_device(vid);
+
+	if (!dev)
+		return -1;
+
+	if (unlikely(!(dev->flags & VIRTIO_DEV_BUILTIN_VIRTIO_NET))) {
+		RTE_LOG(ERR, VHOST_DATA,
+			"(%d) %s: built-in vhost net backend is disabled.\n",
+			dev->vid, __func__);
+		return -1;
+	}
+
+	*log_base = dev->log_base;
+	*log_size = dev->log_size;
+
+	return 0;
+}
+
+int rte_vhost_get_vring_base(int vid, uint16_t queue_id,
+		uint16_t *last_avail_idx, uint16_t *last_used_idx)
+{
+	struct virtio_net *dev = get_device(vid);
+
+	if (!dev)
+		return -1;
+
+	if (unlikely(!(dev->flags & VIRTIO_DEV_BUILTIN_VIRTIO_NET))) {
+		RTE_LOG(ERR, VHOST_DATA,
+			"(%d) %s: built-in vhost net backend is disabled.\n",
+			dev->vid, __func__);
+		return -1;
+	}
+
+	*last_avail_idx = dev->virtqueue[queue_id]->last_avail_idx;
+	*last_used_idx = dev->virtqueue[queue_id]->last_used_idx;
+
+	return 0;
+}
+
+int rte_vhost_set_vring_base(int vid, uint16_t queue_id,
+		uint16_t last_avail_idx, uint16_t last_used_idx)
+{
+	struct virtio_net *dev = get_device(vid);
+
+	if (!dev)
+		return -1;
+
+	if (unlikely(!(dev->flags & VIRTIO_DEV_BUILTIN_VIRTIO_NET))) {
+		RTE_LOG(ERR, VHOST_DATA,
+			"(%d) %s: built-in vhost net backend is disabled.\n",
+			dev->vid, __func__);
+		return -1;
+	}
+
+	dev->virtqueue[queue_id]->last_avail_idx = last_avail_idx;
+	dev->virtqueue[queue_id]->last_used_idx = last_used_idx;
+
+	return 0;
+}
-- 
2.13.6

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* Re: [PATCH v2 1/6] vhost: export vhost feature definitions
  2018-02-13  9:21   ` [PATCH v2 1/6] vhost: export vhost feature definitions Zhihong Wang
@ 2018-03-06  9:37     ` Tan, Jianfeng
  2018-03-06 14:03       ` Maxime Coquelin
  0 siblings, 1 reply; 67+ messages in thread
From: Tan, Jianfeng @ 2018-03-06  9:37 UTC (permalink / raw)
  To: Wang, Zhihong, dev
  Cc: Bie, Tiwei, maxime.coquelin, yliu, Liang, Cunming, Wang, Xiao W,
	Daly, Dan



> -----Original Message-----
> From: Wang, Zhihong
> Sent: Tuesday, February 13, 2018 5:21 PM
> To: dev@dpdk.org
> Cc: Tan, Jianfeng; Bie, Tiwei; maxime.coquelin@redhat.com;
> yliu@fridaylinux.org; Liang, Cunming; Wang, Xiao W; Daly, Dan; Wang,
> Zhihong
> Subject: [PATCH v2 1/6] vhost: export vhost feature definitions
> 
> This patch exports vhost-user protocol features to support device driver
> development.
> 
> Signed-off-by: Zhihong Wang <zhihong.wang@intel.com>
> ---
>  lib/librte_vhost/rte_vhost.h  |  8 ++++++++
>  lib/librte_vhost/vhost.h      |  4 +---
>  lib/librte_vhost/vhost_user.c |  9 +++++----
>  lib/librte_vhost/vhost_user.h | 20 +++++++-------------
>  4 files changed, 21 insertions(+), 20 deletions(-)
> 
> diff --git a/lib/librte_vhost/rte_vhost.h b/lib/librte_vhost/rte_vhost.h
> index d33206997..b05162366 100644
> --- a/lib/librte_vhost/rte_vhost.h
> +++ b/lib/librte_vhost/rte_vhost.h
> @@ -29,6 +29,14 @@ extern "C" {
>  #define RTE_VHOST_USER_DEQUEUE_ZERO_COPY	(1ULL << 2)
>  #define RTE_VHOST_USER_IOMMU_SUPPORT	(1ULL << 3)
> 
> +#define RTE_VHOST_USER_PROTOCOL_F_MQ		0

Instead of adding a "RTE_" prefix. I prefer to define it like this:
#ifndef VHOST_USER_PROTOCOL_F_MQ
#define VHOST_USER_PROTOCOL_F_MQ                                           0
#endif

Similar to other macros.

> +#define RTE_VHOST_USER_PROTOCOL_F_LOG_SHMFD	1
> +#define RTE_VHOST_USER_PROTOCOL_F_RARP		2
> +#define RTE_VHOST_USER_PROTOCOL_F_REPLY_ACK	3
> +#define RTE_VHOST_USER_PROTOCOL_F_NET_MTU	4
> +#define RTE_VHOST_USER_PROTOCOL_F_SLAVE_REQ	5
> +#define RTE_VHOST_USER_F_PROTOCOL_FEATURES	30
> +
>  /**
>   * Information relating to memory regions including offsets to
>   * addresses in QEMUs memory file.
> diff --git a/lib/librte_vhost/vhost.h b/lib/librte_vhost/vhost.h
> index 58aec2e0d..a0b0520e2 100644
> --- a/lib/librte_vhost/vhost.h
> +++ b/lib/librte_vhost/vhost.h
> @@ -174,8 +174,6 @@ struct vhost_msg {
>   #define VIRTIO_F_VERSION_1 32
>  #endif
> 
> -#define VHOST_USER_F_PROTOCOL_FEATURES	30
> -
>  /* Features supported by this builtin vhost-user net driver. */
>  #define VIRTIO_NET_SUPPORTED_FEATURES ((1ULL <<
> VIRTIO_NET_F_MRG_RXBUF) | \
>  				(1ULL << VIRTIO_F_ANY_LAYOUT) | \
> @@ -185,7 +183,7 @@ struct vhost_msg {
>  				(1ULL << VIRTIO_NET_F_MQ)      | \
>  				(1ULL << VIRTIO_F_VERSION_1)   | \
>  				(1ULL << VHOST_F_LOG_ALL)      | \
> -				(1ULL <<
> VHOST_USER_F_PROTOCOL_FEATURES) | \
> +				(1ULL <<
> RTE_VHOST_USER_F_PROTOCOL_FEATURES) | \
>  				(1ULL << VIRTIO_NET_F_GSO) | \
>  				(1ULL << VIRTIO_NET_F_HOST_TSO4) | \
>  				(1ULL << VIRTIO_NET_F_HOST_TSO6) | \
> diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c
> index 5c5361066..c93e48e4d 100644
> --- a/lib/librte_vhost/vhost_user.c
> +++ b/lib/librte_vhost/vhost_user.c
> @@ -527,7 +527,7 @@ vhost_user_set_vring_addr(struct virtio_net **pdev,
> VhostUserMsg *msg)
>  	vring_invalidate(dev, vq);
> 
>  	if (vq->enabled && (dev->features &
> -				(1ULL <<
> VHOST_USER_F_PROTOCOL_FEATURES))) {
> +				(1ULL <<
> RTE_VHOST_USER_F_PROTOCOL_FEATURES))) {
>  		dev = translate_ring_addresses(dev, msg-
> >payload.addr.index);
>  		if (!dev)
>  			return -1;
> @@ -897,11 +897,11 @@ vhost_user_set_vring_kick(struct virtio_net
> **pdev, struct VhostUserMsg *pmsg)
>  	vq = dev->virtqueue[file.index];
> 
>  	/*
> -	 * When VHOST_USER_F_PROTOCOL_FEATURES is not negotiated,
> +	 * When RTE_VHOST_USER_F_PROTOCOL_FEATURES is not
> negotiated,
>  	 * the ring starts already enabled. Otherwise, it is enabled via
>  	 * the SET_VRING_ENABLE message.
>  	 */
> -	if (!(dev->features & (1ULL <<
> VHOST_USER_F_PROTOCOL_FEATURES)))
> +	if (!(dev->features & (1ULL <<
> RTE_VHOST_USER_F_PROTOCOL_FEATURES)))
>  		vq->enabled = 1;
> 
>  	if (vq->kickfd >= 0)
> @@ -1012,7 +1012,8 @@ vhost_user_get_protocol_features(struct
> virtio_net *dev,
>  	 * Qemu versions (from v2.7.0 to v2.9.0).
>  	 */
>  	if (!(features & (1ULL << VIRTIO_F_IOMMU_PLATFORM)))
> -		protocol_features &= ~(1ULL <<
> VHOST_USER_PROTOCOL_F_REPLY_ACK);
> +		protocol_features &=
> +			~(1ULL <<
> RTE_VHOST_USER_PROTOCOL_F_REPLY_ACK);
> 
>  	msg->payload.u64 = protocol_features;
>  	msg->size = sizeof(msg->payload.u64);
> diff --git a/lib/librte_vhost/vhost_user.h b/lib/librte_vhost/vhost_user.h
> index 0fafbe6e0..066e772dd 100644
> --- a/lib/librte_vhost/vhost_user.h
> +++ b/lib/librte_vhost/vhost_user.h
> @@ -14,19 +14,13 @@
> 
>  #define VHOST_MEMORY_MAX_NREGIONS 8
> 
> -#define VHOST_USER_PROTOCOL_F_MQ	0
> -#define VHOST_USER_PROTOCOL_F_LOG_SHMFD	1
> -#define VHOST_USER_PROTOCOL_F_RARP	2
> -#define VHOST_USER_PROTOCOL_F_REPLY_ACK	3
> -#define VHOST_USER_PROTOCOL_F_NET_MTU 4
> -#define VHOST_USER_PROTOCOL_F_SLAVE_REQ 5
> -
> -#define VHOST_USER_PROTOCOL_FEATURES	((1ULL <<
> VHOST_USER_PROTOCOL_F_MQ) | \
> -					 (1ULL <<
> VHOST_USER_PROTOCOL_F_LOG_SHMFD) |\
> -					 (1ULL <<
> VHOST_USER_PROTOCOL_F_RARP) | \
> -					 (1ULL <<
> VHOST_USER_PROTOCOL_F_REPLY_ACK) | \
> -					 (1ULL <<
> VHOST_USER_PROTOCOL_F_NET_MTU) | \
> -					 (1ULL <<
> VHOST_USER_PROTOCOL_F_SLAVE_REQ))
> +#define VHOST_USER_PROTOCOL_FEATURES \
> +			((1ULL << RTE_VHOST_USER_PROTOCOL_F_MQ) | \
> +			 (1ULL <<
> RTE_VHOST_USER_PROTOCOL_F_LOG_SHMFD) |\
> +			 (1ULL << RTE_VHOST_USER_PROTOCOL_F_RARP) | \
> +			 (1ULL <<
> RTE_VHOST_USER_PROTOCOL_F_REPLY_ACK) | \
> +			 (1ULL <<
> RTE_VHOST_USER_PROTOCOL_F_NET_MTU) | \
> +			 (1ULL <<
> RTE_VHOST_USER_PROTOCOL_F_SLAVE_REQ))
> 
>  typedef enum VhostUserRequest {
>  	VHOST_USER_NONE = 0,
> --
> 2.13.6

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v2 6/6] vhost: export new apis
  2018-02-13  9:21   ` [PATCH v2 6/6] vhost: export new apis Zhihong Wang
@ 2018-03-06  9:51     ` Tan, Jianfeng
  2018-03-15 10:55       ` Wang, Zhihong
  0 siblings, 1 reply; 67+ messages in thread
From: Tan, Jianfeng @ 2018-03-06  9:51 UTC (permalink / raw)
  To: Wang, Zhihong, dev
  Cc: Bie, Tiwei, maxime.coquelin, yliu, Liang, Cunming, Wang, Xiao W,
	Daly, Dan



> -----Original Message-----
> From: Wang, Zhihong
> Sent: Tuesday, February 13, 2018 5:21 PM
> To: dev@dpdk.org
> Cc: Tan, Jianfeng; Bie, Tiwei; maxime.coquelin@redhat.com;
> yliu@fridaylinux.org; Liang, Cunming; Wang, Xiao W; Daly, Dan; Wang,
> Zhihong
> Subject: [PATCH v2 6/6] vhost: export new apis
> 
> This patch exports new APIs as experimental.

How about squeezing this patch with patch 2 where the APIs are introduced, as well as the related doc update?

Thanks,
Jianfeng
 
> 
> Signed-off-by: Zhihong Wang <zhihong.wang@intel.com>
> ---
>  lib/librte_vhost/rte_vdpa.h            | 16 +++++++++++-----
>  lib/librte_vhost/rte_vhost.h           | 33 ++++++++++++++++++++++-----------
>  lib/librte_vhost/rte_vhost_version.map | 19 +++++++++++++++++++
>  3 files changed, 52 insertions(+), 16 deletions(-)
> 
> diff --git a/lib/librte_vhost/rte_vdpa.h b/lib/librte_vhost/rte_vdpa.h
> index 1bde36f7f..23fb471be 100644
> --- a/lib/librte_vhost/rte_vdpa.h
> +++ b/lib/librte_vhost/rte_vdpa.h
> @@ -100,15 +100,21 @@ extern struct rte_vdpa_engine *vdpa_engines[];
>  extern uint32_t vdpa_engine_num;
> 
>  /* engine management */
> -int rte_vdpa_register_engine(const char *name, struct rte_vdpa_eng_addr
> *addr);
> -int rte_vdpa_unregister_engine(int eid);
> +int __rte_experimental
> +rte_vdpa_register_engine(const char *name, struct rte_vdpa_eng_addr
> *addr);
> 
> -int rte_vdpa_find_engine_id(struct rte_vdpa_eng_addr *addr);
> +int __rte_experimental
> +rte_vdpa_unregister_engine(int eid);
> 
> -int rte_vdpa_info_query(int eid, struct rte_vdpa_eng_attr *attr);
> +int __rte_experimental
> +rte_vdpa_find_engine_id(struct rte_vdpa_eng_addr *addr);
> +
> +int __rte_experimental
> +rte_vdpa_info_query(int eid, struct rte_vdpa_eng_attr *attr);
> 
>  /* driver register api */
> -void rte_vdpa_register_driver(struct rte_vdpa_eng_driver *drv);
> +void __rte_experimental
> +rte_vdpa_register_driver(struct rte_vdpa_eng_driver *drv);
> 
>  #define RTE_VDPA_REGISTER_DRIVER(nm, drv) \
>  RTE_INIT(vdpainitfn_ ##nm); \
> diff --git a/lib/librte_vhost/rte_vhost.h b/lib/librte_vhost/rte_vhost.h
> index 48005d9ff..d5589c543 100644
> --- a/lib/librte_vhost/rte_vhost.h
> +++ b/lib/librte_vhost/rte_vhost.h
> @@ -187,7 +187,8 @@ int rte_vhost_driver_unregister(const char *path);
>   * @return
>   *  0 on success, -1 on failure
>   */
> -int rte_vhost_driver_set_vdpa_eid(const char *path, int eid);
> +int __rte_experimental
> +rte_vhost_driver_set_vdpa_eid(const char *path, int eid);
> 
>  /**
>   * Set the device id, enforce single connection per socket
> @@ -199,7 +200,8 @@ int rte_vhost_driver_set_vdpa_eid(const char *path,
> int eid);
>   * @return
>   *  0 on success, -1 on failure
>   */
> -int rte_vhost_driver_set_vdpa_did(const char *path, int did);
> +int __rte_experimental
> +rte_vhost_driver_set_vdpa_did(const char *path, int did);
> 
>  /**
>   * Get the engine id
> @@ -209,7 +211,8 @@ int rte_vhost_driver_set_vdpa_did(const char *path,
> int did);
>   * @return
>   *  Engine id, -1 on failure
>   */
> -int rte_vhost_driver_get_vdpa_eid(const char *path);
> +int __rte_experimental
> +rte_vhost_driver_get_vdpa_eid(const char *path);
> 
>  /**
>   * Get the device id
> @@ -219,7 +222,8 @@ int rte_vhost_driver_get_vdpa_eid(const char *path);
>   * @return
>   *  Device id, -1 on failure
>   */
> -int rte_vhost_driver_get_vdpa_did(const char *path);
> +int __rte_experimental
> +rte_vhost_driver_get_vdpa_did(const char *path);
> 
>  /**
>   * Set the feature bits the vhost-user driver supports.
> @@ -286,7 +290,8 @@ int rte_vhost_driver_get_features(const char *path,
> uint64_t *features);
>   * @return
>   *  0 on success, -1 on failure
>   */
> -int rte_vhost_driver_get_protocol_features(const char *path,
> +int __rte_experimental
> +rte_vhost_driver_get_protocol_features(const char *path,
>  		uint64_t *protocol_features);
> 
>  /**
> @@ -299,7 +304,8 @@ int rte_vhost_driver_get_protocol_features(const
> char *path,
>   * @return
>   *  0 on success, -1 on failure
>   */
> -int rte_vhost_driver_get_queue_num(const char *path, uint32_t
> *queue_num);
> +int __rte_experimental
> +rte_vhost_driver_get_queue_num(const char *path, uint32_t
> *queue_num);
> 
>  /**
>   * Get the feature bits after negotiation
> @@ -523,7 +529,8 @@ uint32_t rte_vhost_rx_queue_count(int vid, uint16_t
> qid);
>   * @return
>   *  0 on success, -1 on failure
>   */
> -int rte_vhost_get_log_base(int vid, uint64_t *log_base,
> +int __rte_experimental
> +rte_vhost_get_log_base(int vid, uint64_t *log_base,
>  		uint64_t *log_size);
> 
>  /**
> @@ -540,7 +547,8 @@ int rte_vhost_get_log_base(int vid, uint64_t
> *log_base,
>   * @return
>   *  0 on success, -1 on failure
>   */
> -int rte_vhost_get_vring_base(int vid, uint16_t queue_id,
> +int __rte_experimental
> +rte_vhost_get_vring_base(int vid, uint16_t queue_id,
>  		uint16_t *last_avail_idx, uint16_t *last_used_idx);
> 
>  /**
> @@ -557,7 +565,8 @@ int rte_vhost_get_vring_base(int vid, uint16_t
> queue_id,
>   * @return
>   *  0 on success, -1 on failure
>   */
> -int rte_vhost_set_vring_base(int vid, uint16_t queue_id,
> +int __rte_experimental
> +rte_vhost_set_vring_base(int vid, uint16_t queue_id,
>  		uint16_t last_avail_idx, uint16_t last_used_idx);
> 
>  /**
> @@ -568,7 +577,8 @@ int rte_vhost_set_vring_base(int vid, uint16_t
> queue_id,
>   * @return
>   *  engine id
>   */
> -int rte_vhost_get_vdpa_eid(int vid);
> +int __rte_experimental
> +rte_vhost_get_vdpa_eid(int vid);
> 
>  /**
>   * Get vdpa device id for vhost device.
> @@ -578,7 +588,8 @@ int rte_vhost_get_vdpa_eid(int vid);
>   * @return
>   *  device id
>   */
> -int rte_vhost_get_vdpa_did(int vid);
> +int __rte_experimental
> +rte_vhost_get_vdpa_did(int vid);
> 
>  #ifdef __cplusplus
>  }
> diff --git a/lib/librte_vhost/rte_vhost_version.map
> b/lib/librte_vhost/rte_vhost_version.map
> index df0103129..36257e51b 100644
> --- a/lib/librte_vhost/rte_vhost_version.map
> +++ b/lib/librte_vhost/rte_vhost_version.map
> @@ -59,3 +59,22 @@ DPDK_18.02 {
>  	rte_vhost_vring_call;
> 
>  } DPDK_17.08;
> +
> +EXPERIMENTAL {
> +	rte_vhost_driver_set_vdpa_eid;
> +	rte_vhost_driver_set_vdpa_did;
> +	rte_vhost_driver_get_vdpa_eid;
> +	rte_vhost_driver_get_vdpa_did;
> +	rte_vhost_driver_get_protocol_features;
> +	rte_vhost_driver_get_queue_num;
> +	rte_vhost_get_log_base;
> +	rte_vhost_get_vring_base;
> +	rte_vhost_set_vring_base;
> +	rte_vhost_get_vdpa_eid;
> +	rte_vhost_get_vdpa_did;
> +	rte_vdpa_register_engine;
> +	rte_vdpa_unregister_engine;
> +	rte_vdpa_find_engine_id;
> +	rte_vdpa_info_query;
> +	rte_vdpa_register_driver;
> +} DPDK_18.02;
> --
> 2.13.6

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v2 1/6] vhost: export vhost feature definitions
  2018-03-06  9:37     ` Tan, Jianfeng
@ 2018-03-06 14:03       ` Maxime Coquelin
  2018-03-15 10:58         ` Wang, Zhihong
  0 siblings, 1 reply; 67+ messages in thread
From: Maxime Coquelin @ 2018-03-06 14:03 UTC (permalink / raw)
  To: Tan, Jianfeng, Wang, Zhihong, dev
  Cc: Bie, Tiwei, yliu, Liang, Cunming, Wang, Xiao W, Daly, Dan



On 03/06/2018 10:37 AM, Tan, Jianfeng wrote:
> 
> 
>> -----Original Message-----
>> From: Wang, Zhihong
>> Sent: Tuesday, February 13, 2018 5:21 PM
>> To: dev@dpdk.org
>> Cc: Tan, Jianfeng; Bie, Tiwei; maxime.coquelin@redhat.com;
>> yliu@fridaylinux.org; Liang, Cunming; Wang, Xiao W; Daly, Dan; Wang,
>> Zhihong
>> Subject: [PATCH v2 1/6] vhost: export vhost feature definitions
>>
>> This patch exports vhost-user protocol features to support device driver
>> development.
>>
>> Signed-off-by: Zhihong Wang <zhihong.wang@intel.com>
>> ---
>>   lib/librte_vhost/rte_vhost.h  |  8 ++++++++
>>   lib/librte_vhost/vhost.h      |  4 +---
>>   lib/librte_vhost/vhost_user.c |  9 +++++----
>>   lib/librte_vhost/vhost_user.h | 20 +++++++-------------
>>   4 files changed, 21 insertions(+), 20 deletions(-)
>>
>> diff --git a/lib/librte_vhost/rte_vhost.h b/lib/librte_vhost/rte_vhost.h
>> index d33206997..b05162366 100644
>> --- a/lib/librte_vhost/rte_vhost.h
>> +++ b/lib/librte_vhost/rte_vhost.h
>> @@ -29,6 +29,14 @@ extern "C" {
>>   #define RTE_VHOST_USER_DEQUEUE_ZERO_COPY	(1ULL << 2)
>>   #define RTE_VHOST_USER_IOMMU_SUPPORT	(1ULL << 3)
>>
>> +#define RTE_VHOST_USER_PROTOCOL_F_MQ		0
> 
> Instead of adding a "RTE_" prefix. I prefer to define it like this:
> #ifndef VHOST_USER_PROTOCOL_F_MQ
> #define VHOST_USER_PROTOCOL_F_MQ                                           0
> #endif
> 
> Similar to other macros.

I agree, it is better to keep same naming as in the spec IMHO.

>> +#define RTE_VHOST_USER_PROTOCOL_F_LOG_SHMFD	1
>> +#define RTE_VHOST_USER_PROTOCOL_F_RARP		2
>> +#define RTE_VHOST_USER_PROTOCOL_F_REPLY_ACK	3
>> +#define RTE_VHOST_USER_PROTOCOL_F_NET_MTU	4
>> +#define RTE_VHOST_USER_PROTOCOL_F_SLAVE_REQ	5
>> +#define RTE_VHOST_USER_F_PROTOCOL_FEATURES	30

Please put the above declaration separately, it could be misleading,
making to think it is a vhost-user protocol feature whereas it is a
Virtio feature.

>> +
>>   /**
>>    * Information relating to memory regions including offsets to
>>    * addresses in QEMUs memory file.
>> diff --git a/lib/librte_vhost/vhost.h b/lib/librte_vhost/vhost.h
>> index 58aec2e0d..a0b0520e2 100644
>> --- a/lib/librte_vhost/vhost.h
>> +++ b/lib/librte_vhost/vhost.h
>> @@ -174,8 +174,6 @@ struct vhost_msg {
>>    #define VIRTIO_F_VERSION_1 32
>>   #endif
>>
>> -#define VHOST_USER_F_PROTOCOL_FEATURES	30
>> -
>>   /* Features supported by this builtin vhost-user net driver. */
>>   #define VIRTIO_NET_SUPPORTED_FEATURES ((1ULL <<
>> VIRTIO_NET_F_MRG_RXBUF) | \
>>   				(1ULL << VIRTIO_F_ANY_LAYOUT) | \
>> @@ -185,7 +183,7 @@ struct vhost_msg {
>>   				(1ULL << VIRTIO_NET_F_MQ)      | \
>>   				(1ULL << VIRTIO_F_VERSION_1)   | \
>>   				(1ULL << VHOST_F_LOG_ALL)      | \
>> -				(1ULL <<
>> VHOST_USER_F_PROTOCOL_FEATURES) | \
>> +				(1ULL <<
>> RTE_VHOST_USER_F_PROTOCOL_FEATURES) | \
>>   				(1ULL << VIRTIO_NET_F_GSO) | \
>>   				(1ULL << VIRTIO_NET_F_HOST_TSO4) | \
>>   				(1ULL << VIRTIO_NET_F_HOST_TSO6) | \
>> diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c
>> index 5c5361066..c93e48e4d 100644
>> --- a/lib/librte_vhost/vhost_user.c
>> +++ b/lib/librte_vhost/vhost_user.c
>> @@ -527,7 +527,7 @@ vhost_user_set_vring_addr(struct virtio_net **pdev,
>> VhostUserMsg *msg)
>>   	vring_invalidate(dev, vq);
>>
>>   	if (vq->enabled && (dev->features &
>> -				(1ULL <<
>> VHOST_USER_F_PROTOCOL_FEATURES))) {
>> +				(1ULL <<
>> RTE_VHOST_USER_F_PROTOCOL_FEATURES))) {
>>   		dev = translate_ring_addresses(dev, msg-
>>> payload.addr.index);
>>   		if (!dev)
>>   			return -1;
>> @@ -897,11 +897,11 @@ vhost_user_set_vring_kick(struct virtio_net
>> **pdev, struct VhostUserMsg *pmsg)
>>   	vq = dev->virtqueue[file.index];
>>
>>   	/*
>> -	 * When VHOST_USER_F_PROTOCOL_FEATURES is not negotiated,
>> +	 * When RTE_VHOST_USER_F_PROTOCOL_FEATURES is not
>> negotiated,
>>   	 * the ring starts already enabled. Otherwise, it is enabled via
>>   	 * the SET_VRING_ENABLE message.
>>   	 */
>> -	if (!(dev->features & (1ULL <<
>> VHOST_USER_F_PROTOCOL_FEATURES)))
>> +	if (!(dev->features & (1ULL <<
>> RTE_VHOST_USER_F_PROTOCOL_FEATURES)))
>>   		vq->enabled = 1;
>>
>>   	if (vq->kickfd >= 0)
>> @@ -1012,7 +1012,8 @@ vhost_user_get_protocol_features(struct
>> virtio_net *dev,
>>   	 * Qemu versions (from v2.7.0 to v2.9.0).
>>   	 */
>>   	if (!(features & (1ULL << VIRTIO_F_IOMMU_PLATFORM)))
>> -		protocol_features &= ~(1ULL <<
>> VHOST_USER_PROTOCOL_F_REPLY_ACK);
>> +		protocol_features &=
>> +			~(1ULL <<
>> RTE_VHOST_USER_PROTOCOL_F_REPLY_ACK);
>>
>>   	msg->payload.u64 = protocol_features;
>>   	msg->size = sizeof(msg->payload.u64);
>> diff --git a/lib/librte_vhost/vhost_user.h b/lib/librte_vhost/vhost_user.h
>> index 0fafbe6e0..066e772dd 100644
>> --- a/lib/librte_vhost/vhost_user.h
>> +++ b/lib/librte_vhost/vhost_user.h
>> @@ -14,19 +14,13 @@
>>
>>   #define VHOST_MEMORY_MAX_NREGIONS 8
>>
>> -#define VHOST_USER_PROTOCOL_F_MQ	0
>> -#define VHOST_USER_PROTOCOL_F_LOG_SHMFD	1
>> -#define VHOST_USER_PROTOCOL_F_RARP	2
>> -#define VHOST_USER_PROTOCOL_F_REPLY_ACK	3
>> -#define VHOST_USER_PROTOCOL_F_NET_MTU 4
>> -#define VHOST_USER_PROTOCOL_F_SLAVE_REQ 5
>> -
>> -#define VHOST_USER_PROTOCOL_FEATURES	((1ULL <<
>> VHOST_USER_PROTOCOL_F_MQ) | \
>> -					 (1ULL <<
>> VHOST_USER_PROTOCOL_F_LOG_SHMFD) |\
>> -					 (1ULL <<
>> VHOST_USER_PROTOCOL_F_RARP) | \
>> -					 (1ULL <<
>> VHOST_USER_PROTOCOL_F_REPLY_ACK) | \
>> -					 (1ULL <<
>> VHOST_USER_PROTOCOL_F_NET_MTU) | \
>> -					 (1ULL <<
>> VHOST_USER_PROTOCOL_F_SLAVE_REQ))
>> +#define VHOST_USER_PROTOCOL_FEATURES \
>> +			((1ULL << RTE_VHOST_USER_PROTOCOL_F_MQ) | \
>> +			 (1ULL <<
>> RTE_VHOST_USER_PROTOCOL_F_LOG_SHMFD) |\
>> +			 (1ULL << RTE_VHOST_USER_PROTOCOL_F_RARP) | \
>> +			 (1ULL <<
>> RTE_VHOST_USER_PROTOCOL_F_REPLY_ACK) | \
>> +			 (1ULL <<
>> RTE_VHOST_USER_PROTOCOL_F_NET_MTU) | \
>> +			 (1ULL <<
>> RTE_VHOST_USER_PROTOCOL_F_SLAVE_REQ))
>>
>>   typedef enum VhostUserRequest {
>>   	VHOST_USER_NONE = 0,
>> --
>> 2.13.6
> 

^ permalink raw reply	[flat|nested] 67+ messages in thread

* [PATCH v4 0/5] vhost: support selective datapath
  2018-02-02 23:28 [PATCH 0/7] vhost: support selective datapath Zhihong Wang
                   ` (8 preceding siblings ...)
  2018-02-27 10:13 ` [PATCH v3 0/5] vhost: support selective datapath Zhihong Wang
@ 2018-03-10 10:01 ` Zhihong Wang
  2018-03-10 10:01   ` [PATCH v4 1/5] vhost: export vhost feature definitions Zhihong Wang
                     ` (4 more replies)
  2018-04-02 11:46 ` [PATCH v5 0/5] vhost: support selective datapath Zhihong Wang
  10 siblings, 5 replies; 67+ messages in thread
From: Zhihong Wang @ 2018-03-10 10:01 UTC (permalink / raw)
  To: dev
  Cc: jianfeng.tan, tiwei.bie, maxime.coquelin, yliu, cunming.liang,
	xiao.w.wang, dan.daly, Zhihong Wang

This patch set introduces support for selective datapath in DPDK vhost-user
lib. vDPA stands for vhost Data Path Acceleration. The idea is to support
virtio ring compatible devices to serve virtio driver directly to enable
datapath acceleration.

Design details
====

A vDPA device is a virtio ring compatible backend. It's defined as follows:

struct rte_vdpa_dev_addr {
	enum vdpa_addr_type type;
	union {
		uint8_t __dummy[64];
		struct rte_pci_addr pci_addr;
	};
};

struct rte_vdpa_dev_ops {
	vdpa_dev_queue_num_get_t  queue_num_get;
	vdpa_dev_feature_get_t    feature_get;
	vdpa_dev_feature_get_t    protocol_feature_get;
	vdpa_dev_conf_t           dev_conf;
	vdpa_dev_close_t          dev_close;
	vdpa_vring_state_set_t    vring_state_set;
	vdpa_feature_set_t        feature_set;
	vdpa_migration_done_t     migration_done;
	vdpa_get_vfio_group_fd_t  get_vfio_group_fd;
	vdpa_get_vfio_device_fd_t get_vfio_device_fd;
	vdpa_get_notify_area_t    get_notify_area;
};

struct rte_vdpa_device {
	struct rte_vdpa_dev_addr addr;
	struct rte_vdpa_dev_ops *ops;
} __rte_cache_aligned;


Changes to the current vhost-user lib are:
====

 1. Make vhost device capabilities configurable to adopt various devices.
    Such capabilities include supported features, protocol features, queue
    number. APIs are introduced to configure these capabilities.

 2. A set of device ops is defined for device specific operations:

     a. queue_num_get: Called to get supported queue number of the device.

     b. feature_get: Called to get supported features of the device.

     c. protocol_feature_get: Called to get supported protocol features of
        the device.

     d. dev_conf: Called to configure the actual device when the virtio
        device becomes ready.

     e. dev_close: Called to close the actual device when the virtio device
        is stopped.

     f. vring_state_set: Called to change the state of the vring in the
        actual device when vring state changes.

     g. feature_set: Called to set the negotiated features to device.

     h. migration_done: Called to allow the device to response to RARP
        sending.

     i. get_vfio_group_fd: Called to get the VFIO group fd of the device.

     j. get_vfio_device_fd: Called to get the VFIO device fd of the device.

     k. get_notify_area: Called to get the notify area info of the queue.

 3. To make vhost aware of its datapath type, an device id (did) is added
    into the vhost data structure to identify the actual device. APIs are
    introduced to configure it. When the default software datapath is used,
    did is set to -1. When alternative datapath is used, did should be set
    to specify which device to use, and each vhost-user socket can have
    only 1 connection in this case.

Working process:
====

 1. Register vDPA device with address and device ops, and get a did.

 2. For vhost device creation:

      a. Register vhost-user socket.

      b. Set did of the vhost-user socket.

      c. Register vhost-user callbacks.

      d. Start to wait for connection.

 3. When connection comes and virtio device data structure is negotiated,
    the device will be configured with all needed info.

---
Changes in v4:

 1. Remove the "engine" concept in the lib.

---
Changes in v3:

 1. Keep macro names the same as in the spec.

 2. Export new APIs where they're introduced.

---
Changes in v2:

 1. Ensure negotiated capabilities are supported in vhost-user lib.

 2. Add APIs for live migration.

 3. Configure the data path at the right time.

 4. Add VFIO related vDPA device ops.

 5. Rebase on dpdk-next-virtio.

Zhihong Wang (5):
  vhost: export vhost feature definitions
  vhost: support selective datapath
  vhost: add apis for datapath configuration
  vhost: adapt vhost lib for selective datapath
  vhost: add apis for live migration

 lib/librte_vhost/Makefile              |   4 +-
 lib/librte_vhost/rte_vdpa.h            |  94 ++++++++++++++++++++++
 lib/librte_vhost/rte_vhost.h           | 143 +++++++++++++++++++++++++++++++++
 lib/librte_vhost/rte_vhost_version.map |  14 ++++
 lib/librte_vhost/socket.c              | 130 ++++++++++++++++++++++++++++--
 lib/librte_vhost/vdpa.c                |  96 ++++++++++++++++++++++
 lib/librte_vhost/vhost.c               |  91 +++++++++++++++++++++
 lib/librte_vhost/vhost.h               |  13 ++-
 lib/librte_vhost/vhost_user.c          |  54 +++++++++++--
 lib/librte_vhost/vhost_user.h          |   7 --
 10 files changed, 625 insertions(+), 21 deletions(-)
 create mode 100644 lib/librte_vhost/rte_vdpa.h
 create mode 100644 lib/librte_vhost/vdpa.c

-- 
2.13.6

^ permalink raw reply	[flat|nested] 67+ messages in thread

* [PATCH v4 1/5] vhost: export vhost feature definitions
  2018-03-10 10:01 ` [PATCH v4 " Zhihong Wang
@ 2018-03-10 10:01   ` Zhihong Wang
  2018-03-31  5:56     ` Maxime Coquelin
  2018-03-10 10:01   ` [PATCH v4 2/5] vhost: support selective datapath Zhihong Wang
                     ` (3 subsequent siblings)
  4 siblings, 1 reply; 67+ messages in thread
From: Zhihong Wang @ 2018-03-10 10:01 UTC (permalink / raw)
  To: dev
  Cc: jianfeng.tan, tiwei.bie, maxime.coquelin, yliu, cunming.liang,
	xiao.w.wang, dan.daly, Zhihong Wang

This patch exports vhost-user protocol features to support device driver
development.

Signed-off-by: Zhihong Wang <zhihong.wang@intel.com>
---
Changes in v3:

 1. Keep macro names the same as in the spec.

 lib/librte_vhost/rte_vhost.h  | 30 ++++++++++++++++++++++++++++++
 lib/librte_vhost/vhost.h      |  2 --
 lib/librte_vhost/vhost_user.h |  7 -------
 3 files changed, 30 insertions(+), 9 deletions(-)

diff --git a/lib/librte_vhost/rte_vhost.h b/lib/librte_vhost/rte_vhost.h
index d33206997..671ea5053 100644
--- a/lib/librte_vhost/rte_vhost.h
+++ b/lib/librte_vhost/rte_vhost.h
@@ -29,6 +29,36 @@ extern "C" {
 #define RTE_VHOST_USER_DEQUEUE_ZERO_COPY	(1ULL << 2)
 #define RTE_VHOST_USER_IOMMU_SUPPORT	(1ULL << 3)
 
+/** Protocol features. */
+#ifndef VHOST_USER_PROTOCOL_F_MQ
+#define VHOST_USER_PROTOCOL_F_MQ	0
+#endif
+
+#ifndef VHOST_USER_PROTOCOL_F_LOG_SHMFD
+#define VHOST_USER_PROTOCOL_F_LOG_SHMFD	1
+#endif
+
+#ifndef VHOST_USER_PROTOCOL_F_RARP
+#define VHOST_USER_PROTOCOL_F_RARP	2
+#endif
+
+#ifndef VHOST_USER_PROTOCOL_F_REPLY_ACK
+#define VHOST_USER_PROTOCOL_F_REPLY_ACK	3
+#endif
+
+#ifndef VHOST_USER_PROTOCOL_F_NET_MTU
+#define VHOST_USER_PROTOCOL_F_NET_MTU	4
+#endif
+
+#ifndef VHOST_USER_PROTOCOL_F_SLAVE_REQ
+#define VHOST_USER_PROTOCOL_F_SLAVE_REQ	5
+#endif
+
+/** Indicate whether protocol features negotiation is supported. */
+#ifndef VHOST_USER_F_PROTOCOL_FEATURES
+#define VHOST_USER_F_PROTOCOL_FEATURES	30
+#endif
+
 /**
  * Information relating to memory regions including offsets to
  * addresses in QEMUs memory file.
diff --git a/lib/librte_vhost/vhost.h b/lib/librte_vhost/vhost.h
index 58aec2e0d..2e28e4026 100644
--- a/lib/librte_vhost/vhost.h
+++ b/lib/librte_vhost/vhost.h
@@ -174,8 +174,6 @@ struct vhost_msg {
  #define VIRTIO_F_VERSION_1 32
 #endif
 
-#define VHOST_USER_F_PROTOCOL_FEATURES	30
-
 /* Features supported by this builtin vhost-user net driver. */
 #define VIRTIO_NET_SUPPORTED_FEATURES ((1ULL << VIRTIO_NET_F_MRG_RXBUF) | \
 				(1ULL << VIRTIO_F_ANY_LAYOUT) | \
diff --git a/lib/librte_vhost/vhost_user.h b/lib/librte_vhost/vhost_user.h
index 0fafbe6e0..97afabc47 100644
--- a/lib/librte_vhost/vhost_user.h
+++ b/lib/librte_vhost/vhost_user.h
@@ -14,13 +14,6 @@
 
 #define VHOST_MEMORY_MAX_NREGIONS 8
 
-#define VHOST_USER_PROTOCOL_F_MQ	0
-#define VHOST_USER_PROTOCOL_F_LOG_SHMFD	1
-#define VHOST_USER_PROTOCOL_F_RARP	2
-#define VHOST_USER_PROTOCOL_F_REPLY_ACK	3
-#define VHOST_USER_PROTOCOL_F_NET_MTU 4
-#define VHOST_USER_PROTOCOL_F_SLAVE_REQ 5
-
 #define VHOST_USER_PROTOCOL_FEATURES	((1ULL << VHOST_USER_PROTOCOL_F_MQ) | \
 					 (1ULL << VHOST_USER_PROTOCOL_F_LOG_SHMFD) |\
 					 (1ULL << VHOST_USER_PROTOCOL_F_RARP) | \
-- 
2.13.6

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v4 2/5] vhost: support selective datapath
  2018-03-10 10:01 ` [PATCH v4 " Zhihong Wang
  2018-03-10 10:01   ` [PATCH v4 1/5] vhost: export vhost feature definitions Zhihong Wang
@ 2018-03-10 10:01   ` Zhihong Wang
  2018-03-31  6:10     ` Maxime Coquelin
  2018-03-31  7:38     ` Maxime Coquelin
  2018-03-10 10:01   ` [PATCH v4 3/5] vhost: add apis for datapath configuration Zhihong Wang
                     ` (2 subsequent siblings)
  4 siblings, 2 replies; 67+ messages in thread
From: Zhihong Wang @ 2018-03-10 10:01 UTC (permalink / raw)
  To: dev
  Cc: jianfeng.tan, tiwei.bie, maxime.coquelin, yliu, cunming.liang,
	xiao.w.wang, dan.daly, Zhihong Wang

This patch set introduces support for selective datapath in DPDK vhost-user
lib. vDPA stands for vhost Data Path Acceleration. The idea is to support
virtio ring compatible devices to serve virtio driver directly to enable
datapath acceleration.

A set of device ops is defined for device specific operations:

     a. queue_num_get: Called to get supported queue number of the device.

     b. feature_get: Called to get supported features of the device.

     c. protocol_feature_get: Called to get supported protocol features of
        the device.

     d. dev_conf: Called to configure the actual device when the virtio
        device becomes ready.

     e. dev_close: Called to close the actual device when the virtio device
        is stopped.

     f. vring_state_set: Called to change the state of the vring in the
        actual device when vring state changes.

     g. feature_set: Called to set the negotiated features to device.

     h. migration_done: Called to allow the device to response to RARP
        sending.

     i. get_vfio_group_fd: Called to get the VFIO group fd of the device.

     j. get_vfio_device_fd: Called to get the VFIO device fd of the device.

     k. get_notify_area: Called to get the notify area info of the queue.

Signed-off-by: Zhihong Wang <zhihong.wang@intel.com>
---
Changes in v4:

 1. Remove the "engine" concept in the lib.

---
Changes in v2:

 1. Add VFIO related vDPA device ops.

 lib/librte_vhost/Makefile              |  4 +-
 lib/librte_vhost/rte_vdpa.h            | 94 +++++++++++++++++++++++++++++++++
 lib/librte_vhost/rte_vhost_version.map |  6 +++
 lib/librte_vhost/vdpa.c                | 96 ++++++++++++++++++++++++++++++++++
 4 files changed, 198 insertions(+), 2 deletions(-)
 create mode 100644 lib/librte_vhost/rte_vdpa.h
 create mode 100644 lib/librte_vhost/vdpa.c

diff --git a/lib/librte_vhost/Makefile b/lib/librte_vhost/Makefile
index 5d6c6abae..37044ac03 100644
--- a/lib/librte_vhost/Makefile
+++ b/lib/librte_vhost/Makefile
@@ -22,9 +22,9 @@ LDLIBS += -lrte_eal -lrte_mempool -lrte_mbuf -lrte_ethdev -lrte_net
 
 # all source are stored in SRCS-y
 SRCS-$(CONFIG_RTE_LIBRTE_VHOST) := fd_man.c iotlb.c socket.c vhost.c \
-					vhost_user.c virtio_net.c
+					vhost_user.c virtio_net.c vdpa.c
 
 # install includes
-SYMLINK-$(CONFIG_RTE_LIBRTE_VHOST)-include += rte_vhost.h
+SYMLINK-$(CONFIG_RTE_LIBRTE_VHOST)-include += rte_vhost.h rte_vdpa.h
 
 include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/lib/librte_vhost/rte_vdpa.h b/lib/librte_vhost/rte_vdpa.h
new file mode 100644
index 000000000..a4bbbd93d
--- /dev/null
+++ b/lib/librte_vhost/rte_vdpa.h
@@ -0,0 +1,94 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Intel Corporation
+ */
+
+#ifndef _RTE_VDPA_H_
+#define _RTE_VDPA_H_
+
+/**
+ * @file
+ *
+ * Device specific vhost lib
+ */
+
+#include <rte_pci.h>
+#include "rte_vhost.h"
+
+#define MAX_VDPA_NAME_LEN 128
+
+enum vdpa_addr_type {
+	PCI_ADDR,
+	VDPA_ADDR_MAX
+};
+
+struct rte_vdpa_dev_addr {
+	enum vdpa_addr_type type;
+	union {
+		uint8_t __dummy[64];
+		struct rte_pci_addr pci_addr;
+	};
+};
+
+/* Get capabilities of this device */
+typedef int (*vdpa_dev_queue_num_get_t)(int did, uint32_t *queue_num);
+typedef int (*vdpa_dev_feature_get_t)(int did, uint64_t *features);
+
+/* Driver configure/close the device */
+typedef int (*vdpa_dev_conf_t)(int vid);
+typedef int (*vdpa_dev_close_t)(int vid);
+
+/* Enable/disable this vring */
+typedef int (*vdpa_vring_state_set_t)(int vid, int vring, int state);
+
+/* Set features when changed */
+typedef int (*vdpa_feature_set_t)(int vid);
+
+/* Destination operations when migration done */
+typedef int (*vdpa_migration_done_t)(int vid);
+
+/* Get the vfio group fd */
+typedef int (*vdpa_get_vfio_group_fd_t)(int vid);
+
+/* Get the vfio device fd */
+typedef int (*vdpa_get_vfio_device_fd_t)(int vid);
+
+/* Get the notify area info of the queue */
+typedef int (*vdpa_get_notify_area_t)(int vid, int qid, uint64_t *offset,
+		uint64_t *size);
+/* Device ops */
+struct rte_vdpa_dev_ops {
+	vdpa_dev_queue_num_get_t  queue_num_get;
+	vdpa_dev_feature_get_t    feature_get;
+	vdpa_dev_feature_get_t    protocol_feature_get;
+	vdpa_dev_conf_t           dev_conf;
+	vdpa_dev_close_t          dev_close;
+	vdpa_vring_state_set_t    vring_state_set;
+	vdpa_feature_set_t        feature_set;
+	vdpa_migration_done_t     migration_done;
+	vdpa_get_vfio_group_fd_t  get_vfio_group_fd;
+	vdpa_get_vfio_device_fd_t get_vfio_device_fd;
+	vdpa_get_notify_area_t    get_notify_area;
+};
+
+struct rte_vdpa_device {
+	struct rte_vdpa_dev_addr addr;
+	struct rte_vdpa_dev_ops *ops;
+} __rte_cache_aligned;
+
+extern struct rte_vdpa_device *vdpa_devices[];
+extern uint32_t vdpa_device_num;
+
+/* Register a vdpa device, return did if successful, -1 on failure */
+int __rte_experimental
+rte_vdpa_register_device(struct rte_vdpa_dev_addr *addr,
+		struct rte_vdpa_dev_ops *ops);
+
+/* Unregister a vdpa device, return -1 on failure */
+int __rte_experimental
+rte_vdpa_unregister_device(int did);
+
+/* Find did of a vdpa device, return -1 on failure */
+int __rte_experimental
+rte_vdpa_find_device_id(struct rte_vdpa_dev_addr *addr);
+
+#endif /* _RTE_VDPA_H_ */
diff --git a/lib/librte_vhost/rte_vhost_version.map b/lib/librte_vhost/rte_vhost_version.map
index df0103129..7bcffb490 100644
--- a/lib/librte_vhost/rte_vhost_version.map
+++ b/lib/librte_vhost/rte_vhost_version.map
@@ -59,3 +59,9 @@ DPDK_18.02 {
 	rte_vhost_vring_call;
 
 } DPDK_17.08;
+
+EXPERIMENTAL {
+	rte_vdpa_register_device;
+	rte_vdpa_unregister_device;
+	rte_vdpa_find_device_id;
+} DPDK_18.02;
diff --git a/lib/librte_vhost/vdpa.c b/lib/librte_vhost/vdpa.c
new file mode 100644
index 000000000..0c950d45f
--- /dev/null
+++ b/lib/librte_vhost/vdpa.c
@@ -0,0 +1,96 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Intel Corporation
+ */
+
+/**
+ * @file
+ *
+ * Device specific vhost lib
+ */
+
+#include <stdbool.h>
+
+#include <rte_malloc.h>
+#include "rte_vdpa.h"
+#include "vhost.h"
+
+struct rte_vdpa_device *vdpa_devices[MAX_VHOST_DEVICE];
+uint32_t vdpa_device_num;
+
+static int is_same_vdpa_dev_addr(struct rte_vdpa_dev_addr *a,
+		struct rte_vdpa_dev_addr *b)
+{
+	int ret = 0;
+
+	if (a->type != b->type)
+		return -1;
+
+	switch (a->type) {
+	case PCI_ADDR:
+		if (a->pci_addr.domain != b->pci_addr.domain ||
+				a->pci_addr.bus != b->pci_addr.bus ||
+				a->pci_addr.devid != b->pci_addr.devid ||
+				a->pci_addr.function != b->pci_addr.function)
+			ret = -1;
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
+
+int rte_vdpa_register_device(struct rte_vdpa_dev_addr *addr,
+		struct rte_vdpa_dev_ops *ops)
+{
+	struct rte_vdpa_device *dev;
+	char device_name[MAX_VDPA_NAME_LEN];
+	int i;
+
+	if (vdpa_device_num >= MAX_VHOST_DEVICE)
+		return -1;
+
+	for (i = 0; i < MAX_VHOST_DEVICE; i++) {
+		if (vdpa_devices[i] == NULL)
+			break;
+	}
+
+	sprintf(device_name, "vdpa-dev-%d", i);
+	dev = rte_zmalloc(device_name, sizeof(struct rte_vdpa_device),
+			RTE_CACHE_LINE_SIZE);
+	if (!dev)
+		return -1;
+
+	memcpy(&dev->addr, addr, sizeof(struct rte_vdpa_dev_addr));
+	dev->ops = ops;
+	vdpa_devices[i] = dev;
+	vdpa_device_num++;
+
+	return i;
+}
+
+int rte_vdpa_unregister_device(int did)
+{
+	if (did < 0 || did >= MAX_VHOST_DEVICE || vdpa_devices[did] == NULL)
+		return -1;
+
+	rte_free(vdpa_devices[did]);
+	vdpa_devices[did] = NULL;
+	vdpa_device_num--;
+
+	return did;
+}
+
+int rte_vdpa_find_device_id(struct rte_vdpa_dev_addr *addr)
+{
+	struct rte_vdpa_device *dev;
+	int i;
+
+	for (i = 0; i < MAX_VHOST_DEVICE; ++i) {
+		dev = vdpa_devices[i];
+		if (dev && is_same_vdpa_dev_addr(&dev->addr, addr) == 0)
+			return i;
+	}
+
+	return -1;
+}
-- 
2.13.6

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v4 3/5] vhost: add apis for datapath configuration
  2018-03-10 10:01 ` [PATCH v4 " Zhihong Wang
  2018-03-10 10:01   ` [PATCH v4 1/5] vhost: export vhost feature definitions Zhihong Wang
  2018-03-10 10:01   ` [PATCH v4 2/5] vhost: support selective datapath Zhihong Wang
@ 2018-03-10 10:01   ` Zhihong Wang
  2018-03-31  7:04     ` Maxime Coquelin
  2018-03-10 10:01   ` [PATCH v4 4/5] vhost: adapt vhost lib for selective datapath Zhihong Wang
  2018-03-10 10:01   ` [PATCH v4 5/5] vhost: add apis for live migration Zhihong Wang
  4 siblings, 1 reply; 67+ messages in thread
From: Zhihong Wang @ 2018-03-10 10:01 UTC (permalink / raw)
  To: dev
  Cc: jianfeng.tan, tiwei.bie, maxime.coquelin, yliu, cunming.liang,
	xiao.w.wang, dan.daly, Zhihong Wang

This patch adds APIs for datapath configuration.

The did of the vhost-user socket can be set to identify the backend device,
in this case each vhost-user socket can have only 1 connection. The did is
set to -1 by default when the software datapath is used.

Signed-off-by: Zhihong Wang <zhihong.wang@intel.com>
---
Changes in v4:

 1. Remove the "engine" concept in the lib.

 lib/librte_vhost/rte_vhost.h           | 35 +++++++++++++++++++++++++++++++++
 lib/librte_vhost/rte_vhost_version.map |  3 +++
 lib/librte_vhost/socket.c              | 36 ++++++++++++++++++++++++++++++++++
 lib/librte_vhost/vhost.c               | 25 +++++++++++++++++++++++
 lib/librte_vhost/vhost.h               |  9 +++++++++
 5 files changed, 108 insertions(+)

diff --git a/lib/librte_vhost/rte_vhost.h b/lib/librte_vhost/rte_vhost.h
index 671ea5053..d50f4c67d 100644
--- a/lib/librte_vhost/rte_vhost.h
+++ b/lib/librte_vhost/rte_vhost.h
@@ -200,6 +200,30 @@ int rte_vhost_driver_register(const char *path, uint64_t flags);
 int rte_vhost_driver_unregister(const char *path);
 
 /**
+ * Set the device id, enforce single connection per socket
+ *
+ * @param path
+ *  The vhost-user socket file path
+ * @param did
+ *  Device id
+ * @return
+ *  0 on success, -1 on failure
+ */
+int __rte_experimental
+rte_vhost_driver_set_vdpa_did(const char *path, int did);
+
+/**
+ * Get the device id
+ *
+ * @param path
+ *  The vhost-user socket file path
+ * @return
+ *  Device id, -1 on failure
+ */
+int __rte_experimental
+rte_vhost_driver_get_vdpa_did(const char *path);
+
+/**
  * Set the feature bits the vhost-user driver supports.
  *
  * @param path
@@ -464,6 +488,17 @@ int rte_vhost_vring_call(int vid, uint16_t vring_idx);
  */
 uint32_t rte_vhost_rx_queue_count(int vid, uint16_t qid);
 
+/**
+ * Get vdpa device id for vhost device.
+ *
+ * @param vid
+ *  vhost device ID
+ * @return
+ *  device id
+ */
+int __rte_experimental
+rte_vhost_get_vdpa_did(int vid);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/librte_vhost/rte_vhost_version.map b/lib/librte_vhost/rte_vhost_version.map
index 7bcffb490..6e2d5364a 100644
--- a/lib/librte_vhost/rte_vhost_version.map
+++ b/lib/librte_vhost/rte_vhost_version.map
@@ -64,4 +64,7 @@ EXPERIMENTAL {
 	rte_vdpa_register_device;
 	rte_vdpa_unregister_device;
 	rte_vdpa_find_device_id;
+	rte_vhost_driver_set_vdpa_did;
+	rte_vhost_driver_get_vdpa_did;
+	rte_vhost_get_vdpa_did;
 } DPDK_18.02;
diff --git a/lib/librte_vhost/socket.c b/lib/librte_vhost/socket.c
index cfc31e179..3d58da94e 100644
--- a/lib/librte_vhost/socket.c
+++ b/lib/librte_vhost/socket.c
@@ -52,6 +52,13 @@ struct vhost_user_socket {
 	uint64_t supported_features;
 	uint64_t features;
 
+	/*
+	 * Device id to identify a specific backend device.
+	 * It's set to -1 for the default software implementation.
+	 * If valid, one socket can have 1 connection only.
+	 */
+	int did;
+
 	struct vhost_device_ops const *notify_ops;
 };
 
@@ -545,6 +552,35 @@ find_vhost_user_socket(const char *path)
 }
 
 int
+rte_vhost_driver_set_vdpa_did(const char *path, int did)
+{
+	struct vhost_user_socket *vsocket;
+
+	pthread_mutex_lock(&vhost_user.mutex);
+	vsocket = find_vhost_user_socket(path);
+	if (vsocket)
+		vsocket->did = did;
+	pthread_mutex_unlock(&vhost_user.mutex);
+
+	return vsocket ? 0 : -1;
+}
+
+int
+rte_vhost_driver_get_vdpa_did(const char *path)
+{
+	struct vhost_user_socket *vsocket;
+	int did = -1;
+
+	pthread_mutex_lock(&vhost_user.mutex);
+	vsocket = find_vhost_user_socket(path);
+	if (vsocket)
+		did = vsocket->did;
+	pthread_mutex_unlock(&vhost_user.mutex);
+
+	return did;
+}
+
+int
 rte_vhost_driver_disable_features(const char *path, uint64_t features)
 {
 	struct vhost_user_socket *vsocket;
diff --git a/lib/librte_vhost/vhost.c b/lib/librte_vhost/vhost.c
index f6f12a03b..1740cc1ab 100644
--- a/lib/librte_vhost/vhost.c
+++ b/lib/librte_vhost/vhost.c
@@ -283,6 +283,7 @@ vhost_new_device(void)
 	dev->vid = i;
 	dev->flags = VIRTIO_DEV_BUILTIN_VIRTIO_NET;
 	dev->slave_req_fd = -1;
+	dev->did = -1;
 
 	return i;
 }
@@ -311,6 +312,20 @@ vhost_destroy_device(int vid)
 }
 
 void
+vhost_set_vdpa_did(int vid, int did)
+{
+	struct virtio_net *dev = get_device(vid);
+
+	if (did < 0)
+		return;
+
+	if (dev == NULL)
+		return;
+
+	dev->did = did;
+}
+
+void
 vhost_set_ifname(int vid, const char *if_name, unsigned int if_len)
 {
 	struct virtio_net *dev;
@@ -614,3 +629,13 @@ rte_vhost_rx_queue_count(int vid, uint16_t qid)
 
 	return *((volatile uint16_t *)&vq->avail->idx) - vq->last_avail_idx;
 }
+
+int rte_vhost_get_vdpa_did(int vid)
+{
+	struct virtio_net *dev = get_device(vid);
+
+	if (dev == NULL)
+		return -1;
+
+	return dev->did;
+}
diff --git a/lib/librte_vhost/vhost.h b/lib/librte_vhost/vhost.h
index 2e28e4026..2970c1eab 100644
--- a/lib/librte_vhost/vhost.h
+++ b/lib/librte_vhost/vhost.h
@@ -19,6 +19,7 @@
 #include <rte_rwlock.h>
 
 #include "rte_vhost.h"
+#include "rte_vdpa.h"
 
 /* Used to indicate that the device is running on a data core */
 #define VIRTIO_DEV_RUNNING 1
@@ -239,6 +240,12 @@ struct virtio_net {
 	struct guest_page       *guest_pages;
 
 	int			slave_req_fd;
+
+	/*
+	 * Device id to identify a specific backend device.
+	 * It's set to -1 for the default software implementation.
+	 */
+	int			did;
 } __rte_cache_aligned;
 
 
@@ -365,6 +372,8 @@ void free_vq(struct vhost_virtqueue *vq);
 
 int alloc_vring_queue(struct virtio_net *dev, uint32_t vring_idx);
 
+void vhost_set_vdpa_did(int vid, int did);
+
 void vhost_set_ifname(int, const char *if_name, unsigned int if_len);
 void vhost_enable_dequeue_zero_copy(int vid);
 void vhost_set_builtin_virtio_net(int vid, bool enable);
-- 
2.13.6

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v4 4/5] vhost: adapt vhost lib for selective datapath
  2018-03-10 10:01 ` [PATCH v4 " Zhihong Wang
                     ` (2 preceding siblings ...)
  2018-03-10 10:01   ` [PATCH v4 3/5] vhost: add apis for datapath configuration Zhihong Wang
@ 2018-03-10 10:01   ` Zhihong Wang
  2018-03-31  7:35     ` Maxime Coquelin
  2018-03-10 10:01   ` [PATCH v4 5/5] vhost: add apis for live migration Zhihong Wang
  4 siblings, 1 reply; 67+ messages in thread
From: Zhihong Wang @ 2018-03-10 10:01 UTC (permalink / raw)
  To: dev
  Cc: jianfeng.tan, tiwei.bie, maxime.coquelin, yliu, cunming.liang,
	xiao.w.wang, dan.daly, Zhihong Wang

This patch adapts vhost lib for selective datapath by calling device ops
at the corresponding stage.

Signed-off-by: Zhihong Wang <zhihong.wang@intel.com>
---
Changes in v4:

 1. Remove the "engine" concept in the lib.

---
Changes in v2:

 1. Ensure negotiated capabilities are supported in vhost-user lib.

 2. Configure the data path at the right time.

 lib/librte_vhost/rte_vhost.h           | 27 ++++++++++
 lib/librte_vhost/rte_vhost_version.map |  2 +
 lib/librte_vhost/socket.c              | 94 ++++++++++++++++++++++++++++++++--
 lib/librte_vhost/vhost.c               |  3 ++
 lib/librte_vhost/vhost.h               |  2 +
 lib/librte_vhost/vhost_user.c          | 54 +++++++++++++++++--
 6 files changed, 172 insertions(+), 10 deletions(-)

diff --git a/lib/librte_vhost/rte_vhost.h b/lib/librte_vhost/rte_vhost.h
index d50f4c67d..3c3334d3e 100644
--- a/lib/librte_vhost/rte_vhost.h
+++ b/lib/librte_vhost/rte_vhost.h
@@ -279,6 +279,33 @@ int rte_vhost_driver_disable_features(const char *path, uint64_t features);
 int rte_vhost_driver_get_features(const char *path, uint64_t *features);
 
 /**
+ * Get the protocol feature bits before feature negotiation.
+ *
+ * @param path
+ *  The vhost-user socket file path
+ * @param protocol_features
+ *  A pointer to store the queried protocol feature bits
+ * @return
+ *  0 on success, -1 on failure
+ */
+int __rte_experimental
+rte_vhost_driver_get_protocol_features(const char *path,
+		uint64_t *protocol_features);
+
+/**
+ * Get the queue number bits before feature negotiation.
+ *
+ * @param path
+ *  The vhost-user socket file path
+ * @param queue_num
+ *  A pointer to store the queried queue number bits
+ * @return
+ *  0 on success, -1 on failure
+ */
+int __rte_experimental
+rte_vhost_driver_get_queue_num(const char *path, uint32_t *queue_num);
+
+/**
  * Get the feature bits after negotiation
  *
  * @param vid
diff --git a/lib/librte_vhost/rte_vhost_version.map b/lib/librte_vhost/rte_vhost_version.map
index 6e2d5364a..812ccd72b 100644
--- a/lib/librte_vhost/rte_vhost_version.map
+++ b/lib/librte_vhost/rte_vhost_version.map
@@ -67,4 +67,6 @@ EXPERIMENTAL {
 	rte_vhost_driver_set_vdpa_did;
 	rte_vhost_driver_get_vdpa_did;
 	rte_vhost_get_vdpa_did;
+	rte_vhost_driver_get_protocol_features;
+	rte_vhost_driver_get_queue_num;
 } DPDK_18.02;
diff --git a/lib/librte_vhost/socket.c b/lib/librte_vhost/socket.c
index 3d58da94e..ba7b422a0 100644
--- a/lib/librte_vhost/socket.c
+++ b/lib/librte_vhost/socket.c
@@ -216,6 +216,8 @@ vhost_user_add_connection(int fd, struct vhost_user_socket *vsocket)
 
 	vhost_set_builtin_virtio_net(vid, vsocket->use_builtin_virtio_net);
 
+	vhost_set_vdpa_did(vid, vsocket->did);
+
 	if (vsocket->dequeue_zero_copy)
 		vhost_enable_dequeue_zero_copy(vid);
 
@@ -648,20 +650,102 @@ int
 rte_vhost_driver_get_features(const char *path, uint64_t *features)
 {
 	struct vhost_user_socket *vsocket;
+	uint64_t vdpa_features;
+	int did = -1;
+	int ret = 0;
 
 	pthread_mutex_lock(&vhost_user.mutex);
 	vsocket = find_vhost_user_socket(path);
-	if (vsocket)
-		*features = vsocket->features;
+	if (vsocket) {
+		did = vsocket->did;
+		if (did < 0 || vdpa_devices[did]->ops->feature_get == NULL)
+			*features = vsocket->features;
+		else if (vdpa_devices[did]->ops->feature_get(did,
+					&vdpa_features) < 0) {
+			RTE_LOG(ERR, VHOST_CONFIG,
+					"failed to get vdpa features "
+					"for socket file %s.\n", path);
+			ret = -1;
+		} else
+			*features = vsocket->features & vdpa_features;
+	} else {
+		RTE_LOG(ERR, VHOST_CONFIG,
+			"socket file %s is not registered yet.\n", path);
+		ret = -1;
+	}
 	pthread_mutex_unlock(&vhost_user.mutex);
 
-	if (!vsocket) {
+	return ret;
+}
+
+int
+rte_vhost_driver_get_protocol_features(const char *path,
+		uint64_t *protocol_features)
+{
+	struct vhost_user_socket *vsocket;
+	uint64_t vdpa_protocol_features;
+	int did = -1;
+	int ret = 0;
+
+	pthread_mutex_lock(&vhost_user.mutex);
+	vsocket = find_vhost_user_socket(path);
+	if (vsocket) {
+		did = vsocket->did;
+		if (did < 0 || vdpa_devices[did]->ops->protocol_feature_get
+				== NULL)
+			*protocol_features = VHOST_USER_PROTOCOL_FEATURES;
+		else if (vdpa_devices[did]->ops->protocol_feature_get(did,
+					&vdpa_protocol_features) < 0) {
+			RTE_LOG(ERR, VHOST_CONFIG,
+					"failed to get vdpa protocol features "
+					"for socket file %s.\n", path);
+			ret = -1;
+		} else
+			*protocol_features = VHOST_USER_PROTOCOL_FEATURES
+				& vdpa_protocol_features;
+	} else {
 		RTE_LOG(ERR, VHOST_CONFIG,
 			"socket file %s is not registered yet.\n", path);
-		return -1;
+		ret = -1;
+	}
+	pthread_mutex_unlock(&vhost_user.mutex);
+
+	return ret;
+}
+
+int
+rte_vhost_driver_get_queue_num(const char *path,
+		uint32_t *queue_num)
+{
+	struct vhost_user_socket *vsocket;
+	uint32_t vdpa_queue_num;
+	int did = -1;
+	int ret = 0;
+
+	pthread_mutex_lock(&vhost_user.mutex);
+	vsocket = find_vhost_user_socket(path);
+	if (vsocket) {
+		did = vsocket->did;
+		if (did < 0 || vdpa_devices[did]->ops->queue_num_get == NULL)
+			*queue_num = VHOST_MAX_QUEUE_PAIRS;
+		else if (vdpa_devices[did]->ops->queue_num_get(
+					did, &vdpa_queue_num) < 0) {
+			RTE_LOG(ERR, VHOST_CONFIG,
+					"failed to get vdpa queue number "
+					"for socket file %s.\n", path);
+			ret = -1;
+		} else if (vdpa_queue_num > VHOST_MAX_QUEUE_PAIRS)
+			*queue_num = VHOST_MAX_QUEUE_PAIRS;
+		else
+			*queue_num = vdpa_queue_num;
 	} else {
-		return 0;
+		RTE_LOG(ERR, VHOST_CONFIG,
+			"socket file %s is not registered yet.\n", path);
+		ret = -1;
 	}
+	pthread_mutex_unlock(&vhost_user.mutex);
+
+	return ret;
 }
 
 /*
diff --git a/lib/librte_vhost/vhost.c b/lib/librte_vhost/vhost.c
index 1740cc1ab..66b6b492f 100644
--- a/lib/librte_vhost/vhost.c
+++ b/lib/librte_vhost/vhost.c
@@ -296,11 +296,14 @@ void
 vhost_destroy_device(int vid)
 {
 	struct virtio_net *dev = get_device(vid);
+	int did = dev->did;
 
 	if (dev == NULL)
 		return;
 
 	if (dev->flags & VIRTIO_DEV_RUNNING) {
+		if (did >= 0 && vdpa_devices[did]->ops->dev_close)
+			vdpa_devices[did]->ops->dev_close(dev->vid);
 		dev->flags &= ~VIRTIO_DEV_RUNNING;
 		dev->notify_ops->destroy_device(vid);
 	}
diff --git a/lib/librte_vhost/vhost.h b/lib/librte_vhost/vhost.h
index 2970c1eab..30e8a0cfe 100644
--- a/lib/librte_vhost/vhost.h
+++ b/lib/librte_vhost/vhost.h
@@ -27,6 +27,8 @@
 #define VIRTIO_DEV_READY 2
 /* Used to indicate that the built-in vhost net device backend is enabled */
 #define VIRTIO_DEV_BUILTIN_VIRTIO_NET 4
+/* Used to indicate that the device has its own data path and configured */
+#define VIRTIO_DEV_VDPA_CONFIGURED 8
 
 /* Backend value set by guest. */
 #define VIRTIO_DEV_STOPPED -1
diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c
index 5c5361066..5049c8e55 100644
--- a/lib/librte_vhost/vhost_user.c
+++ b/lib/librte_vhost/vhost_user.c
@@ -133,7 +133,11 @@ vhost_user_set_owner(void)
 static int
 vhost_user_reset_owner(struct virtio_net *dev)
 {
+	int did = dev->did;
+
 	if (dev->flags & VIRTIO_DEV_RUNNING) {
+		if (did >= 0 && vdpa_devices[did]->ops->dev_close)
+			vdpa_devices[did]->ops->dev_close(dev->vid);
 		dev->flags &= ~VIRTIO_DEV_RUNNING;
 		dev->notify_ops->destroy_device(dev->vid);
 	}
@@ -156,12 +160,25 @@ vhost_user_get_features(struct virtio_net *dev)
 }
 
 /*
+ * The queue number that we support are requested.
+ */
+static uint32_t
+vhost_user_get_queue_num(struct virtio_net *dev)
+{
+	uint32_t queue_num = 0;
+
+	rte_vhost_driver_get_queue_num(dev->ifname, &queue_num);
+	return (uint64_t)queue_num;
+}
+
+/*
  * We receive the negotiated features supported by us and the virtio device.
  */
 static int
 vhost_user_set_features(struct virtio_net *dev, uint64_t features)
 {
 	uint64_t vhost_features = 0;
+	int did = dev->did;
 
 	rte_vhost_driver_get_features(dev->ifname, &vhost_features);
 	if (features & ~vhost_features) {
@@ -191,6 +208,9 @@ vhost_user_set_features(struct virtio_net *dev, uint64_t features)
 			dev->notify_ops->features_changed(dev->vid, features);
 	}
 
+	if (did >= 0 && vdpa_devices[did]->ops->feature_set)
+		vdpa_devices[did]->ops->feature_set(dev->vid);
+
 	dev->features = features;
 	if (dev->features &
 		((1 << VIRTIO_NET_F_MRG_RXBUF) | (1ULL << VIRTIO_F_VERSION_1))) {
@@ -933,14 +953,18 @@ vhost_user_get_vring_base(struct virtio_net *dev,
 			  VhostUserMsg *msg)
 {
 	struct vhost_virtqueue *vq = dev->virtqueue[msg->payload.state.index];
+	int did = dev->did;
 
 	/* We have to stop the queue (virtio) if it is running. */
 	if (dev->flags & VIRTIO_DEV_RUNNING) {
+		if (did >= 0 && vdpa_devices[did]->ops->dev_close)
+			vdpa_devices[did]->ops->dev_close(dev->vid);
 		dev->flags &= ~VIRTIO_DEV_RUNNING;
 		dev->notify_ops->destroy_device(dev->vid);
 	}
 
 	dev->flags &= ~VIRTIO_DEV_READY;
+	dev->flags &= ~VIRTIO_DEV_VDPA_CONFIGURED;
 
 	/* Here we are safe to get the last avail index */
 	msg->payload.state.num = vq->last_avail_idx;
@@ -983,16 +1007,22 @@ vhost_user_set_vring_enable(struct virtio_net *dev,
 			    VhostUserMsg *msg)
 {
 	int enable = (int)msg->payload.state.num;
+	int index = (int)msg->payload.state.index;
+	int did = dev->did;
 
 	RTE_LOG(INFO, VHOST_CONFIG,
 		"set queue enable: %d to qp idx: %d\n",
-		enable, msg->payload.state.index);
+		enable, index);
+
+	if (did >= 0 && vdpa_devices[did]->ops->vring_state_set)
+		vdpa_devices[did]->ops->vring_state_set(dev->vid,
+				index, enable);
 
 	if (dev->notify_ops->vring_state_changed)
 		dev->notify_ops->vring_state_changed(dev->vid,
-				msg->payload.state.index, enable);
+				index, enable);
 
-	dev->virtqueue[msg->payload.state.index]->enabled = enable;
+	dev->virtqueue[index]->enabled = enable;
 
 	return 0;
 }
@@ -1001,9 +1031,10 @@ static void
 vhost_user_get_protocol_features(struct virtio_net *dev,
 				 struct VhostUserMsg *msg)
 {
-	uint64_t features, protocol_features = VHOST_USER_PROTOCOL_FEATURES;
+	uint64_t features, protocol_features;
 
 	rte_vhost_driver_get_features(dev->ifname, &features);
+	rte_vhost_driver_get_protocol_features(dev->ifname, &protocol_features);
 
 	/*
 	 * REPLY_ACK protocol feature is only mandatory for now
@@ -1099,6 +1130,7 @@ static int
 vhost_user_send_rarp(struct virtio_net *dev, struct VhostUserMsg *msg)
 {
 	uint8_t *mac = (uint8_t *)&msg->payload.u64;
+	int did = dev->did;
 
 	RTE_LOG(DEBUG, VHOST_CONFIG,
 		":: mac: %02x:%02x:%02x:%02x:%02x:%02x\n",
@@ -1114,6 +1146,8 @@ vhost_user_send_rarp(struct virtio_net *dev, struct VhostUserMsg *msg)
 	 */
 	rte_smp_wmb();
 	rte_atomic16_set(&dev->broadcast_rarp, 1);
+	if (did >= 0 && vdpa_devices[did]->ops->migration_done)
+		vdpa_devices[did]->ops->migration_done(dev->vid);
 
 	return 0;
 }
@@ -1375,6 +1409,7 @@ vhost_user_msg_handler(int vid, int fd)
 {
 	struct virtio_net *dev;
 	struct VhostUserMsg msg;
+	int did;
 	int ret;
 	int unlock_required = 0;
 
@@ -1527,7 +1562,7 @@ vhost_user_msg_handler(int vid, int fd)
 		break;
 
 	case VHOST_USER_GET_QUEUE_NUM:
-		msg.payload.u64 = VHOST_MAX_QUEUE_PAIRS;
+		msg.payload.u64 = (uint64_t)vhost_user_get_queue_num(dev);
 		msg.size = sizeof(msg.payload.u64);
 		send_vhost_reply(fd, &msg);
 		break;
@@ -1580,6 +1615,15 @@ vhost_user_msg_handler(int vid, int fd)
 		}
 	}
 
+	did = dev->did;
+	if (did >= 0 && virtio_is_ready(dev) &&
+			!(dev->flags & VIRTIO_DEV_VDPA_CONFIGURED) &&
+			msg.request.master == VHOST_USER_SET_VRING_ENABLE) {
+		if (vdpa_devices[did]->ops->dev_conf)
+			vdpa_devices[did]->ops->dev_conf(vid);
+		dev->flags |= VIRTIO_DEV_VDPA_CONFIGURED;
+	}
+
 	return 0;
 }
 
-- 
2.13.6

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v4 5/5] vhost: add apis for live migration
  2018-03-10 10:01 ` [PATCH v4 " Zhihong Wang
                     ` (3 preceding siblings ...)
  2018-03-10 10:01   ` [PATCH v4 4/5] vhost: adapt vhost lib for selective datapath Zhihong Wang
@ 2018-03-10 10:01   ` Zhihong Wang
  2018-03-31  7:39     ` Maxime Coquelin
  4 siblings, 1 reply; 67+ messages in thread
From: Zhihong Wang @ 2018-03-10 10:01 UTC (permalink / raw)
  To: dev
  Cc: jianfeng.tan, tiwei.bie, maxime.coquelin, yliu, cunming.liang,
	xiao.w.wang, dan.daly, Zhihong Wang

This patch adds APIs to enable live migration for non-builtin data paths.

At src side, last_avail/used_idx from the device need to be set into the
virtio_net structure, and the log_base and log_size from the virtio_net
structure need to be set into the device.

At dst side, last_avail/used_idx need to be read from the virtio_net
structure and set into the device.

Signed-off-by: Zhihong Wang <zhihong.wang@intel.com>
---
 lib/librte_vhost/rte_vhost.h           | 51 +++++++++++++++++++++++++++
 lib/librte_vhost/rte_vhost_version.map |  3 ++
 lib/librte_vhost/vhost.c               | 63 ++++++++++++++++++++++++++++++++++
 3 files changed, 117 insertions(+)

diff --git a/lib/librte_vhost/rte_vhost.h b/lib/librte_vhost/rte_vhost.h
index 3c3334d3e..ff98ebd59 100644
--- a/lib/librte_vhost/rte_vhost.h
+++ b/lib/librte_vhost/rte_vhost.h
@@ -516,6 +516,57 @@ int rte_vhost_vring_call(int vid, uint16_t vring_idx);
 uint32_t rte_vhost_rx_queue_count(int vid, uint16_t qid);
 
 /**
+ * Get log base and log size of the vhost device
+ *
+ * @param vid
+ *  vhost device ID
+ * @param log_base
+ *  vhost log base
+ * @param log_size
+ *  vhost log size
+ * @return
+ *  0 on success, -1 on failure
+ */
+int __rte_experimental
+rte_vhost_get_log_base(int vid, uint64_t *log_base, uint64_t *log_size);
+
+/**
+ * Get last_avail/used_idx of the vhost virtqueue
+ *
+ * @param vid
+ *  vhost device ID
+ * @param queue_id
+ *  vhost queue index
+ * @param last_avail_idx
+ *  vhost last_avail_idx to get
+ * @param last_used_idx
+ *  vhost last_used_idx to get
+ * @return
+ *  0 on success, -1 on failure
+ */
+int __rte_experimental
+rte_vhost_get_vring_base(int vid, uint16_t queue_id,
+		uint16_t *last_avail_idx, uint16_t *last_used_idx);
+
+/**
+ * Set last_avail/used_idx of the vhost virtqueue
+ *
+ * @param vid
+ *  vhost device ID
+ * @param queue_id
+ *  vhost queue index
+ * @param last_avail_idx
+ *  last_avail_idx to set
+ * @param last_used_idx
+ *  last_used_idx to set
+ * @return
+ *  0 on success, -1 on failure
+ */
+int __rte_experimental
+rte_vhost_set_vring_base(int vid, uint16_t queue_id,
+		uint16_t last_avail_idx, uint16_t last_used_idx);
+
+/**
  * Get vdpa device id for vhost device.
  *
  * @param vid
diff --git a/lib/librte_vhost/rte_vhost_version.map b/lib/librte_vhost/rte_vhost_version.map
index 812ccd72b..81479d433 100644
--- a/lib/librte_vhost/rte_vhost_version.map
+++ b/lib/librte_vhost/rte_vhost_version.map
@@ -69,4 +69,7 @@ EXPERIMENTAL {
 	rte_vhost_get_vdpa_did;
 	rte_vhost_driver_get_protocol_features;
 	rte_vhost_driver_get_queue_num;
+	rte_vhost_get_log_base;
+	rte_vhost_get_vring_base;
+	rte_vhost_set_vring_base;
 } DPDK_18.02;
diff --git a/lib/librte_vhost/vhost.c b/lib/librte_vhost/vhost.c
index 66b6b492f..b52f7dad4 100644
--- a/lib/librte_vhost/vhost.c
+++ b/lib/librte_vhost/vhost.c
@@ -642,3 +642,66 @@ int rte_vhost_get_vdpa_did(int vid)
 
 	return dev->did;
 }
+
+int rte_vhost_get_log_base(int vid, uint64_t *log_base,
+		uint64_t *log_size)
+{
+	struct virtio_net *dev = get_device(vid);
+
+	if (!dev)
+		return -1;
+
+	if (unlikely(!(dev->flags & VIRTIO_DEV_BUILTIN_VIRTIO_NET))) {
+		RTE_LOG(ERR, VHOST_DATA,
+			"(%d) %s: built-in vhost net backend is disabled.\n",
+			dev->vid, __func__);
+		return -1;
+	}
+
+	*log_base = dev->log_base;
+	*log_size = dev->log_size;
+
+	return 0;
+}
+
+int rte_vhost_get_vring_base(int vid, uint16_t queue_id,
+		uint16_t *last_avail_idx, uint16_t *last_used_idx)
+{
+	struct virtio_net *dev = get_device(vid);
+
+	if (!dev)
+		return -1;
+
+	if (unlikely(!(dev->flags & VIRTIO_DEV_BUILTIN_VIRTIO_NET))) {
+		RTE_LOG(ERR, VHOST_DATA,
+			"(%d) %s: built-in vhost net backend is disabled.\n",
+			dev->vid, __func__);
+		return -1;
+	}
+
+	*last_avail_idx = dev->virtqueue[queue_id]->last_avail_idx;
+	*last_used_idx = dev->virtqueue[queue_id]->last_used_idx;
+
+	return 0;
+}
+
+int rte_vhost_set_vring_base(int vid, uint16_t queue_id,
+		uint16_t last_avail_idx, uint16_t last_used_idx)
+{
+	struct virtio_net *dev = get_device(vid);
+
+	if (!dev)
+		return -1;
+
+	if (unlikely(!(dev->flags & VIRTIO_DEV_BUILTIN_VIRTIO_NET))) {
+		RTE_LOG(ERR, VHOST_DATA,
+			"(%d) %s: built-in vhost net backend is disabled.\n",
+			dev->vid, __func__);
+		return -1;
+	}
+
+	dev->virtqueue[queue_id]->last_avail_idx = last_avail_idx;
+	dev->virtqueue[queue_id]->last_used_idx = last_used_idx;
+
+	return 0;
+}
-- 
2.13.6

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* Re: [PATCH v2 6/6] vhost: export new apis
  2018-03-06  9:51     ` Tan, Jianfeng
@ 2018-03-15 10:55       ` Wang, Zhihong
  0 siblings, 0 replies; 67+ messages in thread
From: Wang, Zhihong @ 2018-03-15 10:55 UTC (permalink / raw)
  To: Tan, Jianfeng, dev
  Cc: Bie, Tiwei, maxime.coquelin, yliu, Liang, Cunming, Wang, Xiao W,
	Daly, Dan



> -----Original Message-----
> From: Tan, Jianfeng
> Sent: Tuesday, March 6, 2018 5:52 PM
> To: Wang, Zhihong <zhihong.wang@intel.com>; dev@dpdk.org
> Cc: Bie, Tiwei <tiwei.bie@intel.com>; maxime.coquelin@redhat.com;
> yliu@fridaylinux.org; Liang, Cunming <cunming.liang@intel.com>; Wang, Xiao
> W <xiao.w.wang@intel.com>; Daly, Dan <dan.daly@intel.com>
> Subject: RE: [PATCH v2 6/6] vhost: export new apis
> 
> 
> 
> > -----Original Message-----
> > From: Wang, Zhihong
> > Sent: Tuesday, February 13, 2018 5:21 PM
> > To: dev@dpdk.org
> > Cc: Tan, Jianfeng; Bie, Tiwei; maxime.coquelin@redhat.com;
> > yliu@fridaylinux.org; Liang, Cunming; Wang, Xiao W; Daly, Dan; Wang,
> > Zhihong
> > Subject: [PATCH v2 6/6] vhost: export new apis
> >
> > This patch exports new APIs as experimental.
> 
> How about squeezing this patch with patch 2 where the APIs are introduced,
> as well as the related doc update?

Ok, will do that.

Thanks
-Zhihong

> 
> Thanks,
> Jianfeng
> 
> >
> > Signed-off-by: Zhihong Wang <zhihong.wang@intel.com>
> > ---
> >  lib/librte_vhost/rte_vdpa.h            | 16 +++++++++++-----
> >  lib/librte_vhost/rte_vhost.h           | 33 ++++++++++++++++++++++---------
> --
> >  lib/librte_vhost/rte_vhost_version.map | 19 +++++++++++++++++++
> >  3 files changed, 52 insertions(+), 16 deletions(-)
> >
> > diff --git a/lib/librte_vhost/rte_vdpa.h b/lib/librte_vhost/rte_vdpa.h
> > index 1bde36f7f..23fb471be 100644
> > --- a/lib/librte_vhost/rte_vdpa.h
> > +++ b/lib/librte_vhost/rte_vdpa.h
> > @@ -100,15 +100,21 @@ extern struct rte_vdpa_engine *vdpa_engines[];
> >  extern uint32_t vdpa_engine_num;
> >
> >  /* engine management */
> > -int rte_vdpa_register_engine(const char *name, struct
> rte_vdpa_eng_addr
> > *addr);
> > -int rte_vdpa_unregister_engine(int eid);
> > +int __rte_experimental
> > +rte_vdpa_register_engine(const char *name, struct rte_vdpa_eng_addr
> > *addr);
> >
> > -int rte_vdpa_find_engine_id(struct rte_vdpa_eng_addr *addr);
> > +int __rte_experimental
> > +rte_vdpa_unregister_engine(int eid);
> >
> > -int rte_vdpa_info_query(int eid, struct rte_vdpa_eng_attr *attr);
> > +int __rte_experimental
> > +rte_vdpa_find_engine_id(struct rte_vdpa_eng_addr *addr);
> > +
> > +int __rte_experimental
> > +rte_vdpa_info_query(int eid, struct rte_vdpa_eng_attr *attr);
> >
> >  /* driver register api */
> > -void rte_vdpa_register_driver(struct rte_vdpa_eng_driver *drv);
> > +void __rte_experimental
> > +rte_vdpa_register_driver(struct rte_vdpa_eng_driver *drv);
> >
> >  #define RTE_VDPA_REGISTER_DRIVER(nm, drv) \
> >  RTE_INIT(vdpainitfn_ ##nm); \
> > diff --git a/lib/librte_vhost/rte_vhost.h b/lib/librte_vhost/rte_vhost.h
> > index 48005d9ff..d5589c543 100644
> > --- a/lib/librte_vhost/rte_vhost.h
> > +++ b/lib/librte_vhost/rte_vhost.h
> > @@ -187,7 +187,8 @@ int rte_vhost_driver_unregister(const char *path);
> >   * @return
> >   *  0 on success, -1 on failure
> >   */
> > -int rte_vhost_driver_set_vdpa_eid(const char *path, int eid);
> > +int __rte_experimental
> > +rte_vhost_driver_set_vdpa_eid(const char *path, int eid);
> >
> >  /**
> >   * Set the device id, enforce single connection per socket
> > @@ -199,7 +200,8 @@ int rte_vhost_driver_set_vdpa_eid(const char
> *path,
> > int eid);
> >   * @return
> >   *  0 on success, -1 on failure
> >   */
> > -int rte_vhost_driver_set_vdpa_did(const char *path, int did);
> > +int __rte_experimental
> > +rte_vhost_driver_set_vdpa_did(const char *path, int did);
> >
> >  /**
> >   * Get the engine id
> > @@ -209,7 +211,8 @@ int rte_vhost_driver_set_vdpa_did(const char
> *path,
> > int did);
> >   * @return
> >   *  Engine id, -1 on failure
> >   */
> > -int rte_vhost_driver_get_vdpa_eid(const char *path);
> > +int __rte_experimental
> > +rte_vhost_driver_get_vdpa_eid(const char *path);
> >
> >  /**
> >   * Get the device id
> > @@ -219,7 +222,8 @@ int rte_vhost_driver_get_vdpa_eid(const char
> *path);
> >   * @return
> >   *  Device id, -1 on failure
> >   */
> > -int rte_vhost_driver_get_vdpa_did(const char *path);
> > +int __rte_experimental
> > +rte_vhost_driver_get_vdpa_did(const char *path);
> >
> >  /**
> >   * Set the feature bits the vhost-user driver supports.
> > @@ -286,7 +290,8 @@ int rte_vhost_driver_get_features(const char *path,
> > uint64_t *features);
> >   * @return
> >   *  0 on success, -1 on failure
> >   */
> > -int rte_vhost_driver_get_protocol_features(const char *path,
> > +int __rte_experimental
> > +rte_vhost_driver_get_protocol_features(const char *path,
> >  		uint64_t *protocol_features);
> >
> >  /**
> > @@ -299,7 +304,8 @@ int rte_vhost_driver_get_protocol_features(const
> > char *path,
> >   * @return
> >   *  0 on success, -1 on failure
> >   */
> > -int rte_vhost_driver_get_queue_num(const char *path, uint32_t
> > *queue_num);
> > +int __rte_experimental
> > +rte_vhost_driver_get_queue_num(const char *path, uint32_t
> > *queue_num);
> >
> >  /**
> >   * Get the feature bits after negotiation
> > @@ -523,7 +529,8 @@ uint32_t rte_vhost_rx_queue_count(int vid,
> uint16_t
> > qid);
> >   * @return
> >   *  0 on success, -1 on failure
> >   */
> > -int rte_vhost_get_log_base(int vid, uint64_t *log_base,
> > +int __rte_experimental
> > +rte_vhost_get_log_base(int vid, uint64_t *log_base,
> >  		uint64_t *log_size);
> >
> >  /**
> > @@ -540,7 +547,8 @@ int rte_vhost_get_log_base(int vid, uint64_t
> > *log_base,
> >   * @return
> >   *  0 on success, -1 on failure
> >   */
> > -int rte_vhost_get_vring_base(int vid, uint16_t queue_id,
> > +int __rte_experimental
> > +rte_vhost_get_vring_base(int vid, uint16_t queue_id,
> >  		uint16_t *last_avail_idx, uint16_t *last_used_idx);
> >
> >  /**
> > @@ -557,7 +565,8 @@ int rte_vhost_get_vring_base(int vid, uint16_t
> > queue_id,
> >   * @return
> >   *  0 on success, -1 on failure
> >   */
> > -int rte_vhost_set_vring_base(int vid, uint16_t queue_id,
> > +int __rte_experimental
> > +rte_vhost_set_vring_base(int vid, uint16_t queue_id,
> >  		uint16_t last_avail_idx, uint16_t last_used_idx);
> >
> >  /**
> > @@ -568,7 +577,8 @@ int rte_vhost_set_vring_base(int vid, uint16_t
> > queue_id,
> >   * @return
> >   *  engine id
> >   */
> > -int rte_vhost_get_vdpa_eid(int vid);
> > +int __rte_experimental
> > +rte_vhost_get_vdpa_eid(int vid);
> >
> >  /**
> >   * Get vdpa device id for vhost device.
> > @@ -578,7 +588,8 @@ int rte_vhost_get_vdpa_eid(int vid);
> >   * @return
> >   *  device id
> >   */
> > -int rte_vhost_get_vdpa_did(int vid);
> > +int __rte_experimental
> > +rte_vhost_get_vdpa_did(int vid);
> >
> >  #ifdef __cplusplus
> >  }
> > diff --git a/lib/librte_vhost/rte_vhost_version.map
> > b/lib/librte_vhost/rte_vhost_version.map
> > index df0103129..36257e51b 100644
> > --- a/lib/librte_vhost/rte_vhost_version.map
> > +++ b/lib/librte_vhost/rte_vhost_version.map
> > @@ -59,3 +59,22 @@ DPDK_18.02 {
> >  	rte_vhost_vring_call;
> >
> >  } DPDK_17.08;
> > +
> > +EXPERIMENTAL {
> > +	rte_vhost_driver_set_vdpa_eid;
> > +	rte_vhost_driver_set_vdpa_did;
> > +	rte_vhost_driver_get_vdpa_eid;
> > +	rte_vhost_driver_get_vdpa_did;
> > +	rte_vhost_driver_get_protocol_features;
> > +	rte_vhost_driver_get_queue_num;
> > +	rte_vhost_get_log_base;
> > +	rte_vhost_get_vring_base;
> > +	rte_vhost_set_vring_base;
> > +	rte_vhost_get_vdpa_eid;
> > +	rte_vhost_get_vdpa_did;
> > +	rte_vdpa_register_engine;
> > +	rte_vdpa_unregister_engine;
> > +	rte_vdpa_find_engine_id;
> > +	rte_vdpa_info_query;
> > +	rte_vdpa_register_driver;
> > +} DPDK_18.02;
> > --
> > 2.13.6

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v2 1/6] vhost: export vhost feature definitions
  2018-03-06 14:03       ` Maxime Coquelin
@ 2018-03-15 10:58         ` Wang, Zhihong
  0 siblings, 0 replies; 67+ messages in thread
From: Wang, Zhihong @ 2018-03-15 10:58 UTC (permalink / raw)
  To: Maxime Coquelin, Tan, Jianfeng, dev
  Cc: Bie, Tiwei, yliu, Liang, Cunming, Wang, Xiao W, Daly, Dan



> -----Original Message-----
> From: Maxime Coquelin [mailto:maxime.coquelin@redhat.com]
> Sent: Tuesday, March 6, 2018 10:03 PM
> To: Tan, Jianfeng <jianfeng.tan@intel.com>; Wang, Zhihong
> <zhihong.wang@intel.com>; dev@dpdk.org
> Cc: Bie, Tiwei <tiwei.bie@intel.com>; yliu@fridaylinux.org; Liang, Cunming
> <cunming.liang@intel.com>; Wang, Xiao W <xiao.w.wang@intel.com>; Daly,
> Dan <dan.daly@intel.com>
> Subject: Re: [PATCH v2 1/6] vhost: export vhost feature definitions
> 
> 
> 
> On 03/06/2018 10:37 AM, Tan, Jianfeng wrote:
> >
> >
> >> -----Original Message-----
> >> From: Wang, Zhihong
> >> Sent: Tuesday, February 13, 2018 5:21 PM
> >> To: dev@dpdk.org
> >> Cc: Tan, Jianfeng; Bie, Tiwei; maxime.coquelin@redhat.com;
> >> yliu@fridaylinux.org; Liang, Cunming; Wang, Xiao W; Daly, Dan; Wang,
> >> Zhihong
> >> Subject: [PATCH v2 1/6] vhost: export vhost feature definitions
> >>
> >> This patch exports vhost-user protocol features to support device driver
> >> development.
> >>
> >> Signed-off-by: Zhihong Wang <zhihong.wang@intel.com>
> >> ---
> >>   lib/librte_vhost/rte_vhost.h  |  8 ++++++++
> >>   lib/librte_vhost/vhost.h      |  4 +---
> >>   lib/librte_vhost/vhost_user.c |  9 +++++----
> >>   lib/librte_vhost/vhost_user.h | 20 +++++++-------------
> >>   4 files changed, 21 insertions(+), 20 deletions(-)
> >>
> >> diff --git a/lib/librte_vhost/rte_vhost.h b/lib/librte_vhost/rte_vhost.h
> >> index d33206997..b05162366 100644
> >> --- a/lib/librte_vhost/rte_vhost.h
> >> +++ b/lib/librte_vhost/rte_vhost.h
> >> @@ -29,6 +29,14 @@ extern "C" {
> >>   #define RTE_VHOST_USER_DEQUEUE_ZERO_COPY	(1ULL << 2)
> >>   #define RTE_VHOST_USER_IOMMU_SUPPORT	(1ULL << 3)
> >>
> >> +#define RTE_VHOST_USER_PROTOCOL_F_MQ		0
> >
> > Instead of adding a "RTE_" prefix. I prefer to define it like this:
> > #ifndef VHOST_USER_PROTOCOL_F_MQ
> > #define VHOST_USER_PROTOCOL_F_MQ                                           0
> > #endif
> >
> > Similar to other macros.
> 
> I agree, it is better to keep same naming as in the spec IMHO.

Ok. Thanks Jianfeng and Maxime.

> 
> >> +#define RTE_VHOST_USER_PROTOCOL_F_LOG_SHMFD	1
> >> +#define RTE_VHOST_USER_PROTOCOL_F_RARP		2
> >> +#define RTE_VHOST_USER_PROTOCOL_F_REPLY_ACK	3
> >> +#define RTE_VHOST_USER_PROTOCOL_F_NET_MTU	4
> >> +#define RTE_VHOST_USER_PROTOCOL_F_SLAVE_REQ	5
> >> +#define RTE_VHOST_USER_F_PROTOCOL_FEATURES	30
> 
> Please put the above declaration separately, it could be misleading,
> making to think it is a vhost-user protocol feature whereas it is a
> Virtio feature.

Good point. Will change it.

-Zhihong

> 
> >> +
> >>   /**
> >>    * Information relating to memory regions including offsets to
> >>    * addresses in QEMUs memory file.
> >> diff --git a/lib/librte_vhost/vhost.h b/lib/librte_vhost/vhost.h
> >> index 58aec2e0d..a0b0520e2 100644
> >> --- a/lib/librte_vhost/vhost.h
> >> +++ b/lib/librte_vhost/vhost.h
> >> @@ -174,8 +174,6 @@ struct vhost_msg {
> >>    #define VIRTIO_F_VERSION_1 32
> >>   #endif
> >>
> >> -#define VHOST_USER_F_PROTOCOL_FEATURES	30
> >> -
> >>   /* Features supported by this builtin vhost-user net driver. */
> >>   #define VIRTIO_NET_SUPPORTED_FEATURES ((1ULL <<
> >> VIRTIO_NET_F_MRG_RXBUF) | \
> >>   				(1ULL << VIRTIO_F_ANY_LAYOUT) | \
> >> @@ -185,7 +183,7 @@ struct vhost_msg {
> >>   				(1ULL << VIRTIO_NET_F_MQ)      | \
> >>   				(1ULL << VIRTIO_F_VERSION_1)   | \
> >>   				(1ULL << VHOST_F_LOG_ALL)      | \
> >> -				(1ULL <<
> >> VHOST_USER_F_PROTOCOL_FEATURES) | \
> >> +				(1ULL <<
> >> RTE_VHOST_USER_F_PROTOCOL_FEATURES) | \
> >>   				(1ULL << VIRTIO_NET_F_GSO) | \
> >>   				(1ULL << VIRTIO_NET_F_HOST_TSO4) | \
> >>   				(1ULL << VIRTIO_NET_F_HOST_TSO6) | \
> >> diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c
> >> index 5c5361066..c93e48e4d 100644
> >> --- a/lib/librte_vhost/vhost_user.c
> >> +++ b/lib/librte_vhost/vhost_user.c
> >> @@ -527,7 +527,7 @@ vhost_user_set_vring_addr(struct virtio_net
> **pdev,
> >> VhostUserMsg *msg)
> >>   	vring_invalidate(dev, vq);
> >>
> >>   	if (vq->enabled && (dev->features &
> >> -				(1ULL <<
> >> VHOST_USER_F_PROTOCOL_FEATURES))) {
> >> +				(1ULL <<
> >> RTE_VHOST_USER_F_PROTOCOL_FEATURES))) {
> >>   		dev = translate_ring_addresses(dev, msg-
> >>> payload.addr.index);
> >>   		if (!dev)
> >>   			return -1;
> >> @@ -897,11 +897,11 @@ vhost_user_set_vring_kick(struct virtio_net
> >> **pdev, struct VhostUserMsg *pmsg)
> >>   	vq = dev->virtqueue[file.index];
> >>
> >>   	/*
> >> -	 * When VHOST_USER_F_PROTOCOL_FEATURES is not negotiated,
> >> +	 * When RTE_VHOST_USER_F_PROTOCOL_FEATURES is not
> >> negotiated,
> >>   	 * the ring starts already enabled. Otherwise, it is enabled via
> >>   	 * the SET_VRING_ENABLE message.
> >>   	 */
> >> -	if (!(dev->features & (1ULL <<
> >> VHOST_USER_F_PROTOCOL_FEATURES)))
> >> +	if (!(dev->features & (1ULL <<
> >> RTE_VHOST_USER_F_PROTOCOL_FEATURES)))
> >>   		vq->enabled = 1;
> >>
> >>   	if (vq->kickfd >= 0)
> >> @@ -1012,7 +1012,8 @@ vhost_user_get_protocol_features(struct
> >> virtio_net *dev,
> >>   	 * Qemu versions (from v2.7.0 to v2.9.0).
> >>   	 */
> >>   	if (!(features & (1ULL << VIRTIO_F_IOMMU_PLATFORM)))
> >> -		protocol_features &= ~(1ULL <<
> >> VHOST_USER_PROTOCOL_F_REPLY_ACK);
> >> +		protocol_features &=
> >> +			~(1ULL <<
> >> RTE_VHOST_USER_PROTOCOL_F_REPLY_ACK);
> >>
> >>   	msg->payload.u64 = protocol_features;
> >>   	msg->size = sizeof(msg->payload.u64);
> >> diff --git a/lib/librte_vhost/vhost_user.h b/lib/librte_vhost/vhost_user.h
> >> index 0fafbe6e0..066e772dd 100644
> >> --- a/lib/librte_vhost/vhost_user.h
> >> +++ b/lib/librte_vhost/vhost_user.h
> >> @@ -14,19 +14,13 @@
> >>
> >>   #define VHOST_MEMORY_MAX_NREGIONS 8
> >>
> >> -#define VHOST_USER_PROTOCOL_F_MQ	0
> >> -#define VHOST_USER_PROTOCOL_F_LOG_SHMFD	1
> >> -#define VHOST_USER_PROTOCOL_F_RARP	2
> >> -#define VHOST_USER_PROTOCOL_F_REPLY_ACK	3
> >> -#define VHOST_USER_PROTOCOL_F_NET_MTU 4
> >> -#define VHOST_USER_PROTOCOL_F_SLAVE_REQ 5
> >> -
> >> -#define VHOST_USER_PROTOCOL_FEATURES	((1ULL <<
> >> VHOST_USER_PROTOCOL_F_MQ) | \
> >> -					 (1ULL <<
> >> VHOST_USER_PROTOCOL_F_LOG_SHMFD) |\
> >> -					 (1ULL <<
> >> VHOST_USER_PROTOCOL_F_RARP) | \
> >> -					 (1ULL <<
> >> VHOST_USER_PROTOCOL_F_REPLY_ACK) | \
> >> -					 (1ULL <<
> >> VHOST_USER_PROTOCOL_F_NET_MTU) | \
> >> -					 (1ULL <<
> >> VHOST_USER_PROTOCOL_F_SLAVE_REQ))
> >> +#define VHOST_USER_PROTOCOL_FEATURES \
> >> +			((1ULL << RTE_VHOST_USER_PROTOCOL_F_MQ) | \
> >> +			 (1ULL <<
> >> RTE_VHOST_USER_PROTOCOL_F_LOG_SHMFD) |\
> >> +			 (1ULL << RTE_VHOST_USER_PROTOCOL_F_RARP) | \
> >> +			 (1ULL <<
> >> RTE_VHOST_USER_PROTOCOL_F_REPLY_ACK) | \
> >> +			 (1ULL <<
> >> RTE_VHOST_USER_PROTOCOL_F_NET_MTU) | \
> >> +			 (1ULL <<
> >> RTE_VHOST_USER_PROTOCOL_F_SLAVE_REQ))
> >>
> >>   typedef enum VhostUserRequest {
> >>   	VHOST_USER_NONE = 0,
> >> --
> >> 2.13.6
> >

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v3 2/5] vhost: support selective datapath
  2018-02-27 10:13   ` [PATCH v3 2/5] vhost: support selective datapath Zhihong Wang
@ 2018-03-21 21:05     ` Maxime Coquelin
  2018-03-22  7:55       ` Wang, Zhihong
  0 siblings, 1 reply; 67+ messages in thread
From: Maxime Coquelin @ 2018-03-21 21:05 UTC (permalink / raw)
  To: Zhihong Wang, dev
  Cc: jianfeng.tan, tiwei.bie, yliu, cunming.liang, xiao.w.wang, dan.daly



On 02/27/2018 11:13 AM, Zhihong Wang wrote:
> This patch introduces support for selective datapath in DPDK vhost-user lib
> to enable various types of virtio-compatible devices to do data transfer
> with virtio driver directly to enable acceleration. The default datapath is
> the existing software implementation, more options will be available when
> new engines are registered.
> 
> An engine is a group of virtio-compatible devices under a single address.
> The engine driver includes:
> 
>   1. A set of engine ops is defined in rte_vdpa_eng_ops to perform engine
>      init, uninit, and attributes reporting.
>      
>   2. A set of device ops is defined in rte_vdpa_dev_ops for virtio devices
>      in the engine to do device specific operations:
> 
>       a. dev_conf: Called to configure the actual device when the virtio
>          device becomes ready.
> 
>       b. dev_close: Called to close the actual device when the virtio device
>          is stopped.
> 
>       c. vring_state_set: Called to change the state of the vring in the
>          actual device when vring state changes.
> 
>       d. feature_set: Called to set the negotiated features to device.
> 
>       e. migration_done: Called to allow the device to response to RARP
>          sending.
> 
>       f. get_vfio_group_fd: Called to get the VFIO group fd of the device.
> 
>       g. get_vfio_device_fd: Called to get the VFIO device fd of the device.
> 
>       h. get_notify_area: Called to get the notify area info of the queue.
> 
> Signed-off-by: Zhihong Wang <zhihong.wang@intel.com>
> ---
> Changes in v2:
> 
>   1. Add VFIO related vDPA device ops.
> 
>   lib/librte_vhost/Makefile              |   4 +-
>   lib/librte_vhost/rte_vdpa.h            | 126 +++++++++++++++++++++++++++++++++
>   lib/librte_vhost/rte_vhost_version.map |   8 +++
>   lib/librte_vhost/vdpa.c                | 124 ++++++++++++++++++++++++++++++++
>   4 files changed, 260 insertions(+), 2 deletions(-)
>   create mode 100644 lib/librte_vhost/rte_vdpa.h
>   create mode 100644 lib/librte_vhost/vdpa.c
> 
> diff --git a/lib/librte_vhost/Makefile b/lib/librte_vhost/Makefile
> index 5d6c6abae..37044ac03 100644
> --- a/lib/librte_vhost/Makefile
> +++ b/lib/librte_vhost/Makefile
> @@ -22,9 +22,9 @@ LDLIBS += -lrte_eal -lrte_mempool -lrte_mbuf -lrte_ethdev -lrte_net
>   
>   # all source are stored in SRCS-y
>   SRCS-$(CONFIG_RTE_LIBRTE_VHOST) := fd_man.c iotlb.c socket.c vhost.c \
> -					vhost_user.c virtio_net.c
> +					vhost_user.c virtio_net.c vdpa.c
>   
>   # install includes
> -SYMLINK-$(CONFIG_RTE_LIBRTE_VHOST)-include += rte_vhost.h
> +SYMLINK-$(CONFIG_RTE_LIBRTE_VHOST)-include += rte_vhost.h rte_vdpa.h
>   
>   include $(RTE_SDK)/mk/rte.lib.mk
> diff --git a/lib/librte_vhost/rte_vdpa.h b/lib/librte_vhost/rte_vdpa.h
> new file mode 100644
> index 000000000..23fb471be
> --- /dev/null
> +++ b/lib/librte_vhost/rte_vdpa.h
> @@ -0,0 +1,126 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright(c) 2018 Intel Corporation
> + */
> +
> +#ifndef _RTE_VDPA_H_
> +#define _RTE_VDPA_H_
> +
> +/**
> + * @file
> + *
> + * Device specific vhost lib
> + */
> +
> +#include <rte_pci.h>
> +#include "rte_vhost.h"
> +
> +#define MAX_VDPA_ENGINE_NUM 128
> +#define MAX_VDPA_NAME_LEN 128
> +
> +struct rte_vdpa_eng_addr {
> +	union {
> +		uint8_t __dummy[64];
> +		struct rte_pci_addr pci_addr;
I think we should not only support PCI, but any type of buses.
At least in the API.

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v3 3/5] vhost: add apis for datapath configuration
  2018-02-27 10:13   ` [PATCH v3 3/5] vhost: add apis for datapath configuration Zhihong Wang
@ 2018-03-21 21:08     ` Maxime Coquelin
  2018-03-22  8:22       ` Wang, Zhihong
  0 siblings, 1 reply; 67+ messages in thread
From: Maxime Coquelin @ 2018-03-21 21:08 UTC (permalink / raw)
  To: Zhihong Wang, dev
  Cc: jianfeng.tan, tiwei.bie, yliu, cunming.liang, xiao.w.wang, dan.daly



On 02/27/2018 11:13 AM, Zhihong Wang wrote:
> This patch adds APIs for datapath configuration. The eid and did of the
> vhost-user socket can be configured to identify the actual device.
> 
> When the default software datapath is used, eid and did are set to -1.
> When alternative datapath is used, eid and did are set by app to specify
> which device to use. Each vhost-user socket can have only 1 connection in
> this case.
> 
> Signed-off-by: Zhihong Wang <zhihong.wang@intel.com>
> ---
>   lib/librte_vhost/rte_vhost.h           | 70 ++++++++++++++++++++++++++++++++++
>   lib/librte_vhost/rte_vhost_version.map |  6 +++
>   lib/librte_vhost/socket.c              | 65 +++++++++++++++++++++++++++++++
>   lib/librte_vhost/vhost.c               | 50 ++++++++++++++++++++++++
>   lib/librte_vhost/vhost.h               | 10 +++++
>   5 files changed, 201 insertions(+)
> 

Isn't the notion of EID & DID Intel specifics?
At vhost API level, shouldn't we only care of the offload device ID?

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v3 2/5] vhost: support selective datapath
  2018-03-21 21:05     ` Maxime Coquelin
@ 2018-03-22  7:55       ` Wang, Zhihong
  2018-03-22  8:31         ` Maxime Coquelin
  0 siblings, 1 reply; 67+ messages in thread
From: Wang, Zhihong @ 2018-03-22  7:55 UTC (permalink / raw)
  To: Maxime Coquelin, dev
  Cc: Tan, Jianfeng, Bie, Tiwei, yliu, Liang, Cunming, Wang, Xiao W, Daly, Dan



> -----Original Message-----
> From: Maxime Coquelin [mailto:maxime.coquelin@redhat.com]
> Sent: Thursday, March 22, 2018 5:06 AM
> To: Wang, Zhihong <zhihong.wang@intel.com>; dev@dpdk.org
> Cc: Tan, Jianfeng <jianfeng.tan@intel.com>; Bie, Tiwei
> <tiwei.bie@intel.com>; yliu@fridaylinux.org; Liang, Cunming
> <cunming.liang@intel.com>; Wang, Xiao W <xiao.w.wang@intel.com>; Daly,
> Dan <dan.daly@intel.com>
> Subject: Re: [PATCH v3 2/5] vhost: support selective datapath
> 
> 
> 
> On 02/27/2018 11:13 AM, Zhihong Wang wrote:
> > This patch introduces support for selective datapath in DPDK vhost-user lib
> > to enable various types of virtio-compatible devices to do data transfer
> > with virtio driver directly to enable acceleration. The default datapath is
> > the existing software implementation, more options will be available when
> > new engines are registered.
> >
> > An engine is a group of virtio-compatible devices under a single address.
> > The engine driver includes:
> >
> >   1. A set of engine ops is defined in rte_vdpa_eng_ops to perform engine
> >      init, uninit, and attributes reporting.
> >
> >   2. A set of device ops is defined in rte_vdpa_dev_ops for virtio devices
> >      in the engine to do device specific operations:
> >
> >       a. dev_conf: Called to configure the actual device when the virtio
> >          device becomes ready.
> >
> >       b. dev_close: Called to close the actual device when the virtio device
> >          is stopped.
> >
> >       c. vring_state_set: Called to change the state of the vring in the
> >          actual device when vring state changes.
> >
> >       d. feature_set: Called to set the negotiated features to device.
> >
> >       e. migration_done: Called to allow the device to response to RARP
> >          sending.
> >
> >       f. get_vfio_group_fd: Called to get the VFIO group fd of the device.
> >
> >       g. get_vfio_device_fd: Called to get the VFIO device fd of the device.
> >
> >       h. get_notify_area: Called to get the notify area info of the queue.
> >
> > Signed-off-by: Zhihong Wang <zhihong.wang@intel.com>
> > ---
> > Changes in v2:
> >
> >   1. Add VFIO related vDPA device ops.
> >
> >   lib/librte_vhost/Makefile              |   4 +-
> >   lib/librte_vhost/rte_vdpa.h            | 126
> +++++++++++++++++++++++++++++++++
> >   lib/librte_vhost/rte_vhost_version.map |   8 +++
> >   lib/librte_vhost/vdpa.c                | 124
> ++++++++++++++++++++++++++++++++
> >   4 files changed, 260 insertions(+), 2 deletions(-)
> >   create mode 100644 lib/librte_vhost/rte_vdpa.h
> >   create mode 100644 lib/librte_vhost/vdpa.c
> >
> > diff --git a/lib/librte_vhost/Makefile b/lib/librte_vhost/Makefile
> > index 5d6c6abae..37044ac03 100644
> > --- a/lib/librte_vhost/Makefile
> > +++ b/lib/librte_vhost/Makefile
> > @@ -22,9 +22,9 @@ LDLIBS += -lrte_eal -lrte_mempool -lrte_mbuf -
> lrte_ethdev -lrte_net
> >
> >   # all source are stored in SRCS-y
> >   SRCS-$(CONFIG_RTE_LIBRTE_VHOST) := fd_man.c iotlb.c socket.c vhost.c
> \
> > -					vhost_user.c virtio_net.c
> > +					vhost_user.c virtio_net.c vdpa.c
> >
> >   # install includes
> > -SYMLINK-$(CONFIG_RTE_LIBRTE_VHOST)-include += rte_vhost.h
> > +SYMLINK-$(CONFIG_RTE_LIBRTE_VHOST)-include += rte_vhost.h
> rte_vdpa.h
> >
> >   include $(RTE_SDK)/mk/rte.lib.mk
> > diff --git a/lib/librte_vhost/rte_vdpa.h b/lib/librte_vhost/rte_vdpa.h
> > new file mode 100644
> > index 000000000..23fb471be
> > --- /dev/null
> > +++ b/lib/librte_vhost/rte_vdpa.h
> > @@ -0,0 +1,126 @@
> > +/* SPDX-License-Identifier: BSD-3-Clause
> > + * Copyright(c) 2018 Intel Corporation
> > + */
> > +
> > +#ifndef _RTE_VDPA_H_
> > +#define _RTE_VDPA_H_
> > +
> > +/**
> > + * @file
> > + *
> > + * Device specific vhost lib
> > + */
> > +
> > +#include <rte_pci.h>
> > +#include "rte_vhost.h"
> > +
> > +#define MAX_VDPA_ENGINE_NUM 128
> > +#define MAX_VDPA_NAME_LEN 128
> > +
> > +struct rte_vdpa_eng_addr {
> > +	union {
> > +		uint8_t __dummy[64];
> > +		struct rte_pci_addr pci_addr;
> I think we should not only support PCI, but any type of buses.
> At least in the API.

Exactly, so we defined a 64 bytes union so any bus types can be added
without breaking the ABI.

But there is one place that may be impacted is the is_same_eng() function.
Maybe comparing all the bytes in __dummy[64] is a better way. What do you
think?

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v3 3/5] vhost: add apis for datapath configuration
  2018-03-21 21:08     ` Maxime Coquelin
@ 2018-03-22  8:22       ` Wang, Zhihong
  2018-03-22 14:18         ` Maxime Coquelin
  0 siblings, 1 reply; 67+ messages in thread
From: Wang, Zhihong @ 2018-03-22  8:22 UTC (permalink / raw)
  To: Maxime Coquelin, dev
  Cc: Tan, Jianfeng, Bie, Tiwei, yliu, Liang, Cunming, Wang, Xiao W, Daly, Dan



> -----Original Message-----
> From: Maxime Coquelin [mailto:maxime.coquelin@redhat.com]
> Sent: Thursday, March 22, 2018 5:08 AM
> To: Wang, Zhihong <zhihong.wang@intel.com>; dev@dpdk.org
> Cc: Tan, Jianfeng <jianfeng.tan@intel.com>; Bie, Tiwei
> <tiwei.bie@intel.com>; yliu@fridaylinux.org; Liang, Cunming
> <cunming.liang@intel.com>; Wang, Xiao W <xiao.w.wang@intel.com>; Daly,
> Dan <dan.daly@intel.com>
> Subject: Re: [PATCH v3 3/5] vhost: add apis for datapath configuration
> 
> 
> 
> On 02/27/2018 11:13 AM, Zhihong Wang wrote:
> > This patch adds APIs for datapath configuration. The eid and did of the
> > vhost-user socket can be configured to identify the actual device.
> >
> > When the default software datapath is used, eid and did are set to -1.
> > When alternative datapath is used, eid and did are set by app to specify
> > which device to use. Each vhost-user socket can have only 1 connection in
> > this case.
> >
> > Signed-off-by: Zhihong Wang <zhihong.wang@intel.com>
> > ---
> >   lib/librte_vhost/rte_vhost.h           | 70
> ++++++++++++++++++++++++++++++++++
> >   lib/librte_vhost/rte_vhost_version.map |  6 +++
> >   lib/librte_vhost/socket.c              | 65
> +++++++++++++++++++++++++++++++
> >   lib/librte_vhost/vhost.c               | 50 ++++++++++++++++++++++++
> >   lib/librte_vhost/vhost.h               | 10 +++++
> >   5 files changed, 201 insertions(+)
> >
> 
> Isn't the notion of EID & DID Intel specifics?
> At vhost API level, shouldn't we only care of the offload device ID?

It's not vendor specific: Engine id refers to an engine which is a device
on a bus, the engine could have multiple queue pairs or virtual functions.
The driver can manage them to present multiple vhost ports with vDPA to
application, so logically the concept of device id exists.

In a lot of acceleration cases, application needs to be able to choose the
exact port to use instead of letting the driver to decide (because it does
make a difference), therefore it's necessary to expose the device id here.

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v3 2/5] vhost: support selective datapath
  2018-03-22  7:55       ` Wang, Zhihong
@ 2018-03-22  8:31         ` Maxime Coquelin
  0 siblings, 0 replies; 67+ messages in thread
From: Maxime Coquelin @ 2018-03-22  8:31 UTC (permalink / raw)
  To: Wang, Zhihong, dev
  Cc: Tan, Jianfeng, Bie, Tiwei, yliu, Liang, Cunming, Wang, Xiao W, Daly, Dan



On 03/22/2018 08:55 AM, Wang, Zhihong wrote:
> 
> 
>> -----Original Message-----
>> From: Maxime Coquelin [mailto:maxime.coquelin@redhat.com]
>> Sent: Thursday, March 22, 2018 5:06 AM
>> To: Wang, Zhihong <zhihong.wang@intel.com>; dev@dpdk.org
>> Cc: Tan, Jianfeng <jianfeng.tan@intel.com>; Bie, Tiwei
>> <tiwei.bie@intel.com>; yliu@fridaylinux.org; Liang, Cunming
>> <cunming.liang@intel.com>; Wang, Xiao W <xiao.w.wang@intel.com>; Daly,
>> Dan <dan.daly@intel.com>
>> Subject: Re: [PATCH v3 2/5] vhost: support selective datapath
>>
>>
>>
>> On 02/27/2018 11:13 AM, Zhihong Wang wrote:
>>> This patch introduces support for selective datapath in DPDK vhost-user lib
>>> to enable various types of virtio-compatible devices to do data transfer
>>> with virtio driver directly to enable acceleration. The default datapath is
>>> the existing software implementation, more options will be available when
>>> new engines are registered.
>>>
>>> An engine is a group of virtio-compatible devices under a single address.
>>> The engine driver includes:
>>>
>>>    1. A set of engine ops is defined in rte_vdpa_eng_ops to perform engine
>>>       init, uninit, and attributes reporting.
>>>
>>>    2. A set of device ops is defined in rte_vdpa_dev_ops for virtio devices
>>>       in the engine to do device specific operations:
>>>
>>>        a. dev_conf: Called to configure the actual device when the virtio
>>>           device becomes ready.
>>>
>>>        b. dev_close: Called to close the actual device when the virtio device
>>>           is stopped.
>>>
>>>        c. vring_state_set: Called to change the state of the vring in the
>>>           actual device when vring state changes.
>>>
>>>        d. feature_set: Called to set the negotiated features to device.
>>>
>>>        e. migration_done: Called to allow the device to response to RARP
>>>           sending.
>>>
>>>        f. get_vfio_group_fd: Called to get the VFIO group fd of the device.
>>>
>>>        g. get_vfio_device_fd: Called to get the VFIO device fd of the device.
>>>
>>>        h. get_notify_area: Called to get the notify area info of the queue.
>>>
>>> Signed-off-by: Zhihong Wang <zhihong.wang@intel.com>
>>> ---
>>> Changes in v2:
>>>
>>>    1. Add VFIO related vDPA device ops.
>>>
>>>    lib/librte_vhost/Makefile              |   4 +-
>>>    lib/librte_vhost/rte_vdpa.h            | 126
>> +++++++++++++++++++++++++++++++++
>>>    lib/librte_vhost/rte_vhost_version.map |   8 +++
>>>    lib/librte_vhost/vdpa.c                | 124
>> ++++++++++++++++++++++++++++++++
>>>    4 files changed, 260 insertions(+), 2 deletions(-)
>>>    create mode 100644 lib/librte_vhost/rte_vdpa.h
>>>    create mode 100644 lib/librte_vhost/vdpa.c
>>>
>>> diff --git a/lib/librte_vhost/Makefile b/lib/librte_vhost/Makefile
>>> index 5d6c6abae..37044ac03 100644
>>> --- a/lib/librte_vhost/Makefile
>>> +++ b/lib/librte_vhost/Makefile
>>> @@ -22,9 +22,9 @@ LDLIBS += -lrte_eal -lrte_mempool -lrte_mbuf -
>> lrte_ethdev -lrte_net
>>>
>>>    # all source are stored in SRCS-y
>>>    SRCS-$(CONFIG_RTE_LIBRTE_VHOST) := fd_man.c iotlb.c socket.c vhost.c
>> \
>>> -					vhost_user.c virtio_net.c
>>> +					vhost_user.c virtio_net.c vdpa.c
>>>
>>>    # install includes
>>> -SYMLINK-$(CONFIG_RTE_LIBRTE_VHOST)-include += rte_vhost.h
>>> +SYMLINK-$(CONFIG_RTE_LIBRTE_VHOST)-include += rte_vhost.h
>> rte_vdpa.h
>>>
>>>    include $(RTE_SDK)/mk/rte.lib.mk
>>> diff --git a/lib/librte_vhost/rte_vdpa.h b/lib/librte_vhost/rte_vdpa.h
>>> new file mode 100644
>>> index 000000000..23fb471be
>>> --- /dev/null
>>> +++ b/lib/librte_vhost/rte_vdpa.h
>>> @@ -0,0 +1,126 @@
>>> +/* SPDX-License-Identifier: BSD-3-Clause
>>> + * Copyright(c) 2018 Intel Corporation
>>> + */
>>> +
>>> +#ifndef _RTE_VDPA_H_
>>> +#define _RTE_VDPA_H_
>>> +
>>> +/**
>>> + * @file
>>> + *
>>> + * Device specific vhost lib
>>> + */
>>> +
>>> +#include <rte_pci.h>
>>> +#include "rte_vhost.h"
>>> +
>>> +#define MAX_VDPA_ENGINE_NUM 128
>>> +#define MAX_VDPA_NAME_LEN 128
>>> +
>>> +struct rte_vdpa_eng_addr {
>>> +	union {
>>> +		uint8_t __dummy[64];
>>> +		struct rte_pci_addr pci_addr;
>> I think we should not only support PCI, but any type of buses.
>> At least in the API.
> 
> Exactly, so we defined a 64 bytes union so any bus types can be added
> without breaking the ABI.

Oh right, I missed that. That's good to me.

> But there is one place that may be impacted is the is_same_eng() function.
> Maybe comparing all the bytes in __dummy[64] is a better way. What do you
> think?

I think that for now that's fine to keep comparing PCI addresses as we 
don't have other bus supported than PCI. My concern was about the API,
and I mistakenly didn't see you already took care of it.

Thanks!
Maxime

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v3 3/5] vhost: add apis for datapath configuration
  2018-03-22  8:22       ` Wang, Zhihong
@ 2018-03-22 14:18         ` Maxime Coquelin
  2018-03-23 10:35           ` Wang, Zhihong
  0 siblings, 1 reply; 67+ messages in thread
From: Maxime Coquelin @ 2018-03-22 14:18 UTC (permalink / raw)
  To: Wang, Zhihong, dev
  Cc: Tan, Jianfeng, Bie, Tiwei, yliu, Liang, Cunming, Wang, Xiao W, Daly, Dan

Hi,

On 03/22/2018 09:22 AM, Wang, Zhihong wrote:
> 
> 
>> -----Original Message-----
>> From: Maxime Coquelin [mailto:maxime.coquelin@redhat.com]
>> Sent: Thursday, March 22, 2018 5:08 AM
>> To: Wang, Zhihong <zhihong.wang@intel.com>; dev@dpdk.org
>> Cc: Tan, Jianfeng <jianfeng.tan@intel.com>; Bie, Tiwei
>> <tiwei.bie@intel.com>; yliu@fridaylinux.org; Liang, Cunming
>> <cunming.liang@intel.com>; Wang, Xiao W <xiao.w.wang@intel.com>; Daly,
>> Dan <dan.daly@intel.com>
>> Subject: Re: [PATCH v3 3/5] vhost: add apis for datapath configuration
>>
>>
>>
>> On 02/27/2018 11:13 AM, Zhihong Wang wrote:
>>> This patch adds APIs for datapath configuration. The eid and did of the
>>> vhost-user socket can be configured to identify the actual device.
>>>
>>> When the default software datapath is used, eid and did are set to -1.
>>> When alternative datapath is used, eid and did are set by app to specify
>>> which device to use. Each vhost-user socket can have only 1 connection in
>>> this case.
>>>
>>> Signed-off-by: Zhihong Wang <zhihong.wang@intel.com>
>>> ---
>>>    lib/librte_vhost/rte_vhost.h           | 70
>> ++++++++++++++++++++++++++++++++++
>>>    lib/librte_vhost/rte_vhost_version.map |  6 +++
>>>    lib/librte_vhost/socket.c              | 65
>> +++++++++++++++++++++++++++++++
>>>    lib/librte_vhost/vhost.c               | 50 ++++++++++++++++++++++++
>>>    lib/librte_vhost/vhost.h               | 10 +++++
>>>    5 files changed, 201 insertions(+)
>>>
>>
>> Isn't the notion of EID & DID Intel specifics?
>> At vhost API level, shouldn't we only care of the offload device ID?
> 
> It's not vendor specific: Engine id refers to an engine which is a device
> on a bus, the engine could have multiple queue pairs or virtual functions.
> The driver can manage them to present multiple vhost ports with vDPA to
> application, so logically the concept of device id exists.
> 
> In a lot of acceleration cases, application needs to be able to choose the
> exact port to use instead of letting the driver to decide (because it does
> make a difference), therefore it's necessary to expose the device id here.

Yes, but if I understood correctly with the IFCVF driver, we could pass 
directly the virtual function to the vhost-user lib, no need to specify
the engine. We would just need to register one device per VF, but that 
looks like the right think to do looking at how IFCVF manages MAC
addresses and link status for example.

Thanks,
Maxime

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v3 3/5] vhost: add apis for datapath configuration
  2018-03-22 14:18         ` Maxime Coquelin
@ 2018-03-23 10:35           ` Wang, Zhihong
  0 siblings, 0 replies; 67+ messages in thread
From: Wang, Zhihong @ 2018-03-23 10:35 UTC (permalink / raw)
  To: Maxime Coquelin, dev
  Cc: Tan, Jianfeng, Bie, Tiwei, yliu, Liang, Cunming, Wang, Xiao W, Daly, Dan

Hi Maxime,

> -----Original Message-----
> From: Maxime Coquelin [mailto:maxime.coquelin@redhat.com]
> Sent: Thursday, March 22, 2018 10:19 PM
> To: Wang, Zhihong <zhihong.wang@intel.com>; dev@dpdk.org
> Cc: Tan, Jianfeng <jianfeng.tan@intel.com>; Bie, Tiwei
> <tiwei.bie@intel.com>; yliu@fridaylinux.org; Liang, Cunming
> <cunming.liang@intel.com>; Wang, Xiao W <xiao.w.wang@intel.com>; Daly,
> Dan <dan.daly@intel.com>
> Subject: Re: [PATCH v3 3/5] vhost: add apis for datapath configuration
> 
> Hi,
> 
> On 03/22/2018 09:22 AM, Wang, Zhihong wrote:
> >
> >
> >> -----Original Message-----
> >> From: Maxime Coquelin [mailto:maxime.coquelin@redhat.com]
> >> Sent: Thursday, March 22, 2018 5:08 AM
> >> To: Wang, Zhihong <zhihong.wang@intel.com>; dev@dpdk.org
> >> Cc: Tan, Jianfeng <jianfeng.tan@intel.com>; Bie, Tiwei
> >> <tiwei.bie@intel.com>; yliu@fridaylinux.org; Liang, Cunming
> >> <cunming.liang@intel.com>; Wang, Xiao W <xiao.w.wang@intel.com>;
> Daly,
> >> Dan <dan.daly@intel.com>
> >> Subject: Re: [PATCH v3 3/5] vhost: add apis for datapath configuration
> >>
> >>
> >>
> >> On 02/27/2018 11:13 AM, Zhihong Wang wrote:
> >>> This patch adds APIs for datapath configuration. The eid and did of the
> >>> vhost-user socket can be configured to identify the actual device.
> >>>
> >>> When the default software datapath is used, eid and did are set to -1.
> >>> When alternative datapath is used, eid and did are set by app to specify
> >>> which device to use. Each vhost-user socket can have only 1 connection
> in
> >>> this case.
> >>>
> >>> Signed-off-by: Zhihong Wang <zhihong.wang@intel.com>
> >>> ---
> >>>    lib/librte_vhost/rte_vhost.h           | 70
> >> ++++++++++++++++++++++++++++++++++
> >>>    lib/librte_vhost/rte_vhost_version.map |  6 +++
> >>>    lib/librte_vhost/socket.c              | 65
> >> +++++++++++++++++++++++++++++++
> >>>    lib/librte_vhost/vhost.c               | 50 ++++++++++++++++++++++++
> >>>    lib/librte_vhost/vhost.h               | 10 +++++
> >>>    5 files changed, 201 insertions(+)
> >>>
> >>
> >> Isn't the notion of EID & DID Intel specifics?
> >> At vhost API level, shouldn't we only care of the offload device ID?
> >
> > It's not vendor specific: Engine id refers to an engine which is a device
> > on a bus, the engine could have multiple queue pairs or virtual functions.
> > The driver can manage them to present multiple vhost ports with vDPA to
> > application, so logically the concept of device id exists.
> >
> > In a lot of acceleration cases, application needs to be able to choose the
> > exact port to use instead of letting the driver to decide (because it does
> > make a difference), therefore it's necessary to expose the device id here.
> 
> Yes, but if I understood correctly with the IFCVF driver, we could pass
> directly the virtual function to the vhost-user lib, no need to specify
> the engine. We would just need to register one device per VF, but that
> looks like the right think to do looking at how IFCVF manages MAC
> addresses and link status for example.

The lib is for generic designs. An engine could also be an AFU device [1]
which has multiple virtio ring compatible queue pairs that can serve
different VMs independently, instead of multiple virtual functions. In
this case, we need eid to index the AFU device, and did to index the queue
pair(s).

[1] http://dpdk.org/ml/archives/dev/2018-March/093343.html (struct rte_afu_device)

Thanks
-Zhihong

> 
> Thanks,
> Maxime

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v3 0/5] vhost: support selective datapath
  2018-02-27 10:13 ` [PATCH v3 0/5] vhost: support selective datapath Zhihong Wang
                     ` (4 preceding siblings ...)
  2018-02-27 10:13   ` [PATCH v3 5/5] vhost: add apis for live migration Zhihong Wang
@ 2018-03-29 12:15   ` Wodkowski, PawelX
  2018-03-30  9:35     ` Wang, Zhihong
  5 siblings, 1 reply; 67+ messages in thread
From: Wodkowski, PawelX @ 2018-03-29 12:15 UTC (permalink / raw)
  To: Wang, Zhihong, dev
  Cc: Tan, Jianfeng, Bie, Tiwei, maxime.coquelin, yliu, Liang, Cunming,
	Wang, Xiao W, Daly, Dan, Wang, Zhihong

> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Zhihong Wang
> Sent: Tuesday, February 27, 2018 11:14 AM
> To: dev@dpdk.org
> Cc: Tan, Jianfeng <jianfeng.tan@intel.com>; Bie, Tiwei <tiwei.bie@intel.com>;
> maxime.coquelin@redhat.com; yliu@fridaylinux.org; Liang, Cunming
> <cunming.liang@intel.com>; Wang, Xiao W <xiao.w.wang@intel.com>; Daly,
> Dan <dan.daly@intel.com>; Wang, Zhihong <zhihong.wang@intel.com>
> Subject: [dpdk-dev] [PATCH v3 0/5] vhost: support selective datapath
> 
> This patch set introduces support for selective datapath in DPDK vhost-user
> lib. vDPA stands for vhost Data Path Acceleration. The idea is to enable
> various types of virtio-compatible devices to do data transfer with virtio
> driver directly to enable acceleration.
> 
> The default datapath is the existing software implementation, more options
> will be available when new engines are added.
> 
> Design details
> ====
> 
> An engine is a group of virtio-compatible devices. The definition of engine
> is as follows:
> 
> struct rte_vdpa_eng_addr {
> 	union {
> 		uint8_t __dummy[64];
> 		struct rte_pci_addr pci_addr;
> 	};
> };
> 
> struct rte_vdpa_eng_info {
> 	char name[MAX_VDPA_NAME_LEN];
> 	struct rte_vdpa_eng_addr *addr;
> };
> 
> struct rte_vdpa_dev_ops {
> 	vdpa_dev_conf_t        dev_conf;
> 	vdpa_dev_close_t       dev_close;
> 	vdpa_vring_state_set_t vring_state_set;
> 	vdpa_feature_set_t     feature_set;
> 	vdpa_migration_done_t  migration_done;
> 	vdpa_get_vfio_group_fd_t  get_vfio_group_fd;
> 	vdpa_get_vfio_device_fd_t get_vfio_device_fd;
> 	vdpa_get_notify_area_t    get_notify_area;
> };
> 
> struct rte_vdpa_eng_ops {
> 	vdpa_eng_init_t   eng_init;
> 	vdpa_eng_uninit_t eng_uninit;
> 	vdpa_info_query_t info_query;
> };
> 
> struct rte_vdpa_eng_driver {
> 	const char *name;
> 	struct rte_vdpa_eng_ops eng_ops;
> 	struct rte_vdpa_dev_ops dev_ops;
> } __rte_cache_aligned;
> 
> struct rte_vdpa_engine {
> 	struct rte_vdpa_eng_info    eng_info;
> 	struct rte_vdpa_eng_driver *eng_drv;
> } __rte_cache_aligned;
> 
> A set of engine ops is defined in rte_vdpa_eng_ops for engine init, uninit,
> and attributes reporting. The attributes are defined as follows:
> 
> struct rte_vdpa_eng_attr {
> 	uint64_t features;
> 	uint64_t protocol_features;
> 	uint32_t queue_num;
> 	uint32_t dev_num;
> };
> 
> A set of device ops is defined in rte_vdpa_dev_ops for each virtio device
> in the engine to do device specific operations.
> 
> Changes to the current vhost-user lib are:
> ====
> 
>  1. Make vhost device capabilities configurable to adopt various engines.
>     Such capabilities include supported features, protocol features, queue
>     number. APIs are introduced to let app configure these capabilities.
> 
>  2. In addition to the existing vhost framework, a set of callbacks is
>     added for vhost to call the driver for device operations at the right
>     time:
> 
>      a. dev_conf: Called to configure the actual device when the virtio
>         device becomes ready.
> 
>      b. dev_close: Called to close the actual device when the virtio device
>         is stopped.
> 
>      c. vring_state_set: Called to change the state of the vring in the
>         actual device when vring state changes.
> 
>      d. feature_set: Called to set the negotiated features to device.
> 
>      e. migration_done: Called to allow the device to response to RARP
>         sending.
> 
>      f. get_vfio_group_fd: Called to get the VFIO group fd of the device.
> 
>      g. get_vfio_device_fd: Called to get the VFIO device fd of the device.
> 
>      h. get_notify_area: Called to get the notify area info of the queue.
> 
>  3. To make vhost aware of its own type, an engine id (eid) and a device
>     id (did) are added into the vhost data structure to identify the actual
>     device. APIs are introduced to let app configure them. When the default
>     software datapath is used, eid and did are set to -1. When alternative
>     datapath is used, eid and did are set by app to specify which device to
>     use. Each vhost-user socket can have only 1 connection in this case.

Why only one connection is possible? We are already working on multiple
simultaneous connections in SPDK. So this will be some kind of step backward.

> 
> Working process:
> ====
> 
>  1. Register driver during DPDK initialization.
> 
>  2. Register engine with driver name and address.
> 
>  3. Get engine attributes.
> 
>  4. For vhost device creation:
> 
>       a. Register vhost-user socket.
> 
>       b. Set eid and did of the vhost-user socket.
> 
>       c. Register vhost-user callbacks.
> 
>       d. Start to wait for connection.
> 
>  4. When connection comes and virtio device data structure is negotiated,
>     the device will be configured with all needed info.
> 

Can you please provide new or modify existing example to show how to use this new API?
It would be easier to find any possible gaps if we can see real use case.

Pawel

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v3 0/5] vhost: support selective datapath
  2018-03-29 12:15   ` [PATCH v3 0/5] vhost: support selective datapath Wodkowski, PawelX
@ 2018-03-30  9:35     ` Wang, Zhihong
  0 siblings, 0 replies; 67+ messages in thread
From: Wang, Zhihong @ 2018-03-30  9:35 UTC (permalink / raw)
  To: Wodkowski, PawelX, dev
  Cc: Tan, Jianfeng, Bie, Tiwei, maxime.coquelin, yliu, Liang, Cunming,
	Wang, Xiao W, Daly, Dan

Pawel,

> >  3. To make vhost aware of its own type, an engine id (eid) and a device
> >     id (did) are added into the vhost data structure to identify the actual
> >     device. APIs are introduced to let app configure them. When the default
> >     software datapath is used, eid and did are set to -1. When alternative
> >     datapath is used, eid and did are set by app to specify which device to
> >     use. Each vhost-user socket can have only 1 connection in this case.
> 
> Why only one connection is possible? We are already working on multiple
> simultaneous connections in SPDK. So this will be some kind of step
> backward.

Nothing is changed for existing use cases. This design is only true when
alternative vDPA backend (most likely HW) is used, because in this case
resource locking per vhost port is required for provisioning consideration.

> 
> >
> > Working process:
> > ====
> >
> >  1. Register driver during DPDK initialization.
> >
> >  2. Register engine with driver name and address.
> >
> >  3. Get engine attributes.
> >
> >  4. For vhost device creation:
> >
> >       a. Register vhost-user socket.
> >
> >       b. Set eid and did of the vhost-user socket.
> >
> >       c. Register vhost-user callbacks.
> >
> >       d. Start to wait for connection.
> >
> >  4. When connection comes and virtio device data structure is negotiated,
> >     the device will be configured with all needed info.
> >
> 
> Can you please provide new or modify existing example to show how to use
> this new API?
> It would be easier to find any possible gaps if we can see real use case.

This patch has only the lib change, a driver is also in progress at:
http://dpdk.org/ml/archives/dev/2018-March/093305.html

You can learn how it works from an old RFC patch at:
http://dpdk.org/ml/archives/dev/2017-December/085044.html
A lot of details are changed, but the idea is the same.

-Zhihong

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v4 1/5] vhost: export vhost feature definitions
  2018-03-10 10:01   ` [PATCH v4 1/5] vhost: export vhost feature definitions Zhihong Wang
@ 2018-03-31  5:56     ` Maxime Coquelin
  0 siblings, 0 replies; 67+ messages in thread
From: Maxime Coquelin @ 2018-03-31  5:56 UTC (permalink / raw)
  To: Zhihong Wang, dev
  Cc: jianfeng.tan, tiwei.bie, yliu, cunming.liang, xiao.w.wang, dan.daly



On 03/10/2018 11:01 AM, Zhihong Wang wrote:
> This patch exports vhost-user protocol features to support device driver
> development.
> 
> Signed-off-by: Zhihong Wang <zhihong.wang@intel.com>
> ---
> Changes in v3:
> 
>   1. Keep macro names the same as in the spec.
> 
>   lib/librte_vhost/rte_vhost.h  | 30 ++++++++++++++++++++++++++++++
>   lib/librte_vhost/vhost.h      |  2 --
>   lib/librte_vhost/vhost_user.h |  7 -------
>   3 files changed, 30 insertions(+), 9 deletions(-)
> 

Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>

Thanks,
Maxime

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v4 2/5] vhost: support selective datapath
  2018-03-10 10:01   ` [PATCH v4 2/5] vhost: support selective datapath Zhihong Wang
@ 2018-03-31  6:10     ` Maxime Coquelin
  2018-04-02  1:58       ` Wang, Zhihong
  2018-03-31  7:38     ` Maxime Coquelin
  1 sibling, 1 reply; 67+ messages in thread
From: Maxime Coquelin @ 2018-03-31  6:10 UTC (permalink / raw)
  To: Zhihong Wang, dev
  Cc: jianfeng.tan, tiwei.bie, yliu, cunming.liang, xiao.w.wang, dan.daly



On 03/10/2018 11:01 AM, Zhihong Wang wrote:
> This patch set introduces support for selective datapath in DPDK vhost-user
> lib. vDPA stands for vhost Data Path Acceleration. The idea is to support
> virtio ring compatible devices to serve virtio driver directly to enable
> datapath acceleration.
> 
> A set of device ops is defined for device specific operations:
> 
>       a. queue_num_get: Called to get supported queue number of the device.
> 
>       b. feature_get: Called to get supported features of the device.
> 
>       c. protocol_feature_get: Called to get supported protocol features of
>          the device.
> 
>       d. dev_conf: Called to configure the actual device when the virtio
>          device becomes ready.
> 
>       e. dev_close: Called to close the actual device when the virtio device
>          is stopped.
> 
>       f. vring_state_set: Called to change the state of the vring in the
>          actual device when vring state changes.
> 
>       g. feature_set: Called to set the negotiated features to device.
> 
>       h. migration_done: Called to allow the device to response to RARP
>          sending.
> 
>       i. get_vfio_group_fd: Called to get the VFIO group fd of the device.
> 
>       j. get_vfio_device_fd: Called to get the VFIO device fd of the device.
> 
>       k. get_notify_area: Called to get the notify area info of the queue.
> 
> Signed-off-by: Zhihong Wang <zhihong.wang@intel.com>
> ---
> Changes in v4:
> 
>   1. Remove the "engine" concept in the lib.
> 
> ---
> Changes in v2:
> 
>   1. Add VFIO related vDPA device ops.
> 
>   lib/librte_vhost/Makefile              |  4 +-
>   lib/librte_vhost/rte_vdpa.h            | 94 +++++++++++++++++++++++++++++++++
>   lib/librte_vhost/rte_vhost_version.map |  6 +++
>   lib/librte_vhost/vdpa.c                | 96 ++++++++++++++++++++++++++++++++++
>   4 files changed, 198 insertions(+), 2 deletions(-)
>   create mode 100644 lib/librte_vhost/rte_vdpa.h
>   create mode 100644 lib/librte_vhost/vdpa.c
> 
> diff --git a/lib/librte_vhost/Makefile b/lib/librte_vhost/Makefile
> index 5d6c6abae..37044ac03 100644
> --- a/lib/librte_vhost/Makefile
> +++ b/lib/librte_vhost/Makefile
> @@ -22,9 +22,9 @@ LDLIBS += -lrte_eal -lrte_mempool -lrte_mbuf -lrte_ethdev -lrte_net
>   
>   # all source are stored in SRCS-y
>   SRCS-$(CONFIG_RTE_LIBRTE_VHOST) := fd_man.c iotlb.c socket.c vhost.c \
> -					vhost_user.c virtio_net.c
> +					vhost_user.c virtio_net.c vdpa.c
>   
>   # install includes
> -SYMLINK-$(CONFIG_RTE_LIBRTE_VHOST)-include += rte_vhost.h
> +SYMLINK-$(CONFIG_RTE_LIBRTE_VHOST)-include += rte_vhost.h rte_vdpa.h
>   
>   include $(RTE_SDK)/mk/rte.lib.mk
> diff --git a/lib/librte_vhost/rte_vdpa.h b/lib/librte_vhost/rte_vdpa.h
> new file mode 100644
> index 000000000..a4bbbd93d
> --- /dev/null
> +++ b/lib/librte_vhost/rte_vdpa.h
> @@ -0,0 +1,94 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright(c) 2018 Intel Corporation
> + */
> +
> +#ifndef _RTE_VDPA_H_
> +#define _RTE_VDPA_H_
> +
> +/**
> + * @file
> + *
> + * Device specific vhost lib
> + */
> +
> +#include <rte_pci.h>
> +#include "rte_vhost.h"
> +
> +#define MAX_VDPA_NAME_LEN 128
> +
> +enum vdpa_addr_type {
> +	PCI_ADDR,
> +	VDPA_ADDR_MAX
> +};
> +
> +struct rte_vdpa_dev_addr {
> +	enum vdpa_addr_type type;
> +	union {
> +		uint8_t __dummy[64];
> +		struct rte_pci_addr pci_addr;
> +	};
> +};
> +
> +/* Get capabilities of this device */
> +typedef int (*vdpa_dev_queue_num_get_t)(int did, uint32_t *queue_num);
> +typedef int (*vdpa_dev_feature_get_t)(int did, uint64_t *features);
> +
> +/* Driver configure/close the device */
> +typedef int (*vdpa_dev_conf_t)(int vid);
> +typedef int (*vdpa_dev_close_t)(int vid);
> +
> +/* Enable/disable this vring */
> +typedef int (*vdpa_vring_state_set_t)(int vid, int vring, int state);
> +
> +/* Set features when changed */
> +typedef int (*vdpa_feature_set_t)(int vid);
> +
> +/* Destination operations when migration done */
> +typedef int (*vdpa_migration_done_t)(int vid);
> +
> +/* Get the vfio group fd */
> +typedef int (*vdpa_get_vfio_group_fd_t)(int vid);
> +
> +/* Get the vfio device fd */
> +typedef int (*vdpa_get_vfio_device_fd_t)(int vid);
> +
> +/* Get the notify area info of the queue */
> +typedef int (*vdpa_get_notify_area_t)(int vid, int qid, uint64_t *offset,
> +		uint64_t *size);
> +/* Device ops */
> +struct rte_vdpa_dev_ops {
> +	vdpa_dev_queue_num_get_t  queue_num_get;
> +	vdpa_dev_feature_get_t    feature_get;
> +	vdpa_dev_feature_get_t    protocol_feature_get;
> +	vdpa_dev_conf_t           dev_conf;
> +	vdpa_dev_close_t          dev_close;
> +	vdpa_vring_state_set_t    vring_state_set;
> +	vdpa_feature_set_t        feature_set;
> +	vdpa_migration_done_t     migration_done;
> +	vdpa_get_vfio_group_fd_t  get_vfio_group_fd;
> +	vdpa_get_vfio_device_fd_t get_vfio_device_fd;
> +	vdpa_get_notify_area_t    get_notify_area;

Maybe you could reserve some room here to avoid breaking the ABI in the
future if we need to add some optional ops.

> +};
> +
> +struct rte_vdpa_device {
> +	struct rte_vdpa_dev_addr addr;
> +	struct rte_vdpa_dev_ops *ops;
> +} __rte_cache_aligned;
> +
> +extern struct rte_vdpa_device *vdpa_devices[];
> +extern uint32_t vdpa_device_num;
> +
> +/* Register a vdpa device, return did if successful, -1 on failure */
> +int __rte_experimental
> +rte_vdpa_register_device(struct rte_vdpa_dev_addr *addr,
> +		struct rte_vdpa_dev_ops *ops);
> +
> +/* Unregister a vdpa device, return -1 on failure */
> +int __rte_experimental
> +rte_vdpa_unregister_device(int did);
> +
> +/* Find did of a vdpa device, return -1 on failure */
> +int __rte_experimental
> +rte_vdpa_find_device_id(struct rte_vdpa_dev_addr *addr);
> +
> +#endif /* _RTE_VDPA_H_ */
> diff --git a/lib/librte_vhost/rte_vhost_version.map b/lib/librte_vhost/rte_vhost_version.map
> index df0103129..7bcffb490 100644
> --- a/lib/librte_vhost/rte_vhost_version.map
> +++ b/lib/librte_vhost/rte_vhost_version.map
> @@ -59,3 +59,9 @@ DPDK_18.02 {
>   	rte_vhost_vring_call;
>   
>   } DPDK_17.08;
> +
> +EXPERIMENTAL {
> +	rte_vdpa_register_device;
> +	rte_vdpa_unregister_device;
> +	rte_vdpa_find_device_id;

I think you need also to declare the new structs here,
not only the new functions.

> +} DPDK_18.02;
> diff --git a/lib/librte_vhost/vdpa.c b/lib/librte_vhost/vdpa.c
> new file mode 100644
> index 000000000..0c950d45f
> --- /dev/null
> +++ b/lib/librte_vhost/vdpa.c
> @@ -0,0 +1,96 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright(c) 2018 Intel Corporation
> + */
> +
> +/**
> + * @file
> + *
> + * Device specific vhost lib
> + */
> +
> +#include <stdbool.h>
> +
> +#include <rte_malloc.h>
> +#include "rte_vdpa.h"
> +#include "vhost.h"
> +
> +struct rte_vdpa_device *vdpa_devices[MAX_VHOST_DEVICE];
> +uint32_t vdpa_device_num;
> +
> +static int is_same_vdpa_dev_addr(struct rte_vdpa_dev_addr *a,
> +		struct rte_vdpa_dev_addr *b)
> +{

Given the boolean nature of the function name, I would return 1 if same
device, 0 if different.

> +	int ret = 0;
> +
> +	if (a->type != b->type)
> +		return -1;
> +
> +	switch (a->type) {
> +	case PCI_ADDR:
> +		if (a->pci_addr.domain != b->pci_addr.domain ||
> +				a->pci_addr.bus != b->pci_addr.bus ||
> +				a->pci_addr.devid != b->pci_addr.devid ||
> +				a->pci_addr.function != b->pci_addr.function)
> +			ret = -1;
> +		break;
> +	default:
> +		break;
> +	}
> +
> +	return ret;
> +}
> +
> +int rte_vdpa_register_device(struct rte_vdpa_dev_addr *addr,
> +		struct rte_vdpa_dev_ops *ops)
> +{
> +	struct rte_vdpa_device *dev;
> +	char device_name[MAX_VDPA_NAME_LEN];
> +	int i;
> +
> +	if (vdpa_device_num >= MAX_VHOST_DEVICE)
> +		return -1;
> +
> +	for (i = 0; i < MAX_VHOST_DEVICE; i++) {
> +		if (vdpa_devices[i] == NULL)
> +			break;
You might want to check same device isn't being registering a second
time, and return an error in that case.

This is not a blocker though, and can be done in a dedicated patch.

> +	}
> +
> +	sprintf(device_name, "vdpa-dev-%d", i);
> +	dev = rte_zmalloc(device_name, sizeof(struct rte_vdpa_device),
> +			RTE_CACHE_LINE_SIZE);
> +	if (!dev)
> +		return -1;
> +
> +	memcpy(&dev->addr, addr, sizeof(struct rte_vdpa_dev_addr));
> +	dev->ops = ops;
> +	vdpa_devices[i] = dev;
> +	vdpa_device_num++;
> +
> +	return i;
> +}
> +
> +int rte_vdpa_unregister_device(int did)
> +{
> +	if (did < 0 || did >= MAX_VHOST_DEVICE || vdpa_devices[did] == NULL)
> +		return -1;
> +
> +	rte_free(vdpa_devices[did]);
> +	vdpa_devices[did] = NULL;
> +	vdpa_device_num--;
> +
> +	return did;
> +}
> +
> +int rte_vdpa_find_device_id(struct rte_vdpa_dev_addr *addr)
> +{
> +	struct rte_vdpa_device *dev;
> +	int i;
> +
> +	for (i = 0; i < MAX_VHOST_DEVICE; ++i) {
> +		dev = vdpa_devices[i];
> +		if (dev && is_same_vdpa_dev_addr(&dev->addr, addr) == 0)
> +			return i;
> +	}
> +
> +	return -1;
> +}
> 

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v4 3/5] vhost: add apis for datapath configuration
  2018-03-10 10:01   ` [PATCH v4 3/5] vhost: add apis for datapath configuration Zhihong Wang
@ 2018-03-31  7:04     ` Maxime Coquelin
  2018-04-02  2:01       ` Wang, Zhihong
  0 siblings, 1 reply; 67+ messages in thread
From: Maxime Coquelin @ 2018-03-31  7:04 UTC (permalink / raw)
  To: Zhihong Wang, dev
  Cc: jianfeng.tan, tiwei.bie, yliu, cunming.liang, xiao.w.wang, dan.daly



On 03/10/2018 11:01 AM, Zhihong Wang wrote:
> This patch adds APIs for datapath configuration.
> 
> The did of the vhost-user socket can be set to identify the backend device,
> in this case each vhost-user socket can have only 1 connection. The did is
> set to -1 by default when the software datapath is used.
> 
> Signed-off-by: Zhihong Wang <zhihong.wang@intel.com>
> ---
> Changes in v4:
> 
>   1. Remove the "engine" concept in the lib.
> 
>   lib/librte_vhost/rte_vhost.h           | 35 +++++++++++++++++++++++++++++++++
>   lib/librte_vhost/rte_vhost_version.map |  3 +++
>   lib/librte_vhost/socket.c              | 36 ++++++++++++++++++++++++++++++++++
>   lib/librte_vhost/vhost.c               | 25 +++++++++++++++++++++++
>   lib/librte_vhost/vhost.h               |  9 +++++++++
>   5 files changed, 108 insertions(+)
> 
> diff --git a/lib/librte_vhost/rte_vhost.h b/lib/librte_vhost/rte_vhost.h
> index 671ea5053..d50f4c67d 100644
> --- a/lib/librte_vhost/rte_vhost.h
> +++ b/lib/librte_vhost/rte_vhost.h
> @@ -200,6 +200,30 @@ int rte_vhost_driver_register(const char *path, uint64_t flags);
>   int rte_vhost_driver_unregister(const char *path);
>   
>   /**
> + * Set the device id, enforce single connection per socket
> + *
> + * @param path
> + *  The vhost-user socket file path
> + * @param did
> + *  Device id
> + * @return
> + *  0 on success, -1 on failure
> + */
> +int __rte_experimental
> +rte_vhost_driver_set_vdpa_did(const char *path, int did);

IIUC, we call this to attach a VDPA device to a Vhost-user port?

What about having this named explicitly? Something like:

rte_vhost_driver_attach_vdpa_did(const char *path, int did)
rte_vhost_driver_detach_vdpa_did(const char *path)

The later would set to did -1

This is not mandatory though

> +
> +/**
> + * Get the device id
> + *
> + * @param path
> + *  The vhost-user socket file path
> + * @return
> + *  Device id, -1 on failure
> + */
> +int __rte_experimental
> +rte_vhost_driver_get_vdpa_did(const char *path);
> +
> +/**
>    * Set the feature bits the vhost-user driver supports.
>    *
>    * @param path
> @@ -464,6 +488,17 @@ int rte_vhost_vring_call(int vid, uint16_t vring_idx);
>    */
>   uint32_t rte_vhost_rx_queue_count(int vid, uint16_t qid);
>   
> +/**
> + * Get vdpa device id for vhost device.
> + *
> + * @param vid
> + *  vhost device ID
> + * @return
> + *  device id
> + */
> +int __rte_experimental
> +rte_vhost_get_vdpa_did(int vid);
> +
>   #ifdef __cplusplus
>   }
>   #endif
> diff --git a/lib/librte_vhost/rte_vhost_version.map b/lib/librte_vhost/rte_vhost_version.map
> index 7bcffb490..6e2d5364a 100644
> --- a/lib/librte_vhost/rte_vhost_version.map
> +++ b/lib/librte_vhost/rte_vhost_version.map
> @@ -64,4 +64,7 @@ EXPERIMENTAL {
>   	rte_vdpa_register_device;
>   	rte_vdpa_unregister_device;
>   	rte_vdpa_find_device_id;
> +	rte_vhost_driver_set_vdpa_did;
> +	rte_vhost_driver_get_vdpa_did;
> +	rte_vhost_get_vdpa_did;
>   } DPDK_18.02;
> diff --git a/lib/librte_vhost/socket.c b/lib/librte_vhost/socket.c
> index cfc31e179..3d58da94e 100644
> --- a/lib/librte_vhost/socket.c
> +++ b/lib/librte_vhost/socket.c
> @@ -52,6 +52,13 @@ struct vhost_user_socket {
>   	uint64_t supported_features;
>   	uint64_t features;
>   
> +	/*
> +	 * Device id to identify a specific backend device.
> +	 * It's set to -1 for the default software implementation.
> +	 * If valid, one socket can have 1 connection only.
> +	 */
> +	int did;
I would rename it to something like vdpa_did or even better,
vdpa_dev_id. At least prefix it with vdpa not to confuse the user.

> +
>   	struct vhost_device_ops const *notify_ops;
>   };
>   
> @@ -545,6 +552,35 @@ find_vhost_user_socket(const char *path)
>   }
>   
>   int
> +rte_vhost_driver_set_vdpa_did(const char *path, int did)
> +{
> +	struct vhost_user_socket *vsocket;
> +
> +	pthread_mutex_lock(&vhost_user.mutex);
> +	vsocket = find_vhost_user_socket(path);
> +	if (vsocket)
> +		vsocket->did = did;

I guess it is possible to know whether the did exists
at that time. Maybe we could check this?

> +	pthread_mutex_unlock(&vhost_user.mutex);
> +
> +	return vsocket ? 0 : -1;
> +}
> +
> +int
> +rte_vhost_driver_get_vdpa_did(const char *path)
> +{
> +	struct vhost_user_socket *vsocket;
> +	int did = -1;
> +
> +	pthread_mutex_lock(&vhost_user.mutex);
> +	vsocket = find_vhost_user_socket(path);
> +	if (vsocket)
> +		did = vsocket->did;
> +	pthread_mutex_unlock(&vhost_user.mutex);
> +
> +	return did;
> +}
> +
> +int
>   rte_vhost_driver_disable_features(const char *path, uint64_t features)
>   {
>   	struct vhost_user_socket *vsocket;
> diff --git a/lib/librte_vhost/vhost.c b/lib/librte_vhost/vhost.c
> index f6f12a03b..1740cc1ab 100644
> --- a/lib/librte_vhost/vhost.c
> +++ b/lib/librte_vhost/vhost.c
> @@ -283,6 +283,7 @@ vhost_new_device(void)
>   	dev->vid = i;
>   	dev->flags = VIRTIO_DEV_BUILTIN_VIRTIO_NET;
>   	dev->slave_req_fd = -1;
> +	dev->did = -1;
>   
>   	return i;
>   }
> @@ -311,6 +312,20 @@ vhost_destroy_device(int vid)
>   }
>   
>   void
> +vhost_set_vdpa_did(int vid, int did)
> +{
> +	struct virtio_net *dev = get_device(vid);
> +
> +	if (did < 0)
> +		return;
> +
> +	if (dev == NULL)
> +		return;
> +
> +	dev->did = did;
> +}
> +
> +void
>   vhost_set_ifname(int vid, const char *if_name, unsigned int if_len)
>   {
>   	struct virtio_net *dev;
> @@ -614,3 +629,13 @@ rte_vhost_rx_queue_count(int vid, uint16_t qid)
>   
>   	return *((volatile uint16_t *)&vq->avail->idx) - vq->last_avail_idx;
>   }
> +
> +int rte_vhost_get_vdpa_did(int vid)
> +{
> +	struct virtio_net *dev = get_device(vid);
> +
> +	if (dev == NULL)
> +		return -1;
> +
> +	return dev->did;
> +}
> diff --git a/lib/librte_vhost/vhost.h b/lib/librte_vhost/vhost.h
> index 2e28e4026..2970c1eab 100644
> --- a/lib/librte_vhost/vhost.h
> +++ b/lib/librte_vhost/vhost.h
> @@ -19,6 +19,7 @@
>   #include <rte_rwlock.h>
>   
>   #include "rte_vhost.h"
> +#include "rte_vdpa.h"
>   
>   /* Used to indicate that the device is running on a data core */
>   #define VIRTIO_DEV_RUNNING 1
> @@ -239,6 +240,12 @@ struct virtio_net {
>   	struct guest_page       *guest_pages;
>   
>   	int			slave_req_fd;
> +
> +	/*
> +	 * Device id to identify a specific backend device.
> +	 * It's set to -1 for the default software implementation.
> +	 */
> +	int			did;

Same as for struct vhost_user_socket, it would be less confusing to
prefix it with vdpa.

>   } __rte_cache_aligned;
>   
>   
> @@ -365,6 +372,8 @@ void free_vq(struct vhost_virtqueue *vq);
>   
>   int alloc_vring_queue(struct virtio_net *dev, uint32_t vring_idx);
>   
> +void vhost_set_vdpa_did(int vid, int did);
> +
>   void vhost_set_ifname(int, const char *if_name, unsigned int if_len);
>   void vhost_enable_dequeue_zero_copy(int vid);
>   void vhost_set_builtin_virtio_net(int vid, bool enable);
> 

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v4 4/5] vhost: adapt vhost lib for selective datapath
  2018-03-10 10:01   ` [PATCH v4 4/5] vhost: adapt vhost lib for selective datapath Zhihong Wang
@ 2018-03-31  7:35     ` Maxime Coquelin
  2018-04-02 11:52       ` Wang, Zhihong
  0 siblings, 1 reply; 67+ messages in thread
From: Maxime Coquelin @ 2018-03-31  7:35 UTC (permalink / raw)
  To: Zhihong Wang, dev
  Cc: jianfeng.tan, tiwei.bie, yliu, cunming.liang, xiao.w.wang, dan.daly



On 03/10/2018 11:01 AM, Zhihong Wang wrote:
> This patch adapts vhost lib for selective datapath by calling device ops
> at the corresponding stage.
> 
> Signed-off-by: Zhihong Wang <zhihong.wang@intel.com>
> ---
> Changes in v4:
> 
>   1. Remove the "engine" concept in the lib.
> 
> ---
> Changes in v2:
> 
>   1. Ensure negotiated capabilities are supported in vhost-user lib.
> 
>   2. Configure the data path at the right time.
> 
>   lib/librte_vhost/rte_vhost.h           | 27 ++++++++++
>   lib/librte_vhost/rte_vhost_version.map |  2 +
>   lib/librte_vhost/socket.c              | 94 ++++++++++++++++++++++++++++++++--
>   lib/librte_vhost/vhost.c               |  3 ++
>   lib/librte_vhost/vhost.h               |  2 +
>   lib/librte_vhost/vhost_user.c          | 54 +++++++++++++++++--
>   6 files changed, 172 insertions(+), 10 deletions(-)
> 
> diff --git a/lib/librte_vhost/rte_vhost.h b/lib/librte_vhost/rte_vhost.h
> index d50f4c67d..3c3334d3e 100644
> --- a/lib/librte_vhost/rte_vhost.h
> +++ b/lib/librte_vhost/rte_vhost.h
> @@ -279,6 +279,33 @@ int rte_vhost_driver_disable_features(const char *path, uint64_t features);
>   int rte_vhost_driver_get_features(const char *path, uint64_t *features);
>   
>   /**
> + * Get the protocol feature bits before feature negotiation.
> + *
> + * @param path
> + *  The vhost-user socket file path
> + * @param protocol_features
> + *  A pointer to store the queried protocol feature bits
> + * @return
> + *  0 on success, -1 on failure
> + */
> +int __rte_experimental
> +rte_vhost_driver_get_protocol_features(const char *path,
> +		uint64_t *protocol_features);
> +
> +/**
> + * Get the queue number bits before feature negotiation.
> + *
> + * @param path
> + *  The vhost-user socket file path
> + * @param queue_num
> + *  A pointer to store the queried queue number bits
> + * @return
> + *  0 on success, -1 on failure
> + */
> +int __rte_experimental
> +rte_vhost_driver_get_queue_num(const char *path, uint32_t *queue_num);
> +
> +/**
>    * Get the feature bits after negotiation
>    *
>    * @param vid
> diff --git a/lib/librte_vhost/rte_vhost_version.map b/lib/librte_vhost/rte_vhost_version.map
> index 6e2d5364a..812ccd72b 100644
> --- a/lib/librte_vhost/rte_vhost_version.map
> +++ b/lib/librte_vhost/rte_vhost_version.map
> @@ -67,4 +67,6 @@ EXPERIMENTAL {
>   	rte_vhost_driver_set_vdpa_did;
>   	rte_vhost_driver_get_vdpa_did;
>   	rte_vhost_get_vdpa_did;
> +	rte_vhost_driver_get_protocol_features;
> +	rte_vhost_driver_get_queue_num;
>   } DPDK_18.02;
> diff --git a/lib/librte_vhost/socket.c b/lib/librte_vhost/socket.c
> index 3d58da94e..ba7b422a0 100644
> --- a/lib/librte_vhost/socket.c
> +++ b/lib/librte_vhost/socket.c
> @@ -216,6 +216,8 @@ vhost_user_add_connection(int fd, struct vhost_user_socket *vsocket)
>   
>   	vhost_set_builtin_virtio_net(vid, vsocket->use_builtin_virtio_net);
>   
> +	vhost_set_vdpa_did(vid, vsocket->did);
> +
>   	if (vsocket->dequeue_zero_copy)
>   		vhost_enable_dequeue_zero_copy(vid);
>   
> @@ -648,20 +650,102 @@ int
>   rte_vhost_driver_get_features(const char *path, uint64_t *features)
>   {
>   	struct vhost_user_socket *vsocket;
> +	uint64_t vdpa_features;
> +	int did = -1;
> +	int ret = 0;
>   
>   	pthread_mutex_lock(&vhost_user.mutex);
>   	vsocket = find_vhost_user_socket(path);
> -	if (vsocket)
> -		*features = vsocket->features;
> +	if (vsocket) {
> +		did = vsocket->did;
> +		if (did < 0 || vdpa_devices[did]->ops->feature_get == NULL)
> +			*features = vsocket->features;
> +		else if (vdpa_devices[did]->ops->feature_get(did,
> +					&vdpa_features) < 0) {
> +			RTE_LOG(ERR, VHOST_CONFIG,
> +					"failed to get vdpa features "
> +					"for socket file %s.\n", path);
> +			ret = -1;
> +		} else
> +			*features = vsocket->features & vdpa_features;

It seems correct but it is not very intuitive.
Also, you have to put braces everywhere if one of the if/else if/else
have some.

What about something like this:

rte_vhost_driver_get_features(const char *path, uint64_t *features)
{
	struct vhost_user_socket *vsocket;
	uint64_t vdpa_features;
	int did = -1;
	int ret = 0;
	struct rte_vdpa_device *vdpa_dev;

	pthread_mutex_lock(&vhost_user.mutex);
	vsocket = find_vhost_user_socket(path);
	if (!vsocket) {
		RTE_LOG(ERR, VHOST_CONFIG,
			"socket file %s is not registered yet.\n"
			, path);
		ret = -1;
		goto out_unlock;
	}

	did = vsocket->did;
	vdpa_dev = rte_vdpa_device_get(did);
	if (!vdpa_dev || !vdpa->ops->feature_get) {
		*features = vsocket->features;
		goto out_unlock;
	}

	if (vdpa_dev->ops->feature_get(did, &vdpa_features) < 0) {
		RTE_LOG(ERR, VHOST_CONFIG,
				"failed to get vdpa features "
				"for socket file %s.\n", path);
		ret = -1;
		goto out_unlock;
	}

	*features = vsocket->features & vdpa_features;

out_unlock:
	pthread_mutex_unlock(&vhost_user.mutex);
	return ret;
}

with in rte_vdpa.h:

static inline struct rte_vdpa_device *
rte_vdpa_device_get(int did)
{
	if (did < 0 || did >= MAX_VHOST_DEVICE)
		return NULL;

	return vdpa_devices[did];
}


Doing this you have 3 checks in 1, so you avoid NULL pointer
de-referencing if did > 0 but invalid.

Same logic applies to functions below:

> +	} else {
> +		RTE_LOG(ERR, VHOST_CONFIG,
> +			"socket file %s is not registered yet.\n", path);
> +		ret = -1;
> +	}
>   	pthread_mutex_unlock(&vhost_user.mutex);
>   
> -	if (!vsocket) {
> +	return ret;
> +}
> +
> +int
> +rte_vhost_driver_get_protocol_features(const char *path,
> +		uint64_t *protocol_features)
> +{
> +	struct vhost_user_socket *vsocket;
> +	uint64_t vdpa_protocol_features;
> +	int did = -1;
> +	int ret = 0;
> +
> +	pthread_mutex_lock(&vhost_user.mutex);
> +	vsocket = find_vhost_user_socket(path);
> +	if (vsocket) {
> +		did = vsocket->did;
> +		if (did < 0 || vdpa_devices[did]->ops->protocol_feature_get
> +				== NULL)
> +			*protocol_features = VHOST_USER_PROTOCOL_FEATURES;
> +		else if (vdpa_devices[did]->ops->protocol_feature_get(did,
> +					&vdpa_protocol_features) < 0) {
> +			RTE_LOG(ERR, VHOST_CONFIG,
> +					"failed to get vdpa protocol features "
> +					"for socket file %s.\n", path);
> +			ret = -1;
> +		} else
> +			*protocol_features = VHOST_USER_PROTOCOL_FEATURES
> +				& vdpa_protocol_features;
> +	} else {
>   		RTE_LOG(ERR, VHOST_CONFIG,
>   			"socket file %s is not registered yet.\n", path);
> -		return -1;
> +		ret = -1;
> +	}
> +	pthread_mutex_unlock(&vhost_user.mutex);
> +
> +	return ret;
> +}
> +
> +int
> +rte_vhost_driver_get_queue_num(const char *path,
> +		uint32_t *queue_num)
> +{
> +	struct vhost_user_socket *vsocket;
> +	uint32_t vdpa_queue_num;
> +	int did = -1;
> +	int ret = 0;
> +
> +	pthread_mutex_lock(&vhost_user.mutex);
> +	vsocket = find_vhost_user_socket(path);
> +	if (vsocket) {
> +		did = vsocket->did;
> +		if (did < 0 || vdpa_devices[did]->ops->queue_num_get == NULL)
> +			*queue_num = VHOST_MAX_QUEUE_PAIRS;
> +		else if (vdpa_devices[did]->ops->queue_num_get(
> +					did, &vdpa_queue_num) < 0) {
> +			RTE_LOG(ERR, VHOST_CONFIG,
> +					"failed to get vdpa queue number "
> +					"for socket file %s.\n", path);
> +			ret = -1;
> +		} else if (vdpa_queue_num > VHOST_MAX_QUEUE_PAIRS)
> +			*queue_num = VHOST_MAX_QUEUE_PAIRS;
> +		else
> +			*queue_num = vdpa_queue_num;
>   	} else {
> -		return 0;
> +		RTE_LOG(ERR, VHOST_CONFIG,
> +			"socket file %s is not registered yet.\n", path);
> +		ret = -1;
>   	}
> +	pthread_mutex_unlock(&vhost_user.mutex);
> +
> +	return ret;
>   }
>   
>   /*
> diff --git a/lib/librte_vhost/vhost.c b/lib/librte_vhost/vhost.c
> index 1740cc1ab..66b6b492f 100644
> --- a/lib/librte_vhost/vhost.c
> +++ b/lib/librte_vhost/vhost.c
> @@ -296,11 +296,14 @@ void
>   vhost_destroy_device(int vid)
>   {
>   	struct virtio_net *dev = get_device(vid);
> +	int did = dev->did;
>   
>   	if (dev == NULL)
>   		return;
>   
>   	if (dev->flags & VIRTIO_DEV_RUNNING) {
> +		if (did >= 0 && vdpa_devices[did]->ops->dev_close)
> +			vdpa_devices[did]->ops->dev_close(dev->vid);

Ditto.

>   		dev->flags &= ~VIRTIO_DEV_RUNNING;
>   		dev->notify_ops->destroy_device(vid);
>   	}
> diff --git a/lib/librte_vhost/vhost.h b/lib/librte_vhost/vhost.h
> index 2970c1eab..30e8a0cfe 100644
> --- a/lib/librte_vhost/vhost.h
> +++ b/lib/librte_vhost/vhost.h
> @@ -27,6 +27,8 @@
>   #define VIRTIO_DEV_READY 2
>   /* Used to indicate that the built-in vhost net device backend is enabled */
>   #define VIRTIO_DEV_BUILTIN_VIRTIO_NET 4
> +/* Used to indicate that the device has its own data path and configured */
> +#define VIRTIO_DEV_VDPA_CONFIGURED 8
>   
>   /* Backend value set by guest. */
>   #define VIRTIO_DEV_STOPPED -1
> diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c
> index 5c5361066..5049c8e55 100644
> --- a/lib/librte_vhost/vhost_user.c
> +++ b/lib/librte_vhost/vhost_user.c
> @@ -133,7 +133,11 @@ vhost_user_set_owner(void)
>   static int
>   vhost_user_reset_owner(struct virtio_net *dev)
>   {
> +	int did = dev->did;
> +
>   	if (dev->flags & VIRTIO_DEV_RUNNING) {
> +		if (did >= 0 && vdpa_devices[did]->ops->dev_close)
> +			vdpa_devices[did]->ops->dev_close(dev->vid);

Ditto.

>   		dev->flags &= ~VIRTIO_DEV_RUNNING;
>   		dev->notify_ops->destroy_device(dev->vid);
>   	}
> @@ -156,12 +160,25 @@ vhost_user_get_features(struct virtio_net *dev)
>   }
>   
>   /*
> + * The queue number that we support are requested.
> + */
> +static uint32_t
> +vhost_user_get_queue_num(struct virtio_net *dev)
> +{
> +	uint32_t queue_num = 0;
> +
> +	rte_vhost_driver_get_queue_num(dev->ifname, &queue_num);
> +	return (uint64_t)queue_num;
> +}
> +
> +/*
>    * We receive the negotiated features supported by us and the virtio device.
>    */
>   static int
>   vhost_user_set_features(struct virtio_net *dev, uint64_t features)
>   {
>   	uint64_t vhost_features = 0;
> +	int did = dev->did;
>   
>   	rte_vhost_driver_get_features(dev->ifname, &vhost_features);
>   	if (features & ~vhost_features) {
> @@ -191,6 +208,9 @@ vhost_user_set_features(struct virtio_net *dev, uint64_t features)
>   			dev->notify_ops->features_changed(dev->vid, features);
>   	}
>   
> +	if (did >= 0 && vdpa_devices[did]->ops->feature_set)
> +		vdpa_devices[did]->ops->feature_set(dev->vid);
> +
>   	dev->features = features;
>   	if (dev->features &
>   		((1 << VIRTIO_NET_F_MRG_RXBUF) | (1ULL << VIRTIO_F_VERSION_1))) {
> @@ -933,14 +953,18 @@ vhost_user_get_vring_base(struct virtio_net *dev,
>   			  VhostUserMsg *msg)
>   {
>   	struct vhost_virtqueue *vq = dev->virtqueue[msg->payload.state.index];
> +	int did = dev->did;
>   
>   	/* We have to stop the queue (virtio) if it is running. */
>   	if (dev->flags & VIRTIO_DEV_RUNNING) {
> +		if (did >= 0 && vdpa_devices[did]->ops->dev_close)
> +			vdpa_devices[did]->ops->dev_close(dev->vid);
>   		dev->flags &= ~VIRTIO_DEV_RUNNING;
>   		dev->notify_ops->destroy_device(dev->vid);
>   	}
>   
>   	dev->flags &= ~VIRTIO_DEV_READY;
> +	dev->flags &= ~VIRTIO_DEV_VDPA_CONFIGURED;
>   
>   	/* Here we are safe to get the last avail index */
>   	msg->payload.state.num = vq->last_avail_idx;
> @@ -983,16 +1007,22 @@ vhost_user_set_vring_enable(struct virtio_net *dev,
>   			    VhostUserMsg *msg)
>   {
>   	int enable = (int)msg->payload.state.num;
> +	int index = (int)msg->payload.state.index;
> +	int did = dev->did;
>   
>   	RTE_LOG(INFO, VHOST_CONFIG,
>   		"set queue enable: %d to qp idx: %d\n",
> -		enable, msg->payload.state.index);
> +		enable, index);
> +
> +	if (did >= 0 && vdpa_devices[did]->ops->vring_state_set)
> +		vdpa_devices[did]->ops->vring_state_set(dev->vid,
> +				index, enable);
>   
>   	if (dev->notify_ops->vring_state_changed)
>   		dev->notify_ops->vring_state_changed(dev->vid,
> -				msg->payload.state.index, enable);
> +				index, enable);
>   
> -	dev->virtqueue[msg->payload.state.index]->enabled = enable;
> +	dev->virtqueue[index]->enabled = enable;
>   
>   	return 0;
>   }
> @@ -1001,9 +1031,10 @@ static void
>   vhost_user_get_protocol_features(struct virtio_net *dev,
>   				 struct VhostUserMsg *msg)
>   {
> -	uint64_t features, protocol_features = VHOST_USER_PROTOCOL_FEATURES;
> +	uint64_t features, protocol_features;
>   
>   	rte_vhost_driver_get_features(dev->ifname, &features);
> +	rte_vhost_driver_get_protocol_features(dev->ifname, &protocol_features);
>   
>   	/*
>   	 * REPLY_ACK protocol feature is only mandatory for now
> @@ -1099,6 +1130,7 @@ static int
>   vhost_user_send_rarp(struct virtio_net *dev, struct VhostUserMsg *msg)
>   {
>   	uint8_t *mac = (uint8_t *)&msg->payload.u64;
> +	int did = dev->did;
>   
>   	RTE_LOG(DEBUG, VHOST_CONFIG,
>   		":: mac: %02x:%02x:%02x:%02x:%02x:%02x\n",
> @@ -1114,6 +1146,8 @@ vhost_user_send_rarp(struct virtio_net *dev, struct VhostUserMsg *msg)
>   	 */
>   	rte_smp_wmb();
>   	rte_atomic16_set(&dev->broadcast_rarp, 1);
> +	if (did >= 0 && vdpa_devices[did]->ops->migration_done)
> +		vdpa_devices[did]->ops->migration_done(dev->vid);
>   
>   	return 0;
>   }
> @@ -1375,6 +1409,7 @@ vhost_user_msg_handler(int vid, int fd)
>   {
>   	struct virtio_net *dev;
>   	struct VhostUserMsg msg;
> +	int did;
>   	int ret;
>   	int unlock_required = 0;
>   
> @@ -1527,7 +1562,7 @@ vhost_user_msg_handler(int vid, int fd)
>   		break;
>   
>   	case VHOST_USER_GET_QUEUE_NUM:
> -		msg.payload.u64 = VHOST_MAX_QUEUE_PAIRS;
> +		msg.payload.u64 = (uint64_t)vhost_user_get_queue_num(dev);
>   		msg.size = sizeof(msg.payload.u64);
>   		send_vhost_reply(fd, &msg);
>   		break;
> @@ -1580,6 +1615,15 @@ vhost_user_msg_handler(int vid, int fd)
>   		}
>   	}
>   
> +	did = dev->did;
> +	if (did >= 0 && virtio_is_ready(dev) &&
> +			!(dev->flags & VIRTIO_DEV_VDPA_CONFIGURED) &&
> +			msg.request.master == VHOST_USER_SET_VRING_ENABLE) {
> +		if (vdpa_devices[did]->ops->dev_conf)
> +			vdpa_devices[did]->ops->dev_conf(vid);
> +		dev->flags |= VIRTIO_DEV_VDPA_CONFIGURED;
> +	}
> +
>   	return 0;
>   }
>   
> 

Other than the code refactoring I propose, the patch looks good to me.

Thanks!
Maxime

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v4 2/5] vhost: support selective datapath
  2018-03-10 10:01   ` [PATCH v4 2/5] vhost: support selective datapath Zhihong Wang
  2018-03-31  6:10     ` Maxime Coquelin
@ 2018-03-31  7:38     ` Maxime Coquelin
  2018-04-02  2:03       ` Wang, Zhihong
  1 sibling, 1 reply; 67+ messages in thread
From: Maxime Coquelin @ 2018-03-31  7:38 UTC (permalink / raw)
  To: Zhihong Wang, dev
  Cc: jianfeng.tan, tiwei.bie, yliu, cunming.liang, xiao.w.wang, dan.daly



On 03/10/2018 11:01 AM, Zhihong Wang wrote:
> +		uint64_t *size);
> +/* Device ops */
> +struct rte_vdpa_dev_ops {
> +	vdpa_dev_queue_num_get_t  queue_num_get;
> +	vdpa_dev_feature_get_t    feature_get;
> +	vdpa_dev_feature_get_t    protocol_feature_get;

I would prefer them to be named as in Vhost-user spec:

get_queue_num
get_features
get_protocol_features

Thanks,
Maxime

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v4 5/5] vhost: add apis for live migration
  2018-03-10 10:01   ` [PATCH v4 5/5] vhost: add apis for live migration Zhihong Wang
@ 2018-03-31  7:39     ` Maxime Coquelin
  0 siblings, 0 replies; 67+ messages in thread
From: Maxime Coquelin @ 2018-03-31  7:39 UTC (permalink / raw)
  To: Zhihong Wang, dev
  Cc: jianfeng.tan, tiwei.bie, yliu, cunming.liang, xiao.w.wang, dan.daly



On 03/10/2018 11:01 AM, Zhihong Wang wrote:
> This patch adds APIs to enable live migration for non-builtin data paths.
> 
> At src side, last_avail/used_idx from the device need to be set into the
> virtio_net structure, and the log_base and log_size from the virtio_net
> structure need to be set into the device.
> 
> At dst side, last_avail/used_idx need to be read from the virtio_net
> structure and set into the device.
> 
> Signed-off-by: Zhihong Wang <zhihong.wang@intel.com>
> ---
>   lib/librte_vhost/rte_vhost.h           | 51 +++++++++++++++++++++++++++
>   lib/librte_vhost/rte_vhost_version.map |  3 ++
>   lib/librte_vhost/vhost.c               | 63 ++++++++++++++++++++++++++++++++++
>   3 files changed, 117 insertions(+)
> 

Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>

Thanks,
Maxime

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v4 2/5] vhost: support selective datapath
  2018-03-31  6:10     ` Maxime Coquelin
@ 2018-04-02  1:58       ` Wang, Zhihong
  0 siblings, 0 replies; 67+ messages in thread
From: Wang, Zhihong @ 2018-04-02  1:58 UTC (permalink / raw)
  To: Maxime Coquelin, dev
  Cc: Tan, Jianfeng, Bie, Tiwei, yliu, Liang, Cunming, Wang, Xiao W, Daly, Dan



> -----Original Message-----
> From: Maxime Coquelin [mailto:maxime.coquelin@redhat.com]
> Sent: Saturday, March 31, 2018 2:10 PM
> To: Wang, Zhihong <zhihong.wang@intel.com>; dev@dpdk.org
> Cc: Tan, Jianfeng <jianfeng.tan@intel.com>; Bie, Tiwei
> <tiwei.bie@intel.com>; yliu@fridaylinux.org; Liang, Cunming
> <cunming.liang@intel.com>; Wang, Xiao W <xiao.w.wang@intel.com>; Daly,
> Dan <dan.daly@intel.com>
> Subject: Re: [PATCH v4 2/5] vhost: support selective datapath
> 
> 
> 
> On 03/10/2018 11:01 AM, Zhihong Wang wrote:
> > This patch set introduces support for selective datapath in DPDK vhost-user
> > lib. vDPA stands for vhost Data Path Acceleration. The idea is to support
> > virtio ring compatible devices to serve virtio driver directly to enable
> > datapath acceleration.
> >
> > A set of device ops is defined for device specific operations:
> >
> >       a. queue_num_get: Called to get supported queue number of the
> device.
> >
> >       b. feature_get: Called to get supported features of the device.
> >
> >       c. protocol_feature_get: Called to get supported protocol features of
> >          the device.
> >
> >       d. dev_conf: Called to configure the actual device when the virtio
> >          device becomes ready.
> >
> >       e. dev_close: Called to close the actual device when the virtio device
> >          is stopped.
> >
> >       f. vring_state_set: Called to change the state of the vring in the
> >          actual device when vring state changes.
> >
> >       g. feature_set: Called to set the negotiated features to device.
> >
> >       h. migration_done: Called to allow the device to response to RARP
> >          sending.
> >
> >       i. get_vfio_group_fd: Called to get the VFIO group fd of the device.
> >
> >       j. get_vfio_device_fd: Called to get the VFIO device fd of the device.
> >
> >       k. get_notify_area: Called to get the notify area info of the queue.
> >
> > Signed-off-by: Zhihong Wang <zhihong.wang@intel.com>
> > ---
> > Changes in v4:
> >
> >   1. Remove the "engine" concept in the lib.
> >
> > ---
> > Changes in v2:
> >
> >   1. Add VFIO related vDPA device ops.
> >
> >   lib/librte_vhost/Makefile              |  4 +-
> >   lib/librte_vhost/rte_vdpa.h            | 94
> +++++++++++++++++++++++++++++++++
> >   lib/librte_vhost/rte_vhost_version.map |  6 +++
> >   lib/librte_vhost/vdpa.c                | 96
> ++++++++++++++++++++++++++++++++++
> >   4 files changed, 198 insertions(+), 2 deletions(-)
> >   create mode 100644 lib/librte_vhost/rte_vdpa.h
> >   create mode 100644 lib/librte_vhost/vdpa.c
> >
> > diff --git a/lib/librte_vhost/Makefile b/lib/librte_vhost/Makefile
> > index 5d6c6abae..37044ac03 100644
> > --- a/lib/librte_vhost/Makefile
> > +++ b/lib/librte_vhost/Makefile
> > @@ -22,9 +22,9 @@ LDLIBS += -lrte_eal -lrte_mempool -lrte_mbuf -
> lrte_ethdev -lrte_net
> >
> >   # all source are stored in SRCS-y
> >   SRCS-$(CONFIG_RTE_LIBRTE_VHOST) := fd_man.c iotlb.c socket.c vhost.c
> \
> > -					vhost_user.c virtio_net.c
> > +					vhost_user.c virtio_net.c vdpa.c
> >
> >   # install includes
> > -SYMLINK-$(CONFIG_RTE_LIBRTE_VHOST)-include += rte_vhost.h
> > +SYMLINK-$(CONFIG_RTE_LIBRTE_VHOST)-include += rte_vhost.h
> rte_vdpa.h
> >
> >   include $(RTE_SDK)/mk/rte.lib.mk
> > diff --git a/lib/librte_vhost/rte_vdpa.h b/lib/librte_vhost/rte_vdpa.h
> > new file mode 100644
> > index 000000000..a4bbbd93d
> > --- /dev/null
> > +++ b/lib/librte_vhost/rte_vdpa.h
> > @@ -0,0 +1,94 @@
> > +/* SPDX-License-Identifier: BSD-3-Clause
> > + * Copyright(c) 2018 Intel Corporation
> > + */
> > +
> > +#ifndef _RTE_VDPA_H_
> > +#define _RTE_VDPA_H_
> > +
> > +/**
> > + * @file
> > + *
> > + * Device specific vhost lib
> > + */
> > +
> > +#include <rte_pci.h>
> > +#include "rte_vhost.h"
> > +
> > +#define MAX_VDPA_NAME_LEN 128
> > +
> > +enum vdpa_addr_type {
> > +	PCI_ADDR,
> > +	VDPA_ADDR_MAX
> > +};
> > +
> > +struct rte_vdpa_dev_addr {
> > +	enum vdpa_addr_type type;
> > +	union {
> > +		uint8_t __dummy[64];
> > +		struct rte_pci_addr pci_addr;
> > +	};
> > +};
> > +
> > +/* Get capabilities of this device */
> > +typedef int (*vdpa_dev_queue_num_get_t)(int did, uint32_t
> *queue_num);
> > +typedef int (*vdpa_dev_feature_get_t)(int did, uint64_t *features);
> > +
> > +/* Driver configure/close the device */
> > +typedef int (*vdpa_dev_conf_t)(int vid);
> > +typedef int (*vdpa_dev_close_t)(int vid);
> > +
> > +/* Enable/disable this vring */
> > +typedef int (*vdpa_vring_state_set_t)(int vid, int vring, int state);
> > +
> > +/* Set features when changed */
> > +typedef int (*vdpa_feature_set_t)(int vid);
> > +
> > +/* Destination operations when migration done */
> > +typedef int (*vdpa_migration_done_t)(int vid);
> > +
> > +/* Get the vfio group fd */
> > +typedef int (*vdpa_get_vfio_group_fd_t)(int vid);
> > +
> > +/* Get the vfio device fd */
> > +typedef int (*vdpa_get_vfio_device_fd_t)(int vid);
> > +
> > +/* Get the notify area info of the queue */
> > +typedef int (*vdpa_get_notify_area_t)(int vid, int qid, uint64_t *offset,
> > +		uint64_t *size);
> > +/* Device ops */
> > +struct rte_vdpa_dev_ops {
> > +	vdpa_dev_queue_num_get_t  queue_num_get;
> > +	vdpa_dev_feature_get_t    feature_get;
> > +	vdpa_dev_feature_get_t    protocol_feature_get;
> > +	vdpa_dev_conf_t           dev_conf;
> > +	vdpa_dev_close_t          dev_close;
> > +	vdpa_vring_state_set_t    vring_state_set;
> > +	vdpa_feature_set_t        feature_set;
> > +	vdpa_migration_done_t     migration_done;
> > +	vdpa_get_vfio_group_fd_t  get_vfio_group_fd;
> > +	vdpa_get_vfio_device_fd_t get_vfio_device_fd;
> > +	vdpa_get_notify_area_t    get_notify_area;
> 
> Maybe you could reserve some room here to avoid breaking the ABI in the
> future if we need to add some optional ops.

Good suggestion.

> 
> > +};
> > +
> > +struct rte_vdpa_device {
> > +	struct rte_vdpa_dev_addr addr;
> > +	struct rte_vdpa_dev_ops *ops;
> > +} __rte_cache_aligned;
> > +
> > +extern struct rte_vdpa_device *vdpa_devices[];
> > +extern uint32_t vdpa_device_num;
> > +
> > +/* Register a vdpa device, return did if successful, -1 on failure */
> > +int __rte_experimental
> > +rte_vdpa_register_device(struct rte_vdpa_dev_addr *addr,
> > +		struct rte_vdpa_dev_ops *ops);
> > +
> > +/* Unregister a vdpa device, return -1 on failure */
> > +int __rte_experimental
> > +rte_vdpa_unregister_device(int did);
> > +
> > +/* Find did of a vdpa device, return -1 on failure */
> > +int __rte_experimental
> > +rte_vdpa_find_device_id(struct rte_vdpa_dev_addr *addr);
> > +
> > +#endif /* _RTE_VDPA_H_ */
> > diff --git a/lib/librte_vhost/rte_vhost_version.map
> b/lib/librte_vhost/rte_vhost_version.map
> > index df0103129..7bcffb490 100644
> > --- a/lib/librte_vhost/rte_vhost_version.map
> > +++ b/lib/librte_vhost/rte_vhost_version.map
> > @@ -59,3 +59,9 @@ DPDK_18.02 {
> >   	rte_vhost_vring_call;
> >
> >   } DPDK_17.08;
> > +
> > +EXPERIMENTAL {
> > +	rte_vdpa_register_device;
> > +	rte_vdpa_unregister_device;
> > +	rte_vdpa_find_device_id;
> 
> I think you need also to declare the new structs here,
> not only the new functions.

Ok.

> 
> > +} DPDK_18.02;
> > diff --git a/lib/librte_vhost/vdpa.c b/lib/librte_vhost/vdpa.c
> > new file mode 100644
> > index 000000000..0c950d45f
> > --- /dev/null
> > +++ b/lib/librte_vhost/vdpa.c
> > @@ -0,0 +1,96 @@
> > +/* SPDX-License-Identifier: BSD-3-Clause
> > + * Copyright(c) 2018 Intel Corporation
> > + */
> > +
> > +/**
> > + * @file
> > + *
> > + * Device specific vhost lib
> > + */
> > +
> > +#include <stdbool.h>
> > +
> > +#include <rte_malloc.h>
> > +#include "rte_vdpa.h"
> > +#include "vhost.h"
> > +
> > +struct rte_vdpa_device *vdpa_devices[MAX_VHOST_DEVICE];
> > +uint32_t vdpa_device_num;
> > +
> > +static int is_same_vdpa_dev_addr(struct rte_vdpa_dev_addr *a,
> > +		struct rte_vdpa_dev_addr *b)
> > +{
> 
> Given the boolean nature of the function name, I would return 1 if same
> device, 0 if different.

Ok, will use bool.

> 
> > +	int ret = 0;
> > +
> > +	if (a->type != b->type)
> > +		return -1;
> > +
> > +	switch (a->type) {
> > +	case PCI_ADDR:
> > +		if (a->pci_addr.domain != b->pci_addr.domain ||
> > +				a->pci_addr.bus != b->pci_addr.bus ||
> > +				a->pci_addr.devid != b->pci_addr.devid ||
> > +				a->pci_addr.function != b->pci_addr.function)
> > +			ret = -1;
> > +		break;
> > +	default:
> > +		break;
> > +	}
> > +
> > +	return ret;
> > +}
> > +
> > +int rte_vdpa_register_device(struct rte_vdpa_dev_addr *addr,
> > +		struct rte_vdpa_dev_ops *ops)
> > +{
> > +	struct rte_vdpa_device *dev;
> > +	char device_name[MAX_VDPA_NAME_LEN];
> > +	int i;
> > +
> > +	if (vdpa_device_num >= MAX_VHOST_DEVICE)
> > +		return -1;
> > +
> > +	for (i = 0; i < MAX_VHOST_DEVICE; i++) {
> > +		if (vdpa_devices[i] == NULL)
> > +			break;
> You might want to check same device isn't being registering a second
> time, and return an error in that case.

Will do.

Thanks
-Zhihong

> 
> This is not a blocker though, and can be done in a dedicated patch.
> 
> > +	}
> > +
> > +	sprintf(device_name, "vdpa-dev-%d", i);
> > +	dev = rte_zmalloc(device_name, sizeof(struct rte_vdpa_device),
> > +			RTE_CACHE_LINE_SIZE);
> > +	if (!dev)
> > +		return -1;
> > +
> > +	memcpy(&dev->addr, addr, sizeof(struct rte_vdpa_dev_addr));
> > +	dev->ops = ops;
> > +	vdpa_devices[i] = dev;
> > +	vdpa_device_num++;
> > +
> > +	return i;
> > +}
> > +
> > +int rte_vdpa_unregister_device(int did)
> > +{
> > +	if (did < 0 || did >= MAX_VHOST_DEVICE || vdpa_devices[did] ==
> NULL)
> > +		return -1;
> > +
> > +	rte_free(vdpa_devices[did]);
> > +	vdpa_devices[did] = NULL;
> > +	vdpa_device_num--;
> > +
> > +	return did;
> > +}
> > +
> > +int rte_vdpa_find_device_id(struct rte_vdpa_dev_addr *addr)
> > +{
> > +	struct rte_vdpa_device *dev;
> > +	int i;
> > +
> > +	for (i = 0; i < MAX_VHOST_DEVICE; ++i) {
> > +		dev = vdpa_devices[i];
> > +		if (dev && is_same_vdpa_dev_addr(&dev->addr, addr) == 0)
> > +			return i;
> > +	}
> > +
> > +	return -1;
> > +}
> >

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v4 3/5] vhost: add apis for datapath configuration
  2018-03-31  7:04     ` Maxime Coquelin
@ 2018-04-02  2:01       ` Wang, Zhihong
  0 siblings, 0 replies; 67+ messages in thread
From: Wang, Zhihong @ 2018-04-02  2:01 UTC (permalink / raw)
  To: Maxime Coquelin, dev
  Cc: Tan, Jianfeng, Bie, Tiwei, yliu, Liang, Cunming, Wang, Xiao W, Daly, Dan



> -----Original Message-----
> From: Maxime Coquelin [mailto:maxime.coquelin@redhat.com]
> Sent: Saturday, March 31, 2018 3:04 PM
> To: Wang, Zhihong <zhihong.wang@intel.com>; dev@dpdk.org
> Cc: Tan, Jianfeng <jianfeng.tan@intel.com>; Bie, Tiwei
> <tiwei.bie@intel.com>; yliu@fridaylinux.org; Liang, Cunming
> <cunming.liang@intel.com>; Wang, Xiao W <xiao.w.wang@intel.com>; Daly,
> Dan <dan.daly@intel.com>
> Subject: Re: [PATCH v4 3/5] vhost: add apis for datapath configuration
> 
> 
> 
> On 03/10/2018 11:01 AM, Zhihong Wang wrote:
> > This patch adds APIs for datapath configuration.
> >
> > The did of the vhost-user socket can be set to identify the backend device,
> > in this case each vhost-user socket can have only 1 connection. The did is
> > set to -1 by default when the software datapath is used.
> >
> > Signed-off-by: Zhihong Wang <zhihong.wang@intel.com>
> > ---
> > Changes in v4:
> >
> >   1. Remove the "engine" concept in the lib.
> >
> >   lib/librte_vhost/rte_vhost.h           | 35
> +++++++++++++++++++++++++++++++++
> >   lib/librte_vhost/rte_vhost_version.map |  3 +++
> >   lib/librte_vhost/socket.c              | 36
> ++++++++++++++++++++++++++++++++++
> >   lib/librte_vhost/vhost.c               | 25 +++++++++++++++++++++++
> >   lib/librte_vhost/vhost.h               |  9 +++++++++
> >   5 files changed, 108 insertions(+)
> >
> > diff --git a/lib/librte_vhost/rte_vhost.h b/lib/librte_vhost/rte_vhost.h
> > index 671ea5053..d50f4c67d 100644
> > --- a/lib/librte_vhost/rte_vhost.h
> > +++ b/lib/librte_vhost/rte_vhost.h
> > @@ -200,6 +200,30 @@ int rte_vhost_driver_register(const char *path,
> uint64_t flags);
> >   int rte_vhost_driver_unregister(const char *path);
> >
> >   /**
> > + * Set the device id, enforce single connection per socket
> > + *
> > + * @param path
> > + *  The vhost-user socket file path
> > + * @param did
> > + *  Device id
> > + * @return
> > + *  0 on success, -1 on failure
> > + */
> > +int __rte_experimental
> > +rte_vhost_driver_set_vdpa_did(const char *path, int did);
> 
> IIUC, we call this to attach a VDPA device to a Vhost-user port?
> 
> What about having this named explicitly? Something like:
> 
> rte_vhost_driver_attach_vdpa_did(const char *path, int did)
> rte_vhost_driver_detach_vdpa_did(const char *path)
> 
> The later would set to did -1

Great. This does make things clearer.

> 
> This is not mandatory though
> 
> > +
> > +/**
> > + * Get the device id
> > + *
> > + * @param path
> > + *  The vhost-user socket file path
> > + * @return
> > + *  Device id, -1 on failure
> > + */
> > +int __rte_experimental
> > +rte_vhost_driver_get_vdpa_did(const char *path);
> > +
> > +/**
> >    * Set the feature bits the vhost-user driver supports.
> >    *
> >    * @param path
> > @@ -464,6 +488,17 @@ int rte_vhost_vring_call(int vid, uint16_t vring_idx);
> >    */
> >   uint32_t rte_vhost_rx_queue_count(int vid, uint16_t qid);
> >
> > +/**
> > + * Get vdpa device id for vhost device.
> > + *
> > + * @param vid
> > + *  vhost device ID
> > + * @return
> > + *  device id
> > + */
> > +int __rte_experimental
> > +rte_vhost_get_vdpa_did(int vid);
> > +
> >   #ifdef __cplusplus
> >   }
> >   #endif
> > diff --git a/lib/librte_vhost/rte_vhost_version.map
> b/lib/librte_vhost/rte_vhost_version.map
> > index 7bcffb490..6e2d5364a 100644
> > --- a/lib/librte_vhost/rte_vhost_version.map
> > +++ b/lib/librte_vhost/rte_vhost_version.map
> > @@ -64,4 +64,7 @@ EXPERIMENTAL {
> >   	rte_vdpa_register_device;
> >   	rte_vdpa_unregister_device;
> >   	rte_vdpa_find_device_id;
> > +	rte_vhost_driver_set_vdpa_did;
> > +	rte_vhost_driver_get_vdpa_did;
> > +	rte_vhost_get_vdpa_did;
> >   } DPDK_18.02;
> > diff --git a/lib/librte_vhost/socket.c b/lib/librte_vhost/socket.c
> > index cfc31e179..3d58da94e 100644
> > --- a/lib/librte_vhost/socket.c
> > +++ b/lib/librte_vhost/socket.c
> > @@ -52,6 +52,13 @@ struct vhost_user_socket {
> >   	uint64_t supported_features;
> >   	uint64_t features;
> >
> > +	/*
> > +	 * Device id to identify a specific backend device.
> > +	 * It's set to -1 for the default software implementation.
> > +	 * If valid, one socket can have 1 connection only.
> > +	 */
> > +	int did;
> I would rename it to something like vdpa_did or even better,
> vdpa_dev_id. At least prefix it with vdpa not to confuse the user.

Good suggestion.

> 
> > +
> >   	struct vhost_device_ops const *notify_ops;
> >   };
> >
> > @@ -545,6 +552,35 @@ find_vhost_user_socket(const char *path)
> >   }
> >
> >   int
> > +rte_vhost_driver_set_vdpa_did(const char *path, int did)
> > +{
> > +	struct vhost_user_socket *vsocket;
> > +
> > +	pthread_mutex_lock(&vhost_user.mutex);
> > +	vsocket = find_vhost_user_socket(path);
> > +	if (vsocket)
> > +		vsocket->did = did;
> 
> I guess it is possible to know whether the did exists
> at that time. Maybe we could check this?

Ok.

> 
> > +	pthread_mutex_unlock(&vhost_user.mutex);
> > +
> > +	return vsocket ? 0 : -1;
> > +}
> > +
> > +int
> > +rte_vhost_driver_get_vdpa_did(const char *path)
> > +{
> > +	struct vhost_user_socket *vsocket;
> > +	int did = -1;
> > +
> > +	pthread_mutex_lock(&vhost_user.mutex);
> > +	vsocket = find_vhost_user_socket(path);
> > +	if (vsocket)
> > +		did = vsocket->did;
> > +	pthread_mutex_unlock(&vhost_user.mutex);
> > +
> > +	return did;
> > +}
> > +
> > +int
> >   rte_vhost_driver_disable_features(const char *path, uint64_t features)
> >   {
> >   	struct vhost_user_socket *vsocket;
> > diff --git a/lib/librte_vhost/vhost.c b/lib/librte_vhost/vhost.c
> > index f6f12a03b..1740cc1ab 100644
> > --- a/lib/librte_vhost/vhost.c
> > +++ b/lib/librte_vhost/vhost.c
> > @@ -283,6 +283,7 @@ vhost_new_device(void)
> >   	dev->vid = i;
> >   	dev->flags = VIRTIO_DEV_BUILTIN_VIRTIO_NET;
> >   	dev->slave_req_fd = -1;
> > +	dev->did = -1;
> >
> >   	return i;
> >   }
> > @@ -311,6 +312,20 @@ vhost_destroy_device(int vid)
> >   }
> >
> >   void
> > +vhost_set_vdpa_did(int vid, int did)
> > +{
> > +	struct virtio_net *dev = get_device(vid);
> > +
> > +	if (did < 0)
> > +		return;
> > +
> > +	if (dev == NULL)
> > +		return;
> > +
> > +	dev->did = did;
> > +}
> > +
> > +void
> >   vhost_set_ifname(int vid, const char *if_name, unsigned int if_len)
> >   {
> >   	struct virtio_net *dev;
> > @@ -614,3 +629,13 @@ rte_vhost_rx_queue_count(int vid, uint16_t qid)
> >
> >   	return *((volatile uint16_t *)&vq->avail->idx) - vq->last_avail_idx;
> >   }
> > +
> > +int rte_vhost_get_vdpa_did(int vid)
> > +{
> > +	struct virtio_net *dev = get_device(vid);
> > +
> > +	if (dev == NULL)
> > +		return -1;
> > +
> > +	return dev->did;
> > +}
> > diff --git a/lib/librte_vhost/vhost.h b/lib/librte_vhost/vhost.h
> > index 2e28e4026..2970c1eab 100644
> > --- a/lib/librte_vhost/vhost.h
> > +++ b/lib/librte_vhost/vhost.h
> > @@ -19,6 +19,7 @@
> >   #include <rte_rwlock.h>
> >
> >   #include "rte_vhost.h"
> > +#include "rte_vdpa.h"
> >
> >   /* Used to indicate that the device is running on a data core */
> >   #define VIRTIO_DEV_RUNNING 1
> > @@ -239,6 +240,12 @@ struct virtio_net {
> >   	struct guest_page       *guest_pages;
> >
> >   	int			slave_req_fd;
> > +
> > +	/*
> > +	 * Device id to identify a specific backend device.
> > +	 * It's set to -1 for the default software implementation.
> > +	 */
> > +	int			did;
> 
> Same as for struct vhost_user_socket, it would be less confusing to
> prefix it with vdpa.

Ok.

Thanks
-Zhihong

> 
> >   } __rte_cache_aligned;
> >
> >
> > @@ -365,6 +372,8 @@ void free_vq(struct vhost_virtqueue *vq);
> >
> >   int alloc_vring_queue(struct virtio_net *dev, uint32_t vring_idx);
> >
> > +void vhost_set_vdpa_did(int vid, int did);
> > +
> >   void vhost_set_ifname(int, const char *if_name, unsigned int if_len);
> >   void vhost_enable_dequeue_zero_copy(int vid);
> >   void vhost_set_builtin_virtio_net(int vid, bool enable);
> >

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v4 2/5] vhost: support selective datapath
  2018-03-31  7:38     ` Maxime Coquelin
@ 2018-04-02  2:03       ` Wang, Zhihong
  0 siblings, 0 replies; 67+ messages in thread
From: Wang, Zhihong @ 2018-04-02  2:03 UTC (permalink / raw)
  To: Maxime Coquelin, dev
  Cc: Tan, Jianfeng, Bie, Tiwei, yliu, Liang, Cunming, Wang, Xiao W, Daly, Dan



> -----Original Message-----
> From: Maxime Coquelin [mailto:maxime.coquelin@redhat.com]
> Sent: Saturday, March 31, 2018 3:38 PM
> To: Wang, Zhihong <zhihong.wang@intel.com>; dev@dpdk.org
> Cc: Tan, Jianfeng <jianfeng.tan@intel.com>; Bie, Tiwei
> <tiwei.bie@intel.com>; yliu@fridaylinux.org; Liang, Cunming
> <cunming.liang@intel.com>; Wang, Xiao W <xiao.w.wang@intel.com>; Daly,
> Dan <dan.daly@intel.com>
> Subject: Re: [PATCH v4 2/5] vhost: support selective datapath
> 
> 
> 
> On 03/10/2018 11:01 AM, Zhihong Wang wrote:
> > +		uint64_t *size);
> > +/* Device ops */
> > +struct rte_vdpa_dev_ops {
> > +	vdpa_dev_queue_num_get_t  queue_num_get;
> > +	vdpa_dev_feature_get_t    feature_get;
> > +	vdpa_dev_feature_get_t    protocol_feature_get;
> 
> I would prefer them to be named as in Vhost-user spec:
> 
> get_queue_num
> get_features
> get_protocol_features

Ok. Will change them.

> 
> Thanks,
> Maxime

^ permalink raw reply	[flat|nested] 67+ messages in thread

* [PATCH v5 0/5] vhost: support selective datapath
  2018-02-02 23:28 [PATCH 0/7] vhost: support selective datapath Zhihong Wang
                   ` (9 preceding siblings ...)
  2018-03-10 10:01 ` [PATCH v4 " Zhihong Wang
@ 2018-04-02 11:46 ` Zhihong Wang
  2018-04-02 11:46   ` [PATCH v5 1/5] vhost: export vhost feature definitions Zhihong Wang
                     ` (5 more replies)
  10 siblings, 6 replies; 67+ messages in thread
From: Zhihong Wang @ 2018-04-02 11:46 UTC (permalink / raw)
  To: dev
  Cc: jianfeng.tan, tiwei.bie, maxime.coquelin, yliu, cunming.liang,
	xiao.w.wang, dan.daly, Zhihong Wang

This patch set introduces support for selective datapath in DPDK vhost-user
lib. vDPA stands for vhost Data Path Acceleration. The idea is to support
virtio ring compatible devices to serve virtio driver directly to enable
datapath acceleration.

Design details
====

A vDPA device is a virtio ring compatible backend. It's defined as follows:

struct rte_vdpa_dev_addr {
	enum vdpa_addr_type type;
	union {
		uint8_t __dummy[64];
		struct rte_pci_addr pci_addr;
	};
};

struct rte_vdpa_dev_ops {
	/* Get capabilities of this device */
	int (*get_queue_num)(int did, uint32_t *queue_num);
	int (*get_features)(int did, uint64_t *features);
	int (*get_protocol_features)(int did, uint64_t *protocol_features);

	/* Driver configure/close the device */
	int (*dev_conf)(int vid);
	int (*dev_close)(int vid);

	/* Enable/disable this vring */
	int (*set_vring_state)(int vid, int vring, int state);

	/* Set features when changed */
	int (*set_features)(int vid);

	/* Destination operations when migration done */
	int (*migration_done)(int vid);

	/* Get the vfio group fd */
	int (*get_vfio_group_fd)(int vid);

	/* Get the vfio device fd */
	int (*get_vfio_device_fd)(int vid);

	/* Get the notify area info of the queue */
	int (*get_notify_area)(int vid, int qid,
			uint64_t *offset, uint64_t *size);

	/* Reserved for future extension */
	void *reserved[5];
};

struct rte_vdpa_device {
	struct rte_vdpa_dev_addr addr;
	struct rte_vdpa_dev_ops *ops;
} __rte_cache_aligned;


Changes to the current vhost-user lib are:
====

 1. Make vhost device capabilities configurable to adopt various devices.
    Such capabilities include supported features, protocol features, queue
    number. APIs are introduced to configure these capabilities.

 2. A set of device ops is defined for device specific operations:

     a. get_queue_num: Called to get supported queue number of the device.

     b. get_features: Called to get supported features of the device.

     c. get_protocol_features: Called to get supported protocol features of
        the device.

     d. dev_conf: Called to configure the actual device when the virtio
        device becomes ready.

     e. dev_close: Called to close the actual device when the virtio device
        is stopped.

     f. set_vring_state: Called to change the state of the vring in the
        actual device when vring state changes.

     g. set_features: Called to set the negotiated features to device.

     h. migration_done: Called to allow the device to response to RARP
        sending.

     i. get_vfio_group_fd: Called to get the VFIO group fd of the device.

     j. get_vfio_device_fd: Called to get the VFIO device fd of the device.

     k. get_notify_area: Called to get the notify area info of the queue.

 3. To make vhost aware of its datapath type, an device id (did) is added
    into the vhost data structure to identify the actual device. APIs are
    introduced to configure it. When the default software datapath is used,
    did is set to -1. When alternative datapath is used, did should be set
    to specify which device to use, and each vhost-user socket can have
    only 1 connection in this case.

Working process:
====

 1. Register vDPA device with address and device ops, and get a did.

 2. For vhost device creation:

      a. Register vhost-user socket.

      b. Set did of the vhost-user socket.

      c. Register vhost-user callbacks.

      d. Start to wait for connection.

 3. When connection comes and virtio device data structure is negotiated,
    the device will be configured with all needed info.

---
Changes in v5:

 1. Rename the vDPA device ops to follow convention.

 2. Rename APIs for better description.

 3. Improve sanity check.

---
Changes in v4:

 1. Remove the "engine" concept in the lib.

---
Changes in v3:

 1. Keep macro names the same as in the spec.

 2. Export new APIs where they're introduced.

---
Changes in v2:

 1. Ensure negotiated capabilities are supported in vhost-user lib.

 2. Add APIs for live migration.

 3. Configure the data path at the right time.

 4. Add VFIO related vDPA device ops.

 5. Rebase on dpdk-next-virtio.

Zhihong Wang (5):
  vhost: export vhost feature definitions
  vhost: support selective datapath
  vhost: add apis for datapath configuration
  vhost: adapt vhost lib for selective datapath
  vhost: add apis for live migration

 lib/librte_vhost/Makefile              |   4 +-
 lib/librte_vhost/rte_vdpa.h            |  87 +++++++++++++++++
 lib/librte_vhost/rte_vhost.h           | 154 ++++++++++++++++++++++++++++++
 lib/librte_vhost/rte_vhost_version.map |  16 ++++
 lib/librte_vhost/socket.c              | 166 ++++++++++++++++++++++++++++++++-
 lib/librte_vhost/vdpa.c                | 115 +++++++++++++++++++++++
 lib/librte_vhost/vhost.c               | 105 +++++++++++++++++++++
 lib/librte_vhost/vhost.h               |  14 ++-
 lib/librte_vhost/vhost_user.c          |  70 +++++++++++++-
 lib/librte_vhost/vhost_user.h          |   7 --
 10 files changed, 718 insertions(+), 20 deletions(-)
 create mode 100644 lib/librte_vhost/rte_vdpa.h
 create mode 100644 lib/librte_vhost/vdpa.c

-- 
2.13.6

^ permalink raw reply	[flat|nested] 67+ messages in thread

* [PATCH v5 1/5] vhost: export vhost feature definitions
  2018-04-02 11:46 ` [PATCH v5 0/5] vhost: support selective datapath Zhihong Wang
@ 2018-04-02 11:46   ` Zhihong Wang
  2018-04-02 11:46   ` [PATCH v5 2/5] vhost: support selective datapath Zhihong Wang
                     ` (4 subsequent siblings)
  5 siblings, 0 replies; 67+ messages in thread
From: Zhihong Wang @ 2018-04-02 11:46 UTC (permalink / raw)
  To: dev
  Cc: jianfeng.tan, tiwei.bie, maxime.coquelin, yliu, cunming.liang,
	xiao.w.wang, dan.daly, Zhihong Wang

This patch exports vhost-user protocol features to support device driver
development.

Signed-off-by: Zhihong Wang <zhihong.wang@intel.com>
Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>
---
Changes in v3:

 1. Keep macro names the same as in the spec.

 lib/librte_vhost/rte_vhost.h  | 30 ++++++++++++++++++++++++++++++
 lib/librte_vhost/vhost.h      |  2 --
 lib/librte_vhost/vhost_user.h |  7 -------
 3 files changed, 30 insertions(+), 9 deletions(-)

diff --git a/lib/librte_vhost/rte_vhost.h b/lib/librte_vhost/rte_vhost.h
index d33206997..671ea5053 100644
--- a/lib/librte_vhost/rte_vhost.h
+++ b/lib/librte_vhost/rte_vhost.h
@@ -29,6 +29,36 @@ extern "C" {
 #define RTE_VHOST_USER_DEQUEUE_ZERO_COPY	(1ULL << 2)
 #define RTE_VHOST_USER_IOMMU_SUPPORT	(1ULL << 3)
 
+/** Protocol features. */
+#ifndef VHOST_USER_PROTOCOL_F_MQ
+#define VHOST_USER_PROTOCOL_F_MQ	0
+#endif
+
+#ifndef VHOST_USER_PROTOCOL_F_LOG_SHMFD
+#define VHOST_USER_PROTOCOL_F_LOG_SHMFD	1
+#endif
+
+#ifndef VHOST_USER_PROTOCOL_F_RARP
+#define VHOST_USER_PROTOCOL_F_RARP	2
+#endif
+
+#ifndef VHOST_USER_PROTOCOL_F_REPLY_ACK
+#define VHOST_USER_PROTOCOL_F_REPLY_ACK	3
+#endif
+
+#ifndef VHOST_USER_PROTOCOL_F_NET_MTU
+#define VHOST_USER_PROTOCOL_F_NET_MTU	4
+#endif
+
+#ifndef VHOST_USER_PROTOCOL_F_SLAVE_REQ
+#define VHOST_USER_PROTOCOL_F_SLAVE_REQ	5
+#endif
+
+/** Indicate whether protocol features negotiation is supported. */
+#ifndef VHOST_USER_F_PROTOCOL_FEATURES
+#define VHOST_USER_F_PROTOCOL_FEATURES	30
+#endif
+
 /**
  * Information relating to memory regions including offsets to
  * addresses in QEMUs memory file.
diff --git a/lib/librte_vhost/vhost.h b/lib/librte_vhost/vhost.h
index 58aec2e0d..2e28e4026 100644
--- a/lib/librte_vhost/vhost.h
+++ b/lib/librte_vhost/vhost.h
@@ -174,8 +174,6 @@ struct vhost_msg {
  #define VIRTIO_F_VERSION_1 32
 #endif
 
-#define VHOST_USER_F_PROTOCOL_FEATURES	30
-
 /* Features supported by this builtin vhost-user net driver. */
 #define VIRTIO_NET_SUPPORTED_FEATURES ((1ULL << VIRTIO_NET_F_MRG_RXBUF) | \
 				(1ULL << VIRTIO_F_ANY_LAYOUT) | \
diff --git a/lib/librte_vhost/vhost_user.h b/lib/librte_vhost/vhost_user.h
index 0fafbe6e0..97afabc47 100644
--- a/lib/librte_vhost/vhost_user.h
+++ b/lib/librte_vhost/vhost_user.h
@@ -14,13 +14,6 @@
 
 #define VHOST_MEMORY_MAX_NREGIONS 8
 
-#define VHOST_USER_PROTOCOL_F_MQ	0
-#define VHOST_USER_PROTOCOL_F_LOG_SHMFD	1
-#define VHOST_USER_PROTOCOL_F_RARP	2
-#define VHOST_USER_PROTOCOL_F_REPLY_ACK	3
-#define VHOST_USER_PROTOCOL_F_NET_MTU 4
-#define VHOST_USER_PROTOCOL_F_SLAVE_REQ 5
-
 #define VHOST_USER_PROTOCOL_FEATURES	((1ULL << VHOST_USER_PROTOCOL_F_MQ) | \
 					 (1ULL << VHOST_USER_PROTOCOL_F_LOG_SHMFD) |\
 					 (1ULL << VHOST_USER_PROTOCOL_F_RARP) | \
-- 
2.13.6

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v5 2/5] vhost: support selective datapath
  2018-04-02 11:46 ` [PATCH v5 0/5] vhost: support selective datapath Zhihong Wang
  2018-04-02 11:46   ` [PATCH v5 1/5] vhost: export vhost feature definitions Zhihong Wang
@ 2018-04-02 11:46   ` Zhihong Wang
  2018-04-03  8:02     ` Maxime Coquelin
  2018-04-03  8:19     ` Maxime Coquelin
  2018-04-02 11:46   ` [PATCH v5 3/5] vhost: add apis for datapath configuration Zhihong Wang
                     ` (3 subsequent siblings)
  5 siblings, 2 replies; 67+ messages in thread
From: Zhihong Wang @ 2018-04-02 11:46 UTC (permalink / raw)
  To: dev
  Cc: jianfeng.tan, tiwei.bie, maxime.coquelin, yliu, cunming.liang,
	xiao.w.wang, dan.daly, Zhihong Wang

This patch set introduces support for selective datapath in DPDK vhost-user
lib. vDPA stands for vhost Data Path Acceleration. The idea is to support
virtio ring compatible devices to serve virtio driver directly to enable
datapath acceleration.

A set of device ops is defined for device specific operations:

     a. get_queue_num: Called to get supported queue number of the device.

     b. get_features: Called to get supported features of the device.

     c. get_protocol_features: Called to get supported protocol features of
        the device.

     d. dev_conf: Called to configure the actual device when the virtio
        device becomes ready.

     e. dev_close: Called to close the actual device when the virtio device
        is stopped.

     f. set_vring_state: Called to change the state of the vring in the
        actual device when vring state changes.

     g. set_features: Called to set the negotiated features to device.

     h. migration_done: Called to allow the device to response to RARP
        sending.

     i. get_vfio_group_fd: Called to get the VFIO group fd of the device.

     j. get_vfio_device_fd: Called to get the VFIO device fd of the device.

     k. get_notify_area: Called to get the notify area info of the queue.

Signed-off-by: Zhihong Wang <zhihong.wang@intel.com>
---
Changes in v5:

 1. Rename the vDPA device ops to follow convention.

 2. Improve sanity check.

---
Changes in v4:

 1. Remove the "engine" concept in the lib.

---
Changes in v2:

 1. Add VFIO related vDPA device ops.

 lib/librte_vhost/Makefile              |   4 +-
 lib/librte_vhost/rte_vdpa.h            |  87 +++++++++++++++++++++++++
 lib/librte_vhost/rte_vhost_version.map |   7 ++
 lib/librte_vhost/vdpa.c                | 115 +++++++++++++++++++++++++++++++++
 4 files changed, 211 insertions(+), 2 deletions(-)
 create mode 100644 lib/librte_vhost/rte_vdpa.h
 create mode 100644 lib/librte_vhost/vdpa.c

diff --git a/lib/librte_vhost/Makefile b/lib/librte_vhost/Makefile
index 5d6c6abae..37044ac03 100644
--- a/lib/librte_vhost/Makefile
+++ b/lib/librte_vhost/Makefile
@@ -22,9 +22,9 @@ LDLIBS += -lrte_eal -lrte_mempool -lrte_mbuf -lrte_ethdev -lrte_net
 
 # all source are stored in SRCS-y
 SRCS-$(CONFIG_RTE_LIBRTE_VHOST) := fd_man.c iotlb.c socket.c vhost.c \
-					vhost_user.c virtio_net.c
+					vhost_user.c virtio_net.c vdpa.c
 
 # install includes
-SYMLINK-$(CONFIG_RTE_LIBRTE_VHOST)-include += rte_vhost.h
+SYMLINK-$(CONFIG_RTE_LIBRTE_VHOST)-include += rte_vhost.h rte_vdpa.h
 
 include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/lib/librte_vhost/rte_vdpa.h b/lib/librte_vhost/rte_vdpa.h
new file mode 100644
index 000000000..90465ca26
--- /dev/null
+++ b/lib/librte_vhost/rte_vdpa.h
@@ -0,0 +1,87 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Intel Corporation
+ */
+
+#ifndef _RTE_VDPA_H_
+#define _RTE_VDPA_H_
+
+/**
+ * @file
+ *
+ * Device specific vhost lib
+ */
+
+#include <rte_pci.h>
+#include "rte_vhost.h"
+
+#define MAX_VDPA_NAME_LEN 128
+
+enum vdpa_addr_type {
+	PCI_ADDR,
+	VDPA_ADDR_MAX
+};
+
+struct rte_vdpa_dev_addr {
+	enum vdpa_addr_type type;
+	union {
+		uint8_t __dummy[64];
+		struct rte_pci_addr pci_addr;
+	};
+};
+
+struct rte_vdpa_dev_ops {
+	/* Get capabilities of this device */
+	int (*get_queue_num)(int did, uint32_t *queue_num);
+	int (*get_features)(int did, uint64_t *features);
+	int (*get_protocol_features)(int did, uint64_t *protocol_features);
+
+	/* Driver configure/close the device */
+	int (*dev_conf)(int vid);
+	int (*dev_close)(int vid);
+
+	/* Enable/disable this vring */
+	int (*set_vring_state)(int vid, int vring, int state);
+
+	/* Set features when changed */
+	int (*set_features)(int vid);
+
+	/* Destination operations when migration done */
+	int (*migration_done)(int vid);
+
+	/* Get the vfio group fd */
+	int (*get_vfio_group_fd)(int vid);
+
+	/* Get the vfio device fd */
+	int (*get_vfio_device_fd)(int vid);
+
+	/* Get the notify area info of the queue */
+	int (*get_notify_area)(int vid, int qid,
+			uint64_t *offset, uint64_t *size);
+
+	/* Reserved for future extension */
+	void *reserved[5];
+};
+
+struct rte_vdpa_device {
+	struct rte_vdpa_dev_addr addr;
+	struct rte_vdpa_dev_ops *ops;
+} __rte_cache_aligned;
+
+/* Register a vdpa device, return did if successful, -1 on failure */
+int __rte_experimental
+rte_vdpa_register_device(struct rte_vdpa_dev_addr *addr,
+		struct rte_vdpa_dev_ops *ops);
+
+/* Unregister a vdpa device, return -1 on failure */
+int __rte_experimental
+rte_vdpa_unregister_device(int did);
+
+/* Find did of a vdpa device, return -1 on failure */
+int __rte_experimental
+rte_vdpa_find_device_id(struct rte_vdpa_dev_addr *addr);
+
+/* Find a vdpa device based on did */
+struct rte_vdpa_device * __rte_experimental
+rte_vdpa_get_device(int did);
+
+#endif /* _RTE_VDPA_H_ */
diff --git a/lib/librte_vhost/rte_vhost_version.map b/lib/librte_vhost/rte_vhost_version.map
index df0103129..d3453a2a7 100644
--- a/lib/librte_vhost/rte_vhost_version.map
+++ b/lib/librte_vhost/rte_vhost_version.map
@@ -59,3 +59,10 @@ DPDK_18.02 {
 	rte_vhost_vring_call;
 
 } DPDK_17.08;
+
+EXPERIMENTAL {
+	rte_vdpa_register_device;
+	rte_vdpa_unregister_device;
+	rte_vdpa_find_device_id;
+	rte_vdpa_get_device;
+} DPDK_18.02;
diff --git a/lib/librte_vhost/vdpa.c b/lib/librte_vhost/vdpa.c
new file mode 100644
index 000000000..4b339b1c2
--- /dev/null
+++ b/lib/librte_vhost/vdpa.c
@@ -0,0 +1,115 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Intel Corporation
+ */
+
+/**
+ * @file
+ *
+ * Device specific vhost lib
+ */
+
+#include <stdbool.h>
+
+#include <rte_malloc.h>
+#include "rte_vdpa.h"
+#include "vhost.h"
+
+static struct rte_vdpa_device *vdpa_devices[MAX_VHOST_DEVICE];
+static uint32_t vdpa_device_num;
+
+static bool
+is_same_vdpa_device(struct rte_vdpa_dev_addr *a,
+		struct rte_vdpa_dev_addr *b)
+{
+	bool ret = true;
+
+	if (a->type != b->type)
+		return false;
+
+	switch (a->type) {
+	case PCI_ADDR:
+		if (a->pci_addr.domain != b->pci_addr.domain ||
+				a->pci_addr.bus != b->pci_addr.bus ||
+				a->pci_addr.devid != b->pci_addr.devid ||
+				a->pci_addr.function != b->pci_addr.function)
+			ret = false;
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
+
+int
+rte_vdpa_register_device(struct rte_vdpa_dev_addr *addr,
+		struct rte_vdpa_dev_ops *ops)
+{
+	struct rte_vdpa_device *dev;
+	char device_name[MAX_VDPA_NAME_LEN];
+	int i;
+
+	if (vdpa_device_num >= MAX_VHOST_DEVICE)
+		return -1;
+
+	for (i = 0; i < MAX_VHOST_DEVICE; i++) {
+		if (vdpa_devices[i] && is_same_vdpa_device(addr,
+					&vdpa_devices[i]->addr))
+			return -1;
+	}
+
+	for (i = 0; i < MAX_VHOST_DEVICE; i++) {
+		if (vdpa_devices[i] == NULL)
+			break;
+	}
+
+	sprintf(device_name, "vdpa-dev-%d", i);
+	dev = rte_zmalloc(device_name, sizeof(struct rte_vdpa_device),
+			RTE_CACHE_LINE_SIZE);
+	if (!dev)
+		return -1;
+
+	memcpy(&dev->addr, addr, sizeof(struct rte_vdpa_dev_addr));
+	dev->ops = ops;
+	vdpa_devices[i] = dev;
+	vdpa_device_num++;
+
+	return i;
+}
+
+int
+rte_vdpa_unregister_device(int did)
+{
+	if (did < 0 || did >= MAX_VHOST_DEVICE || vdpa_devices[did] == NULL)
+		return -1;
+
+	rte_free(vdpa_devices[did]);
+	vdpa_devices[did] = NULL;
+	vdpa_device_num--;
+
+	return did;
+}
+
+int
+rte_vdpa_find_device_id(struct rte_vdpa_dev_addr *addr)
+{
+	struct rte_vdpa_device *dev;
+	int i;
+
+	for (i = 0; i < MAX_VHOST_DEVICE; ++i) {
+		dev = vdpa_devices[i];
+		if (dev && is_same_vdpa_device(&dev->addr, addr) == 0)
+			return i;
+	}
+
+	return -1;
+}
+
+struct rte_vdpa_device *
+rte_vdpa_get_device(int did)
+{
+	if (did < 0 || did >= MAX_VHOST_DEVICE)
+		return NULL;
+
+	return vdpa_devices[did];
+}
-- 
2.13.6

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v5 3/5] vhost: add apis for datapath configuration
  2018-04-02 11:46 ` [PATCH v5 0/5] vhost: support selective datapath Zhihong Wang
  2018-04-02 11:46   ` [PATCH v5 1/5] vhost: export vhost feature definitions Zhihong Wang
  2018-04-02 11:46   ` [PATCH v5 2/5] vhost: support selective datapath Zhihong Wang
@ 2018-04-02 11:46   ` Zhihong Wang
  2018-04-03  8:07     ` Maxime Coquelin
  2018-04-02 11:46   ` [PATCH v5 4/5] vhost: adapt vhost lib for selective datapath Zhihong Wang
                     ` (2 subsequent siblings)
  5 siblings, 1 reply; 67+ messages in thread
From: Zhihong Wang @ 2018-04-02 11:46 UTC (permalink / raw)
  To: dev
  Cc: jianfeng.tan, tiwei.bie, maxime.coquelin, yliu, cunming.liang,
	xiao.w.wang, dan.daly, Zhihong Wang

This patch adds APIs for datapath configuration.

The did of the vhost-user socket can be set to identify the backend device,
in this case each vhost-user socket can have only 1 connection. The did is
set to -1 by default when the software datapath is used.

Signed-off-by: Zhihong Wang <zhihong.wang@intel.com>
---
Changes in v5:

 1. Rename APIs for better description.

 2. Improve sanity check.

---
Changes in v4:

 1. Remove the "engine" concept in the lib.

 lib/librte_vhost/rte_vhost.h           | 46 +++++++++++++++++++++++++++++
 lib/librte_vhost/rte_vhost_version.map |  4 +++
 lib/librte_vhost/socket.c              | 53 ++++++++++++++++++++++++++++++++++
 lib/librte_vhost/vhost.c               | 36 +++++++++++++++++++++++
 lib/librte_vhost/vhost.h               | 10 +++++++
 5 files changed, 149 insertions(+)

diff --git a/lib/librte_vhost/rte_vhost.h b/lib/librte_vhost/rte_vhost.h
index 671ea5053..8f35167f2 100644
--- a/lib/librte_vhost/rte_vhost.h
+++ b/lib/librte_vhost/rte_vhost.h
@@ -200,6 +200,41 @@ int rte_vhost_driver_register(const char *path, uint64_t flags);
 int rte_vhost_driver_unregister(const char *path);
 
 /**
+ * Set the vdpa device id, enforce single connection per socket
+ *
+ * @param path
+ *  The vhost-user socket file path
+ * @param did
+ *  Device id
+ * @return
+ *  0 on success, -1 on failure
+ */
+int __rte_experimental
+rte_vhost_driver_attach_vdpa_device(const char *path, int did);
+
+/**
+ * Unset the vdpa device id
+ *
+ * @param path
+ *  The vhost-user socket file path
+ * @return
+ *  0 on success, -1 on failure
+ */
+int __rte_experimental
+rte_vhost_driver_detach_vdpa_device(const char *path);
+
+/**
+ * Get the device id
+ *
+ * @param path
+ *  The vhost-user socket file path
+ * @return
+ *  Device id, -1 on failure
+ */
+int __rte_experimental
+rte_vhost_driver_get_vdpa_device_id(const char *path);
+
+/**
  * Set the feature bits the vhost-user driver supports.
  *
  * @param path
@@ -464,6 +499,17 @@ int rte_vhost_vring_call(int vid, uint16_t vring_idx);
  */
 uint32_t rte_vhost_rx_queue_count(int vid, uint16_t qid);
 
+/**
+ * Get vdpa device id for vhost device.
+ *
+ * @param vid
+ *  vhost device id
+ * @return
+ *  device id
+ */
+int __rte_experimental
+rte_vhost_get_vdpa_device_id(int vid);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/librte_vhost/rte_vhost_version.map b/lib/librte_vhost/rte_vhost_version.map
index d3453a2a7..e30285d7f 100644
--- a/lib/librte_vhost/rte_vhost_version.map
+++ b/lib/librte_vhost/rte_vhost_version.map
@@ -65,4 +65,8 @@ EXPERIMENTAL {
 	rte_vdpa_unregister_device;
 	rte_vdpa_find_device_id;
 	rte_vdpa_get_device;
+	rte_vhost_driver_attach_vdpa_device;
+	rte_vhost_driver_detach_vdpa_device;
+	rte_vhost_driver_get_vdpa_device_id;
+	rte_vhost_get_vdpa_device_id;
 } DPDK_18.02;
diff --git a/lib/librte_vhost/socket.c b/lib/librte_vhost/socket.c
index cfc31e179..c26940f7a 100644
--- a/lib/librte_vhost/socket.c
+++ b/lib/librte_vhost/socket.c
@@ -52,6 +52,13 @@ struct vhost_user_socket {
 	uint64_t supported_features;
 	uint64_t features;
 
+	/*
+	 * Device id to identify a specific backend device.
+	 * It's set to -1 for the default software implementation.
+	 * If valid, one socket can have 1 connection only.
+	 */
+	int vdpa_dev_id;
+
 	struct vhost_device_ops const *notify_ops;
 };
 
@@ -545,6 +552,52 @@ find_vhost_user_socket(const char *path)
 }
 
 int
+rte_vhost_driver_attach_vdpa_device(const char *path, int did)
+{
+	struct vhost_user_socket *vsocket;
+
+	if (rte_vdpa_get_device(did) == NULL)
+		return -1;
+
+	pthread_mutex_lock(&vhost_user.mutex);
+	vsocket = find_vhost_user_socket(path);
+	if (vsocket)
+		vsocket->vdpa_dev_id = did;
+	pthread_mutex_unlock(&vhost_user.mutex);
+
+	return vsocket ? 0 : -1;
+}
+
+int
+rte_vhost_driver_detach_vdpa_device(const char *path)
+{
+	struct vhost_user_socket *vsocket;
+
+	pthread_mutex_lock(&vhost_user.mutex);
+	vsocket = find_vhost_user_socket(path);
+	if (vsocket)
+		vsocket->vdpa_dev_id = -1;
+	pthread_mutex_unlock(&vhost_user.mutex);
+
+	return vsocket ? 0 : -1;
+}
+
+int
+rte_vhost_driver_get_vdpa_device_id(const char *path)
+{
+	struct vhost_user_socket *vsocket;
+	int did = -1;
+
+	pthread_mutex_lock(&vhost_user.mutex);
+	vsocket = find_vhost_user_socket(path);
+	if (vsocket)
+		did = vsocket->vdpa_dev_id;
+	pthread_mutex_unlock(&vhost_user.mutex);
+
+	return did;
+}
+
+int
 rte_vhost_driver_disable_features(const char *path, uint64_t features)
 {
 	struct vhost_user_socket *vsocket;
diff --git a/lib/librte_vhost/vhost.c b/lib/librte_vhost/vhost.c
index f6f12a03b..16b0f9a6f 100644
--- a/lib/librte_vhost/vhost.c
+++ b/lib/librte_vhost/vhost.c
@@ -283,6 +283,7 @@ vhost_new_device(void)
 	dev->vid = i;
 	dev->flags = VIRTIO_DEV_BUILTIN_VIRTIO_NET;
 	dev->slave_req_fd = -1;
+	dev->vdpa_dev_id = -1;
 
 	return i;
 }
@@ -311,6 +312,31 @@ vhost_destroy_device(int vid)
 }
 
 void
+vhost_attach_vdpa_device(int vid, int did)
+{
+	struct virtio_net *dev = get_device(vid);
+
+	if (dev == NULL)
+		return;
+
+	if (rte_vdpa_get_device(did) == NULL)
+		return;
+
+	dev->vdpa_dev_id = did;
+}
+
+void
+vhost_detach_vdpa_device(int vid)
+{
+	struct virtio_net *dev = get_device(vid);
+
+	if (dev == NULL)
+		return;
+
+	dev->vdpa_dev_id = -1;
+}
+
+void
 vhost_set_ifname(int vid, const char *if_name, unsigned int if_len)
 {
 	struct virtio_net *dev;
@@ -614,3 +640,13 @@ rte_vhost_rx_queue_count(int vid, uint16_t qid)
 
 	return *((volatile uint16_t *)&vq->avail->idx) - vq->last_avail_idx;
 }
+
+int rte_vhost_get_vdpa_device_id(int vid)
+{
+	struct virtio_net *dev = get_device(vid);
+
+	if (dev == NULL)
+		return -1;
+
+	return dev->vdpa_dev_id;
+}
diff --git a/lib/librte_vhost/vhost.h b/lib/librte_vhost/vhost.h
index 2e28e4026..27f40ea2b 100644
--- a/lib/librte_vhost/vhost.h
+++ b/lib/librte_vhost/vhost.h
@@ -19,6 +19,7 @@
 #include <rte_rwlock.h>
 
 #include "rte_vhost.h"
+#include "rte_vdpa.h"
 
 /* Used to indicate that the device is running on a data core */
 #define VIRTIO_DEV_RUNNING 1
@@ -239,6 +240,12 @@ struct virtio_net {
 	struct guest_page       *guest_pages;
 
 	int			slave_req_fd;
+
+	/*
+	 * Device id to identify a specific backend device.
+	 * It's set to -1 for the default software implementation.
+	 */
+	int			vdpa_dev_id;
 } __rte_cache_aligned;
 
 
@@ -365,6 +372,9 @@ void free_vq(struct vhost_virtqueue *vq);
 
 int alloc_vring_queue(struct virtio_net *dev, uint32_t vring_idx);
 
+void vhost_attach_vdpa_device(int vid, int did);
+void vhost_detach_vdpa_device(int vid);
+
 void vhost_set_ifname(int, const char *if_name, unsigned int if_len);
 void vhost_enable_dequeue_zero_copy(int vid);
 void vhost_set_builtin_virtio_net(int vid, bool enable);
-- 
2.13.6

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v5 4/5] vhost: adapt vhost lib for selective datapath
  2018-04-02 11:46 ` [PATCH v5 0/5] vhost: support selective datapath Zhihong Wang
                     ` (2 preceding siblings ...)
  2018-04-02 11:46   ` [PATCH v5 3/5] vhost: add apis for datapath configuration Zhihong Wang
@ 2018-04-02 11:46   ` Zhihong Wang
  2018-04-03  8:05     ` Maxime Coquelin
  2018-04-02 11:46   ` [PATCH v5 5/5] vhost: add apis for live migration Zhihong Wang
  2018-04-03  8:27   ` [PATCH v5 0/5] vhost: support selective datapath Maxime Coquelin
  5 siblings, 1 reply; 67+ messages in thread
From: Zhihong Wang @ 2018-04-02 11:46 UTC (permalink / raw)
  To: dev
  Cc: jianfeng.tan, tiwei.bie, maxime.coquelin, yliu, cunming.liang,
	xiao.w.wang, dan.daly, Zhihong Wang

This patch adapts vhost lib for selective datapath by calling device ops
at the corresponding stage.

Signed-off-by: Zhihong Wang <zhihong.wang@intel.com>
---
Changes in v5:

 1. Improve sanity check.

---
Changes in v4:

 1. Remove the "engine" concept in the lib.

---
Changes in v2:

 1. Ensure negotiated capabilities are supported in vhost-user lib.

 2. Configure the data path at the right time.

 lib/librte_vhost/rte_vhost.h           |  27 ++++++++
 lib/librte_vhost/rte_vhost_version.map |   2 +
 lib/librte_vhost/socket.c              | 113 +++++++++++++++++++++++++++++++--
 lib/librte_vhost/vhost.c               |   6 ++
 lib/librte_vhost/vhost.h               |   2 +
 lib/librte_vhost/vhost_user.c          |  70 ++++++++++++++++++--
 6 files changed, 211 insertions(+), 9 deletions(-)

diff --git a/lib/librte_vhost/rte_vhost.h b/lib/librte_vhost/rte_vhost.h
index 8f35167f2..fe0338d00 100644
--- a/lib/librte_vhost/rte_vhost.h
+++ b/lib/librte_vhost/rte_vhost.h
@@ -290,6 +290,33 @@ int rte_vhost_driver_disable_features(const char *path, uint64_t features);
 int rte_vhost_driver_get_features(const char *path, uint64_t *features);
 
 /**
+ * Get the protocol feature bits before feature negotiation.
+ *
+ * @param path
+ *  The vhost-user socket file path
+ * @param protocol_features
+ *  A pointer to store the queried protocol feature bits
+ * @return
+ *  0 on success, -1 on failure
+ */
+int __rte_experimental
+rte_vhost_driver_get_protocol_features(const char *path,
+		uint64_t *protocol_features);
+
+/**
+ * Get the queue number bits before feature negotiation.
+ *
+ * @param path
+ *  The vhost-user socket file path
+ * @param queue_num
+ *  A pointer to store the queried queue number bits
+ * @return
+ *  0 on success, -1 on failure
+ */
+int __rte_experimental
+rte_vhost_driver_get_queue_num(const char *path, uint32_t *queue_num);
+
+/**
  * Get the feature bits after negotiation
  *
  * @param vid
diff --git a/lib/librte_vhost/rte_vhost_version.map b/lib/librte_vhost/rte_vhost_version.map
index e30285d7f..55e0af7e7 100644
--- a/lib/librte_vhost/rte_vhost_version.map
+++ b/lib/librte_vhost/rte_vhost_version.map
@@ -69,4 +69,6 @@ EXPERIMENTAL {
 	rte_vhost_driver_detach_vdpa_device;
 	rte_vhost_driver_get_vdpa_device_id;
 	rte_vhost_get_vdpa_device_id;
+	rte_vhost_driver_get_protocol_features;
+	rte_vhost_driver_get_queue_num;
 } DPDK_18.02;
diff --git a/lib/librte_vhost/socket.c b/lib/librte_vhost/socket.c
index c26940f7a..9a44f0d9e 100644
--- a/lib/librte_vhost/socket.c
+++ b/lib/librte_vhost/socket.c
@@ -216,6 +216,8 @@ vhost_user_add_connection(int fd, struct vhost_user_socket *vsocket)
 
 	vhost_set_builtin_virtio_net(vid, vsocket->use_builtin_virtio_net);
 
+	vhost_attach_vdpa_device(vid, vsocket->vdpa_dev_id);
+
 	if (vsocket->dequeue_zero_copy)
 		vhost_enable_dequeue_zero_copy(vid);
 
@@ -665,20 +667,123 @@ int
 rte_vhost_driver_get_features(const char *path, uint64_t *features)
 {
 	struct vhost_user_socket *vsocket;
+	uint64_t vdpa_features;
+	struct rte_vdpa_device *vdpa_dev;
+	int did = -1;
+	int ret = 0;
 
 	pthread_mutex_lock(&vhost_user.mutex);
 	vsocket = find_vhost_user_socket(path);
-	if (vsocket)
+	if (!vsocket) {
+		RTE_LOG(ERR, VHOST_CONFIG,
+			"socket file %s is not registered yet.\n", path);
+		ret = -1;
+		goto unlock_exit;
+	}
+
+	did = vsocket->vdpa_dev_id;
+	vdpa_dev = rte_vdpa_get_device(did);
+	if (!vdpa_dev || !vdpa_dev->ops->get_features) {
 		*features = vsocket->features;
+		goto unlock_exit;
+	}
+
+	if (vdpa_dev->ops->get_features(did, &vdpa_features) < 0) {
+		RTE_LOG(ERR, VHOST_CONFIG,
+				"failed to get vdpa features "
+				"for socket file %s.\n", path);
+		ret = -1;
+		goto unlock_exit;
+	}
+
+	*features = vsocket->features & vdpa_features;
+
+unlock_exit:
 	pthread_mutex_unlock(&vhost_user.mutex);
+	return ret;
+}
 
+int
+rte_vhost_driver_get_protocol_features(const char *path,
+		uint64_t *protocol_features)
+{
+	struct vhost_user_socket *vsocket;
+	uint64_t vdpa_protocol_features;
+	struct rte_vdpa_device *vdpa_dev;
+	int did = -1;
+	int ret = 0;
+
+	pthread_mutex_lock(&vhost_user.mutex);
+	vsocket = find_vhost_user_socket(path);
 	if (!vsocket) {
 		RTE_LOG(ERR, VHOST_CONFIG,
 			"socket file %s is not registered yet.\n", path);
-		return -1;
-	} else {
-		return 0;
+		ret = -1;
+		goto unlock_exit;
 	}
+
+	did = vsocket->vdpa_dev_id;
+	vdpa_dev = rte_vdpa_get_device(did);
+	if (!vdpa_dev || !vdpa_dev->ops->get_protocol_features) {
+		*protocol_features = VHOST_USER_PROTOCOL_FEATURES;
+		goto unlock_exit;
+	}
+
+	if (vdpa_dev->ops->get_protocol_features(did,
+				&vdpa_protocol_features) < 0) {
+		RTE_LOG(ERR, VHOST_CONFIG,
+				"failed to get vdpa protocol features "
+				"for socket file %s.\n", path);
+		ret = -1;
+		goto unlock_exit;
+	}
+
+	*protocol_features = VHOST_USER_PROTOCOL_FEATURES
+		& vdpa_protocol_features;
+
+unlock_exit:
+	pthread_mutex_unlock(&vhost_user.mutex);
+	return ret;
+}
+
+int
+rte_vhost_driver_get_queue_num(const char *path, uint32_t *queue_num)
+{
+	struct vhost_user_socket *vsocket;
+	uint32_t vdpa_queue_num;
+	struct rte_vdpa_device *vdpa_dev;
+	int did = -1;
+	int ret = 0;
+
+	pthread_mutex_lock(&vhost_user.mutex);
+	vsocket = find_vhost_user_socket(path);
+	if (!vsocket) {
+		RTE_LOG(ERR, VHOST_CONFIG,
+			"socket file %s is not registered yet.\n", path);
+		ret = -1;
+		goto unlock_exit;
+	}
+
+	did = vsocket->vdpa_dev_id;
+	vdpa_dev = rte_vdpa_get_device(did);
+	if (!vdpa_dev || !vdpa_dev->ops->get_queue_num) {
+		*queue_num = VHOST_MAX_QUEUE_PAIRS;
+		goto unlock_exit;
+	}
+
+	if (vdpa_dev->ops->get_queue_num(did, &vdpa_queue_num) < 0) {
+		RTE_LOG(ERR, VHOST_CONFIG,
+				"failed to get vdpa queue number "
+				"for socket file %s.\n", path);
+		ret = -1;
+		goto unlock_exit;
+	}
+
+	*queue_num = RTE_MIN((uint32_t)VHOST_MAX_QUEUE_PAIRS, vdpa_queue_num);
+
+unlock_exit:
+	pthread_mutex_unlock(&vhost_user.mutex);
+	return ret;
 }
 
 /*
diff --git a/lib/librte_vhost/vhost.c b/lib/librte_vhost/vhost.c
index 16b0f9a6f..b1afd693a 100644
--- a/lib/librte_vhost/vhost.c
+++ b/lib/librte_vhost/vhost.c
@@ -296,11 +296,17 @@ void
 vhost_destroy_device(int vid)
 {
 	struct virtio_net *dev = get_device(vid);
+	struct rte_vdpa_device *vdpa_dev;
+	int did = -1;
 
 	if (dev == NULL)
 		return;
 
 	if (dev->flags & VIRTIO_DEV_RUNNING) {
+		did = dev->vdpa_dev_id;
+		vdpa_dev = rte_vdpa_get_device(did);
+		if (vdpa_dev && vdpa_dev->ops->dev_close)
+			vdpa_dev->ops->dev_close(dev->vid);
 		dev->flags &= ~VIRTIO_DEV_RUNNING;
 		dev->notify_ops->destroy_device(vid);
 	}
diff --git a/lib/librte_vhost/vhost.h b/lib/librte_vhost/vhost.h
index 27f40ea2b..d80d02c78 100644
--- a/lib/librte_vhost/vhost.h
+++ b/lib/librte_vhost/vhost.h
@@ -27,6 +27,8 @@
 #define VIRTIO_DEV_READY 2
 /* Used to indicate that the built-in vhost net device backend is enabled */
 #define VIRTIO_DEV_BUILTIN_VIRTIO_NET 4
+/* Used to indicate that the device has its own data path and configured */
+#define VIRTIO_DEV_VDPA_CONFIGURED 8
 
 /* Backend value set by guest. */
 #define VIRTIO_DEV_STOPPED -1
diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c
index 5c5361066..88785c095 100644
--- a/lib/librte_vhost/vhost_user.c
+++ b/lib/librte_vhost/vhost_user.c
@@ -133,7 +133,14 @@ vhost_user_set_owner(void)
 static int
 vhost_user_reset_owner(struct virtio_net *dev)
 {
+	struct rte_vdpa_device *vdpa_dev;
+	int did = -1;
+
 	if (dev->flags & VIRTIO_DEV_RUNNING) {
+		did = dev->vdpa_dev_id;
+		vdpa_dev = rte_vdpa_get_device(did);
+		if (vdpa_dev && vdpa_dev->ops->dev_close)
+			vdpa_dev->ops->dev_close(dev->vid);
 		dev->flags &= ~VIRTIO_DEV_RUNNING;
 		dev->notify_ops->destroy_device(dev->vid);
 	}
@@ -156,12 +163,26 @@ vhost_user_get_features(struct virtio_net *dev)
 }
 
 /*
+ * The queue number that we support are requested.
+ */
+static uint32_t
+vhost_user_get_queue_num(struct virtio_net *dev)
+{
+	uint32_t queue_num = 0;
+
+	rte_vhost_driver_get_queue_num(dev->ifname, &queue_num);
+	return queue_num;
+}
+
+/*
  * We receive the negotiated features supported by us and the virtio device.
  */
 static int
 vhost_user_set_features(struct virtio_net *dev, uint64_t features)
 {
 	uint64_t vhost_features = 0;
+	struct rte_vdpa_device *vdpa_dev;
+	int did = -1;
 
 	rte_vhost_driver_get_features(dev->ifname, &vhost_features);
 	if (features & ~vhost_features) {
@@ -191,6 +212,11 @@ vhost_user_set_features(struct virtio_net *dev, uint64_t features)
 			dev->notify_ops->features_changed(dev->vid, features);
 	}
 
+	did = dev->vdpa_dev_id;
+	vdpa_dev = rte_vdpa_get_device(did);
+	if (vdpa_dev && vdpa_dev->ops->set_features)
+		vdpa_dev->ops->set_features(dev->vid);
+
 	dev->features = features;
 	if (dev->features &
 		((1 << VIRTIO_NET_F_MRG_RXBUF) | (1ULL << VIRTIO_F_VERSION_1))) {
@@ -933,14 +959,21 @@ vhost_user_get_vring_base(struct virtio_net *dev,
 			  VhostUserMsg *msg)
 {
 	struct vhost_virtqueue *vq = dev->virtqueue[msg->payload.state.index];
+	struct rte_vdpa_device *vdpa_dev;
+	int did = -1;
 
 	/* We have to stop the queue (virtio) if it is running. */
 	if (dev->flags & VIRTIO_DEV_RUNNING) {
+		did = dev->vdpa_dev_id;
+		vdpa_dev = rte_vdpa_get_device(did);
+		if (vdpa_dev && vdpa_dev->ops->dev_close)
+			vdpa_dev->ops->dev_close(dev->vid);
 		dev->flags &= ~VIRTIO_DEV_RUNNING;
 		dev->notify_ops->destroy_device(dev->vid);
 	}
 
 	dev->flags &= ~VIRTIO_DEV_READY;
+	dev->flags &= ~VIRTIO_DEV_VDPA_CONFIGURED;
 
 	/* Here we are safe to get the last avail index */
 	msg->payload.state.num = vq->last_avail_idx;
@@ -983,16 +1016,24 @@ vhost_user_set_vring_enable(struct virtio_net *dev,
 			    VhostUserMsg *msg)
 {
 	int enable = (int)msg->payload.state.num;
+	int index = (int)msg->payload.state.index;
+	struct rte_vdpa_device *vdpa_dev;
+	int did = -1;
 
 	RTE_LOG(INFO, VHOST_CONFIG,
 		"set queue enable: %d to qp idx: %d\n",
-		enable, msg->payload.state.index);
+		enable, index);
+
+	did = dev->vdpa_dev_id;
+	vdpa_dev = rte_vdpa_get_device(did);
+	if (vdpa_dev && vdpa_dev->ops->set_vring_state)
+		vdpa_dev->ops->set_vring_state(dev->vid, index, enable);
 
 	if (dev->notify_ops->vring_state_changed)
 		dev->notify_ops->vring_state_changed(dev->vid,
-				msg->payload.state.index, enable);
+				index, enable);
 
-	dev->virtqueue[msg->payload.state.index]->enabled = enable;
+	dev->virtqueue[index]->enabled = enable;
 
 	return 0;
 }
@@ -1001,9 +1042,10 @@ static void
 vhost_user_get_protocol_features(struct virtio_net *dev,
 				 struct VhostUserMsg *msg)
 {
-	uint64_t features, protocol_features = VHOST_USER_PROTOCOL_FEATURES;
+	uint64_t features, protocol_features;
 
 	rte_vhost_driver_get_features(dev->ifname, &features);
+	rte_vhost_driver_get_protocol_features(dev->ifname, &protocol_features);
 
 	/*
 	 * REPLY_ACK protocol feature is only mandatory for now
@@ -1099,6 +1141,8 @@ static int
 vhost_user_send_rarp(struct virtio_net *dev, struct VhostUserMsg *msg)
 {
 	uint8_t *mac = (uint8_t *)&msg->payload.u64;
+	struct rte_vdpa_device *vdpa_dev;
+	int did = -1;
 
 	RTE_LOG(DEBUG, VHOST_CONFIG,
 		":: mac: %02x:%02x:%02x:%02x:%02x:%02x\n",
@@ -1114,6 +1158,10 @@ vhost_user_send_rarp(struct virtio_net *dev, struct VhostUserMsg *msg)
 	 */
 	rte_smp_wmb();
 	rte_atomic16_set(&dev->broadcast_rarp, 1);
+	did = dev->vdpa_dev_id;
+	vdpa_dev = rte_vdpa_get_device(did);
+	if (vdpa_dev && vdpa_dev->ops->migration_done)
+		vdpa_dev->ops->migration_done(dev->vid);
 
 	return 0;
 }
@@ -1375,6 +1423,8 @@ vhost_user_msg_handler(int vid, int fd)
 {
 	struct virtio_net *dev;
 	struct VhostUserMsg msg;
+	struct rte_vdpa_device *vdpa_dev;
+	int did = -1;
 	int ret;
 	int unlock_required = 0;
 
@@ -1527,7 +1577,7 @@ vhost_user_msg_handler(int vid, int fd)
 		break;
 
 	case VHOST_USER_GET_QUEUE_NUM:
-		msg.payload.u64 = VHOST_MAX_QUEUE_PAIRS;
+		msg.payload.u64 = (uint64_t)vhost_user_get_queue_num(dev);
 		msg.size = sizeof(msg.payload.u64);
 		send_vhost_reply(fd, &msg);
 		break;
@@ -1580,6 +1630,16 @@ vhost_user_msg_handler(int vid, int fd)
 		}
 	}
 
+	did = dev->vdpa_dev_id;
+	vdpa_dev = rte_vdpa_get_device(did);
+	if (vdpa_dev && virtio_is_ready(dev) &&
+			!(dev->flags & VIRTIO_DEV_VDPA_CONFIGURED) &&
+			msg.request.master == VHOST_USER_SET_VRING_ENABLE) {
+		if (vdpa_dev->ops->dev_conf)
+			vdpa_dev->ops->dev_conf(dev->vid);
+		dev->flags |= VIRTIO_DEV_VDPA_CONFIGURED;
+	}
+
 	return 0;
 }
 
-- 
2.13.6

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [PATCH v5 5/5] vhost: add apis for live migration
  2018-04-02 11:46 ` [PATCH v5 0/5] vhost: support selective datapath Zhihong Wang
                     ` (3 preceding siblings ...)
  2018-04-02 11:46   ` [PATCH v5 4/5] vhost: adapt vhost lib for selective datapath Zhihong Wang
@ 2018-04-02 11:46   ` Zhihong Wang
  2018-04-03  8:27   ` [PATCH v5 0/5] vhost: support selective datapath Maxime Coquelin
  5 siblings, 0 replies; 67+ messages in thread
From: Zhihong Wang @ 2018-04-02 11:46 UTC (permalink / raw)
  To: dev
  Cc: jianfeng.tan, tiwei.bie, maxime.coquelin, yliu, cunming.liang,
	xiao.w.wang, dan.daly, Zhihong Wang

This patch adds APIs to enable live migration for non-builtin data paths.

At src side, last_avail/used_idx from the device need to be set into the
virtio_net structure, and the log_base and log_size from the virtio_net
structure need to be set into the device.

At dst side, last_avail/used_idx need to be read from the virtio_net
structure and set into the device.

Signed-off-by: Zhihong Wang <zhihong.wang@intel.com>
Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>
---
 lib/librte_vhost/rte_vhost.h           | 51 +++++++++++++++++++++++++++
 lib/librte_vhost/rte_vhost_version.map |  3 ++
 lib/librte_vhost/vhost.c               | 63 ++++++++++++++++++++++++++++++++++
 3 files changed, 117 insertions(+)

diff --git a/lib/librte_vhost/rte_vhost.h b/lib/librte_vhost/rte_vhost.h
index fe0338d00..807da8c4b 100644
--- a/lib/librte_vhost/rte_vhost.h
+++ b/lib/librte_vhost/rte_vhost.h
@@ -527,6 +527,57 @@ int rte_vhost_vring_call(int vid, uint16_t vring_idx);
 uint32_t rte_vhost_rx_queue_count(int vid, uint16_t qid);
 
 /**
+ * Get log base and log size of the vhost device
+ *
+ * @param vid
+ *  vhost device ID
+ * @param log_base
+ *  vhost log base
+ * @param log_size
+ *  vhost log size
+ * @return
+ *  0 on success, -1 on failure
+ */
+int __rte_experimental
+rte_vhost_get_log_base(int vid, uint64_t *log_base, uint64_t *log_size);
+
+/**
+ * Get last_avail/used_idx of the vhost virtqueue
+ *
+ * @param vid
+ *  vhost device ID
+ * @param queue_id
+ *  vhost queue index
+ * @param last_avail_idx
+ *  vhost last_avail_idx to get
+ * @param last_used_idx
+ *  vhost last_used_idx to get
+ * @return
+ *  0 on success, -1 on failure
+ */
+int __rte_experimental
+rte_vhost_get_vring_base(int vid, uint16_t queue_id,
+		uint16_t *last_avail_idx, uint16_t *last_used_idx);
+
+/**
+ * Set last_avail/used_idx of the vhost virtqueue
+ *
+ * @param vid
+ *  vhost device ID
+ * @param queue_id
+ *  vhost queue index
+ * @param last_avail_idx
+ *  last_avail_idx to set
+ * @param last_used_idx
+ *  last_used_idx to set
+ * @return
+ *  0 on success, -1 on failure
+ */
+int __rte_experimental
+rte_vhost_set_vring_base(int vid, uint16_t queue_id,
+		uint16_t last_avail_idx, uint16_t last_used_idx);
+
+/**
  * Get vdpa device id for vhost device.
  *
  * @param vid
diff --git a/lib/librte_vhost/rte_vhost_version.map b/lib/librte_vhost/rte_vhost_version.map
index 55e0af7e7..9d3049342 100644
--- a/lib/librte_vhost/rte_vhost_version.map
+++ b/lib/librte_vhost/rte_vhost_version.map
@@ -71,4 +71,7 @@ EXPERIMENTAL {
 	rte_vhost_get_vdpa_device_id;
 	rte_vhost_driver_get_protocol_features;
 	rte_vhost_driver_get_queue_num;
+	rte_vhost_get_log_base;
+	rte_vhost_get_vring_base;
+	rte_vhost_set_vring_base;
 } DPDK_18.02;
diff --git a/lib/librte_vhost/vhost.c b/lib/librte_vhost/vhost.c
index b1afd693a..1f17cdd75 100644
--- a/lib/librte_vhost/vhost.c
+++ b/lib/librte_vhost/vhost.c
@@ -656,3 +656,66 @@ int rte_vhost_get_vdpa_device_id(int vid)
 
 	return dev->vdpa_dev_id;
 }
+
+int rte_vhost_get_log_base(int vid, uint64_t *log_base,
+		uint64_t *log_size)
+{
+	struct virtio_net *dev = get_device(vid);
+
+	if (!dev)
+		return -1;
+
+	if (unlikely(!(dev->flags & VIRTIO_DEV_BUILTIN_VIRTIO_NET))) {
+		RTE_LOG(ERR, VHOST_DATA,
+			"(%d) %s: built-in vhost net backend is disabled.\n",
+			dev->vid, __func__);
+		return -1;
+	}
+
+	*log_base = dev->log_base;
+	*log_size = dev->log_size;
+
+	return 0;
+}
+
+int rte_vhost_get_vring_base(int vid, uint16_t queue_id,
+		uint16_t *last_avail_idx, uint16_t *last_used_idx)
+{
+	struct virtio_net *dev = get_device(vid);
+
+	if (!dev)
+		return -1;
+
+	if (unlikely(!(dev->flags & VIRTIO_DEV_BUILTIN_VIRTIO_NET))) {
+		RTE_LOG(ERR, VHOST_DATA,
+			"(%d) %s: built-in vhost net backend is disabled.\n",
+			dev->vid, __func__);
+		return -1;
+	}
+
+	*last_avail_idx = dev->virtqueue[queue_id]->last_avail_idx;
+	*last_used_idx = dev->virtqueue[queue_id]->last_used_idx;
+
+	return 0;
+}
+
+int rte_vhost_set_vring_base(int vid, uint16_t queue_id,
+		uint16_t last_avail_idx, uint16_t last_used_idx)
+{
+	struct virtio_net *dev = get_device(vid);
+
+	if (!dev)
+		return -1;
+
+	if (unlikely(!(dev->flags & VIRTIO_DEV_BUILTIN_VIRTIO_NET))) {
+		RTE_LOG(ERR, VHOST_DATA,
+			"(%d) %s: built-in vhost net backend is disabled.\n",
+			dev->vid, __func__);
+		return -1;
+	}
+
+	dev->virtqueue[queue_id]->last_avail_idx = last_avail_idx;
+	dev->virtqueue[queue_id]->last_used_idx = last_used_idx;
+
+	return 0;
+}
-- 
2.13.6

^ permalink raw reply related	[flat|nested] 67+ messages in thread

* Re: [PATCH v4 4/5] vhost: adapt vhost lib for selective datapath
  2018-03-31  7:35     ` Maxime Coquelin
@ 2018-04-02 11:52       ` Wang, Zhihong
  0 siblings, 0 replies; 67+ messages in thread
From: Wang, Zhihong @ 2018-04-02 11:52 UTC (permalink / raw)
  To: Maxime Coquelin, dev
  Cc: Tan, Jianfeng, Bie, Tiwei, yliu, Liang, Cunming, Wang, Xiao W, Daly, Dan



> -----Original Message-----
> From: Maxime Coquelin [mailto:maxime.coquelin@redhat.com]
> Sent: Saturday, March 31, 2018 3:36 PM
> To: Wang, Zhihong <zhihong.wang@intel.com>; dev@dpdk.org
> Cc: Tan, Jianfeng <jianfeng.tan@intel.com>; Bie, Tiwei
> <tiwei.bie@intel.com>; yliu@fridaylinux.org; Liang, Cunming
> <cunming.liang@intel.com>; Wang, Xiao W <xiao.w.wang@intel.com>; Daly,
> Dan <dan.daly@intel.com>
> Subject: Re: [PATCH v4 4/5] vhost: adapt vhost lib for selective datapath
> 
> 
> 
> On 03/10/2018 11:01 AM, Zhihong Wang wrote:
> > This patch adapts vhost lib for selective datapath by calling device ops
> > at the corresponding stage.
> >
> > Signed-off-by: Zhihong Wang <zhihong.wang@intel.com>
> > ---
> > Changes in v4:
> >
> >   1. Remove the "engine" concept in the lib.
> >
> > ---
> > Changes in v2:
> >
> >   1. Ensure negotiated capabilities are supported in vhost-user lib.
> >
> >   2. Configure the data path at the right time.
> >
> >   lib/librte_vhost/rte_vhost.h           | 27 ++++++++++
> >   lib/librte_vhost/rte_vhost_version.map |  2 +
> >   lib/librte_vhost/socket.c              | 94
> ++++++++++++++++++++++++++++++++--
> >   lib/librte_vhost/vhost.c               |  3 ++
> >   lib/librte_vhost/vhost.h               |  2 +
> >   lib/librte_vhost/vhost_user.c          | 54 +++++++++++++++++--
> >   6 files changed, 172 insertions(+), 10 deletions(-)
> >
> > diff --git a/lib/librte_vhost/rte_vhost.h b/lib/librte_vhost/rte_vhost.h
> > index d50f4c67d..3c3334d3e 100644
> > --- a/lib/librte_vhost/rte_vhost.h
> > +++ b/lib/librte_vhost/rte_vhost.h
> > @@ -279,6 +279,33 @@ int rte_vhost_driver_disable_features(const char
> *path, uint64_t features);
> >   int rte_vhost_driver_get_features(const char *path, uint64_t *features);
> >
> >   /**
> > + * Get the protocol feature bits before feature negotiation.
> > + *
> > + * @param path
> > + *  The vhost-user socket file path
> > + * @param protocol_features
> > + *  A pointer to store the queried protocol feature bits
> > + * @return
> > + *  0 on success, -1 on failure
> > + */
> > +int __rte_experimental
> > +rte_vhost_driver_get_protocol_features(const char *path,
> > +		uint64_t *protocol_features);
> > +
> > +/**
> > + * Get the queue number bits before feature negotiation.
> > + *
> > + * @param path
> > + *  The vhost-user socket file path
> > + * @param queue_num
> > + *  A pointer to store the queried queue number bits
> > + * @return
> > + *  0 on success, -1 on failure
> > + */
> > +int __rte_experimental
> > +rte_vhost_driver_get_queue_num(const char *path, uint32_t
> *queue_num);
> > +
> > +/**
> >    * Get the feature bits after negotiation
> >    *
> >    * @param vid
> > diff --git a/lib/librte_vhost/rte_vhost_version.map
> b/lib/librte_vhost/rte_vhost_version.map
> > index 6e2d5364a..812ccd72b 100644
> > --- a/lib/librte_vhost/rte_vhost_version.map
> > +++ b/lib/librte_vhost/rte_vhost_version.map
> > @@ -67,4 +67,6 @@ EXPERIMENTAL {
> >   	rte_vhost_driver_set_vdpa_did;
> >   	rte_vhost_driver_get_vdpa_did;
> >   	rte_vhost_get_vdpa_did;
> > +	rte_vhost_driver_get_protocol_features;
> > +	rte_vhost_driver_get_queue_num;
> >   } DPDK_18.02;
> > diff --git a/lib/librte_vhost/socket.c b/lib/librte_vhost/socket.c
> > index 3d58da94e..ba7b422a0 100644
> > --- a/lib/librte_vhost/socket.c
> > +++ b/lib/librte_vhost/socket.c
> > @@ -216,6 +216,8 @@ vhost_user_add_connection(int fd, struct
> vhost_user_socket *vsocket)
> >
> >   	vhost_set_builtin_virtio_net(vid, vsocket->use_builtin_virtio_net);
> >
> > +	vhost_set_vdpa_did(vid, vsocket->did);
> > +
> >   	if (vsocket->dequeue_zero_copy)
> >   		vhost_enable_dequeue_zero_copy(vid);
> >
> > @@ -648,20 +650,102 @@ int
> >   rte_vhost_driver_get_features(const char *path, uint64_t *features)
> >   {
> >   	struct vhost_user_socket *vsocket;
> > +	uint64_t vdpa_features;
> > +	int did = -1;
> > +	int ret = 0;
> >
> >   	pthread_mutex_lock(&vhost_user.mutex);
> >   	vsocket = find_vhost_user_socket(path);
> > -	if (vsocket)
> > -		*features = vsocket->features;
> > +	if (vsocket) {
> > +		did = vsocket->did;
> > +		if (did < 0 || vdpa_devices[did]->ops->feature_get == NULL)
> > +			*features = vsocket->features;
> > +		else if (vdpa_devices[did]->ops->feature_get(did,
> > +					&vdpa_features) < 0) {
> > +			RTE_LOG(ERR, VHOST_CONFIG,
> > +					"failed to get vdpa features "
> > +					"for socket file %s.\n", path);
> > +			ret = -1;
> > +		} else
> > +			*features = vsocket->features & vdpa_features;
> 
> It seems correct but it is not very intuitive.
> Also, you have to put braces everywhere if one of the if/else if/else
> have some.

Noted.

> 
> What about something like this:
> 
> rte_vhost_driver_get_features(const char *path, uint64_t *features)
> {
> 	struct vhost_user_socket *vsocket;
> 	uint64_t vdpa_features;
> 	int did = -1;
> 	int ret = 0;
> 	struct rte_vdpa_device *vdpa_dev;
> 
> 	pthread_mutex_lock(&vhost_user.mutex);
> 	vsocket = find_vhost_user_socket(path);
> 	if (!vsocket) {
> 		RTE_LOG(ERR, VHOST_CONFIG,
> 			"socket file %s is not registered yet.\n"
> 			, path);
> 		ret = -1;
> 		goto out_unlock;
> 	}
> 
> 	did = vsocket->did;
> 	vdpa_dev = rte_vdpa_device_get(did);
> 	if (!vdpa_dev || !vdpa->ops->feature_get) {
> 		*features = vsocket->features;
> 		goto out_unlock;
> 	}
> 
> 	if (vdpa_dev->ops->feature_get(did, &vdpa_features) < 0) {
> 		RTE_LOG(ERR, VHOST_CONFIG,
> 				"failed to get vdpa features "
> 				"for socket file %s.\n", path);
> 		ret = -1;
> 		goto out_unlock;
> 	}
> 
> 	*features = vsocket->features & vdpa_features;
> 
> out_unlock:
> 	pthread_mutex_unlock(&vhost_user.mutex);
> 	return ret;
> }
> 
> with in rte_vdpa.h:
> 
> static inline struct rte_vdpa_device *
> rte_vdpa_device_get(int did)
> {
> 	if (did < 0 || did >= MAX_VHOST_DEVICE)
> 		return NULL;
> 
> 	return vdpa_devices[did];
> }
> 
> 
> Doing this you have 3 checks in 1, so you avoid NULL pointer
> de-referencing if did > 0 but invalid.

Yeah it's clearer to do it this way.

> 
> Same logic applies to functions below:
> 
> > +	} else {
> > +		RTE_LOG(ERR, VHOST_CONFIG,
> > +			"socket file %s is not registered yet.\n", path);
> > +		ret = -1;
> > +	}
> >   	pthread_mutex_unlock(&vhost_user.mutex);
> >
> > -	if (!vsocket) {
> > +	return ret;
> > +}
> > +
> > +int
> > +rte_vhost_driver_get_protocol_features(const char *path,
> > +		uint64_t *protocol_features)
> > +{
> > +	struct vhost_user_socket *vsocket;
> > +	uint64_t vdpa_protocol_features;
> > +	int did = -1;
> > +	int ret = 0;
> > +
> > +	pthread_mutex_lock(&vhost_user.mutex);
> > +	vsocket = find_vhost_user_socket(path);
> > +	if (vsocket) {
> > +		did = vsocket->did;
> > +		if (did < 0 || vdpa_devices[did]->ops->protocol_feature_get
> > +				== NULL)
> > +			*protocol_features =
> VHOST_USER_PROTOCOL_FEATURES;
> > +		else if (vdpa_devices[did]->ops->protocol_feature_get(did,
> > +					&vdpa_protocol_features) < 0) {
> > +			RTE_LOG(ERR, VHOST_CONFIG,
> > +					"failed to get vdpa protocol features "
> > +					"for socket file %s.\n", path);
> > +			ret = -1;
> > +		} else
> > +			*protocol_features =
> VHOST_USER_PROTOCOL_FEATURES
> > +				& vdpa_protocol_features;
> > +	} else {
> >   		RTE_LOG(ERR, VHOST_CONFIG,
> >   			"socket file %s is not registered yet.\n", path);
> > -		return -1;
> > +		ret = -1;
> > +	}
> > +	pthread_mutex_unlock(&vhost_user.mutex);
> > +
> > +	return ret;
> > +}
> > +
> > +int
> > +rte_vhost_driver_get_queue_num(const char *path,
> > +		uint32_t *queue_num)
> > +{
> > +	struct vhost_user_socket *vsocket;
> > +	uint32_t vdpa_queue_num;
> > +	int did = -1;
> > +	int ret = 0;
> > +
> > +	pthread_mutex_lock(&vhost_user.mutex);
> > +	vsocket = find_vhost_user_socket(path);
> > +	if (vsocket) {
> > +		did = vsocket->did;
> > +		if (did < 0 || vdpa_devices[did]->ops->queue_num_get ==
> NULL)
> > +			*queue_num = VHOST_MAX_QUEUE_PAIRS;
> > +		else if (vdpa_devices[did]->ops->queue_num_get(
> > +					did, &vdpa_queue_num) < 0) {
> > +			RTE_LOG(ERR, VHOST_CONFIG,
> > +					"failed to get vdpa queue number "
> > +					"for socket file %s.\n", path);
> > +			ret = -1;
> > +		} else if (vdpa_queue_num > VHOST_MAX_QUEUE_PAIRS)
> > +			*queue_num = VHOST_MAX_QUEUE_PAIRS;
> > +		else
> > +			*queue_num = vdpa_queue_num;
> >   	} else {
> > -		return 0;
> > +		RTE_LOG(ERR, VHOST_CONFIG,
> > +			"socket file %s is not registered yet.\n", path);
> > +		ret = -1;
> >   	}
> > +	pthread_mutex_unlock(&vhost_user.mutex);
> > +
> > +	return ret;
> >   }
> >
> >   /*
> > diff --git a/lib/librte_vhost/vhost.c b/lib/librte_vhost/vhost.c
> > index 1740cc1ab..66b6b492f 100644
> > --- a/lib/librte_vhost/vhost.c
> > +++ b/lib/librte_vhost/vhost.c
> > @@ -296,11 +296,14 @@ void
> >   vhost_destroy_device(int vid)
> >   {
> >   	struct virtio_net *dev = get_device(vid);
> > +	int did = dev->did;
> >
> >   	if (dev == NULL)
> >   		return;
> >
> >   	if (dev->flags & VIRTIO_DEV_RUNNING) {
> > +		if (did >= 0 && vdpa_devices[did]->ops->dev_close)
> > +			vdpa_devices[did]->ops->dev_close(dev->vid);
> 
> Ditto.

Ok.

> 
> >   		dev->flags &= ~VIRTIO_DEV_RUNNING;
> >   		dev->notify_ops->destroy_device(vid);
> >   	}
> > diff --git a/lib/librte_vhost/vhost.h b/lib/librte_vhost/vhost.h
> > index 2970c1eab..30e8a0cfe 100644
> > --- a/lib/librte_vhost/vhost.h
> > +++ b/lib/librte_vhost/vhost.h
> > @@ -27,6 +27,8 @@
> >   #define VIRTIO_DEV_READY 2
> >   /* Used to indicate that the built-in vhost net device backend is enabled
> */
> >   #define VIRTIO_DEV_BUILTIN_VIRTIO_NET 4
> > +/* Used to indicate that the device has its own data path and configured
> */
> > +#define VIRTIO_DEV_VDPA_CONFIGURED 8
> >
> >   /* Backend value set by guest. */
> >   #define VIRTIO_DEV_STOPPED -1
> > diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c
> > index 5c5361066..5049c8e55 100644
> > --- a/lib/librte_vhost/vhost_user.c
> > +++ b/lib/librte_vhost/vhost_user.c
> > @@ -133,7 +133,11 @@ vhost_user_set_owner(void)
> >   static int
> >   vhost_user_reset_owner(struct virtio_net *dev)
> >   {
> > +	int did = dev->did;
> > +
> >   	if (dev->flags & VIRTIO_DEV_RUNNING) {
> > +		if (did >= 0 && vdpa_devices[did]->ops->dev_close)
> > +			vdpa_devices[did]->ops->dev_close(dev->vid);
> 
> Ditto.

Ok.

> 
> >   		dev->flags &= ~VIRTIO_DEV_RUNNING;
> >   		dev->notify_ops->destroy_device(dev->vid);
> >   	}
> > @@ -156,12 +160,25 @@ vhost_user_get_features(struct virtio_net *dev)
> >   }
> >
> >   /*
> > + * The queue number that we support are requested.
> > + */
> > +static uint32_t
> > +vhost_user_get_queue_num(struct virtio_net *dev)
> > +{
> > +	uint32_t queue_num = 0;
> > +
> > +	rte_vhost_driver_get_queue_num(dev->ifname, &queue_num);
> > +	return (uint64_t)queue_num;
> > +}
> > +
> > +/*
> >    * We receive the negotiated features supported by us and the virtio
> device.
> >    */
> >   static int
> >   vhost_user_set_features(struct virtio_net *dev, uint64_t features)
> >   {
> >   	uint64_t vhost_features = 0;
> > +	int did = dev->did;
> >
> >   	rte_vhost_driver_get_features(dev->ifname, &vhost_features);
> >   	if (features & ~vhost_features) {
> > @@ -191,6 +208,9 @@ vhost_user_set_features(struct virtio_net *dev,
> uint64_t features)
> >   			dev->notify_ops->features_changed(dev->vid,
> features);
> >   	}
> >
> > +	if (did >= 0 && vdpa_devices[did]->ops->feature_set)
> > +		vdpa_devices[did]->ops->feature_set(dev->vid);
> > +
> >   	dev->features = features;
> >   	if (dev->features &
> >   		((1 << VIRTIO_NET_F_MRG_RXBUF) | (1ULL <<
> VIRTIO_F_VERSION_1))) {
> > @@ -933,14 +953,18 @@ vhost_user_get_vring_base(struct virtio_net
> *dev,
> >   			  VhostUserMsg *msg)
> >   {
> >   	struct vhost_virtqueue *vq = dev->virtqueue[msg-
> >payload.state.index];
> > +	int did = dev->did;
> >
> >   	/* We have to stop the queue (virtio) if it is running. */
> >   	if (dev->flags & VIRTIO_DEV_RUNNING) {
> > +		if (did >= 0 && vdpa_devices[did]->ops->dev_close)
> > +			vdpa_devices[did]->ops->dev_close(dev->vid);
> >   		dev->flags &= ~VIRTIO_DEV_RUNNING;
> >   		dev->notify_ops->destroy_device(dev->vid);
> >   	}
> >
> >   	dev->flags &= ~VIRTIO_DEV_READY;
> > +	dev->flags &= ~VIRTIO_DEV_VDPA_CONFIGURED;
> >
> >   	/* Here we are safe to get the last avail index */
> >   	msg->payload.state.num = vq->last_avail_idx;
> > @@ -983,16 +1007,22 @@ vhost_user_set_vring_enable(struct virtio_net
> *dev,
> >   			    VhostUserMsg *msg)
> >   {
> >   	int enable = (int)msg->payload.state.num;
> > +	int index = (int)msg->payload.state.index;
> > +	int did = dev->did;
> >
> >   	RTE_LOG(INFO, VHOST_CONFIG,
> >   		"set queue enable: %d to qp idx: %d\n",
> > -		enable, msg->payload.state.index);
> > +		enable, index);
> > +
> > +	if (did >= 0 && vdpa_devices[did]->ops->vring_state_set)
> > +		vdpa_devices[did]->ops->vring_state_set(dev->vid,
> > +				index, enable);
> >
> >   	if (dev->notify_ops->vring_state_changed)
> >   		dev->notify_ops->vring_state_changed(dev->vid,
> > -				msg->payload.state.index, enable);
> > +				index, enable);
> >
> > -	dev->virtqueue[msg->payload.state.index]->enabled = enable;
> > +	dev->virtqueue[index]->enabled = enable;
> >
> >   	return 0;
> >   }
> > @@ -1001,9 +1031,10 @@ static void
> >   vhost_user_get_protocol_features(struct virtio_net *dev,
> >   				 struct VhostUserMsg *msg)
> >   {
> > -	uint64_t features, protocol_features =
> VHOST_USER_PROTOCOL_FEATURES;
> > +	uint64_t features, protocol_features;
> >
> >   	rte_vhost_driver_get_features(dev->ifname, &features);
> > +	rte_vhost_driver_get_protocol_features(dev->ifname,
> &protocol_features);
> >
> >   	/*
> >   	 * REPLY_ACK protocol feature is only mandatory for now
> > @@ -1099,6 +1130,7 @@ static int
> >   vhost_user_send_rarp(struct virtio_net *dev, struct VhostUserMsg *msg)
> >   {
> >   	uint8_t *mac = (uint8_t *)&msg->payload.u64;
> > +	int did = dev->did;
> >
> >   	RTE_LOG(DEBUG, VHOST_CONFIG,
> >   		":: mac: %02x:%02x:%02x:%02x:%02x:%02x\n",
> > @@ -1114,6 +1146,8 @@ vhost_user_send_rarp(struct virtio_net *dev,
> struct VhostUserMsg *msg)
> >   	 */
> >   	rte_smp_wmb();
> >   	rte_atomic16_set(&dev->broadcast_rarp, 1);
> > +	if (did >= 0 && vdpa_devices[did]->ops->migration_done)
> > +		vdpa_devices[did]->ops->migration_done(dev->vid);
> >
> >   	return 0;
> >   }
> > @@ -1375,6 +1409,7 @@ vhost_user_msg_handler(int vid, int fd)
> >   {
> >   	struct virtio_net *dev;
> >   	struct VhostUserMsg msg;
> > +	int did;
> >   	int ret;
> >   	int unlock_required = 0;
> >
> > @@ -1527,7 +1562,7 @@ vhost_user_msg_handler(int vid, int fd)
> >   		break;
> >
> >   	case VHOST_USER_GET_QUEUE_NUM:
> > -		msg.payload.u64 = VHOST_MAX_QUEUE_PAIRS;
> > +		msg.payload.u64 =
> (uint64_t)vhost_user_get_queue_num(dev);
> >   		msg.size = sizeof(msg.payload.u64);
> >   		send_vhost_reply(fd, &msg);
> >   		break;
> > @@ -1580,6 +1615,15 @@ vhost_user_msg_handler(int vid, int fd)
> >   		}
> >   	}
> >
> > +	did = dev->did;
> > +	if (did >= 0 && virtio_is_ready(dev) &&
> > +			!(dev->flags & VIRTIO_DEV_VDPA_CONFIGURED)
> &&
> > +			msg.request.master ==
> VHOST_USER_SET_VRING_ENABLE) {
> > +		if (vdpa_devices[did]->ops->dev_conf)
> > +			vdpa_devices[did]->ops->dev_conf(vid);
> > +		dev->flags |= VIRTIO_DEV_VDPA_CONFIGURED;
> > +	}
> > +
> >   	return 0;
> >   }
> >
> >
> 
> Other than the code refactoring I propose, the patch looks good to me.

Really appreciate your detailed review and comments!
I'll send out v5 soon.

-Zhihong

> 
> Thanks!
> Maxime

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v5 2/5] vhost: support selective datapath
  2018-04-02 11:46   ` [PATCH v5 2/5] vhost: support selective datapath Zhihong Wang
@ 2018-04-03  8:02     ` Maxime Coquelin
  2018-04-15 17:39       ` Thomas Monjalon
  2018-04-03  8:19     ` Maxime Coquelin
  1 sibling, 1 reply; 67+ messages in thread
From: Maxime Coquelin @ 2018-04-03  8:02 UTC (permalink / raw)
  To: Zhihong Wang, dev
  Cc: jianfeng.tan, tiwei.bie, yliu, cunming.liang, xiao.w.wang, dan.daly



On 04/02/2018 01:46 PM, Zhihong Wang wrote:
> This patch set introduces support for selective datapath in DPDK vhost-user
> lib. vDPA stands for vhost Data Path Acceleration. The idea is to support
> virtio ring compatible devices to serve virtio driver directly to enable
> datapath acceleration.
> 
> A set of device ops is defined for device specific operations:
> 
>       a. get_queue_num: Called to get supported queue number of the device.
> 
>       b. get_features: Called to get supported features of the device.
> 
>       c. get_protocol_features: Called to get supported protocol features of
>          the device.
> 
>       d. dev_conf: Called to configure the actual device when the virtio
>          device becomes ready.
> 
>       e. dev_close: Called to close the actual device when the virtio device
>          is stopped.
> 
>       f. set_vring_state: Called to change the state of the vring in the
>          actual device when vring state changes.
> 
>       g. set_features: Called to set the negotiated features to device.
> 
>       h. migration_done: Called to allow the device to response to RARP
>          sending.
> 
>       i. get_vfio_group_fd: Called to get the VFIO group fd of the device.
> 
>       j. get_vfio_device_fd: Called to get the VFIO device fd of the device.
> 
>       k. get_notify_area: Called to get the notify area info of the queue.
> 
> Signed-off-by: Zhihong Wang <zhihong.wang@intel.com>
> ---
> Changes in v5:
> 
>   1. Rename the vDPA device ops to follow convention.
> 
>   2. Improve sanity check.
> 
> ---
> Changes in v4:
> 
>   1. Remove the "engine" concept in the lib.
> 
> ---
> Changes in v2:
> 
>   1. Add VFIO related vDPA device ops.
> 
>   lib/librte_vhost/Makefile              |   4 +-
>   lib/librte_vhost/rte_vdpa.h            |  87 +++++++++++++++++++++++++
>   lib/librte_vhost/rte_vhost_version.map |   7 ++
>   lib/librte_vhost/vdpa.c                | 115 +++++++++++++++++++++++++++++++++
>   4 files changed, 211 insertions(+), 2 deletions(-)
>   create mode 100644 lib/librte_vhost/rte_vdpa.h
>   create mode 100644 lib/librte_vhost/vdpa.c
> 


With the fix you suggested:
Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>

Thanks!
Maxime

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v5 4/5] vhost: adapt vhost lib for selective datapath
  2018-04-02 11:46   ` [PATCH v5 4/5] vhost: adapt vhost lib for selective datapath Zhihong Wang
@ 2018-04-03  8:05     ` Maxime Coquelin
  0 siblings, 0 replies; 67+ messages in thread
From: Maxime Coquelin @ 2018-04-03  8:05 UTC (permalink / raw)
  To: Zhihong Wang, dev
  Cc: jianfeng.tan, tiwei.bie, yliu, cunming.liang, xiao.w.wang, dan.daly



On 04/02/2018 01:46 PM, Zhihong Wang wrote:
> This patch adapts vhost lib for selective datapath by calling device ops
> at the corresponding stage.
> 
> Signed-off-by: Zhihong Wang<zhihong.wang@intel.com>
> ---
> Changes in v5:
> 
>   1. Improve sanity check.
> 
> ---
> Changes in v4:
> 
>   1. Remove the "engine" concept in the lib.
> 
> ---
> Changes in v2:
> 
>   1. Ensure negotiated capabilities are supported in vhost-user lib.
> 
>   2. Configure the data path at the right time.
> 
>   lib/librte_vhost/rte_vhost.h           |  27 ++++++++
>   lib/librte_vhost/rte_vhost_version.map |   2 +
>   lib/librte_vhost/socket.c              | 113 +++++++++++++++++++++++++++++++--
>   lib/librte_vhost/vhost.c               |   6 ++
>   lib/librte_vhost/vhost.h               |   2 +
>   lib/librte_vhost/vhost_user.c          |  70 ++++++++++++++++++--
>   6 files changed, 211 insertions(+), 9 deletions(-)

Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>

Thanks,
Maxime

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v5 3/5] vhost: add apis for datapath configuration
  2018-04-02 11:46   ` [PATCH v5 3/5] vhost: add apis for datapath configuration Zhihong Wang
@ 2018-04-03  8:07     ` Maxime Coquelin
  0 siblings, 0 replies; 67+ messages in thread
From: Maxime Coquelin @ 2018-04-03  8:07 UTC (permalink / raw)
  To: Zhihong Wang, dev
  Cc: jianfeng.tan, tiwei.bie, yliu, cunming.liang, xiao.w.wang, dan.daly



On 04/02/2018 01:46 PM, Zhihong Wang wrote:
> This patch adds APIs for datapath configuration.
> 
> The did of the vhost-user socket can be set to identify the backend device,
> in this case each vhost-user socket can have only 1 connection. The did is
> set to -1 by default when the software datapath is used.
> 
> Signed-off-by: Zhihong Wang<zhihong.wang@intel.com>
> ---
> Changes in v5:
> 
>   1. Rename APIs for better description.
> 
>   2. Improve sanity check.
> 
> ---
> Changes in v4:
> 
>   1. Remove the "engine" concept in the lib.
> 
>   lib/librte_vhost/rte_vhost.h           | 46 +++++++++++++++++++++++++++++
>   lib/librte_vhost/rte_vhost_version.map |  4 +++
>   lib/librte_vhost/socket.c              | 53 ++++++++++++++++++++++++++++++++++
>   lib/librte_vhost/vhost.c               | 36 +++++++++++++++++++++++
>   lib/librte_vhost/vhost.h               | 10 +++++++
>   5 files changed, 149 insertions(+)

Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>

Thanks,
Maxime

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v5 2/5] vhost: support selective datapath
  2018-04-02 11:46   ` [PATCH v5 2/5] vhost: support selective datapath Zhihong Wang
  2018-04-03  8:02     ` Maxime Coquelin
@ 2018-04-03  8:19     ` Maxime Coquelin
  2018-04-03 14:35       ` Wang, Zhihong
  1 sibling, 1 reply; 67+ messages in thread
From: Maxime Coquelin @ 2018-04-03  8:19 UTC (permalink / raw)
  To: Zhihong Wang, dev
  Cc: jianfeng.tan, tiwei.bie, yliu, cunming.liang, xiao.w.wang, dan.daly



On 04/02/2018 01:46 PM, Zhihong Wang wrote:
> +int
> +rte_vdpa_register_device(struct rte_vdpa_dev_addr *addr,
> +		struct rte_vdpa_dev_ops *ops)
> +{
> +	struct rte_vdpa_device *dev;
> +	char device_name[MAX_VDPA_NAME_LEN];
> +	int i;
> +
> +	if (vdpa_device_num >= MAX_VHOST_DEVICE)
> +		return -1;
> +
> +	for (i = 0; i < MAX_VHOST_DEVICE; i++) {
> +		if (vdpa_devices[i] && is_same_vdpa_device(addr,
> +					&vdpa_devices[i]->addr))
> +			return -1;
> +	}

For consistency, I changed above check to look like same one in 
_find_device_id:

	for (i = 0; i < MAX_VHOST_DEVICE; i++) {
		dev = vdpa_devices[i];
		if (dev && is_same_vdpa_device(&dev->addr, addr))
			return -1;
	}

> +
> +	for (i = 0; i < MAX_VHOST_DEVICE; i++) {
> +		if (vdpa_devices[i] == NULL)
> +			break;
> +	}
> +
> +	sprintf(device_name, "vdpa-dev-%d", i);
> +	dev = rte_zmalloc(device_name, sizeof(struct rte_vdpa_device),
> +			RTE_CACHE_LINE_SIZE);
> +	if (!dev)
> +		return -1;
> +
> +	memcpy(&dev->addr, addr, sizeof(struct rte_vdpa_dev_addr));
> +	dev->ops = ops;
> +	vdpa_devices[i] = dev;
> +	vdpa_device_num++;
> +
> +	return i;
> +}
> +
> +int
> +rte_vdpa_unregister_device(int did)
> +{
> +	if (did < 0 || did >= MAX_VHOST_DEVICE || vdpa_devices[did] == NULL)
> +		return -1;
> +
> +	rte_free(vdpa_devices[did]);
> +	vdpa_devices[did] = NULL;
> +	vdpa_device_num--;
> +
> +	return did;
> +}
> +
> +int
> +rte_vdpa_find_device_id(struct rte_vdpa_dev_addr *addr)
> +{
> +	struct rte_vdpa_device *dev;
> +	int i;
> +
> +	for (i = 0; i < MAX_VHOST_DEVICE; ++i) {
> +		dev = vdpa_devices[i];
> +		if (dev && is_same_vdpa_device(&dev->addr, addr) == 0)
> +			return i;
> +	}
> +
> +	return -1;
> +}
> +

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v5 0/5] vhost: support selective datapath
  2018-04-02 11:46 ` [PATCH v5 0/5] vhost: support selective datapath Zhihong Wang
                     ` (4 preceding siblings ...)
  2018-04-02 11:46   ` [PATCH v5 5/5] vhost: add apis for live migration Zhihong Wang
@ 2018-04-03  8:27   ` Maxime Coquelin
  5 siblings, 0 replies; 67+ messages in thread
From: Maxime Coquelin @ 2018-04-03  8:27 UTC (permalink / raw)
  To: Zhihong Wang, dev
  Cc: jianfeng.tan, tiwei.bie, yliu, cunming.liang, xiao.w.wang, dan.daly



On 04/02/2018 01:46 PM, Zhihong Wang wrote:
> This patch set introduces support for selective datapath in DPDK vhost-user
> lib. vDPA stands for vhost Data Path Acceleration. The idea is to support
> virtio ring compatible devices to serve virtio driver directly to enable
> datapath acceleration.
> 
> Design details
> ====
> 
> A vDPA device is a virtio ring compatible backend. It's defined as follows:
> 
> struct rte_vdpa_dev_addr {
> 	enum vdpa_addr_type type;
> 	union {
> 		uint8_t __dummy[64];
> 		struct rte_pci_addr pci_addr;
> 	};
> };
> 
> struct rte_vdpa_dev_ops {
> 	/* Get capabilities of this device */
> 	int (*get_queue_num)(int did, uint32_t *queue_num);
> 	int (*get_features)(int did, uint64_t *features);
> 	int (*get_protocol_features)(int did, uint64_t *protocol_features);
> 
> 	/* Driver configure/close the device */
> 	int (*dev_conf)(int vid);
> 	int (*dev_close)(int vid);
> 
> 	/* Enable/disable this vring */
> 	int (*set_vring_state)(int vid, int vring, int state);
> 
> 	/* Set features when changed */
> 	int (*set_features)(int vid);
> 
> 	/* Destination operations when migration done */
> 	int (*migration_done)(int vid);
> 
> 	/* Get the vfio group fd */
> 	int (*get_vfio_group_fd)(int vid);
> 
> 	/* Get the vfio device fd */
> 	int (*get_vfio_device_fd)(int vid);
> 
> 	/* Get the notify area info of the queue */
> 	int (*get_notify_area)(int vid, int qid,
> 			uint64_t *offset, uint64_t *size);
> 
> 	/* Reserved for future extension */
> 	void *reserved[5];
> };
> 
> struct rte_vdpa_device {
> 	struct rte_vdpa_dev_addr addr;
> 	struct rte_vdpa_dev_ops *ops;
> } __rte_cache_aligned;
> 
> 
> Changes to the current vhost-user lib are:
> ====
> 
>   1. Make vhost device capabilities configurable to adopt various devices.
>      Such capabilities include supported features, protocol features, queue
>      number. APIs are introduced to configure these capabilities.
> 
>   2. A set of device ops is defined for device specific operations:
> 
>       a. get_queue_num: Called to get supported queue number of the device.
> 
>       b. get_features: Called to get supported features of the device.
> 
>       c. get_protocol_features: Called to get supported protocol features of
>          the device.
> 
>       d. dev_conf: Called to configure the actual device when the virtio
>          device becomes ready.
> 
>       e. dev_close: Called to close the actual device when the virtio device
>          is stopped.
> 
>       f. set_vring_state: Called to change the state of the vring in the
>          actual device when vring state changes.
> 
>       g. set_features: Called to set the negotiated features to device.
> 
>       h. migration_done: Called to allow the device to response to RARP
>          sending.
> 
>       i. get_vfio_group_fd: Called to get the VFIO group fd of the device.
> 
>       j. get_vfio_device_fd: Called to get the VFIO device fd of the device.
> 
>       k. get_notify_area: Called to get the notify area info of the queue.
> 
>   3. To make vhost aware of its datapath type, an device id (did) is added
>      into the vhost data structure to identify the actual device. APIs are
>      introduced to configure it. When the default software datapath is used,
>      did is set to -1. When alternative datapath is used, did should be set
>      to specify which device to use, and each vhost-user socket can have
>      only 1 connection in this case.
> 
> Working process:
> ====
> 
>   1. Register vDPA device with address and device ops, and get a did.
> 
>   2. For vhost device creation:
> 
>        a. Register vhost-user socket.
> 
>        b. Set did of the vhost-user socket.
> 
>        c. Register vhost-user callbacks.
> 
>        d. Start to wait for connection.
> 
>   3. When connection comes and virtio device data structure is negotiated,
>      the device will be configured with all needed info.
> 
> ---
> Changes in v5:
> 
>   1. Rename the vDPA device ops to follow convention.
> 
>   2. Rename APIs for better description.
> 
>   3. Improve sanity check.
> 
> ---
> Changes in v4:
> 
>   1. Remove the "engine" concept in the lib.
> 
> ---
> Changes in v3:
> 
>   1. Keep macro names the same as in the spec.
> 
>   2. Export new APIs where they're introduced.
> 
> ---
> Changes in v2:
> 
>   1. Ensure negotiated capabilities are supported in vhost-user lib.
> 
>   2. Add APIs for live migration.
> 
>   3. Configure the data path at the right time.
> 
>   4. Add VFIO related vDPA device ops.
> 
>   5. Rebase on dpdk-next-virtio.
> 
> Zhihong Wang (5):
>    vhost: export vhost feature definitions
>    vhost: support selective datapath
>    vhost: add apis for datapath configuration
>    vhost: adapt vhost lib for selective datapath
>    vhost: add apis for live migration
> 
>   lib/librte_vhost/Makefile              |   4 +-
>   lib/librte_vhost/rte_vdpa.h            |  87 +++++++++++++++++
>   lib/librte_vhost/rte_vhost.h           | 154 ++++++++++++++++++++++++++++++
>   lib/librte_vhost/rte_vhost_version.map |  16 ++++
>   lib/librte_vhost/socket.c              | 166 ++++++++++++++++++++++++++++++++-
>   lib/librte_vhost/vdpa.c                | 115 +++++++++++++++++++++++
>   lib/librte_vhost/vhost.c               | 105 +++++++++++++++++++++
>   lib/librte_vhost/vhost.h               |  14 ++-
>   lib/librte_vhost/vhost_user.c          |  70 +++++++++++++-
>   lib/librte_vhost/vhost_user.h          |   7 --
>   10 files changed, 718 insertions(+), 20 deletions(-)
>   create mode 100644 lib/librte_vhost/rte_vdpa.h
>   create mode 100644 lib/librte_vhost/vdpa.c
> 


Series applied to dpdk-next-virtio/master.

Thanks!
Maxime

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v5 2/5] vhost: support selective datapath
  2018-04-03  8:19     ` Maxime Coquelin
@ 2018-04-03 14:35       ` Wang, Zhihong
  0 siblings, 0 replies; 67+ messages in thread
From: Wang, Zhihong @ 2018-04-03 14:35 UTC (permalink / raw)
  To: Maxime Coquelin, dev
  Cc: Tan, Jianfeng, Bie, Tiwei, yliu, Liang, Cunming, Wang, Xiao W, Daly, Dan



> -----Original Message-----
> From: Maxime Coquelin [mailto:maxime.coquelin@redhat.com]
> Sent: Tuesday, April 3, 2018 4:19 PM
> To: Wang, Zhihong <zhihong.wang@intel.com>; dev@dpdk.org
> Cc: Tan, Jianfeng <jianfeng.tan@intel.com>; Bie, Tiwei <tiwei.bie@intel.com>;
> yliu@fridaylinux.org; Liang, Cunming <cunming.liang@intel.com>; Wang, Xiao
> W <xiao.w.wang@intel.com>; Daly, Dan <dan.daly@intel.com>
> Subject: Re: [PATCH v5 2/5] vhost: support selective datapath
> 
> 
> 
> On 04/02/2018 01:46 PM, Zhihong Wang wrote:
> > +int
> > +rte_vdpa_register_device(struct rte_vdpa_dev_addr *addr,
> > +		struct rte_vdpa_dev_ops *ops)
> > +{
> > +	struct rte_vdpa_device *dev;
> > +	char device_name[MAX_VDPA_NAME_LEN];
> > +	int i;
> > +
> > +	if (vdpa_device_num >= MAX_VHOST_DEVICE)
> > +		return -1;
> > +
> > +	for (i = 0; i < MAX_VHOST_DEVICE; i++) {
> > +		if (vdpa_devices[i] && is_same_vdpa_device(addr,
> > +					&vdpa_devices[i]->addr))
> > +			return -1;
> > +	}
> 
> For consistency, I changed above check to look like same one in
> _find_device_id:

That's better. Thanks.

> 
> 	for (i = 0; i < MAX_VHOST_DEVICE; i++) {
> 		dev = vdpa_devices[i];
> 		if (dev && is_same_vdpa_device(&dev->addr, addr))
> 			return -1;
> 	}
> 
> > +
> > +	for (i = 0; i < MAX_VHOST_DEVICE; i++) {
> > +		if (vdpa_devices[i] == NULL)
> > +			break;
> > +	}
> > +
> > +	sprintf(device_name, "vdpa-dev-%d", i);
> > +	dev = rte_zmalloc(device_name, sizeof(struct rte_vdpa_device),
> > +			RTE_CACHE_LINE_SIZE);
> > +	if (!dev)
> > +		return -1;
> > +
> > +	memcpy(&dev->addr, addr, sizeof(struct rte_vdpa_dev_addr));
> > +	dev->ops = ops;
> > +	vdpa_devices[i] = dev;
> > +	vdpa_device_num++;
> > +
> > +	return i;
> > +}
> > +
> > +int
> > +rte_vdpa_unregister_device(int did)
> > +{
> > +	if (did < 0 || did >= MAX_VHOST_DEVICE || vdpa_devices[did] == NULL)
> > +		return -1;
> > +
> > +	rte_free(vdpa_devices[did]);
> > +	vdpa_devices[did] = NULL;
> > +	vdpa_device_num--;
> > +
> > +	return did;
> > +}
> > +
> > +int
> > +rte_vdpa_find_device_id(struct rte_vdpa_dev_addr *addr)
> > +{
> > +	struct rte_vdpa_device *dev;
> > +	int i;
> > +
> > +	for (i = 0; i < MAX_VHOST_DEVICE; ++i) {
> > +		dev = vdpa_devices[i];
> > +		if (dev && is_same_vdpa_device(&dev->addr, addr) == 0)
> > +			return i;
> > +	}
> > +
> > +	return -1;
> > +}
> > +

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v5 2/5] vhost: support selective datapath
  2018-04-03  8:02     ` Maxime Coquelin
@ 2018-04-15 17:39       ` Thomas Monjalon
  2018-04-16  7:26         ` Maxime Coquelin
  0 siblings, 1 reply; 67+ messages in thread
From: Thomas Monjalon @ 2018-04-15 17:39 UTC (permalink / raw)
  To: Maxime Coquelin, Zhihong Wang
  Cc: dev, jianfeng.tan, tiwei.bie, yliu, cunming.liang, xiao.w.wang,
	dan.daly, ferruh.yigit, bruce.richardson

03/04/2018 10:02, Maxime Coquelin:
> On 04/02/2018 01:46 PM, Zhihong Wang wrote:
> >   lib/librte_vhost/Makefile              |   4 +-
> >   lib/librte_vhost/rte_vdpa.h            |  87 +++++++++++++++++++++++++
> >   lib/librte_vhost/rte_vhost_version.map |   7 ++
> >   lib/librte_vhost/vdpa.c                | 115 +++++++++++++++++++++++++++++++++
> 
> With the fix you suggested:
> Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>

This patch is not OK. It is updating the Makefile but not meson.build.
I am fixing/amending it in master:

--- a/lib/librte_vhost/meson.build
+++ b/lib/librte_vhost/meson.build
@@ -9,7 +9,8 @@ if has_libnuma == 1
 endif
 version = 4
 allow_experimental_apis = true
-sources = files('fd_man.c', 'iotlb.c', 'socket.c', 'vhost.c', 'vhost_user.c',
+sources = files('fd_man.c', 'iotlb.c', 'socket.c', 'vdpa.c',
+               'vhost.c', 'vhost_user.c',
                'virtio_net.c', 'vhost_crypto.c')
-headers = files('rte_vhost.h', 'rte_vhost_crypto.h')
+headers = files('rte_vhost.h', 'rte_vdpa.h', 'rte_vhost_crypto.h')

^ permalink raw reply	[flat|nested] 67+ messages in thread

* Re: [PATCH v5 2/5] vhost: support selective datapath
  2018-04-15 17:39       ` Thomas Monjalon
@ 2018-04-16  7:26         ` Maxime Coquelin
  0 siblings, 0 replies; 67+ messages in thread
From: Maxime Coquelin @ 2018-04-16  7:26 UTC (permalink / raw)
  To: Thomas Monjalon, Zhihong Wang
  Cc: dev, jianfeng.tan, tiwei.bie, yliu, cunming.liang, xiao.w.wang,
	dan.daly, ferruh.yigit, bruce.richardson



On 04/15/2018 07:39 PM, Thomas Monjalon wrote:
> 03/04/2018 10:02, Maxime Coquelin:
>> On 04/02/2018 01:46 PM, Zhihong Wang wrote:
>>>    lib/librte_vhost/Makefile              |   4 +-
>>>    lib/librte_vhost/rte_vdpa.h            |  87 +++++++++++++++++++++++++
>>>    lib/librte_vhost/rte_vhost_version.map |   7 ++
>>>    lib/librte_vhost/vdpa.c                | 115 +++++++++++++++++++++++++++++++++
>>
>> With the fix you suggested:
>> Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>
> 
> This patch is not OK. It is updating the Makefile but not meson.build.
> I am fixing/amending it in master:
> 
> --- a/lib/librte_vhost/meson.build
> +++ b/lib/librte_vhost/meson.build
> @@ -9,7 +9,8 @@ if has_libnuma == 1
>   endif
>   version = 4
>   allow_experimental_apis = true
> -sources = files('fd_man.c', 'iotlb.c', 'socket.c', 'vhost.c', 'vhost_user.c',
> +sources = files('fd_man.c', 'iotlb.c', 'socket.c', 'vdpa.c',
> +               'vhost.c', 'vhost_user.c',
>                  'virtio_net.c', 'vhost_crypto.c')
> -headers = files('rte_vhost.h', 'rte_vhost_crypto.h')
> +headers = files('rte_vhost.h', 'rte_vdpa.h', 'rte_vhost_crypto.h')
> 
> 
> 

Right, thanks Thomas.

Sorry for not catching this, I'm in the process of improving my build
scripts, but as you can see it is not yet ready...

Cheers,
Maxime

^ permalink raw reply	[flat|nested] 67+ messages in thread

end of thread, other threads:[~2018-04-16  7:26 UTC | newest]

Thread overview: 67+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-02-02 23:28 [PATCH 0/7] vhost: support selective datapath Zhihong Wang
2018-02-02 23:28 ` [PATCH 1/7] vhost: make capabilities configurable Zhihong Wang
2018-02-06 10:19   ` Maxime Coquelin
2018-02-08  3:03     ` Wang, Zhihong
2018-02-02 23:28 ` [PATCH 2/7] vhost: export vhost feature definitions Zhihong Wang
2018-02-02 23:28 ` [PATCH 3/7] vhost: support selective datapath Zhihong Wang
2018-02-02 23:28 ` [PATCH 4/7] vhost: add apis for datapath configuration Zhihong Wang
2018-02-02 23:28 ` [PATCH 5/7] vhost: adapt vhost lib for selective datapath Zhihong Wang
2018-02-02 23:28 ` [PATCH 6/7] vhost: get callfd before device setup Zhihong Wang
2018-02-02 23:28 ` [PATCH 7/7] vhost: export new apis Zhihong Wang
2018-02-13  9:21 ` [PATCH v2 0/6] vhost: support selective datapath Zhihong Wang
2018-02-13  9:21   ` [PATCH v2 1/6] vhost: export vhost feature definitions Zhihong Wang
2018-03-06  9:37     ` Tan, Jianfeng
2018-03-06 14:03       ` Maxime Coquelin
2018-03-15 10:58         ` Wang, Zhihong
2018-02-13  9:21   ` [PATCH v2 2/6] vhost: support selective datapath Zhihong Wang
2018-02-13  9:21   ` [PATCH v2 3/6] vhost: add apis for datapath configuration Zhihong Wang
2018-02-13  9:21   ` [PATCH v2 4/6] vhost: adapt vhost lib for selective datapath Zhihong Wang
2018-02-13  9:21   ` [PATCH v2 5/6] vhost: add apis for live migration Zhihong Wang
2018-02-13  9:21   ` [PATCH v2 6/6] vhost: export new apis Zhihong Wang
2018-03-06  9:51     ` Tan, Jianfeng
2018-03-15 10:55       ` Wang, Zhihong
2018-02-27 10:13 ` [PATCH v3 0/5] vhost: support selective datapath Zhihong Wang
2018-02-27 10:13   ` [PATCH v3 1/5] vhost: export vhost feature definitions Zhihong Wang
2018-02-27 10:13   ` [PATCH v3 2/5] vhost: support selective datapath Zhihong Wang
2018-03-21 21:05     ` Maxime Coquelin
2018-03-22  7:55       ` Wang, Zhihong
2018-03-22  8:31         ` Maxime Coquelin
2018-02-27 10:13   ` [PATCH v3 3/5] vhost: add apis for datapath configuration Zhihong Wang
2018-03-21 21:08     ` Maxime Coquelin
2018-03-22  8:22       ` Wang, Zhihong
2018-03-22 14:18         ` Maxime Coquelin
2018-03-23 10:35           ` Wang, Zhihong
2018-02-27 10:13   ` [PATCH v3 4/5] vhost: adapt vhost lib for selective datapath Zhihong Wang
2018-02-27 10:13   ` [PATCH v3 5/5] vhost: add apis for live migration Zhihong Wang
2018-03-29 12:15   ` [PATCH v3 0/5] vhost: support selective datapath Wodkowski, PawelX
2018-03-30  9:35     ` Wang, Zhihong
2018-03-10 10:01 ` [PATCH v4 " Zhihong Wang
2018-03-10 10:01   ` [PATCH v4 1/5] vhost: export vhost feature definitions Zhihong Wang
2018-03-31  5:56     ` Maxime Coquelin
2018-03-10 10:01   ` [PATCH v4 2/5] vhost: support selective datapath Zhihong Wang
2018-03-31  6:10     ` Maxime Coquelin
2018-04-02  1:58       ` Wang, Zhihong
2018-03-31  7:38     ` Maxime Coquelin
2018-04-02  2:03       ` Wang, Zhihong
2018-03-10 10:01   ` [PATCH v4 3/5] vhost: add apis for datapath configuration Zhihong Wang
2018-03-31  7:04     ` Maxime Coquelin
2018-04-02  2:01       ` Wang, Zhihong
2018-03-10 10:01   ` [PATCH v4 4/5] vhost: adapt vhost lib for selective datapath Zhihong Wang
2018-03-31  7:35     ` Maxime Coquelin
2018-04-02 11:52       ` Wang, Zhihong
2018-03-10 10:01   ` [PATCH v4 5/5] vhost: add apis for live migration Zhihong Wang
2018-03-31  7:39     ` Maxime Coquelin
2018-04-02 11:46 ` [PATCH v5 0/5] vhost: support selective datapath Zhihong Wang
2018-04-02 11:46   ` [PATCH v5 1/5] vhost: export vhost feature definitions Zhihong Wang
2018-04-02 11:46   ` [PATCH v5 2/5] vhost: support selective datapath Zhihong Wang
2018-04-03  8:02     ` Maxime Coquelin
2018-04-15 17:39       ` Thomas Monjalon
2018-04-16  7:26         ` Maxime Coquelin
2018-04-03  8:19     ` Maxime Coquelin
2018-04-03 14:35       ` Wang, Zhihong
2018-04-02 11:46   ` [PATCH v5 3/5] vhost: add apis for datapath configuration Zhihong Wang
2018-04-03  8:07     ` Maxime Coquelin
2018-04-02 11:46   ` [PATCH v5 4/5] vhost: adapt vhost lib for selective datapath Zhihong Wang
2018-04-03  8:05     ` Maxime Coquelin
2018-04-02 11:46   ` [PATCH v5 5/5] vhost: add apis for live migration Zhihong Wang
2018-04-03  8:27   ` [PATCH v5 0/5] vhost: support selective datapath Maxime Coquelin

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.