* [PATCH net] gve: DQO: fix header length used by gve_can_send_tso() for UDP GSO
@ 2026-09-23 14:59 Eric Dumazet
2026-09-23 17:06 ` Ankit Garg
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Eric Dumazet @ 2026-09-23 14:59 UTC (permalink / raw)
To: David S . Miller, Jakub Kicinski, Paolo Abeni
Cc: Simon Horman, netdev, Willem de Bruijn, eric.dumazet, edumazet,
Eric Dumazet, Ankit Garg, Harshitha Ramamurthy, Joshua Washington
gve_can_send_tso() computes how many buffers each segment of a GSO
packet would span, and for this it needs the length of the headers
that the device replicates in front of every segment.
It unconditionally uses skb_tcp_all_headers(), which reads the doff
field of the TCP header. SKB_GSO_UDP_L4 packets have no TCP header:
tcp_hdrlen() then reads one byte of the UDP payload, and header_len
can be anything in [0, 60] instead of the transport offset plus the
eight bytes of the UDP header that gve_prep_tso() programs into the
TSO context descriptor.
A wrong header length shifts all the segment boundaries computed in
the loop, so the number of buffers per segment can be over or under
estimated. In the first case, GSO is needlessly disabled for this
packet by gve_features_check_dqo() and the stack has to segment it.
In the second case, the driver hands the device a packet whose
segments span more than GVE_TX_MAX_DATA_DESCS buffers.
Use the UDP header length for SKB_GSO_UDP_L4 packets, matching what
gve_prep_tso() does.
Fixes: 014c607f86ab ("gve: add support for UDP GSO for DQO format")
Closes: https://lore.kernel.org/netdev/CANn89i+MS4L60sFQ49=-f-mibeveUfcrpVkD5X+Qy6SOnEpd6w@mail.gmail.com/
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Ankit Garg <nktgrg@google.com>
Cc: Harshitha Ramamurthy <hramamurthy@google.com>
Cc: Joshua Washington <joshwash@google.com>
Cc: Willem de Bruijn <willemb@google.com>
---
drivers/net/ethernet/google/gve/gve_tx_dqo.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/google/gve/gve_tx_dqo.c b/drivers/net/ethernet/google/gve/gve_tx_dqo.c
index 80ab0a449ff54e3d19e9c69226949465d48dfe3f..0f6f7c5dbb2e027bb0a45eeaf76cfabff558ec79 100644
--- a/drivers/net/ethernet/google/gve/gve_tx_dqo.c
+++ b/drivers/net/ethernet/google/gve/gve_tx_dqo.c
@@ -918,13 +918,19 @@ static bool gve_can_send_tso(const struct sk_buff *skb)
{
const int max_bufs_per_seg = GVE_TX_MAX_DATA_DESCS - 1;
const struct skb_shared_info *shinfo = skb_shinfo(skb);
- const int header_len = skb_tcp_all_headers(skb);
const int gso_size = shinfo->gso_size;
int cur_seg_num_bufs;
int prev_frag_size;
int cur_seg_size;
+ int header_len;
int i;
+ /* Must match the header length programmed by gve_prep_tso(). */
+ if (skb_is_gso_tcp(skb))
+ header_len = skb_tcp_all_headers(skb);
+ else
+ header_len = skb_transport_offset(skb) + sizeof(struct udphdr);
+
cur_seg_size = skb_headlen(skb) - header_len;
prev_frag_size = skb_headlen(skb);
cur_seg_num_bufs = cur_seg_size > 0;
--
2.55.0.1082.g2b9226bbc0-goog
^ permalink raw reply related [flat|nested] 4+ messages in thread* Re: [PATCH net] gve: DQO: fix header length used by gve_can_send_tso() for UDP GSO
2026-09-23 14:59 [PATCH net] gve: DQO: fix header length used by gve_can_send_tso() for UDP GSO Eric Dumazet
@ 2026-09-23 17:06 ` Ankit Garg
2026-09-23 19:35 ` Harshitha Ramamurthy
2026-09-24 18:00 ` patchwork-bot+netdevbpf
2 siblings, 0 replies; 4+ messages in thread
From: Ankit Garg @ 2026-09-23 17:06 UTC (permalink / raw)
To: Eric Dumazet
Cc: David S . Miller, Jakub Kicinski, Paolo Abeni, Simon Horman,
netdev, Willem de Bruijn, eric.dumazet, edumazet,
Harshitha Ramamurthy, Joshua Washington
On Wed, Sep 23, 2026 at 7:59 AM Eric Dumazet <edumazet@google.com> wrote:
>
> gve_can_send_tso() computes how many buffers each segment of a GSO
> packet would span, and for this it needs the length of the headers
> that the device replicates in front of every segment.
>
> It unconditionally uses skb_tcp_all_headers(), which reads the doff
> field of the TCP header. SKB_GSO_UDP_L4 packets have no TCP header:
> tcp_hdrlen() then reads one byte of the UDP payload, and header_len
> can be anything in [0, 60] instead of the transport offset plus the
> eight bytes of the UDP header that gve_prep_tso() programs into the
> TSO context descriptor.
>
> A wrong header length shifts all the segment boundaries computed in
> the loop, so the number of buffers per segment can be over or under
> estimated. In the first case, GSO is needlessly disabled for this
> packet by gve_features_check_dqo() and the stack has to segment it.
> In the second case, the driver hands the device a packet whose
> segments span more than GVE_TX_MAX_DATA_DESCS buffers.
>
> Use the UDP header length for SKB_GSO_UDP_L4 packets, matching what
> gve_prep_tso() does.
>
> Fixes: 014c607f86ab ("gve: add support for UDP GSO for DQO format")
> Closes: https://lore.kernel.org/netdev/CANn89i+MS4L60sFQ49=-f-mibeveUfcrpVkD5X+Qy6SOnEpd6w@mail.gmail.com/
> Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Ankit Garg <nktgrg@google.com>
> Cc: Ankit Garg <nktgrg@google.com>
> Cc: Harshitha Ramamurthy <hramamurthy@google.com>
> Cc: Joshua Washington <joshwash@google.com>
> Cc: Willem de Bruijn <willemb@google.com>
> ---
> drivers/net/ethernet/google/gve/gve_tx_dqo.c | 8 +++++++-
> 1 file changed, 7 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/net/ethernet/google/gve/gve_tx_dqo.c b/drivers/net/ethernet/google/gve/gve_tx_dqo.c
> index 80ab0a449ff54e3d19e9c69226949465d48dfe3f..0f6f7c5dbb2e027bb0a45eeaf76cfabff558ec79 100644
> --- a/drivers/net/ethernet/google/gve/gve_tx_dqo.c
> +++ b/drivers/net/ethernet/google/gve/gve_tx_dqo.c
> @@ -918,13 +918,19 @@ static bool gve_can_send_tso(const struct sk_buff *skb)
> {
> const int max_bufs_per_seg = GVE_TX_MAX_DATA_DESCS - 1;
> const struct skb_shared_info *shinfo = skb_shinfo(skb);
> - const int header_len = skb_tcp_all_headers(skb);
> const int gso_size = shinfo->gso_size;
> int cur_seg_num_bufs;
> int prev_frag_size;
> int cur_seg_size;
> + int header_len;
> int i;
>
> + /* Must match the header length programmed by gve_prep_tso(). */
> + if (skb_is_gso_tcp(skb))
> + header_len = skb_tcp_all_headers(skb);
> + else
> + header_len = skb_transport_offset(skb) + sizeof(struct udphdr);
> +
> cur_seg_size = skb_headlen(skb) - header_len;
> prev_frag_size = skb_headlen(skb);
> cur_seg_num_bufs = cur_seg_size > 0;
> --
> 2.55.0.1082.g2b9226bbc0-goog
>
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: [PATCH net] gve: DQO: fix header length used by gve_can_send_tso() for UDP GSO
2026-09-23 14:59 [PATCH net] gve: DQO: fix header length used by gve_can_send_tso() for UDP GSO Eric Dumazet
2026-09-23 17:06 ` Ankit Garg
@ 2026-09-23 19:35 ` Harshitha Ramamurthy
2026-09-24 18:00 ` patchwork-bot+netdevbpf
2 siblings, 0 replies; 4+ messages in thread
From: Harshitha Ramamurthy @ 2026-09-23 19:35 UTC (permalink / raw)
To: Eric Dumazet
Cc: David S . Miller, Jakub Kicinski, Paolo Abeni, Simon Horman,
netdev, Willem de Bruijn, eric.dumazet, edumazet, Ankit Garg,
Joshua Washington
On Wed, Sep 23, 2026 at 7:59 AM Eric Dumazet <edumazet@google.com> wrote:
>
> gve_can_send_tso() computes how many buffers each segment of a GSO
> packet would span, and for this it needs the length of the headers
> that the device replicates in front of every segment.
>
> It unconditionally uses skb_tcp_all_headers(), which reads the doff
> field of the TCP header. SKB_GSO_UDP_L4 packets have no TCP header:
> tcp_hdrlen() then reads one byte of the UDP payload, and header_len
> can be anything in [0, 60] instead of the transport offset plus the
> eight bytes of the UDP header that gve_prep_tso() programs into the
> TSO context descriptor.
>
> A wrong header length shifts all the segment boundaries computed in
> the loop, so the number of buffers per segment can be over or under
> estimated. In the first case, GSO is needlessly disabled for this
> packet by gve_features_check_dqo() and the stack has to segment it.
> In the second case, the driver hands the device a packet whose
> segments span more than GVE_TX_MAX_DATA_DESCS buffers.
>
> Use the UDP header length for SKB_GSO_UDP_L4 packets, matching what
> gve_prep_tso() does.
>
> Fixes: 014c607f86ab ("gve: add support for UDP GSO for DQO format")
> Closes: https://lore.kernel.org/netdev/CANn89i+MS4L60sFQ49=-f-mibeveUfcrpVkD5X+Qy6SOnEpd6w@mail.gmail.com/
> Signed-off-by: Eric Dumazet <edumazet@google.com>
Thanks for the fix, Eric!
Reviewed-by: Harshitha Ramamurthy <hramamurthy@google.com>
> Cc: Ankit Garg <nktgrg@google.com>
> Cc: Harshitha Ramamurthy <hramamurthy@google.com>
> Cc: Joshua Washington <joshwash@google.com>
> Cc: Willem de Bruijn <willemb@google.com>
> ---
> drivers/net/ethernet/google/gve/gve_tx_dqo.c | 8 +++++++-
> 1 file changed, 7 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/net/ethernet/google/gve/gve_tx_dqo.c b/drivers/net/ethernet/google/gve/gve_tx_dqo.c
> index 80ab0a449ff54e3d19e9c69226949465d48dfe3f..0f6f7c5dbb2e027bb0a45eeaf76cfabff558ec79 100644
> --- a/drivers/net/ethernet/google/gve/gve_tx_dqo.c
> +++ b/drivers/net/ethernet/google/gve/gve_tx_dqo.c
> @@ -918,13 +918,19 @@ static bool gve_can_send_tso(const struct sk_buff *skb)
> {
> const int max_bufs_per_seg = GVE_TX_MAX_DATA_DESCS - 1;
> const struct skb_shared_info *shinfo = skb_shinfo(skb);
> - const int header_len = skb_tcp_all_headers(skb);
> const int gso_size = shinfo->gso_size;
> int cur_seg_num_bufs;
> int prev_frag_size;
> int cur_seg_size;
> + int header_len;
> int i;
>
> + /* Must match the header length programmed by gve_prep_tso(). */
> + if (skb_is_gso_tcp(skb))
> + header_len = skb_tcp_all_headers(skb);
> + else
> + header_len = skb_transport_offset(skb) + sizeof(struct udphdr);
> +
> cur_seg_size = skb_headlen(skb) - header_len;
> prev_frag_size = skb_headlen(skb);
> cur_seg_num_bufs = cur_seg_size > 0;
> --
> 2.55.0.1082.g2b9226bbc0-goog
>
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: [PATCH net] gve: DQO: fix header length used by gve_can_send_tso() for UDP GSO
2026-09-23 14:59 [PATCH net] gve: DQO: fix header length used by gve_can_send_tso() for UDP GSO Eric Dumazet
2026-09-23 17:06 ` Ankit Garg
2026-09-23 19:35 ` Harshitha Ramamurthy
@ 2026-09-24 18:00 ` patchwork-bot+netdevbpf
2 siblings, 0 replies; 4+ messages in thread
From: patchwork-bot+netdevbpf @ 2026-09-24 18:00 UTC (permalink / raw)
To: Eric Dumazet
Cc: davem, kuba, pabeni, horms, netdev, willemb, eric.dumazet,
edumazet, nktgrg, hramamurthy, joshwash
Hello:
This patch was applied to netdev/net.git (main)
by Jakub Kicinski <kuba@kernel.org>:
On Wed, 23 Sep 2026 14:59:42 +0000 you wrote:
> gve_can_send_tso() computes how many buffers each segment of a GSO
> packet would span, and for this it needs the length of the headers
> that the device replicates in front of every segment.
>
> It unconditionally uses skb_tcp_all_headers(), which reads the doff
> field of the TCP header. SKB_GSO_UDP_L4 packets have no TCP header:
> tcp_hdrlen() then reads one byte of the UDP payload, and header_len
> can be anything in [0, 60] instead of the transport offset plus the
> eight bytes of the UDP header that gve_prep_tso() programs into the
> TSO context descriptor.
>
> [...]
Here is the summary with links:
- [net] gve: DQO: fix header length used by gve_can_send_tso() for UDP GSO
https://git.kernel.org/netdev/net/c/83769c23fb18
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-09-24 18:01 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-23 14:59 [PATCH net] gve: DQO: fix header length used by gve_can_send_tso() for UDP GSO Eric Dumazet
2026-09-23 17:06 ` Ankit Garg
2026-09-23 19:35 ` Harshitha Ramamurthy
2026-09-24 18:00 ` patchwork-bot+netdevbpf
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox