2022-01-25 13:12:41

by Andrew Melnichenko

[permalink] [raw]
Subject: [RFC PATCH 0/5] TUN/VirtioNet USO features support.

Added new offloads for TUN devices TUN_F_USO4 and TUN_F_USO6.
Technically they enable NETIF_F_GSO_UDP_L4
(and only if USO4 & USO6 are set simultaneously).
It allows to transmission of large UDP packets.

Different features USO4 and USO6 are required for qemu where Windows guests can
enable disable USO receives for IPv4 and IPv6 separately.
On the other side, Linux can't really differentiate USO4 and USO6, for now.
For now, to enable USO for TUN it requires enabling USO4 and USO6 together.
In the future, there would be a mechanism to control UDP_L4 GSO separately.

Test it WIP Qemu https://github.com/daynix/qemu/tree/Dev_USOv2

New types for VirtioNet already on mailing:
https://lists.oasis-open.org/archives/virtio-comment/202110/msg00010.html

Also, there is a known issue with transmitting packages between two guests.
Without hacks with skb's GSO - packages are still segmented on the host's postrouting.

Andrew Melnychenko (5):
uapi/linux/if_tun.h: Added new ioctl for tun/tap.
driver/net/tun: Added features for USO.
uapi/linux/virtio_net.h: Added USO types.
linux/virtio_net.h: Added Support for GSO_UDP_L4 offload.
drivers/net/virtio_net.c: Added USO support.

drivers/net/tap.c | 18 ++++++++++++++++--
drivers/net/tun.c | 15 ++++++++++++++-
drivers/net/virtio_net.c | 22 ++++++++++++++++++----
include/linux/virtio_net.h | 11 +++++++++++
include/uapi/linux/if_tun.h | 3 +++
include/uapi/linux/virtio_net.h | 4 ++++
6 files changed, 66 insertions(+), 7 deletions(-)

--
2.34.1


2022-01-25 13:31:40

by Andrew Melnichenko

[permalink] [raw]
Subject: [RFC PATCH 4/5] linux/virtio_net.h: Added Support for GSO_UDP_L4 offload.

Now, it's possible to convert vnet packets from/to skb.

Signed-off-by: Andrew Melnychenko <[email protected]>
---
include/linux/virtio_net.h | 11 +++++++++++
1 file changed, 11 insertions(+)

diff --git a/include/linux/virtio_net.h b/include/linux/virtio_net.h
index a960de68ac69..9311d41d0a81 100644
--- a/include/linux/virtio_net.h
+++ b/include/linux/virtio_net.h
@@ -17,6 +17,9 @@ static inline bool virtio_net_hdr_match_proto(__be16 protocol, __u8 gso_type)
case VIRTIO_NET_HDR_GSO_UDP:
return protocol == cpu_to_be16(ETH_P_IP) ||
protocol == cpu_to_be16(ETH_P_IPV6);
+ case VIRTIO_NET_HDR_GSO_UDP_L4:
+ return protocol == cpu_to_be16(ETH_P_IP) ||
+ protocol == cpu_to_be16(ETH_P_IPV6);
default:
return false;
}
@@ -31,6 +34,7 @@ static inline int virtio_net_hdr_set_proto(struct sk_buff *skb,
switch (hdr->gso_type & ~VIRTIO_NET_HDR_GSO_ECN) {
case VIRTIO_NET_HDR_GSO_TCPV4:
case VIRTIO_NET_HDR_GSO_UDP:
+ case VIRTIO_NET_HDR_GSO_UDP_L4:
skb->protocol = cpu_to_be16(ETH_P_IP);
break;
case VIRTIO_NET_HDR_GSO_TCPV6:
@@ -69,6 +73,11 @@ static inline int virtio_net_hdr_to_skb(struct sk_buff *skb,
ip_proto = IPPROTO_UDP;
thlen = sizeof(struct udphdr);
break;
+ case VIRTIO_NET_HDR_GSO_UDP_L4:
+ gso_type = SKB_GSO_UDP_L4;
+ ip_proto = IPPROTO_UDP;
+ thlen = sizeof(struct udphdr);
+ break;
default:
return -EINVAL;
}
@@ -182,6 +191,8 @@ static inline int virtio_net_hdr_from_skb(const struct sk_buff *skb,
hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
else if (sinfo->gso_type & SKB_GSO_TCPV6)
hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV6;
+ else if (sinfo->gso_type & SKB_GSO_UDP_L4)
+ hdr->gso_type = VIRTIO_NET_HDR_GSO_UDP_L4;
else
return -EINVAL;
if (sinfo->gso_type & SKB_GSO_TCP_ECN)
--
2.34.1

2022-01-25 13:31:41

by Andrew Melnichenko

[permalink] [raw]
Subject: [RFC PATCH 3/5] uapi/linux/virtio_net.h: Added USO types.

Added new GSO type for USO: VIRTIO_NET_HDR_GSO_UDP_L4.
Feature VIRTIO_NET_F_HOST_USO allows to enable NETIF_F_GSO_UDP_L4.
Separated VIRTIO_NET_F_GUEST_USO4 & VIRTIO_NET_F_GUEST_USO6 features
required for Windows guests.

Signed-off-by: Andrew Melnychenko <[email protected]>
---
include/uapi/linux/virtio_net.h | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/include/uapi/linux/virtio_net.h b/include/uapi/linux/virtio_net.h
index 3f55a4215f11..620addc5767b 100644
--- a/include/uapi/linux/virtio_net.h
+++ b/include/uapi/linux/virtio_net.h
@@ -56,6 +56,9 @@
#define VIRTIO_NET_F_MQ 22 /* Device supports Receive Flow
* Steering */
#define VIRTIO_NET_F_CTRL_MAC_ADDR 23 /* Set MAC address */
+#define VIRTIO_NET_F_GUEST_USO4 54 /* Guest can handle USOv4 in. */
+#define VIRTIO_NET_F_GUEST_USO6 55 /* Guest can handle USOv6 in. */
+#define VIRTIO_NET_F_HOST_USO 56 /* Host can handle USO in. */

#define VIRTIO_NET_F_HASH_REPORT 57 /* Supports hash report */
#define VIRTIO_NET_F_RSS 60 /* Supports RSS RX steering */
@@ -130,6 +133,7 @@ struct virtio_net_hdr_v1 {
#define VIRTIO_NET_HDR_GSO_TCPV4 1 /* GSO frame, IPv4 TCP (TSO) */
#define VIRTIO_NET_HDR_GSO_UDP 3 /* GSO frame, IPv4 UDP (UFO) */
#define VIRTIO_NET_HDR_GSO_TCPV6 4 /* GSO frame, IPv6 TCP */
+#define VIRTIO_NET_HDR_GSO_UDP_L4 5 /* GSO frame, IPv4 & IPv6 UDP (USO) */
#define VIRTIO_NET_HDR_GSO_ECN 0x80 /* TCP has ECN set */
__u8 gso_type;
__virtio16 hdr_len; /* Ethernet + IP + tcp/udp hdrs */
--
2.34.1

2022-01-25 13:31:50

by Andrew Melnichenko

[permalink] [raw]
Subject: [RFC PATCH 5/5] drivers/net/virtio_net.c: Added USO support.

Now, it possible to enable GSO_UDP_L4("tx-udp-segmentation") for VirtioNet.

Signed-off-by: Andrew Melnychenko <[email protected]>
---
drivers/net/virtio_net.c | 22 ++++++++++++++++++----
1 file changed, 18 insertions(+), 4 deletions(-)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index a801ea40908f..a45eee022be4 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -60,13 +60,17 @@ static const unsigned long guest_offloads[] = {
VIRTIO_NET_F_GUEST_TSO6,
VIRTIO_NET_F_GUEST_ECN,
VIRTIO_NET_F_GUEST_UFO,
- VIRTIO_NET_F_GUEST_CSUM
+ VIRTIO_NET_F_GUEST_CSUM,
+ VIRTIO_NET_F_GUEST_USO4,
+ VIRTIO_NET_F_GUEST_USO6
};

#define GUEST_OFFLOAD_GRO_HW_MASK ((1ULL << VIRTIO_NET_F_GUEST_TSO4) | \
(1ULL << VIRTIO_NET_F_GUEST_TSO6) | \
(1ULL << VIRTIO_NET_F_GUEST_ECN) | \
- (1ULL << VIRTIO_NET_F_GUEST_UFO))
+ (1ULL << VIRTIO_NET_F_GUEST_UFO) | \
+ (1ULL << VIRTIO_NET_F_GUEST_USO4) | \
+ (1ULL << VIRTIO_NET_F_GUEST_USO6))

struct virtnet_stat_desc {
char desc[ETH_GSTRING_LEN];
@@ -2530,7 +2534,9 @@ static int virtnet_xdp_set(struct net_device *dev, struct bpf_prog *prog,
virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_TSO6) ||
virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_ECN) ||
virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_UFO) ||
- virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_CSUM))) {
+ virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_CSUM) ||
+ virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_USO4) ||
+ virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_USO6))) {
NL_SET_ERR_MSG_MOD(extack, "Can't set XDP while host is implementing GRO_HW/CSUM, disable GRO_HW/CSUM first");
return -EOPNOTSUPP;
}
@@ -3155,6 +3161,8 @@ static int virtnet_probe(struct virtio_device *vdev)
dev->hw_features |= NETIF_F_TSO6;
if (virtio_has_feature(vdev, VIRTIO_NET_F_HOST_ECN))
dev->hw_features |= NETIF_F_TSO_ECN;
+ if (virtio_has_feature(vdev, VIRTIO_NET_F_HOST_USO))
+ dev->hw_features |= NETIF_F_GSO_UDP_L4;

