Thread (149 messages) 149 messages, 6 authors, 2021-01-18

Re: [dpdk-dev] [PATCH 25/40] net/virtio: add Virtio-user features ops

From: Xia, Chenbo <hidden>
Date: 2021-01-06 11:54:26

Hi Maxime,
-----Original Message-----
From: Maxime Coquelin <redacted>
Sent: Monday, December 21, 2020 5:14 AM
To: dev@dpdk.org; Xia, Chenbo <redacted>; olivier.matz@6wind.com;
amorenoz@redhat.com; david.marchand@redhat.com
Cc: Maxime Coquelin <redacted>
Subject: [PATCH 25/40] net/virtio: add Virtio-user features ops

This patch introduce new callbacks for getting
s/introduce/introduces
quoted hunk ↗ jump to hunk
and setting Virtio features, and implements them
for the different backend types.

Signed-off-by: Maxime Coquelin <redacted>
---
 drivers/net/virtio/virtio_user/vhost.h        |   2 +
 drivers/net/virtio/virtio_user/vhost_kernel.c | 150 +++++++++---------
 .../net/virtio/virtio_user/vhost_kernel_tap.c |  23 +++
 .../net/virtio/virtio_user/vhost_kernel_tap.h |   1 +
 drivers/net/virtio/virtio_user/vhost_user.c   |  63 +++++++-
 drivers/net/virtio/virtio_user/vhost_vdpa.c   |  38 +++--
 .../net/virtio/virtio_user/virtio_user_dev.c  |   5 +-
 drivers/net/virtio/virtio_user_ethdev.c       |   3 +-
 8 files changed, 188 insertions(+), 97 deletions(-)
diff --git a/drivers/net/virtio/virtio_user/vhost.h
b/drivers/net/virtio/virtio_user/vhost.h
index 8e819ecfb8..16978e27ed 100644
--- a/drivers/net/virtio/virtio_user/vhost.h
+++ b/drivers/net/virtio/virtio_user/vhost.h
@@ -102,6 +102,8 @@ struct virtio_user_dev;
 struct virtio_user_backend_ops {
 	int (*setup)(struct virtio_user_dev *dev);
 	int (*set_owner)(struct virtio_user_dev *dev);
+	int (*get_features)(struct virtio_user_dev *dev, uint64_t *features);
+	int (*set_features)(struct virtio_user_dev *dev, uint64_t features);
 	int (*send_request)(struct virtio_user_dev *dev,
 			    enum vhost_user_request req,
 			    void *arg);
diff --git a/drivers/net/virtio/virtio_user/vhost_kernel.c
b/drivers/net/virtio/virtio_user/vhost_kernel.c
index b79dcad179..f44df8ef1f 100644
--- a/drivers/net/virtio/virtio_user/vhost_kernel.c
+++ b/drivers/net/virtio/virtio_user/vhost_kernel.c
@@ -38,6 +38,28 @@ struct vhost_memory_kernel {
 #define VHOST_SET_VRING_ERR _IOW(VHOST_VIRTIO, 0x22, struct vhost_vring_file)
 #define VHOST_NET_SET_BACKEND _IOW(VHOST_VIRTIO, 0x30, struct
vhost_vring_file)

+/* with below features, vhost kernel does not need to do the checksum and TSO,
+ * these info will be passed to virtio_user through virtio net header.
+ */
+#define VHOST_KERNEL_GUEST_OFFLOADS_MASK	\
+	((1ULL << VIRTIO_NET_F_GUEST_CSUM) |	\
+	 (1ULL << VIRTIO_NET_F_GUEST_TSO4) |	\
+	 (1ULL << VIRTIO_NET_F_GUEST_TSO6) |	\
+	 (1ULL << VIRTIO_NET_F_GUEST_ECN)  |	\
+	 (1ULL << VIRTIO_NET_F_GUEST_UFO))
+
+/* with below features, when flows from virtio_user to vhost kernel
+ * (1) if flows goes up through the kernel networking stack, it does not need
+ * to verify checksum, which can save CPU cycles;
+ * (2) if flows goes through a Linux bridge and outside from an interface
+ * (kernel driver), checksum and TSO will be done by GSO in kernel or even
+ * offloaded into real physical device.
+ */
+#define VHOST_KERNEL_HOST_OFFLOADS_MASK		\
+	((1ULL << VIRTIO_NET_F_HOST_TSO4) |	\
+	 (1ULL << VIRTIO_NET_F_HOST_TSO6) |	\
+	 (1ULL << VIRTIO_NET_F_CSUM))
+
 static uint64_t max_regions = 64;

 static void
@@ -77,10 +99,57 @@ vhost_kernel_set_owner(struct virtio_user_dev *dev)
 	return vhost_kernel_ioctl(dev->vhostfds[0], VHOST_SET_OWNER, NULL);
 }

