DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH v2] net/virtio-user: check negotiated features before set
@ 2018-08-27 18:37 eric zhang
  2018-08-28  7:04 ` Tiwei Bie
  0 siblings, 1 reply; 2+ messages in thread
From: eric zhang @ 2018-08-27 18:37 UTC (permalink / raw)
  To: tiwei.bie; +Cc: maxime.coquelin, zhihong.wang, dev, Allain.Legacy, Matt.Peters

This patch checks negotiated features to see if necessary to offload
before set the tap device offload capabilities. It also checks if kernel
support the TUNSETOFFLOAD operation.

Signed-off-by: eric zhang <eric.zhang@windriver.com>

---
v2:
* don't return failure when failed to set offload to tap
* check if offloads available when handling VHOST_GET_FEATURES
---
 drivers/net/virtio/virtio_user/vhost_kernel.c     |  8 ++--
 drivers/net/virtio/virtio_user/vhost_kernel_tap.c | 55 +++++++++++++++++------
 drivers/net/virtio/virtio_user/vhost_kernel_tap.h |  2 +-
 3 files changed, 47 insertions(+), 18 deletions(-)

diff --git a/drivers/net/virtio/virtio_user/vhost_kernel.c b/drivers/net/virtio/virtio_user/vhost_kernel.c
index dd24b6b..5c39f26 100644
--- a/drivers/net/virtio/virtio_user/vhost_kernel.c
+++ b/drivers/net/virtio/virtio_user/vhost_kernel.c
@@ -278,9 +278,11 @@ struct vhost_memory_kernel {
 	if (!ret && req_kernel == VHOST_GET_FEATURES) {
 		/* 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.
+		 * reporting to upper layer. For guest offloads we check if
+		 * they are available in the negotiated features.
 		 */
-		*((uint64_t *)arg) |= VHOST_KERNEL_GUEST_OFFLOADS_MASK;
+		*((uint64_t *)arg) |=
+			(dev->features & VHOST_KERNEL_GUEST_OFFLOADS_MASK);
 		*((uint64_t *)arg) |= VHOST_KERNEL_HOST_OFFLOADS_MASK;
 
 		/* vhost_kernel will not declare this feature, but it does
@@ -381,7 +383,7 @@ struct vhost_memory_kernel {
 		hdr_size = sizeof(struct virtio_net_hdr);
 
 	tapfd = vhost_kernel_open_tap(&dev->ifname, hdr_size, req_mq,
-			 (char *)dev->mac_addr);
+			 (char *)dev->mac_addr, dev->features);
 	if (tapfd < 0) {
 		PMD_DRV_LOG(ERR, "fail to open tap for vhost kernel");
 		return -1;
diff --git a/drivers/net/virtio/virtio_user/vhost_kernel_tap.c b/drivers/net/virtio/virtio_user/vhost_kernel_tap.c
index d036428..5e86404 100644
--- a/drivers/net/virtio/virtio_user/vhost_kernel_tap.c
+++ b/drivers/net/virtio/virtio_user/vhost_kernel_tap.c
@@ -45,21 +45,54 @@
 
 #include "vhost_kernel_tap.h"
 #include "../virtio_logs.h"
+#include "../virtio_pci.h"
+
+static int
+vhost_kernel_tap_set_offload(int fd, uint64_t feature)
+{
+	unsigned int offload = 0;
+
+	if (feature & (1ULL << VIRTIO_NET_F_GUEST_CSUM))
+		offload |= TUN_F_CSUM;
+	if (feature & (1ULL << VIRTIO_NET_F_GUEST_TSO4))
+		offload |= TUN_F_TSO4;
+	if (feature & (1ULL << VIRTIO_NET_F_GUEST_TSO6))
+		offload |= TUN_F_TSO6;
+	if (feature & ((1ULL << VIRTIO_NET_F_GUEST_TSO4) |
+		(1ULL << VIRTIO_NET_F_GUEST_TSO6)) &&
+		(feature & (1ULL << VIRTIO_NET_F_GUEST_ECN)))
+		offload |= TUN_F_TSO_ECN;
+	if (feature & (1ULL << VIRTIO_NET_F_GUEST_UFO))
+		offload |= TUN_F_UFO;
+
+	if (offload != 0) {
+		/* Check if our kernel supports TUNSETOFFLOAD */
+		if (ioctl(fd, TUNSETOFFLOAD, 0) != 0 && errno == EINVAL) {
+			PMD_DRV_LOG(ERR, "Kernel does't support TUNSETOFFLOAD\n");
+			return -ENOTSUP;
+		}
+
+		if (ioctl(fd, TUNSETOFFLOAD, offload) != 0) {
+			offload &= ~TUN_F_UFO;
+			if (ioctl(fd, TUNSETOFFLOAD, offload) != 0) {
+				PMD_DRV_LOG(ERR, "TUNSETOFFLOAD ioctl() failed: %s\n",
+					strerror(errno));
+				return -1;
+			}
+		}
+	}
+
+	return 0;
+}
 
 int
 vhost_kernel_open_tap(char **p_ifname, int hdr_size, int req_mq,
-			 const char *mac)
+			 const char *mac, uint64_t features)
 {
 	unsigned int tap_features;
 	int sndbuf = INT_MAX;
 	struct ifreq ifr;
 	int tapfd;
-	unsigned int offload =
-			TUN_F_CSUM |
-			TUN_F_TSO4 |
-			TUN_F_TSO6 |
-			TUN_F_TSO_ECN |
-			TUN_F_UFO;
 
 	/* TODO:
 	 * 1. verify we can get/set vnet_hdr_len, tap_probe_vnet_hdr_len
@@ -119,13 +152,7 @@
 		goto error;
 	}
 
-	/* TODO: before set the offload capabilities, we'd better (1) check
-	 * negotiated features to see if necessary to offload; (2) query tap
-	 * to see if it supports the offload capabilities.
-	 */
-	if (ioctl(tapfd, TUNSETOFFLOAD, offload) != 0)
-		PMD_DRV_LOG(ERR, "TUNSETOFFLOAD ioctl() failed: %s",
-			   strerror(errno));
+	vhost_kernel_tap_set_offload(tapfd, features);
 
 	memset(&ifr, 0, sizeof(ifr));
 	ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER;
diff --git a/drivers/net/virtio/virtio_user/vhost_kernel_tap.h b/drivers/net/virtio/virtio_user/vhost_kernel_tap.h
index 402f964..ea7a6c9 100644
--- a/drivers/net/virtio/virtio_user/vhost_kernel_tap.h
+++ b/drivers/net/virtio/virtio_user/vhost_kernel_tap.h
@@ -65,4 +65,4 @@
 #define PATH_NET_TUN	"/dev/net/tun"
 
 int vhost_kernel_open_tap(char **p_ifname, int hdr_size, int req_mq,
-			 const char *mac);
+			 const char *mac, uint64_t features);
-- 
1.8.3.1

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

* Re: [dpdk-dev] [PATCH v2] net/virtio-user: check negotiated features before set
  2018-08-27 18:37 [dpdk-dev] [PATCH v2] net/virtio-user: check negotiated features before set eric zhang
@ 2018-08-28  7:04 ` Tiwei Bie
  0 siblings, 0 replies; 2+ messages in thread