dev->features |= NETIF_F_GSO_ROBUST;

@@ -3169,6 +3177,9 @@ static int virtnet_probe(struct virtio_device *vdev)
dev->features |= NETIF_F_GRO_HW;
if (virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_GUEST_OFFLOADS))
dev->hw_features |= NETIF_F_GRO_HW;
+ if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_USO4) ||
+ virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_USO6))
+ dev->hw_features |= NETIF_F_LRO;

dev->vlan_features = dev->features;

@@ -3200,7 +3211,9 @@ static int virtnet_probe(struct virtio_device *vdev)
if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO4) ||
virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO6) ||
virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_ECN) ||
- virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_UFO))
+ virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_UFO) ||
+ virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_USO4) ||
+ virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_USO6))
vi->big_packets = true;

if (virtio_has_feature(vdev, VIRTIO_NET_F_MRG_RXBUF))
@@ -3400,6 +3413,7 @@ static struct virtio_device_id id_table[] = {
VIRTIO_NET_F_HOST_TSO4, VIRTIO_NET_F_HOST_UFO, VIRTIO_NET_F_HOST_TSO6, \
VIRTIO_NET_F_HOST_ECN, VIRTIO_NET_F_GUEST_TSO4, VIRTIO_NET_F_GUEST_TSO6, \
VIRTIO_NET_F_GUEST_ECN, VIRTIO_NET_F_GUEST_UFO, \
+ VIRTIO_NET_F_HOST_USO, VIRTIO_NET_F_GUEST_USO4, VIRTIO_NET_F_GUEST_USO6, \
VIRTIO_NET_F_MRG_RXBUF, VIRTIO_NET_F_STATUS, VIRTIO_NET_F_CTRL_VQ, \
VIRTIO_NET_F_CTRL_RX, VIRTIO_NET_F_CTRL_VLAN, \
VIRTIO_NET_F_GUEST_ANNOUNCE, VIRTIO_NET_F_MQ, \
--
2.34.1

2022-01-25 13:32:23

by Andrew Melnichenko

[permalink] [raw]
Subject: [RFC PATCH 2/5] driver/net/tun: Added features for USO.

Added support for USO4 and USO6, also added code for new ioctl TUNGETSUPPORTEDOFFLOADS.
For now, to "enable" USO, it's required to set both USO4 and USO6 simultaneously.
USO enables NETIF_F_GSO_UDP_L4.

Signed-off-by: Andrew Melnychenko <[email protected]>
---
drivers/net/tap.c | 18 ++++++++++++++++--
drivers/net/tun.c | 15 ++++++++++++++-
2 files changed, 30 insertions(+), 3 deletions(-)

diff --git a/drivers/net/tap.c b/drivers/net/tap.c
index 8e3a28ba6b28..82d742ba78b1 100644
--- a/drivers/net/tap.c
+++ b/drivers/net/tap.c
@@ -940,6 +940,10 @@ static int set_offload(struct tap_queue *q, unsigned long arg)
if (arg & TUN_F_TSO6)
feature_mask |= NETIF_F_TSO6;
}
+
+ /* TODO: for now USO4 and USO6 should work simultaneously */
+ if (arg & (TUN_F_USO4 | TUN_F_USO6) == (TUN_F_USO4 | TUN_F_USO6))
+ features |= NETIF_F_GSO_UDP_L4;
}

/* tun/tap driver inverts the usage for TSO offloads, where
@@ -950,7 +954,8 @@ static int set_offload(struct tap_queue *q, unsigned long arg)
* When user space turns off TSO, we turn off GSO/LRO so that
* user-space will not receive TSO frames.
*/
- if (feature_mask & (NETIF_F_TSO | NETIF_F_TSO6))
+ if (feature_mask & (NETIF_F_TSO | NETIF_F_TSO6) ||
+ feature_mask & (TUN_F_USO4 | TUN_F_USO6) == (TUN_F_USO4 | TUN_F_USO6))
features |= RX_OFFLOADS;
else
features &= ~RX_OFFLOADS;
@@ -979,6 +984,7 @@ static long tap_ioctl(struct file *file, unsigned int cmd,
unsigned short u;
int __user *sp = argp;
struct sockaddr sa;
+ unsigned int supported_offloads;
int s;
int ret;

@@ -1074,7 +1080,8 @@ static long tap_ioctl(struct file *file, unsigned int cmd,
case TUNSETOFFLOAD:
/* let the user check for future flags */
if (arg & ~(TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6 |
- TUN_F_TSO_ECN | TUN_F_UFO))
+ TUN_F_TSO_ECN | TUN_F_UFO |
+ TUN_F_USO4 | TUN_F_USO6))
return -EINVAL;