+static int
+vhost_kernel_get_features(struct virtio_user_dev *dev, uint64_t *features)
+{
+	int ret;
+	unsigned int tap_features;
+
+	ret = vhost_kernel_ioctl(dev->vhostfds[0], VHOST_GET_FEATURES, features);
+	if (ret < 0) {
+		PMD_DRV_LOG(ERR, "Failed to get features");
+		return -1;
+	}
+
+	ret = tap_support_features(&tap_features);
+	if (ret < 0) {
+		PMD_DRV_LOG(ERR, "Failed to get TAP features)");
should delete ')' after 'features'?
+		return -1;
+	}
+
+	/* with tap as the backend, all these features are supported
+	 * but not claimed by vhost-net, so we add them back when
+	 * reporting to upper layer.
+	 */
<snip>
quoted hunk ↗ jump to hunk
 	.dma_map = vhost_vdpa_dma_map,
diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c
b/drivers/net/virtio/virtio_user/virtio_user_dev.c
index f8e4581951..0a85d058a8 100644
--- a/drivers/net/virtio/virtio_user/virtio_user_dev.c
+++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c
@@ -141,7 +141,7 @@ virtio_user_dev_set_features(struct virtio_user_dev *dev)
 	/* Strip VIRTIO_NET_F_CTRL_VQ, as devices do not really need to know */
 	features &= ~(1ull << VIRTIO_NET_F_CTRL_VQ);
 	features &= ~(1ull << VIRTIO_NET_F_STATUS);
-	ret = dev->ops->send_request(dev, VHOST_USER_SET_FEATURES, &features);
+	ret = dev->ops->set_features(dev, features);
I noticed that virtio_user_dev_set_features is called by virtio_user_set_status.
The former may fail but the latter will ignore the failure. So this will happen:
setting features already failed but virtio-user still continue to do things. IMHO, 
this is not very good (similar things may happen for virtio_user_start_device).
What do you think?

Thanks,
Chenbo
quoted hunk ↗ jump to hunk
 	if (ret < 0)
 		goto error;
 	PMD_DRV_LOG(INFO, "set features: %" PRIx64, features);
@@ -488,8 +488,7 @@ virtio_user_dev_init(struct virtio_user_dev *dev, char
*path, int queues,
 			return -1;
 		}

-		if (dev->ops->send_request(dev, VHOST_USER_GET_FEATURES,
-					   &dev->device_features) < 0) {
+		if (dev->ops->get_features(dev, &dev->device_features) < 0) {
 			PMD_INIT_LOG(ERR, "get_features failed: %s",
 				     strerror(errno));
 			return -1;
diff --git a/drivers/net/virtio/virtio_user_ethdev.c
b/drivers/net/virtio/virtio_user_ethdev.c
index 283f5c7a36..4d2635c8aa 100644
--- a/drivers/net/virtio/virtio_user_ethdev.c
+++ b/drivers/net/virtio/virtio_user_ethdev.c
@@ -85,8 +85,7 @@ virtio_user_server_reconnect(struct virtio_user_dev *dev)

 	virtio_set_status(hw, VIRTIO_CONFIG_STATUS_DRIVER);

-	if (dev->ops->send_request(dev, VHOST_USER_GET_FEATURES,
-				   &dev->device_features) < 0) {
+	if (dev->ops->get_features(dev, &dev->device_features) < 0) {
 		PMD_INIT_LOG(ERR, "get_features failed: %s",
 			     strerror(errno));
 		return -1;
--
2.29.2
  
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help