All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net v2] gve: Fix an edge case for TSO skb validity check
@ 2024-07-24 14:34 Praveen Kaligineedi
  2024-07-24 14:51 ` Willem de Bruijn
  2024-07-25 15:00 ` patchwork-bot+netdevbpf
  0 siblings, 2 replies; 3+ messages in thread
From: Praveen Kaligineedi @ 2024-07-24 14:34 UTC (permalink / raw)
  To: netdev
  Cc: davem, edumazet, kuba, pabeni, willemb, shailend, hramamurthy,
	csully, jfraker, stable, Bailey Forrest, Praveen Kaligineedi,
	Jeroen de Borst

From: Bailey Forrest <bcf@google.com>

The NIC requires each TSO segment to not span more than 10
descriptors. NIC further requires each descriptor to not exceed
16KB - 1 (GVE_TX_MAX_BUF_SIZE_DQO).

The descriptors for an skb are generated by
gve_tx_add_skb_no_copy_dqo() for DQO RDA queue format.
gve_tx_add_skb_no_copy_dqo() loops through each skb frag and
generates a descriptor for the entire frag if the frag size is
not greater than GVE_TX_MAX_BUF_SIZE_DQO. If the frag size is
greater than GVE_TX_MAX_BUF_SIZE_DQO, it is split into descriptor(s)
of size GVE_TX_MAX_BUF_SIZE_DQO and a descriptor is generated for
the remainder (frag size % GVE_TX_MAX_BUF_SIZE_DQO).

gve_can_send_tso() checks if the descriptors thus generated for an
skb would meet the requirement that each TSO-segment not span more
than 10 descriptors. However, the current code misses an edge case
when a TSO segment spans multiple descriptors within a large frag.
This change fixes the edge case.

gve_can_send_tso() relies on the assumption that max gso size (9728)
is less than GVE_TX_MAX_BUF_SIZE_DQO and therefore within an skb
fragment a TSO segment can never span more than 2 descriptors.

Fixes: a57e5de476be ("gve: DQO: Add TX path")
Signed-off-by: Praveen Kaligineedi <pkaligineedi@google.com>
Signed-off-by: Bailey Forrest <bcf@google.com>
Reviewed-by: Jeroen de Borst <jeroendb@google.com>
Cc: stable@vger.kernel.org
---
Changes from v1:
 - Added 'stable tag'
 - Added more explanation in the commit message
 - Modified comments to clarify the changes made
 - Changed variable names 'last_frag_size' to 'prev_frag_size' and
   'last_frag_remain' to 'prev_frag_remain'
 - Removed parentheses around single line statement

 drivers/net/ethernet/google/gve/gve_tx_dqo.c | 22 +++++++++++++++++++-
 1 file changed, 21 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 0b3cca3fc792..f879426cb552 100644
--- a/drivers/net/ethernet/google/gve/gve_tx_dqo.c
+++ b/drivers/net/ethernet/google/gve/gve_tx_dqo.c
@@ -866,22 +866,42 @@ static bool gve_can_send_tso(const struct sk_buff *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 i;
 
 	cur_seg_size = skb_headlen(skb) - header_len;
+	prev_frag_size = skb_headlen(skb);
 	cur_seg_num_bufs = cur_seg_size > 0;
 
 	for (i = 0; i < shinfo->nr_frags; i++) {
 		if (cur_seg_size >= gso_size) {
 			cur_seg_size %= gso_size;
 			cur_seg_num_bufs = cur_seg_size > 0;
+
+			if (prev_frag_size > GVE_TX_MAX_BUF_SIZE_DQO) {
+				int prev_frag_remain = prev_frag_size %
+					GVE_TX_MAX_BUF_SIZE_DQO;
+
+				/* If the last descriptor of the previous frag
+				 * is less than cur_seg_size, the segment will
+				 * span two descriptors in the previous frag.
+				 * Since max gso size (9728) is less than
+				 * GVE_TX_MAX_BUF_SIZE_DQO, it is impossible
+				 * for the segment to span more than two
+				 * descriptors.
+				 */
+				if (prev_frag_remain &&
+				    cur_seg_size > prev_frag_remain)
+					cur_seg_num_bufs++;
+			}
 		}
 
 		if (unlikely(++cur_seg_num_bufs > max_bufs_per_seg))
 			return false;
 
-		cur_seg_size += skb_frag_size(&shinfo->frags[i]);
+		prev_frag_size = skb_frag_size(&shinfo->frags[i]);
+		cur_seg_size += prev_frag_size;
 	}
 
 	return true;
-- 
2.45.2.1089.g2a221341d9-goog


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

* Re: [PATCH net v2] gve: Fix an edge case for TSO skb validity check
  2024-07-24 14:34 [PATCH net v2] gve: Fix an edge case for TSO skb validity check Praveen Kaligineedi
@ 2024-07-24 14:51 ` Willem de Bruijn
  2024-07-25 15:00 ` patchwork-bot+netdevbpf
  1 sibling, 0 replies; 3+ messages in thread
From: Willem de Bruijn @ 2024-07-24 14:51 UTC (permalink / raw)
  To: Praveen Kaligineedi
  Cc: netdev, davem, edumazet, kuba, pabeni, willemb, shailend,
	hramamurthy, csully, jfraker, stable, Bailey Forrest,
	Jeroen de Borst

On Wed, Jul 24, 2024 at 10:35 AM Praveen Kaligineedi
<pkaligineedi@google.com> wrote:
>
> From: Bailey Forrest <bcf@google.com>
>
> The NIC requires each TSO segment to not span more than 10
> descriptors. NIC further requires each descriptor to not exceed
> 16KB - 1 (GVE_TX_MAX_BUF_SIZE_DQO).
>
> The descriptors for an skb are generated by
> gve_tx_add_skb_no_copy_dqo() for DQO RDA queue format.
> gve_tx_add_skb_no_copy_dqo() loops through each skb frag and
> generates a descriptor for the entire frag if the frag size is
> not greater than GVE_TX_MAX_BUF_SIZE_DQO. If the frag size is
> greater than GVE_TX_MAX_BUF_SIZE_DQO, it is split into descriptor(s)
> of size GVE_TX_MAX_BUF_SIZE_DQO and a descriptor is generated for
> the remainder (frag size % GVE_TX_MAX_BUF_SIZE_DQO).
>
> gve_can_send_tso() checks if the descriptors thus generated for an
> skb would meet the requirement that each TSO-segment not span more
> than 10 descriptors. However, the current code misses an edge case
> when a TSO segment spans multiple descriptors within a large frag.
> This change fixes the edge case.
>
> gve_can_send_tso() relies on the assumption that max gso size (9728)
> is less than GVE_TX_MAX_BUF_SIZE_DQO and therefore within an skb
> fragment a TSO segment can never span more than 2 descriptors.
>
> Fixes: a57e5de476be ("gve: DQO: Add TX path")
> Signed-off-by: Praveen Kaligineedi <pkaligineedi@google.com>
> Signed-off-by: Bailey Forrest <bcf@google.com>
> Reviewed-by: Jeroen de Borst <jeroendb@google.com>
> Cc: stable@vger.kernel.org

Reviewed-by: Willem de Bruijn <willemb@google.com>

Thanks for the extra description. The way gve_tx_add_skb_no_copy_dqo
lays out descriptors, and the descriptor and segment max lengths are key.
Now I follow the calculation.

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

* Re: [PATCH net v2] gve: Fix an edge case for TSO skb validity check
  2024-07-24 14:34 [PATCH net v2] gve: Fix an edge case for TSO skb validity check Praveen Kaligineedi
  2024-07-24 14:51 ` Willem de Bruijn
@ 2024-07-25 15:00 ` patchwork-bot+netdevbpf
  1 sibling, 0 replies; 3+ messages in thread
From: patchwork-bot+netdevbpf @ 2024-07-25 15:00 UTC (permalink / raw)
  To: Praveen Kaligineedi
  Cc: netdev, davem, edumazet, kuba, pabeni, willemb, shailend,
	hramamurthy, csully, jfraker, stable, bcf, jeroendb

Hello:

This patch was applied to netdev/net.git (main)
by Jakub Kicinski <kuba@kernel.org>:

On Wed, 24 Jul 2024 07:34:31 -0700 you wrote:
> From: Bailey Forrest <bcf@google.com>
> 
> The NIC requires each TSO segment to not span more than 10
> descriptors. NIC further requires each descriptor to not exceed
> 16KB - 1 (GVE_TX_MAX_BUF_SIZE_DQO).
> 
> The descriptors for an skb are generated by
> gve_tx_add_skb_no_copy_dqo() for DQO RDA queue format.
> gve_tx_add_skb_no_copy_dqo() loops through each skb frag and
> generates a descriptor for the entire frag if the frag size is
> not greater than GVE_TX_MAX_BUF_SIZE_DQO. If the frag size is
> greater than GVE_TX_MAX_BUF_SIZE_DQO, it is split into descriptor(s)
> of size GVE_TX_MAX_BUF_SIZE_DQO and a descriptor is generated for
> the remainder (frag size % GVE_TX_MAX_BUF_SIZE_DQO).
> 
> [...]

Here is the summary with links:
  - [net,v2] gve: Fix an edge case for TSO skb validity check
    https://git.kernel.org/netdev/net/c/36e3b949e359

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] 3+ messages in thread

end of thread, other threads:[~2024-07-25 15:00 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-07-24 14:34 [PATCH net v2] gve: Fix an edge case for TSO skb validity check Praveen Kaligineedi
2024-07-24 14:51 ` Willem de Bruijn
2024-07-25 15:00 ` patchwork-bot+netdevbpf

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.