rtnl_lock();
@@ -1082,6 +1089,13 @@ static long tap_ioctl(struct file *file, unsigned int cmd,
rtnl_unlock();
return ret;

+ case TUNGETSUPPORTEDOFFLOADS:
+ supported_offloads = TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6 |
+ TUN_F_TSO_ECN | TUN_F_UFO | TUN_F_USO4 | TUN_F_USO6;
+ if (copy_to_user(&arg, &supported_offloads, sizeof(supported_offloads)))
+ return -EFAULT;
+ return 0;
+
case SIOCGIFHWADDR:
rtnl_lock();
tap = tap_get_tap_dev(q);
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index fed85447701a..4f2105d1e6f1 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -185,7 +185,7 @@ struct tun_struct {
struct net_device *dev;
netdev_features_t set_features;
#define TUN_USER_FEATURES (NETIF_F_HW_CSUM|NETIF_F_TSO_ECN|NETIF_F_TSO| \
- NETIF_F_TSO6)
+ NETIF_F_TSO6 | NETIF_F_GSO_UDP_L4)

int align;
int vnet_hdr_sz;
@@ -2821,6 +2821,12 @@ static int set_offload(struct tun_struct *tun, unsigned long arg)
}

arg &= ~TUN_F_UFO;
+
+ /* TODO: for now USO4 and USO6 should work simultaneously */
+ if (arg & TUN_F_USO4 && arg & TUN_F_USO6) {
+ features |= NETIF_F_GSO_UDP_L4;
+ arg &= ~(TUN_F_USO4 | TUN_F_USO6);
+ }
}

/* This gives the user a way to test for new features in future by
@@ -2991,6 +2997,7 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
int sndbuf;
int vnet_hdr_sz;
int le;
+ unsigned int supported_offloads;
int ret;
bool do_notify = false;

@@ -3154,6 +3161,12 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
case TUNSETOFFLOAD:
ret = set_offload(tun, arg);
break;
+ case TUNGETSUPPORTEDOFFLOADS:
+ supported_offloads = TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6 |
+ TUN_F_TSO_ECN | TUN_F_UFO | TUN_F_USO4 | TUN_F_USO6;
+ if (copy_to_user(&arg, &supported_offloads, sizeof(supported_offloads)))
+ ret = -EFAULT;
+ break;

case TUNSETTXFILTER:
/* Can be set only for TAPs */
--
2.34.1

2022-01-26 20:26:34

by Xuan Zhuo

[permalink] [raw]
Subject: Re: [RFC PATCH 0/5] TUN/VirtioNet USO features support.

On Tue, 25 Jan 2022 10:46:57 +0200, Andrew Melnychenko <[email protected]> wrote:
> Added new offloads for TUN devices TUN_F_USO4 and TUN_F_USO6.
> Technically they enable NETIF_F_GSO_UDP_L4
> (and only if USO4 & USO6 are set simultaneously).
> It allows to transmission of large UDP packets.
>
> Different features USO4 and USO6 are required for qemu where Windows guests can
> enable disable USO receives for IPv4 and IPv6 separately.
> On the other side, Linux can't really differentiate USO4 and USO6, for now.
> For now, to enable USO for TUN it requires enabling USO4 and USO6 together.
> In the future, there would be a mechanism to control UDP_L4 GSO separately.
>
> Test it WIP Qemu https://github.com/daynix/qemu/tree/Dev_USOv2
>
> New types for VirtioNet already on mailing:
> https://lists.oasis-open.org/archives/virtio-comment/202110/msg00010.html

Seems like this hasn't been upvoted yet.

https://github.com/oasis-tcs/virtio-spec#use-of-github-issues

Thanks.

>
> Also, there is a known issue with transmitting packages between two guests.
> Without hacks with skb's GSO - packages are still segmented on the host's postrouting.
>
> Andrew Melnychenko (5):
> uapi/linux/if_tun.h: Added new ioctl for tun/tap.
> driver/net/tun: Added features for USO.
> uapi/linux/virtio_net.h: Added USO types.
> linux/virtio_net.h: Added Support for GSO_UDP_L4 offload.
> drivers/net/virtio_net.c: Added USO support.
>
> drivers/net/tap.c | 18 ++++++++++++++++--
> drivers/net/tun.c | 15 ++++++++++++++-
> drivers/net/virtio_net.c | 22 ++++++++++++++++++----
> include/linux/virtio_net.h | 11 +++++++++++
> include/uapi/linux/if_tun.h | 3 +++
> include/uapi/linux/virtio_net.h | 4 ++++
> 6 files changed, 66 insertions(+), 7 deletions(-)
>
> --
> 2.34.1
>
> _______________________________________________
> Virtualization mailing list
> [email protected]
> https://lists.linuxfoundation.org/mailman/listinfo/virtualization

2022-01-26 20:35:01

by Yuri Benditovich

[permalink] [raw]
Subject: Re: [RFC PATCH 0/5] TUN/VirtioNet USO features support.

On Wed, Jan 26, 2022 at 9:54 AM Xuan Zhuo <[email protected]> wrote:
>
> On Tue, 25 Jan 2022 10:46:57 +0200, Andrew Melnychenko <[email protected]> wrote:
> > Added new offloads for TUN devices TUN_F_USO4 and TUN_F_USO6.
> > Technically they enable NETIF_F_GSO_UDP_L4
> > (and only if USO4 & USO6 are set simultaneously).
> > It allows to transmission of large UDP packets.
> >
> > Different features USO4 and USO6 are required for qemu where Windows guests can
> > enable disable USO receives for IPv4 and IPv6 separately.
> > On the other side, Linux can't really differentiate USO4 and USO6, for now.
> > For now, to enable USO for TUN it requires enabling USO4 and USO6 together.
> > In the future, there would be a mechanism to control UDP_L4 GSO separately.
> >
> > Test it WIP Qemu https://github.com/daynix/qemu/tree/Dev_USOv2
> >
> > New types for VirtioNet already on mailing:
> > https://lists.oasis-open.org/archives/virtio-comment/202110/msg00010.html
>
> Seems like this hasn't been upvoted yet.
>
> https://github.com/oasis-tcs/virtio-spec#use-of-github-issues

Yes, correct. This is a reason why this series of patches is RFC.

>
> Thanks.
>
> >
> > Also, there is a known issue with transmitting packages between two guests.
> > Without hacks with skb's GSO - packages are still segmented on the host's postrouting.
> >
> > Andrew Melnychenko (5):
> > uapi/linux/if_tun.h: Added new ioctl for tun/tap.
> > driver/net/tun: Added features for USO.
> > uapi/linux/virtio_net.h: Added USO types.
> > linux/virtio_net.h: Added Support for GSO_UDP_L4 offload.
> > drivers/net/virtio_net.c: Added USO support.
> >
> > drivers/net/tap.c | 18 ++++++++++++++++--
> > drivers/net/tun.c | 15 ++++++++++++++-
> > drivers/net/virtio_net.c | 22 ++++++++++++++++++----
> > include/linux/virtio_net.h | 11 +++++++++++
> > include/uapi/linux/if_tun.h | 3 +++
> > include/uapi/linux/virtio_net.h | 4 ++++
> > 6 files changed, 66 insertions(+), 7 deletions(-)
> >
> > --
> > 2.34.1
> >
> > _______________________________________________
> > Virtualization mailing list
> > [email protected]
> > https://lists.linuxfoundation.org/mailman/listinfo/virtualization

2022-02-08 13:57:33

by Andrew Melnichenko

[permalink] [raw]
Subject: Re: [RFC PATCH 0/5] TUN/VirtioNet USO features support.

Hi people,
Can you please review this series?

