[dpdk-dev] [PATCH 2/3] virtio-user: add mq in device emulation

Jianfeng Tan jianfeng.tan at intel.com
Thu May 5 10:59:40 CEST 2016


Multi-queue requires VIRTIO_NET_F_MQ and VIRTIO_NET_F_CTRL_VQ in
feature negotiation. Mainly two changes in virtio-user device
emulation layer.
  - Multi-queue requires ctrl-queue. So ctrl-queue will by enabled
    automatically when multi-queue is specified.
  - Provide a method virtio_user_enable_queue_pair() for virtio-user
    driver to enable/disable queues.

Note: Do not support multiple queue for vhost kernel backend.
Signed-off-by: Jianfeng Tan <jianfeng.tan at intel.com>
---
 drivers/net/virtio/virtio_user/virtio_user_dev.c | 65 ++++++++++++++++++++----
 drivers/net/virtio/virtio_user/virtio_user_dev.h |  2 +
 2 files changed, 58 insertions(+), 9 deletions(-)

diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c b/drivers/net/virtio/virtio_user/virtio_user_dev.c
index a8e58c0..ea0d4c4 100644
--- a/drivers/net/virtio/virtio_user/virtio_user_dev.c
+++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c
@@ -136,11 +136,14 @@ virtio_user_start_device(struct virtio_user_hw *hw)
 		}
 	}
 
-	/* After setup all virtqueues, we need to set_features so that
-	 * these features can be set into each virtqueue in vhost side.
-	 * And before that, make sure VIRTIO_NET_F_MAC is stripped.
+	/* After setup all virtqueues, we need to set_features so that these
+	 * features can be set into each virtqueue in vhost side. And before
+	 * that, make sure VHOST_USER_F_PROTOCOL_FEATURES is added if mq is
+	 * enabled, and VIRTIO_NET_F_MAC is stripped.
 	 */
 	features = hw->features;
+	if (hw->type == VHOST_USER && hw->max_queue_pairs > 1)
+		features |= VHOST_USER_MQ;
 	features &= ~(1ull << VIRTIO_NET_F_MAC);
 	ret = vhost_call(hw->vhostfd, hw->type,
 			 VHOST_MSG_SET_FEATURES, &features);
@@ -161,6 +164,18 @@ error:
 	return -1;
 }
 
+int
+virtio_user_enable_queue_pair(struct virtio_user_hw *hw,
+			      unsigned pair_idx, int enable)
+{
+	int r = -1;
+
+	if (hw->type == VHOST_USER)
+		r = vhost_user_enable_queue_pair(hw->vhostfd, pair_idx, enable);
+
+	return r;
+}
+
 int virtio_user_stop_device(struct virtio_user_hw *hw)
 {
 	return vhost_call(hw->vhostfd, hw->type, VHOST_MSG_RESET_OWNER, NULL);
@@ -188,7 +203,7 @@ static inline void parse_mac(struct virtio_user_hw *hw, const char *mac)
 
 static int
 virtio_vdev_init(struct rte_eth_dev_data *data, char *path,
-		 int queues, int nb_cq __rte_unused,
+		 int queues, int enable_ctrl_q,
 		 int queue_size, const char *mac, char *ifname)
 {
 	struct stat s;
@@ -204,8 +219,6 @@ virtio_vdev_init(struct rte_eth_dev_data *data, char *path,
 	uhw->vhostfd = -1;
 	uhw->tapfd = -1;
 
-	/* TODO: cq */
-
 	if (stat(uhw->path, &s) < 0) {
 		PMD_INIT_LOG(ERR, "stat: %s failed, %s", uhw->path,
 			     strerror(errno));
@@ -243,9 +256,36 @@ virtio_vdev_init(struct rte_eth_dev_data *data, char *path,
 	}
 	if (uhw->mac_specified)
 		uhw->features |= (1ull << VIRTIO_NET_F_MAC);
-	/* disable it until we support CQ */
-	uhw->features &= ~(1ull << VIRTIO_NET_F_CTRL_VQ);
-	uhw->features &= ~(1ull << VIRTIO_NET_F_CTRL_RX);
+
+	if (!enable_ctrl_q) {
+		uhw->features &= ~(1ull << VIRTIO_NET_F_CTRL_VQ);
+		/* Also disable features depends on VIRTIO_NET_F_CTRL_VQ */
+		uhw->features &= ~(1ull << VIRTIO_NET_F_CTRL_RX);
+		uhw->features &= ~(1ull << VIRTIO_NET_F_CTRL_VLAN);
+		uhw->features &= ~(1ull << VIRTIO_NET_F_GUEST_ANNOUNCE);
+		uhw->features &= ~(1ull << VIRTIO_NET_F_MQ);
+		uhw->features &= ~(1ull << VIRTIO_NET_F_CTRL_MAC_ADDR);
+	} else {
+		/* vhost user backend does not need to know ctrl-q, so
+		 * actually we need add this bit into features. However,
+		 * DPDK vhost-user does send features with this bit, so we
+		 * check it instead of OR it for now.
+		 */
+		if (!(uhw->features & (1ull << VIRTIO_NET_F_CTRL_VQ)))
+			PMD_INIT_LOG(INFO, "vhost does not support ctrl-q");
+	}
+
+	if (uhw->max_queue_pairs > 1) {
+		if (uhw->type == VHOST_KERNEL) {
+			PMD_INIT_LOG(ERR, "MQ not supported for vhost kernel");
+			return -1;
+		}
+
+		if (!(uhw->features & VHOST_USER_MQ)) {
+			PMD_INIT_LOG(ERR, "MQ not supported by the backend");
+			return -1;
+		}
+	}
 
 	return 0;
 
@@ -411,6 +451,13 @@ rte_virtio_user_pmd_devinit(const char *name, const char *params)
 	if (rte_kvargs_count(kvlist, VIRTIO_USER_ARG_CQ_NUM) == 1)
 		rte_kvargs_process(kvlist, VIRTIO_USER_ARG_CQ_NUM,
 				   &get_integer_arg, &nb_cq);
+	else if (queues > 1)
+		nb_cq = 1;
+
+	if (queues > 1 && nb_cq == 0) {
+		PMD_INIT_LOG(ERR, "multi-q requires ctrl-q");
+		goto end;
+	}
 
 	eth_dev = virtio_user_eth_dev_alloc(name);
 	if (!eth_dev) {
diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.h b/drivers/net/virtio/virtio_user/virtio_user_dev.h
index bc4dc1a..1834a6e 100644
--- a/drivers/net/virtio/virtio_user/virtio_user_dev.h
+++ b/drivers/net/virtio/virtio_user/virtio_user_dev.h
@@ -55,6 +55,8 @@ struct virtio_user_hw {
 
 int virtio_user_start_device(struct virtio_user_hw *hw);
 int virtio_user_stop_device(struct virtio_user_hw *hw);
+int virtio_user_enable_queue_pair(struct virtio_user_hw *hw,
+				  unsigned pair_idx, int enable);
 
 const struct virtio_pci_ops vdev_ops;
 
-- 
2.1.4



More information about the dev mailing list