mirror of
https://github.com/torvalds/linux.git
synced 2026-10-22 23:01:49 +02:00
gve: DQO: accept TSO packets with non-protocol gso_type bits
Since commit014c607f86("gve: add support for UDP GSO for DQO format"), gve_prep_tso() matches shinfo->gso_type exactly. gso_type is a bitmask, though: SKB_GSO_DODGY is set on every GSO packet that comes from tun/tap, packet sockets or other untrusted sources, and SKB_GSO_TCP_ECN and SKB_GSO_TCP_FIXEDID can be set as well. Such packets hit the default case, gve_tx_add_skb_dqo() fails and gve_try_tx_skb() drops them, counting them in tx_dropped. These packets do reach the driver: tcp_gso_segment() passes DODGY skbs through unsegmented to devices that support TSO, after recomputing gso_segs, so drivers must tolerate the bit. This breaks virtual machines behind a tap on GCE instances using the DQO queue formats. Every TSO packet forwarded from a guest (gso_type SKB_GSO_TCPV4 | SKB_GSO_DODGY) is dropped, and guest uploads slow to a crawl of retransmissions or stall entirely, while the host's own TSO traffic (gso_type SKB_GSO_TCPV4) is unaffected. On an n4 instance (DQO-QPL) with a Cloud Hypervisor guest, a 64 MB upload from the guest went from a 60 s timeout at ~0.9 MB/s to 0.19 s with this change, with tx_dropped no longer increasing. Host TCP with ECN is hit as well: gve advertises NETIF_F_TSO_ECN, so a TSO packet carrying CWR has SKB_GSO_TCP_ECN set and is dropped too. Restore the bitmask test that commit1b9f756344("gve: ignore nonrelevant GSO type bits when processing TSO headers") introduced for the same problem, keeping the UDP GSO support. While here, reload shinfo after skb_cow_head(). If the head was cloned, pskb_expand_head() moves skb_shared_info to the new head, and the pointer cached at function entry can then refer to memory that another clone frees. Fixes:014c607f86("gve: add support for UDP GSO for DQO format") Signed-off-by: Hannu Varjoranta <hannu@varjosoft.com> Reviewed-by: Eric Dumazet <edumazet@google.com> Reviewed-by: Ankit Garg <nktgrg@google.com> Reviewed-by: Harshitha Ramamurthy <hramamurthy@google.com> Link: https://patch.msgid.link/20260925115237.56465-1-hannu@varjosoft.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
parent
006c8b834a
commit
f8932b2c0c
|
|
@ -595,25 +595,25 @@ static int gve_prep_tso(struct sk_buff *skb)
|
|||
err = skb_cow_head(skb, 0);
|
||||
if (err < 0)
|
||||
return err;
|
||||
shinfo = skb_shinfo(skb);
|
||||
|
||||
l4_start = skb_transport_offset(skb);
|
||||
paylen = skb->len - l4_start;
|
||||
|
||||
switch (shinfo->gso_type) {
|
||||
case SKB_GSO_TCPV4:
|
||||
case SKB_GSO_TCPV6:
|
||||
/* gso_type is a bitmask: SKB_GSO_DODGY, SKB_GSO_TCP_ECN and
|
||||
* SKB_GSO_TCP_FIXEDID may be set alongside the protocol bit.
|
||||
*/
|
||||
if (shinfo->gso_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6)) {
|
||||
tcp = tcp_hdr(skb);
|
||||
csum_replace_by_diff(&tcp->check,
|
||||
(__force __wsum)htonl(paylen));
|
||||
header_len = skb_tcp_all_headers(skb);
|
||||
break;
|
||||
case SKB_GSO_UDP_L4:
|
||||
} else if (shinfo->gso_type & SKB_GSO_UDP_L4) {
|
||||
udp = udp_hdr(skb);
|
||||
csum_replace_by_diff(&udp->check,
|
||||
(__force __wsum)htonl(paylen));
|
||||
header_len = sizeof(struct udphdr) + l4_start;
|
||||
break;
|
||||
default:
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user