On Wed, Jan 26, 2022 at 10:32 AM Yuri Benditovich
<[email protected]> wrote:
>
> On Wed, Jan 26, 2022 at 9:54 AM Xuan Zhuo <[email protected]> wrote:
> >
> > On Tue, 25 Jan 2022 10:46:57 +0200, Andrew Melnychenko <[email protected]> wrote:
> > > Added new offloads for TUN devices TUN_F_USO4 and TUN_F_USO6.
> > > Technically they enable NETIF_F_GSO_UDP_L4
> > > (and only if USO4 & USO6 are set simultaneously).
> > > It allows to transmission of large UDP packets.
> > >
> > > Different features USO4 and USO6 are required for qemu where Windows guests can
> > > enable disable USO receives for IPv4 and IPv6 separately.
> > > On the other side, Linux can't really differentiate USO4 and USO6, for now.
> > > For now, to enable USO for TUN it requires enabling USO4 and USO6 together.
> > > In the future, there would be a mechanism to control UDP_L4 GSO separately.
> > >
> > > Test it WIP Qemu https://github.com/daynix/qemu/tree/Dev_USOv2
> > >
> > > New types for VirtioNet already on mailing:
> > > https://lists.oasis-open.org/archives/virtio-comment/202110/msg00010.html
> >
> > Seems like this hasn't been upvoted yet.
> >
> > https://github.com/oasis-tcs/virtio-spec#use-of-github-issues
>
> Yes, correct. This is a reason why this series of patches is RFC.
>
> >
> > Thanks.
> >
> > >
> > > Also, there is a known issue with transmitting packages between two guests.
> > > Without hacks with skb's GSO - packages are still segmented on the host's postrouting.
> > >
> > > Andrew Melnychenko (5):
> > > uapi/linux/if_tun.h: Added new ioctl for tun/tap.
> > > driver/net/tun: Added features for USO.
> > > uapi/linux/virtio_net.h: Added USO types.
> > > linux/virtio_net.h: Added Support for GSO_UDP_L4 offload.
> > > drivers/net/virtio_net.c: Added USO support.
> > >
> > > drivers/net/tap.c | 18 ++++++++++++++++--
> > > drivers/net/tun.c | 15 ++++++++++++++-
> > > drivers/net/virtio_net.c | 22 ++++++++++++++++++----
> > > include/linux/virtio_net.h | 11 +++++++++++
> > > include/uapi/linux/if_tun.h | 3 +++
> > > include/uapi/linux/virtio_net.h | 4 ++++
> > > 6 files changed, 66 insertions(+), 7 deletions(-)
> > >
> > > --
> > > 2.34.1
> > >
> > > _______________________________________________
> > > Virtualization mailing list
> > > [email protected]
> > > https://lists.linuxfoundation.org/mailman/listinfo/virtualization

2022-02-09 04:06:25

by Jakub Kicinski

[permalink] [raw]
Subject: Re: [RFC PATCH 0/5] TUN/VirtioNet USO features support.

On Tue, 8 Feb 2022 15:09:21 +0200 Andrew Melnichenko wrote:
> Hi people,
> Can you please review this series?

Adding Willem, he might be interested.

2022-02-09 10:24:23

by Jason Wang

[permalink] [raw]
Subject: Re: [RFC PATCH 0/5] TUN/VirtioNet USO features support.


在 2022/2/8 下午9:09, Andrew Melnichenko 写道:
> Hi people,
> Can you please review this series?


Are there any performance number to demonstrate the difference?

Thanks


>
> On Wed, Jan 26, 2022 at 10:32 AM Yuri Benditovich
> <[email protected]> wrote:
>> On Wed, Jan 26, 2022 at 9:54 AM Xuan Zhuo <[email protected]> wrote:
>>> On Tue, 25 Jan 2022 10:46:57 +0200, Andrew Melnychenko <[email protected]> wrote:
>>>> Added new offloads for TUN devices TUN_F_USO4 and TUN_F_USO6.
>>>> Technically they enable NETIF_F_GSO_UDP_L4
>>>> (and only if USO4 & USO6 are set simultaneously).
>>>> It allows to transmission of large UDP packets.
>>>>
>>>> Different features USO4 and USO6 are required for qemu where Windows guests can
>>>> enable disable USO receives for IPv4 and IPv6 separately.
>>>> On the other side, Linux can't really differentiate USO4 and USO6, for now.
>>>> For now, to enable USO for TUN it requires enabling USO4 and USO6 together.
>>>> In the future, there would be a mechanism to control UDP_L4 GSO separately.
>>>>
>>>> Test it WIP Qemu https://github.com/daynix/qemu/tree/Dev_USOv2
>>>>
>>>> New types for VirtioNet already on mailing:
>>>> https://lists.oasis-open.org/archives/virtio-comment/202110/msg00010.html
>>> Seems like this hasn't been upvoted yet.
>>>
>>> https://github.com/oasis-tcs/virtio-spec#use-of-github-issues
>> Yes, correct. This is a reason why this series of patches is RFC.
>>
>>> Thanks.
>>>
>>>> Also, there is a known issue with transmitting packages between two guests.
>>>> Without hacks with skb's GSO - packages are still segmented on the host's postrouting.
>>>>
>>>> Andrew Melnychenko (5):
>>>> uapi/linux/if_tun.h: Added new ioctl for tun/tap.
>>>> driver/net/tun: Added features for USO.
>>>> uapi/linux/virtio_net.h: Added USO types.
>>>> linux/virtio_net.h: Added Support for GSO_UDP_L4 offload.
>>>> drivers/net/virtio_net.c: Added USO support.
>>>>
>>>> drivers/net/tap.c | 18 ++++++++++++++++--
>>>> drivers/net/tun.c | 15 ++++++++++++++-
>>>> drivers/net/virtio_net.c | 22 ++++++++++++++++++----
>>>> include/linux/virtio_net.h | 11 +++++++++++
>>>> include/uapi/linux/if_tun.h | 3 +++
>>>> include/uapi/linux/virtio_net.h | 4 ++++
>>>> 6 files changed, 66 insertions(+), 7 deletions(-)
>>>>
>>>> --
>>>> 2.34.1
>>>>
>>>> _______________________________________________
>>>> Virtualization mailing list
>>>> [email protected]
>>>> https://lists.linuxfoundation.org/mailman/listinfo/virtualization


2022-02-09 12:35:11

by Jason Wang

[permalink] [raw]
Subject: Re: [RFC PATCH 4/5] linux/virtio_net.h: Added Support for GSO_UDP_L4 offload.


在 2022/1/25 下午4:47, Andrew Melnychenko 写道:
> Now, it's possible to convert vnet packets from/to skb.


I suggest to change the title to "net: support XXX offload in vnet header"

Thanks