From: Tiwei Bie @ 2018-08-28  7:04 UTC (permalink / raw)
  To: eric zhang; +Cc: maxime.coquelin, zhihong.wang, dev, Allain.Legacy, Matt.Peters

On Mon, Aug 27, 2018 at 02:37:24PM -0400, eric zhang wrote:
> This patch checks negotiated features to see if necessary to offload
> before set the tap device offload capabilities. It also checks if kernel
> support the TUNSETOFFLOAD operation.
> 
> Signed-off-by: eric zhang <eric.zhang@windriver.com>
> 
> ---
> v2:
> * don't return failure when failed to set offload to tap
> * check if offloads available when handling VHOST_GET_FEATURES
> ---
>  drivers/net/virtio/virtio_user/vhost_kernel.c     |  8 ++--
>  drivers/net/virtio/virtio_user/vhost_kernel_tap.c | 55 +++++++++++++++++------
>  drivers/net/virtio/virtio_user/vhost_kernel_tap.h |  2 +-
>  3 files changed, 47 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/net/virtio/virtio_user/vhost_kernel.c b/drivers/net/virtio/virtio_user/vhost_kernel.c
> index dd24b6b..5c39f26 100644
> --- a/drivers/net/virtio/virtio_user/vhost_kernel.c
> +++ b/drivers/net/virtio/virtio_user/vhost_kernel.c
> @@ -278,9 +278,11 @@ struct vhost_memory_kernel {
>  	if (!ret && req_kernel == VHOST_GET_FEATURES) {
>  		/* 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.
> +		 * reporting to upper layer. For guest offloads we check if
> +		 * they are available in the negotiated features.
>  		 */
> -		*((uint64_t *)arg) |= VHOST_KERNEL_GUEST_OFFLOADS_MASK;
> +		*((uint64_t *)arg) |=
> +			(dev->features & VHOST_KERNEL_GUEST_OFFLOADS_MASK);

VHOST_GET_FEATURES returns the features supported
by backend instead of the negotiated features. We
need to check whether tap support vnet_hdr etc to
know whether these features are available.

>  		*((uint64_t *)arg) |= VHOST_KERNEL_HOST_OFFLOADS_MASK;
>  
>  		/* vhost_kernel will not declare this feature, but it does
> @@ -381,7 +383,7 @@ struct vhost_memory_kernel {
>  		hdr_size = sizeof(struct virtio_net_hdr);
>  
>  	tapfd = vhost_kernel_open_tap(&dev->ifname, hdr_size, req_mq,
> -			 (char *)dev->mac_addr);
> +			 (char *)dev->mac_addr, dev->features);
>  	if (tapfd < 0) {
>  		PMD_DRV_LOG(ERR, "fail to open tap for vhost kernel");
>  		return -1;
> diff --git a/drivers/net/virtio/virtio_user/vhost_kernel_tap.c b/drivers/net/virtio/virtio_user/vhost_kernel_tap.c
> index d036428..5e86404 100644
> --- a/drivers/net/virtio/virtio_user/vhost_kernel_tap.c
> +++ b/drivers/net/virtio/virtio_user/vhost_kernel_tap.c
> @@ -45,21 +45,54 @@
>  
>  #include "vhost_kernel_tap.h"
>  #include "../virtio_logs.h"
> +#include "../virtio_pci.h"
> +
> +static int
> +vhost_kernel_tap_set_offload(int fd, uint64_t feature)

s/feature/features/

> +{
> +	unsigned int offload = 0;
> +
> +	if (feature & (1ULL << VIRTIO_NET_F_GUEST_CSUM))
> +		offload |= TUN_F_CSUM;
> +	if (feature & (1ULL << VIRTIO_NET_F_GUEST_TSO4))
> +		offload |= TUN_F_TSO4;
> +	if (feature & (1ULL << VIRTIO_NET_F_GUEST_TSO6))
> +		offload |= TUN_F_TSO6;
> +	if (feature & ((1ULL << VIRTIO_NET_F_GUEST_TSO4) |
> +		(1ULL << VIRTIO_NET_F_GUEST_TSO6)) &&
> +		(feature & (1ULL << VIRTIO_NET_F_GUEST_ECN)))
> +		offload |= TUN_F_TSO_ECN;
> +	if (feature & (1ULL << VIRTIO_NET_F_GUEST_UFO))
> +		offload |= TUN_F_UFO;

The features other than CSUM feature depends on the
CSUM feature. Maybe it's better to do what QEMU does,
i.e. announce these offloads in tap only when the
CSUM feature is available:

https://github.com/qemu/qemu/blob/6ad90805383e/net/tap-linux.c#L247-L257

Thanks

> +
> +	if (offload != 0) {
> +		/* Check if our kernel supports TUNSETOFFLOAD */
> +		if (ioctl(fd, TUNSETOFFLOAD, 0) != 0 && errno == EINVAL) {
> +			PMD_DRV_LOG(ERR, "Kernel does't support TUNSETOFFLOAD\n");
> +			return -ENOTSUP;
> +		}
> +
> +		if (ioctl(fd, TUNSETOFFLOAD, offload) != 0) {
> +			offload &= ~TUN_F_UFO;
> +			if (ioctl(fd, TUNSETOFFLOAD, offload) != 0) {
> +				PMD_DRV_LOG(ERR, "TUNSETOFFLOAD ioctl() failed: %s\n",
> +					strerror(errno));
> +				return -1;
> +			}
> +		}
> +	}
> +
> +	return 0;
> +}
>  
>  int
>  vhost_kernel_open_tap(char **p_ifname, int hdr_size, int req_mq,
> -			 const char *mac)
> +			 const char *mac, uint64_t features)
>  {
>  	unsigned int tap_features;
>  	int sndbuf = INT_MAX;
>  	struct ifreq ifr;
>  	int tapfd;
> -	unsigned int offload =
> -			TUN_F_CSUM |
> -			TUN_F_TSO4 |
> -			TUN_F_TSO6 |
> -			TUN_F_TSO_ECN |
> -			TUN_F_UFO;
>  
>  	/* TODO:
>  	 * 1. verify we can get/set vnet_hdr_len, tap_probe_vnet_hdr_len
> @@ -119,13 +152,7 @@
>  		goto error;
>  	}
>  
> -	/* TODO: before set the offload capabilities, we'd better (1) check
> -	 * negotiated features to see if necessary to offload; (2) query tap
> -	 * to see if it supports the offload capabilities.
> -	 */
> -	if (ioctl(tapfd, TUNSETOFFLOAD, offload) != 0)
> -		PMD_DRV_LOG(ERR, "TUNSETOFFLOAD ioctl() failed: %s",
> -			   strerror(errno));
> +	vhost_kernel_tap_set_offload(tapfd, features);
>  
>  	memset(&ifr, 0, sizeof(ifr));
>  	ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER;
> diff --git a/drivers/net/virtio/virtio_user/vhost_kernel_tap.h b/drivers/net/virtio/virtio_user/vhost_kernel_tap.h
> index 402f964..ea7a6c9 100644
> --- a/drivers/net/virtio/virtio_user/vhost_kernel_tap.h
> +++ b/drivers/net/virtio/virtio_user/vhost_kernel_tap.h
> @@ -65,4 +65,4 @@
>  #define PATH_NET_TUN	"/dev/net/tun"
>  
>  int vhost_kernel_open_tap(char **p_ifname, int hdr_size, int req_mq,
> -			 const char *mac);
> +			 const char *mac, uint64_t features);
> -- 
> 1.8.3.1
> 

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

end of thread, other threads:[~2018-08-28  7:08 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-08-27 18:37 [dpdk-dev] [PATCH v2] net/virtio-user: check negotiated features before set eric zhang
2018-08-28  7:04 ` Tiwei Bie

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).