Skip to content

Commit 531d0d3

Browse files
cpaasch-oaikuba-moo
authored andcommitted
net/mlx5: Correctly set gso_size when LRO is used
gso_size is expected by the networking stack to be the size of the payload (thus, not including ethernet/IP/TCP-headers). However, cqe_bcnt is the full sized frame (including the headers). Dividing cqe_bcnt by lro_num_seg will then give incorrect results. For example, running a bpftrace higher up in the TCP-stack (tcp_event_data_recv), we commonly have gso_size set to 1450 or 1451 even though in reality the payload was only 1448 bytes. This can have unintended consequences: - In tcp_measure_rcv_mss() len will be for example 1450, but. rcv_mss will be 1448 (because tp->advmss is 1448). Thus, we will always recompute scaling_ratio each time an LRO-packet is received. - In tcp_gro_receive(), it will interfere with the decision whether or not to flush and thus potentially result in less gro'ed packets. So, we need to discount the protocol headers from cqe_bcnt so we can actually divide the payload by lro_num_seg to get the real gso_size. v2: - Use "(unsigned char *)tcp + tcp->doff * 4 - skb->data)" to compute header-len (Tariq Toukan <[email protected]>) - Improve commit-message (Gal Pressman <[email protected]>) Fixes: e586b3b ("net/mlx5: Ethernet Datapath files") Signed-off-by: Christoph Paasch <[email protected]> Reviewed-by: Tariq Toukan <[email protected]> Reviewed-by: Gal Pressman <[email protected]> Link: https://patch.msgid.link/20250715-cpaasch-pf-925-investigate-incorrect-gso_size-on-cx-7-nic-v2-1-e06c3475f3ac@openai.com Signed-off-by: Jakub Kicinski <[email protected]>
1 parent dae7f9c commit 531d0d3

File tree

1 file changed

+8
-4
lines changed
  • drivers/net/ethernet/mellanox/mlx5/core

1 file changed

+8
-4
lines changed

drivers/net/ethernet/mellanox/mlx5/core/en_rx.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1154,8 +1154,9 @@ static void mlx5e_lro_update_tcp_hdr(struct mlx5_cqe64 *cqe, struct tcphdr *tcp)
11541154
}
11551155
}
11561156

1157-
static void mlx5e_lro_update_hdr(struct sk_buff *skb, struct mlx5_cqe64 *cqe,
1158-
u32 cqe_bcnt)
1157+
static unsigned int mlx5e_lro_update_hdr(struct sk_buff *skb,
1158+
struct mlx5_cqe64 *cqe,
1159+
u32 cqe_bcnt)
11591160
{
11601161
struct ethhdr *eth = (struct ethhdr *)(skb->data);
11611162
struct tcphdr *tcp;
@@ -1205,6 +1206,8 @@ static void mlx5e_lro_update_hdr(struct sk_buff *skb, struct mlx5_cqe64 *cqe,
12051206
tcp->check = tcp_v6_check(payload_len, &ipv6->saddr,
12061207
&ipv6->daddr, check);
12071208
}
1209+
1210+
return (unsigned int)((unsigned char *)tcp + tcp->doff * 4 - skb->data);
12081211
}
12091212

12101213
static void *mlx5e_shampo_get_packet_hd(struct mlx5e_rq *rq, u16 header_index)
@@ -1561,8 +1564,9 @@ static inline void mlx5e_build_rx_skb(struct mlx5_cqe64 *cqe,
15611564
mlx5e_macsec_offload_handle_rx_skb(netdev, skb, cqe);
15621565

15631566
if (lro_num_seg > 1) {
1564-
mlx5e_lro_update_hdr(skb, cqe, cqe_bcnt);
1565-
skb_shinfo(skb)->gso_size = DIV_ROUND_UP(cqe_bcnt, lro_num_seg);
1567+
unsigned int hdrlen = mlx5e_lro_update_hdr(skb, cqe, cqe_bcnt);
1568+
1569+
skb_shinfo(skb)->gso_size = DIV_ROUND_UP(cqe_bcnt - hdrlen, lro_num_seg);
15661570
/* Subtract one since we already counted this as one
15671571
* "regular" packet in mlx5e_complete_rx_cqe()
15681572
*/

0 commit comments

Comments
 (0)