>
> Signed-off-by: Andrew Melnychenko <[email protected]>
> ---
> include/linux/virtio_net.h | 11 +++++++++++
> 1 file changed, 11 insertions(+)
>
> diff --git a/include/linux/virtio_net.h b/include/linux/virtio_net.h
> index a960de68ac69..9311d41d0a81 100644
> --- a/include/linux/virtio_net.h
> +++ b/include/linux/virtio_net.h
> @@ -17,6 +17,9 @@ static inline bool virtio_net_hdr_match_proto(__be16 protocol, __u8 gso_type)
> case VIRTIO_NET_HDR_GSO_UDP:
> return protocol == cpu_to_be16(ETH_P_IP) ||
> protocol == cpu_to_be16(ETH_P_IPV6);
> + case VIRTIO_NET_HDR_GSO_UDP_L4:
> + return protocol == cpu_to_be16(ETH_P_IP) ||
> + protocol == cpu_to_be16(ETH_P_IPV6);
> default:
> return false;
> }
> @@ -31,6 +34,7 @@ static inline int virtio_net_hdr_set_proto(struct sk_buff *skb,
> switch (hdr->gso_type & ~VIRTIO_NET_HDR_GSO_ECN) {
> case VIRTIO_NET_HDR_GSO_TCPV4:
> case VIRTIO_NET_HDR_GSO_UDP:
> + case VIRTIO_NET_HDR_GSO_UDP_L4:
> skb->protocol = cpu_to_be16(ETH_P_IP);
> break;
> case VIRTIO_NET_HDR_GSO_TCPV6:
> @@ -69,6 +73,11 @@ static inline int virtio_net_hdr_to_skb(struct sk_buff *skb,
> ip_proto = IPPROTO_UDP;
> thlen = sizeof(struct udphdr);
> break;
> + case VIRTIO_NET_HDR_GSO_UDP_L4:
> + gso_type = SKB_GSO_UDP_L4;
> + ip_proto = IPPROTO_UDP;
> + thlen = sizeof(struct udphdr);
> + break;
> default:
> return -EINVAL;
> }
> @@ -182,6 +191,8 @@ static inline int virtio_net_hdr_from_skb(const struct sk_buff *skb,
> hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
> else if (sinfo->gso_type & SKB_GSO_TCPV6)
> hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV6;
> + else if (sinfo->gso_type & SKB_GSO_UDP_L4)
> + hdr->gso_type = VIRTIO_NET_HDR_GSO_UDP_L4;
> else
> return -EINVAL;
> if (sinfo->gso_type & SKB_GSO_TCP_ECN)


2022-02-09 12:35:18

by Jason Wang

[permalink] [raw]
Subject: Re: [RFC PATCH 3/5] uapi/linux/virtio_net.h: Added USO types.


在 2022/1/25 下午4:47, Andrew Melnychenko 写道:
> Added new GSO type for USO: VIRTIO_NET_HDR_GSO_UDP_L4.
> Feature VIRTIO_NET_F_HOST_USO allows to enable NETIF_F_GSO_UDP_L4.
> Separated VIRTIO_NET_F_GUEST_USO4 & VIRTIO_NET_F_GUEST_USO6 features
> required for Windows guests.
>
> Signed-off-by: Andrew Melnychenko <[email protected]>
> ---
> include/uapi/linux/virtio_net.h | 4 ++++
> 1 file changed, 4 insertions(+)
>
> diff --git a/include/uapi/linux/virtio_net.h b/include/uapi/linux/virtio_net.h
> index 3f55a4215f11..620addc5767b 100644
> --- a/include/uapi/linux/virtio_net.h
> +++ b/include/uapi/linux/virtio_net.h
> @@ -56,6 +56,9 @@
> #define VIRTIO_NET_F_MQ 22 /* Device supports Receive Flow
> * Steering */
> #define VIRTIO_NET_F_CTRL_MAC_ADDR 23 /* Set MAC address */
> +#define VIRTIO_NET_F_GUEST_USO4 54 /* Guest can handle USOv4 in. */
> +#define VIRTIO_NET_F_GUEST_USO6 55 /* Guest can handle USOv6 in. */
> +#define VIRTIO_NET_F_HOST_USO 56 /* Host can handle USO in. */


I think it's better to be consistent here. Either we split in both guest
and host or not.

Thanks


>
> #define VIRTIO_NET_F_HASH_REPORT 57 /* Supports hash report */
> #define VIRTIO_NET_F_RSS 60 /* Supports RSS RX steering */
> @@ -130,6 +133,7 @@ struct virtio_net_hdr_v1 {
> #define VIRTIO_NET_HDR_GSO_TCPV4 1 /* GSO frame, IPv4 TCP (TSO) */
> #define VIRTIO_NET_HDR_GSO_UDP 3 /* GSO frame, IPv4 UDP (UFO) */
> #define VIRTIO_NET_HDR_GSO_TCPV6 4 /* GSO frame, IPv6 TCP */
> +#define VIRTIO_NET_HDR_GSO_UDP_L4 5 /* GSO frame, IPv4 & IPv6 UDP (USO) */
> #define VIRTIO_NET_HDR_GSO_ECN 0x80 /* TCP has ECN set */
> __u8 gso_type;
> __virtio16 hdr_len; /* Ethernet + IP + tcp/udp hdrs */


2022-02-09 12:35:48

by Jason Wang

[permalink] [raw]
Subject: Re: [RFC PATCH 5/5] drivers/net/virtio_net.c: Added USO support.


在 2022/1/25 下午4:47, Andrew Melnychenko 写道:
> Now, it possible to enable GSO_UDP_L4("tx-udp-segmentation") for VirtioNet.
>
> Signed-off-by: Andrew Melnychenko <[email protected]>
> ---
> drivers/net/virtio_net.c | 22 ++++++++++++++++++----
> 1 file changed, 18 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> index a801ea40908f..a45eee022be4 100644
> --- a/drivers/net/virtio_net.c
> +++ b/drivers/net/virtio_net.c
> @@ -60,13 +60,17 @@ static const unsigned long guest_offloads[] = {
> VIRTIO_NET_F_GUEST_TSO6,
> VIRTIO_NET_F_GUEST_ECN,
> VIRTIO_NET_F_GUEST_UFO,
> - VIRTIO_NET_F_GUEST_CSUM
> + VIRTIO_NET_F_GUEST_CSUM,
> + VIRTIO_NET_F_GUEST_USO4,
> + VIRTIO_NET_F_GUEST_USO6
> };
>
> #define GUEST_OFFLOAD_GRO_HW_MASK ((1ULL << VIRTIO_NET_F_GUEST_TSO4) | \
> (1ULL << VIRTIO_NET_F_GUEST_TSO6) | \
> (1ULL << VIRTIO_NET_F_GUEST_ECN) | \
> - (1ULL << VIRTIO_NET_F_GUEST_UFO))
> + (1ULL << VIRTIO_NET_F_GUEST_UFO) | \
> + (1ULL << VIRTIO_NET_F_GUEST_USO4) | \
> + (1ULL << VIRTIO_NET_F_GUEST_USO6))
>
> struct virtnet_stat_desc {
> char desc[ETH_GSTRING_LEN];
> @@ -2530,7 +2534,9 @@ static int virtnet_xdp_set(struct net_device *dev, struct bpf_prog *prog,
> virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_TSO6) ||
> virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_ECN) ||
> virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_UFO) ||
> - virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_CSUM))) {
> + virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_CSUM) ||
> + virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_USO4) ||
> + virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_USO6))) {
> NL_SET_ERR_MSG_MOD(extack, "Can't set XDP while host is implementing GRO_HW/CSUM, disable GRO_HW/CSUM first");
> return -EOPNOTSUPP;
> }
> @@ -3155,6 +3161,8 @@ static int virtnet_probe(struct virtio_device *vdev)
> dev->hw_features |= NETIF_F_TSO6;
> if (virtio_has_feature(vdev, VIRTIO_NET_F_HOST_ECN))
> dev->hw_features |= NETIF_F_TSO_ECN;
> + if (virtio_has_feature(vdev, VIRTIO_NET_F_HOST_USO))
> + dev->hw_features |= NETIF_F_GSO_UDP_L4;
>
> dev->features |= NETIF_F_GSO_ROBUST;
>
> @@ -3169,6 +3177,9 @@ static int virtnet_probe(struct virtio_device *vdev)
> dev->features |= NETIF_F_GRO_HW;
> if (virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_GUEST_OFFLOADS))
> dev->hw_features |= NETIF_F_GRO_HW;
> + if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_USO4) ||
> + virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_USO6))
> + dev->hw_features |= NETIF_F_LRO;


