From: Dragos Tatulea Date: Mon, 3 Jun 2024 21:22:10 +0000 (+0300) Subject: net/mlx5e: SHAMPO, Disable gso_size for non GRO packets X-Git-Tag: v6.11-rc1~163^2~241^2~9 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=083dbb54c4809bcd56c5c09360ee8c7760a55d71;p=thirdparty%2Flinux.git net/mlx5e: SHAMPO, Disable gso_size for non GRO packets When HW GRO is enabled, forwarding of packets is broken due to gso_size being set incorrectly on non GRO packets. Non GRO packets have a skb GRO count of 1. mlx5 always sets gso_size on the skb, even for non GRO packets. It leans on the fact that gso_size is normally reset in napi_gro_complete(). But this happens only for packets from GRO'able protocols (TCP/UDP) that have a gro_receive() handler. The problematic scenarios are: 1) Non GRO protocol packets are received, validate_xmit_skb() will drop them (see EPROTONOSUPPORT in skb_mac_gso_segment()). The fix for this case would be to not set gso_size at all for SHAMPO packets with header size 0. 2) Packets from a GRO'ed protocol (TCP) are received but immediately flushed because they are not GRO'able (TCP SYN for example). mlx5e_shampo_update_hdr(), which updates the remaining GRO state on the skb, is not called because skb GRO count is 1. The fix here would be to always call mlx5e_shampo_update_hdr(), regardless of skb GRO count. But this call is expensive The unified fix for both cases is to reset gso_size before calling napi_gro_receive(). It is a change that is more effective (no call to mlx5e_shampo_update_hdr() necessary) and simple (smallest code footprint). Signed-off-by: Dragos Tatulea Signed-off-by: Tariq Toukan Link: https://lore.kernel.org/r/20240603212219.1037656-6-tariqt@nvidia.com Signed-off-by: Jakub Kicinski --- diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c index b3ef0dd237298..a13fa760f948a 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c @@ -2267,6 +2267,8 @@ mlx5e_shampo_flush_skb(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe, bool match) mlx5e_shampo_align_fragment(skb, rq->mpwqe.log_stride_sz); if (NAPI_GRO_CB(skb)->count > 1) mlx5e_shampo_update_hdr(rq, cqe, match); + else + skb_shinfo(skb)->gso_size = 0; napi_gro_receive(rq->cq.napi, skb); rq->hw_gro_data->skb = NULL; }