Message ID | 20240705032048.110896-1-chengcheng.luo@smartx.com (mailing list archive) |
---|---|
State | Changes Requested |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | Support for segment offloading on software interfaces for packets from virtual machine guests without the SKB_GSO_UDP_L4 flag. | expand |
echken wrote: > When running virtual machines on a host, and the guest uses a kernel > version below v6.2 (without commit https:// > github.com/torvalds/linux/commit/860b7f27b8f78564ca5a2f607e0820b2d352a562), Prefer format commit 860b7f27b8f7 ("linux/virtio_net.h: Support USO offload in vnet header.") > the UDP packets emitted from the guest do not include the SKB_GSO_UDP_L4 > flag in their skb gso_type. Therefore, UDP packets from such guests always > bypass the __udp_gso_segment during the udp4_ufo_fragment process and go > directly to software segmentation prematurely. GSO packets should have either SKB_GSO_UDP_L4 (UDP segmentation) or SKB_GSO_UDP (UDP fragmentation). Not both. Note that UFO is also long deprecated and discouraged. > When the guest sends UDP > packets significantly larger than the MSS, and there are software > interfaces in the data path, such as Geneve, this can lead to substantial > additional performance overhead. > > Signed-off-by: echken <chengcheng.luo@smartx.com> > --- > net/ipv4/udp_offload.c | 7 +++++++ > 1 file changed, 7 insertions(+) > > diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c > index 59448a2dbf2c..6aa5a97d8bde 100644 > --- a/net/ipv4/udp_offload.c > +++ b/net/ipv4/udp_offload.c > @@ -402,6 +402,13 @@ static struct sk_buff *udp4_ufo_fragment(struct sk_buff *skb, > if (unlikely(skb->len <= mss)) > goto out; > > + if (skb_gso_ok(skb, features | NETIF_F_GSO_ROBUST)) { > + /* Packet is from an untrusted source, reset gso_segs. */ > + skb_shinfo(skb)->gso_segs = DIV_ROUND_UP(skb->len - sizeof(*uh), > + mss); > + return NULL; > + } > + So what this really does is bypass software fragmentation in virtual devices that advertise SKB_GSO_UDP. That's fine, I suppose. But is not what the commit message currently says. > /* Do software UFO. Complete and fill in the UDP checksum as > * HW cannot do checksum of UDP packets sent as multiple > * IP fragments. > -- > 2.34.1 >
diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c index 59448a2dbf2c..6aa5a97d8bde 100644 --- a/net/ipv4/udp_offload.c +++ b/net/ipv4/udp_offload.c @@ -402,6 +402,13 @@ static struct sk_buff *udp4_ufo_fragment(struct sk_buff *skb, if (unlikely(skb->len <= mss)) goto out; + if (skb_gso_ok(skb, features | NETIF_F_GSO_ROBUST)) { + /* Packet is from an untrusted source, reset gso_segs. */ + skb_shinfo(skb)->gso_segs = DIV_ROUND_UP(skb->len - sizeof(*uh), + mss); + return NULL; + } + /* Do software UFO. Complete and fill in the UDP checksum as * HW cannot do checksum of UDP packets sent as multiple * IP fragments.
When running virtual machines on a host, and the guest uses a kernel version below v6.2 (without commit https:// github.com/torvalds/linux/commit/860b7f27b8f78564ca5a2f607e0820b2d352a562), the UDP packets emitted from the guest do not include the SKB_GSO_UDP_L4 flag in their skb gso_type. Therefore, UDP packets from such guests always bypass the __udp_gso_segment during the udp4_ufo_fragment process and go directly to software segmentation prematurely. When the guest sends UDP packets significantly larger than the MSS, and there are software interfaces in the data path, such as Geneve, this can lead to substantial additional performance overhead. Signed-off-by: echken <chengcheng.luo@smartx.com> --- net/ipv4/udp_offload.c | 7 +++++++ 1 file changed, 7 insertions(+)