I think we need to use GRO_HW, see dbcf24d153884 ("virtio-net: use
NETIF_F_GRO_HW instead of NETIF_F_LRO"

Thanks


>
> dev->vlan_features = dev->features;
>
> @@ -3200,7 +3211,9 @@ static int virtnet_probe(struct virtio_device *vdev)
> if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO4) ||
> virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO6) ||
> virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_ECN) ||
> - virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_UFO))
> + virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_UFO) ||
> + virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_USO4) ||
> + virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_USO6))
> vi->big_packets = true;
>
> if (virtio_has_feature(vdev, VIRTIO_NET_F_MRG_RXBUF))
> @@ -3400,6 +3413,7 @@ static struct virtio_device_id id_table[] = {
> VIRTIO_NET_F_HOST_TSO4, VIRTIO_NET_F_HOST_UFO, VIRTIO_NET_F_HOST_TSO6, \
> VIRTIO_NET_F_HOST_ECN, VIRTIO_NET_F_GUEST_TSO4, VIRTIO_NET_F_GUEST_TSO6, \
> VIRTIO_NET_F_GUEST_ECN, VIRTIO_NET_F_GUEST_UFO, \
> + VIRTIO_NET_F_HOST_USO, VIRTIO_NET_F_GUEST_USO4, VIRTIO_NET_F_GUEST_USO6, \
> VIRTIO_NET_F_MRG_RXBUF, VIRTIO_NET_F_STATUS, VIRTIO_NET_F_CTRL_VQ, \
> VIRTIO_NET_F_CTRL_RX, VIRTIO_NET_F_CTRL_VLAN, \
> VIRTIO_NET_F_GUEST_ANNOUNCE, VIRTIO_NET_F_MQ, \


2022-02-09 13:40:45

by Jason Wang

[permalink] [raw]
Subject: Re: [RFC PATCH 2/5] driver/net/tun: Added features for USO.


在 2022/1/25 下午4:46, Andrew Melnychenko 写道:
> Added support for USO4 and USO6, also added code for new ioctl TUNGETSUPPORTEDOFFLOADS.
> For now, to "enable" USO, it's required to set both USO4 and USO6 simultaneously.
> USO enables NETIF_F_GSO_UDP_L4.
>
> Signed-off-by: Andrew Melnychenko <[email protected]>
> ---
> drivers/net/tap.c | 18 ++++++++++++++++--
> drivers/net/tun.c | 15 ++++++++++++++-
> 2 files changed, 30 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/net/tap.c b/drivers/net/tap.c
> index 8e3a28ba6b28..82d742ba78b1 100644
> --- a/drivers/net/tap.c
> +++ b/drivers/net/tap.c
> @@ -940,6 +940,10 @@ static int set_offload(struct tap_queue *q, unsigned long arg)
> if (arg & TUN_F_TSO6)
> feature_mask |= NETIF_F_TSO6;
> }
> +
> + /* TODO: for now USO4 and USO6 should work simultaneously */
> + if (arg & (TUN_F_USO4 | TUN_F_USO6) == (TUN_F_USO4 | TUN_F_USO6))
> + features |= NETIF_F_GSO_UDP_L4;


If kernel doesn't want to split the GSO_UDP features, I wonder how much
value to keep separated features for TUN and virtio.

Thanks


> }
>
> /* tun/tap driver inverts the usage for TSO offloads, where
> @@ -950,7 +954,8 @@ static int set_offload(struct tap_queue *q, unsigned long arg)
> * When user space turns off TSO, we turn off GSO/LRO so that
> * user-space will not receive TSO frames.
> */
> - if (feature_mask & (NETIF_F_TSO | NETIF_F_TSO6))
> + if (feature_mask & (NETIF_F_TSO | NETIF_F_TSO6) ||
> + feature_mask & (TUN_F_USO4 | TUN_F_USO6) == (TUN_F_USO4 | TUN_F_USO6))
> features |= RX_OFFLOADS;
> else
> features &= ~RX_OFFLOADS;
> @@ -979,6 +984,7 @@ static long tap_ioctl(struct file *file, unsigned int cmd,
> unsigned short u;
> int __user *sp = argp;
> struct sockaddr sa;
> + unsigned int supported_offloads;
> int s;
> int ret;
>
> @@ -1074,7 +1080,8 @@ static long tap_ioctl(struct file *file, unsigned int cmd,
> case TUNSETOFFLOAD:
> /* let the user check for future flags */
> if (arg & ~(TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6 |
> - TUN_F_TSO_ECN | TUN_F_UFO))
> + TUN_F_TSO_ECN | TUN_F_UFO |
> + TUN_F_USO4 | TUN_F_USO6))
> return -EINVAL;
>
> rtnl_lock();
> @@ -1082,6 +1089,13 @@ static long tap_ioctl(struct file *file, unsigned int cmd,
> rtnl_unlock();
> return ret;
>
> + case TUNGETSUPPORTEDOFFLOADS:
> + supported_offloads = TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6 |
> + TUN_F_TSO_ECN | TUN_F_UFO | TUN_F_USO4 | TUN_F_USO6;
> + if (copy_to_user(&arg, &supported_offloads, sizeof(supported_offloads)))
> + return -EFAULT;
> + return 0;
> +
> case SIOCGIFHWADDR:
> rtnl_lock();
> tap = tap_get_tap_dev(q);
> diff --git a/drivers/net/tun.c b/drivers/net/tun.c
> index fed85447701a..4f2105d1e6f1 100644
> --- a/drivers/net/tun.c
> +++ b/drivers/net/tun.c
> @@ -185,7 +185,7 @@ struct tun_struct {
> struct net_device *dev;
> netdev_features_t set_features;
> #define TUN_USER_FEATURES (NETIF_F_HW_CSUM|NETIF_F_TSO_ECN|NETIF_F_TSO| \
> - NETIF_F_TSO6)
> + NETIF_F_TSO6 | NETIF_F_GSO_UDP_L4)
>
> int align;
> int vnet_hdr_sz;
> @@ -2821,6 +2821,12 @@ static int set_offload(struct tun_struct *tun, unsigned long arg)
> }
>
> arg &= ~TUN_F_UFO;
> +
> + /* TODO: for now USO4 and USO6 should work simultaneously */
> + if (arg & TUN_F_USO4 && arg & TUN_F_USO6) {
> + features |= NETIF_F_GSO_UDP_L4;
> + arg &= ~(TUN_F_USO4 | TUN_F_USO6);
> + }
> }
>
> /* This gives the user a way to test for new features in future by
> @@ -2991,6 +2997,7 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
> int sndbuf;
> int vnet_hdr_sz;
> int le;
> + unsigned int supported_offloads;
> int ret;
> bool do_notify = false;
>
> @@ -3154,6 +3161,12 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
> case TUNSETOFFLOAD:
> ret = set_offload(tun, arg);
> break;
> + case TUNGETSUPPORTEDOFFLOADS:
> + supported_offloads = TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6 |
> + TUN_F_TSO_ECN | TUN_F_UFO | TUN_F_USO4 | TUN_F_USO6;
> + if (copy_to_user(&arg, &supported_offloads, sizeof(supported_offloads)))
> + ret = -EFAULT;
> + break;
>
> case TUNSETTXFILTER:
> /* Can be set only for TAPs */


2022-02-22 14:41:16

by Andrew Melnichenko

[permalink] [raw]
Subject: Re: [RFC PATCH 0/5] TUN/VirtioNet USO features support.

Hi all,

On Wed, Feb 9, 2022 at 7:41 AM Jason Wang <[email protected]> wrote:
>
>
> 在 2022/2/8 下午9:09, Andrew Melnichenko 写道:
> > Hi people,
> > Can you please review this series?
>
>
> Are there any performance number to demonstrate the difference?
>
> Thanks
>

Yeah, I've used udpgso_bench from Linux to test.
Here are some numbers:

Sending packets with size 10000

Without USO:
```
$ ./udpgso_bench_tx -4 -D 192.168.15.1 -s 10000 -S 1000
random: crng init done
random: 7 urandom warning(s) missed due to ratelimiting
udp tx: 36 MB/s 3863 calls/s 3863 msg/s
udp tx: 32 MB/s 3360 calls/s 3360 msg/s
udp tx: 31 MB/s 3340 calls/s 3340 msg/s
udp tx: 31 MB/s 3353 calls/s 3353 msg/s
udp tx: 32 MB/s 3359 calls/s 3359 msg/s
udp tx: 32 MB/s 3370 calls/s 3370 msg/s
```

With USO:
```
$ ./udpgso_bench_tx -4 -D 192.168.15.1 -s 10000 -S 1000
random: crng init done
random: 7 urandom warning(s) missed due to ratelimiting
udp tx: 120 MB/s 12596 calls/s 12596 msg/s
udp tx: 122 MB/s 12885 calls/s 12885 msg/s
udp tx: 120 MB/s 12667 calls/s 12667 msg/s
udp tx: 123 MB/s 12969 calls/s 12969 msg/s
udp tx: 116 MB/s 12232 calls/s 12232 msg/s
udp tx: 108 MB/s 11389 calls/s 11389 msg/s
```


>
> >
> > On Wed, Jan 26, 2022 at 10:32 AM Yuri Benditovich
> > <[email protected]> wrote:
> >> On Wed, Jan 26, 2022 at 9:54 AM Xuan Zhuo <[email protected]> wrote:
> >>> On Tue, 25 Jan 2022 10:46:57 +0200, Andrew Melnychenko <[email protected]> wrote:
> >>>> Added new offloads for TUN devices TUN_F_USO4 and TUN_F_USO6.
> >>>> Technically they enable NETIF_F_GSO_UDP_L4
> >>>> (and only if USO4 & USO6 are set simultaneously).
> >>>> It allows to transmission of large UDP packets.
> >>>>
> >>>> Different features USO4 and USO6 are required for qemu where Windows guests can
> >>>> enable disable USO receives for IPv4 and IPv6 separately.
> >>>> On the other side, Linux can't really differentiate USO4 and USO6, for now.
> >>>> For now, to enable USO for TUN it requires enabling USO4 and USO6 together.
> >>>> In the future, there would be a mechanism to control UDP_L4 GSO separately.
> >>>>
> >>>> Test it WIP Qemu https://github.com/daynix/qemu/tree/Dev_USOv2
> >>>>
> >>>> New types for VirtioNet already on mailing:
> >>>> https://lists.oasis-open.org/archives/virtio-comment/202110/msg00010.html
> >>> Seems like this hasn't been upvoted yet.
> >>>
> >>> https://github.com/oasis-tcs/virtio-spec#use-of-github-issues
> >> Yes, correct. This is a reason why this series of patches is RFC.
> >>
> >>> Thanks.
> >>>
> >>>> Also, there is a known issue with transmitting packages between two guests.
> >>>> Without hacks with skb's GSO - packages are still segmented on the host's postrouting.
> >>>>
> >>>> Andrew Melnychenko (5):
> >>>> uapi/linux/if_tun.h: Added new ioctl for tun/tap.
> >>>> driver/net/tun: Added features for USO.
> >>>> uapi/linux/virtio_net.h: Added USO types.
> >>>> linux/virtio_net.h: Added Support for GSO_UDP_L4 offload.
> >>>> drivers/net/virtio_net.c: Added USO support.
> >>>>
> >>>> drivers/net/tap.c | 18 ++++++++++++++++--
> >>>> drivers/net/tun.c | 15 ++++++++++++++-
> >>>> drivers/net/virtio_net.c | 22 ++++++++++++++++++----
> >>>> include/linux/virtio_net.h | 11 +++++++++++
> >>>> include/uapi/linux/if_tun.h | 3 +++
> >>>> include/uapi/linux/virtio_net.h | 4 ++++
> >>>> 6 files changed, 66 insertions(+), 7 deletions(-)
> >>>>
> >>>> --
> >>>> 2.34.1
> >>>>
> >>>> _______________________________________________
> >>>> Virtualization mailing list
> >>>> [email protected]
> >>>> https://lists.linuxfoundation.org/mailman/listinfo/virtualization
>

2022-02-22 15:13:09

by Andrew Melnichenko

[permalink] [raw]
Subject: Re: [RFC PATCH 3/5] uapi/linux/virtio_net.h: Added USO types.

Hi all,



On Wed, Feb 9, 2022 at 6:41 AM Jason Wang <[email protected]> wrote:
>
>
> 在 2022/1/25 下午4:47, Andrew Melnychenko 写道:
> > Added new GSO type for USO: VIRTIO_NET_HDR_GSO_UDP_L4.
> > Feature VIRTIO_NET_F_HOST_USO allows to enable NETIF_F_GSO_UDP_L4.
> > Separated VIRTIO_NET_F_GUEST_USO4 & VIRTIO_NET_F_GUEST_USO6 features
> > required for Windows guests.
> >
> > Signed-off-by: Andrew Melnychenko <[email protected]>
> > ---
> > include/uapi/linux/virtio_net.h | 4 ++++
> > 1 file changed, 4 insertions(+)
> >
> > diff --git a/include/uapi/linux/virtio_net.h b/include/uapi/linux/virtio_net.h
> > index 3f55a4215f11..620addc5767b 100644
> > --- a/include/uapi/linux/virtio_net.h
> > +++ b/include/uapi/linux/virtio_net.h
> > @@ -56,6 +56,9 @@
> > #define VIRTIO_NET_F_MQ 22 /* Device supports Receive Flow
> > * Steering */
> > #define VIRTIO_NET_F_CTRL_MAC_ADDR 23 /* Set MAC address */
> > +#define VIRTIO_NET_F_GUEST_USO4 54 /* Guest can handle USOv4 in. */
> > +#define VIRTIO_NET_F_GUEST_USO6 55 /* Guest can handle USOv6 in. */
> > +#define VIRTIO_NET_F_HOST_USO 56 /* Host can handle USO in. */
>
>
> I think it's better to be consistent here. Either we split in both guest
> and host or not.
>
> Thanks
>

The main reason that receives USO packets depends on the kernel, where
transmitting the feature that VirtIO implements.
Windows systems have the option to manipulate receive offload. That's
why there are two GUEST_USO features.
For HOST_USO - technically there is no point in "split" it, and there
is should not be any difference between IPv4/IPv6.
Technically, we either support transmitting big UDP packets or not.

>
> >
> > #define VIRTIO_NET_F_HASH_REPORT 57 /* Supports hash report */
> > #define VIRTIO_NET_F_RSS 60 /* Supports RSS RX steering */
> > @@ -130,6 +133,7 @@ struct virtio_net_hdr_v1 {
> > #define VIRTIO_NET_HDR_GSO_TCPV4 1 /* GSO frame, IPv4 TCP (TSO) */
> > #define VIRTIO_NET_HDR_GSO_UDP 3 /* GSO frame, IPv4 UDP (UFO) */
> > #define VIRTIO_NET_HDR_GSO_TCPV6 4 /* GSO frame, IPv6 TCP */
> > +#define VIRTIO_NET_HDR_GSO_UDP_L4 5 /* GSO frame, IPv4 & IPv6 UDP (USO) */
> > #define VIRTIO_NET_HDR_GSO_ECN 0x80 /* TCP has ECN set */
> > __u8 gso_type;
> > __virtio16 hdr_len; /* Ethernet + IP + tcp/udp hdrs */
>

2022-02-22 15:51:23

by Andrew Melnichenko

[permalink] [raw]
Subject: Re: [RFC PATCH 2/5] driver/net/tun: Added features for USO.

On Wed, Feb 9, 2022 at 6:39 AM Jason Wang <[email protected]> wrote:
>
>
> 在 2022/1/25 下午4:46, Andrew Melnychenko 写道:
> > Added support for USO4 and USO6, also added code for new ioctl TUNGETSUPPORTEDOFFLOADS.
> > For now, to "enable" USO, it's required to set both USO4 and USO6 simultaneously.
> > USO enables NETIF_F_GSO_UDP_L4.
> >
> > Signed-off-by: Andrew Melnychenko <[email protected]>
> > ---
> > drivers/net/tap.c | 18 ++++++++++++++++--
> > drivers/net/tun.c | 15 ++++++++++++++-
> > 2 files changed, 30 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/net/tap.c b/drivers/net/tap.c
> > index 8e3a28ba6b28..82d742ba78b1 100644
> > --- a/drivers/net/tap.c
> > +++ b/drivers/net/tap.c
> > @@ -940,6 +940,10 @@ static int set_offload(struct tap_queue *q, unsigned long arg)
> > if (arg & TUN_F_TSO6)
> > feature_mask |= NETIF_F_TSO6;
> > }
> > +
> > + /* TODO: for now USO4 and USO6 should work simultaneously */
> > + if (arg & (TUN_F_USO4 | TUN_F_USO6) == (TUN_F_USO4 | TUN_F_USO6))
> > + features |= NETIF_F_GSO_UDP_L4;
>
>
> If kernel doesn't want to split the GSO_UDP features, I wonder how much
> value to keep separated features for TUN and virtio.
>
> Thanks
>

It's important for Windows guests that may request USO receive only
for IPv4 or IPv6.
Or there is possible to implement one feature and change its
"meanings" when "split" happens.
I think it's a good idea to implement an interface for iUSO4/USO6 and
do it right away.

>
> > }
> >
> > /* tun/tap driver inverts the usage for TSO offloads, where
> > @@ -950,7 +954,8 @@ static int set_offload(struct tap_queue *q, unsigned long arg)
> > * When user space turns off TSO, we turn off GSO/LRO so that
> > * user-space will not receive TSO frames.
> > */
> > - if (feature_mask & (NETIF_F_TSO | NETIF_F_TSO6))
> > + if (feature_mask & (NETIF_F_TSO | NETIF_F_TSO6) ||
> > + feature_mask & (TUN_F_USO4 | TUN_F_USO6) == (TUN_F_USO4 | TUN_F_USO6))
> > features |= RX_OFFLOADS;
> > else
> > features &= ~RX_OFFLOADS;
> > @@ -979,6 +984,7 @@ static long tap_ioctl(struct file *file, unsigned int cmd,
> > unsigned short u;
> > int __user *sp = argp;
> > struct sockaddr sa;
> > + unsigned int supported_offloads;
> > int s;
> > int ret;
> >
> > @@ -1074,7 +1080,8 @@ static long tap_ioctl(struct file *file, unsigned int cmd,
> > case TUNSETOFFLOAD:
> > /* let the user check for future flags */
> > if (arg & ~(TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6 |
> > - TUN_F_TSO_ECN | TUN_F_UFO))
> > + TUN_F_TSO_ECN | TUN_F_UFO |
> > + TUN_F_USO4 | TUN_F_USO6))
> > return -EINVAL;
> >
> > rtnl_lock();
> > @@ -1082,6 +1089,13 @@ static long tap_ioctl(struct file *file, unsigned int cmd,
> > rtnl_unlock();
> > return ret;
> >
> > + case TUNGETSUPPORTEDOFFLOADS:
> > + supported_offloads = TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6 |
> > + TUN_F_TSO_ECN | TUN_F_UFO | TUN_F_USO4 | TUN_F_USO6;
> > + if (copy_to_user(&arg, &supported_offloads, sizeof(supported_offloads)))
> > + return -EFAULT;
> > + return 0;
> > +
> > case SIOCGIFHWADDR:
> > rtnl_lock();
> > tap = tap_get_tap_dev(q);
> > diff --git a/drivers/net/tun.c b/drivers/net/tun.c
> > index fed85447701a..4f2105d1e6f1 100644
> > --- a/drivers/net/tun.c
> > +++ b/drivers/net/tun.c
> > @@ -185,7 +185,7 @@ struct tun_struct {
> > struct net_device *dev;
> > netdev_features_t set_features;
> > #define TUN_USER_FEATURES (NETIF_F_HW_CSUM|NETIF_F_TSO_ECN|NETIF_F_TSO| \
> > - NETIF_F_TSO6)
> > + NETIF_F_TSO6 | NETIF_F_GSO_UDP_L4)
> >
> > int align;
> > int vnet_hdr_sz;
> > @@ -2821,6 +2821,12 @@ static int set_offload(struct tun_struct *tun, unsigned long arg)
> > }
> >
> > arg &= ~TUN_F_UFO;
> > +
> > + /* TODO: for now USO4 and USO6 should work simultaneously */
> > + if (arg & TUN_F_USO4 && arg & TUN_F_USO6) {
> > + features |= NETIF_F_GSO_UDP_L4;
> > + arg &= ~(TUN_F_USO4 | TUN_F_USO6);
> > + }
> > }
> >
> > /* This gives the user a way to test for new features in future by
> > @@ -2991,6 +2997,7 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
> > int sndbuf;
> > int vnet_hdr_sz;
> > int le;
> > + unsigned int supported_offloads;
> > int ret;
> > bool do_notify = false;
> >
> > @@ -3154,6 +3161,12 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
> > case TUNSETOFFLOAD:
> > ret = set_offload(tun, arg);
> > break;
> > + case TUNGETSUPPORTEDOFFLOADS:
> > + supported_offloads = TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6 |
> > + TUN_F_TSO_ECN | TUN_F_UFO | TUN_F_USO4 | TUN_F_USO6;
> > + if (copy_to_user(&arg, &supported_offloads, sizeof(supported_offloads)))
> > + ret = -EFAULT;
> > + break;
> >
> > case TUNSETTXFILTER:
> > /* Can be set only for TAPs */
>