* FAILED: patch "[PATCH] net/mlx5e: do not HW-GRO coalesce small frames" failed to apply to 6.18-stable tree
@ 2026-09-03 15:09 gregkh
2026-09-09 17:32 ` [PATCH 6.18.y 1/2] net/mlx5e: SHAMPO, Always calculate page size Sasha Levin
2026-09-09 17:32 ` [PATCH 6.18.y 1/2] net/mlx5e: SHAMPO, Always calculate page size Sasha Levin
0 siblings, 2 replies; 5+ messages in thread
From: gregkh @ 2026-09-03 15:09 UTC (permalink / raw)
To: gmj, kuba, tariqt; +Cc: stable
The patch below does not apply to the 6.18-stable tree.
If someone wants it applied there, or to any other stable or longterm
tree, then please email the backport, including the original git commit
id to <stable@vger.kernel.org>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.18.y
git checkout FETCH_HEAD
git cherry-pick -x e2466392a0b8496000e12181cb1ee1535eb0da25
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<stable@vger.kernel.org>' --in-reply-to '2026090308-macarena-speckled-769c@gregkh' --subject-prefix 'PATCH 6.18.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From e2466392a0b8496000e12181cb1ee1535eb0da25 Mon Sep 17 00:00:00 2001
From: Glenn Judd <gmj@meta.com>
Date: Sun, 16 Aug 2026 09:42:59 +0300
Subject: [PATCH] net/mlx5e: do not HW-GRO coalesce small frames
When hardware GRO (SHAMPO) coalesces a small IPv4/TCP segment that was
padded up to the 60-byte minimum Ethernet frame, the trailing padding is
folded into the merged payload causing padding to be delivered
to the user as payload.
Detecting and reproducing the issue: the selftest
tools/testing/selftests/drivers/net/gro.py subtest
hw_ipv4_data_lrg_1byte sends {100, 1} expecting to receive {101}.
In current code, it receives {106} (100 + 1 payload + 5 pad) instead.
This patch avoids giving the user padding as payload by simply not
coalescing small packets (which fails the subtest; the same approach
and behavior as sw gro). This gains code simplicity at the cost of
more computation (passing an extra skb up the stack) for small packets
that could be coalesced.
The threshold is chosen as ETH_ZLEN + 2 * VLAN_HLEN. This is the largest
frame that may still contain minimum-frame padding (+ 2 VLAN tags), so
anything larger is safe to consider for coalesce. (We do not include
ETH_FCS_LEN in that threshold computation as netdev_fix_features()
drops NETIF_F_GRO_HW whenever NETIF_F_RXFCS is set, so retained FCS
can't reach this path.)
Fixes: 92552d3abd32 ("net/mlx5e: HW_GRO cqe handler implementation")
Cc: stable@vger.kernel.org
Signed-off-by: Glenn Judd <gmj@meta.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
Link: https://patch.msgid.link/20260816064259.3279548-1-tariqt@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
index 6fbc0441c4b8..6fc6605d2054 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
@@ -2263,6 +2263,11 @@ static void mlx5e_handle_rx_cqe_mpwrq_shampo(struct mlx5e_rq *rq, struct mlx5_cq
data_offset = wqe_offset & (page_size - 1);
page_idx = wqe_offset >> rq->mpwqe.page_shift;
+ if (unlikely(cqe_bcnt <= ETH_ZLEN + 2 * VLAN_HLEN)) {
+ match = false;
+ flush = true;
+ }
+
if (*skb &&
!(match && mlx5e_hw_gro_skb_has_enough_space(*skb, data_bcnt,
page_size))) {
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 6.18.y 1/2] net/mlx5e: SHAMPO, Always calculate page size
2026-09-03 15:09 FAILED: patch "[PATCH] net/mlx5e: do not HW-GRO coalesce small frames" failed to apply to 6.18-stable tree gregkh
@ 2026-09-09 17:32 ` Sasha Levin
2026-09-09 17:32 ` [PATCH 6.18.y 2/2] net/mlx5e: do not HW-GRO coalesce small frames Sasha Levin
2026-09-09 17:32 ` [PATCH 6.18.y 1/2] net/mlx5e: SHAMPO, Always calculate page size Sasha Levin
1 sibling, 1 reply; 5+ messages in thread
From: Sasha Levin @ 2026-09-09 17:32 UTC (permalink / raw)
To: stable; +Cc: Dragos Tatulea, Cosmin Ratiu, Tariq Toukan, Paolo Abeni,
Sasha Levin
From: Dragos Tatulea <dtatulea@nvidia.com>
[ Upstream commit dff1c3164a69284ac9fedb1c25d4c008139e9fb8 ]
Adapt the rx path in SHAMPO mode to calculate page size based on
configured page_shift when dealing with payload data.
This is necessary as an upcoming patch will add support for using
different page sizes.
This change has no functional changes.
Signed-off-by: Dragos Tatulea <dtatulea@nvidia.com>
Reviewed-by: Cosmin Ratiu <cratiu@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
Link: https://patch.msgid.link/20260223204155.1783580-9-tariqt@nvidia.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Backport to 6.18: preserve the XDP fragment accounting fix from
7d7342a18fadc ("net/mlx5e: RX, Fix XDP multi-buf frag counting for
striding RQ"). Keep new_nr_frags and the original frag_page endpoint;
only replace PAGE_SIZE with page_size in the truesize adjustment.
Reintroducing the old frag_page rewind would break page reference
accounting for fragments consumed by XDP.
Retain the page-size calculations and SHAMPO space-check changes so
e2466392a0b8496000e12181cb1ee1535eb0da25 ("net/mlx5e: do not HW-GRO
coalesce small frames") applies without modification. No functions
are added.
Stable-dep-of: e2466392a0b8 ("net/mlx5e: do not HW-GRO coalesce small frames")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../net/ethernet/mellanox/mlx5/core/en_rx.c | 34 ++++++++++++-------
1 file changed, 22 insertions(+), 12 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
index 2ffa4e6b8c373..8a61c958c5679 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
@@ -2014,11 +2014,14 @@ mlx5e_shampo_fill_skb_data(struct sk_buff *skb, struct mlx5e_rq *rq,
struct mlx5e_frag_page *frag_page,
u32 data_bcnt, u32 data_offset)
{
+ u32 page_size = BIT(rq->mpwqe.page_shift);
+
net_prefetchw(skb->data);
do {
/* Non-linear mode, hence non-XSK, which always uses PAGE_SIZE. */
- u32 pg_consumed_bytes = min_t(u32, PAGE_SIZE - data_offset, data_bcnt);
+ u32 pg_consumed_bytes = min_t(u32, page_size - data_offset,
+ data_bcnt);
unsigned int truesize = pg_consumed_bytes;
mlx5e_add_skb_frag(rq, skb, frag_page, data_offset,
@@ -2039,6 +2042,7 @@ mlx5e_skb_from_cqe_mpwrq_nonlinear(struct mlx5e_rq *rq, struct mlx5e_mpw_info *w
u16 headlen = min_t(u16, MLX5E_RX_MAX_HEAD, cqe_bcnt);
struct mlx5e_frag_page *head_page = frag_page;
struct mlx5e_xdp_buff *mxbuf = &rq->mxbuf;
+ u32 page_size = BIT(rq->mpwqe.page_shift);
u32 frag_offset = head_offset;
u32 byte_cnt = cqe_bcnt;
struct skb_shared_info *sinfo;
@@ -2084,9 +2088,9 @@ mlx5e_skb_from_cqe_mpwrq_nonlinear(struct mlx5e_rq *rq, struct mlx5e_mpw_info *w
linear_hr = skb_headroom(skb);
linear_data_len = headlen;
linear_frame_sz = MLX5_SKB_FRAG_SZ(skb_end_offset(skb));
- if (unlikely(frag_offset >= PAGE_SIZE)) {
+ if (unlikely(frag_offset >= page_size)) {
frag_page++;
- frag_offset -= PAGE_SIZE;
+ frag_offset -= page_size;
}
}
@@ -2098,7 +2102,7 @@ mlx5e_skb_from_cqe_mpwrq_nonlinear(struct mlx5e_rq *rq, struct mlx5e_mpw_info *w
while (byte_cnt) {
/* Non-linear mode, hence non-XSK, which always uses PAGE_SIZE. */
pg_consumed_bytes =
- min_t(u32, PAGE_SIZE - frag_offset, byte_cnt);
+ min_t(u32, page_size - frag_offset, byte_cnt);
if (test_bit(MLX5E_RQ_STATE_SHAMPO, &rq->state))
truesize += pg_consumed_bytes;
@@ -2135,7 +2139,7 @@ mlx5e_skb_from_cqe_mpwrq_nonlinear(struct mlx5e_rq *rq, struct mlx5e_mpw_info *w
new_nr_frags = sinfo->nr_frags;
nr_frags_free = old_nr_frags - new_nr_frags;
if (unlikely(nr_frags_free))
- truesize -= (nr_frags_free - 1) * PAGE_SIZE +
+ truesize -= (nr_frags_free - 1) * page_size +
ALIGN(pg_consumed_bytes,
BIT(rq->mpwqe.log_stride_sz));
@@ -2349,15 +2353,16 @@ mlx5e_shampo_flush_skb(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe, bool match)
rq->hw_gro_data->skb = NULL;
}
-static bool
-mlx5e_hw_gro_skb_has_enough_space(struct sk_buff *skb, u16 data_bcnt)
+static bool mlx5e_hw_gro_skb_has_enough_space(struct sk_buff *skb,
+ u16 data_bcnt,
+ u32 page_size)
{
int nr_frags = skb_shinfo(skb)->nr_frags;
- if (PAGE_SIZE >= GRO_LEGACY_MAX_SIZE)
+ if (page_size >= GRO_LEGACY_MAX_SIZE)
return skb->len + data_bcnt <= GRO_LEGACY_MAX_SIZE;
else
- return PAGE_SIZE * nr_frags + data_bcnt <= GRO_LEGACY_MAX_SIZE;
+ return page_size * nr_frags + data_bcnt <= GRO_LEGACY_MAX_SIZE;
}
static void mlx5e_handle_rx_cqe_mpwrq_shampo(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe)
@@ -2366,18 +2371,19 @@ static void mlx5e_handle_rx_cqe_mpwrq_shampo(struct mlx5e_rq *rq, struct mlx5_cq
u16 header_index = mlx5e_shampo_get_cqe_header_index(rq, cqe);
u32 wqe_offset = be32_to_cpu(cqe->shampo.data_offset);
u16 cstrides = mpwrq_get_cqe_consumed_strides(cqe);
- u32 data_offset = wqe_offset & (PAGE_SIZE - 1);
u32 cqe_bcnt = mpwrq_get_cqe_byte_cnt(cqe);
u16 wqe_id = be16_to_cpu(cqe->wqe_id);
- u32 page_idx = wqe_offset >> PAGE_SHIFT;
u16 head_size = cqe->shampo.header_size;
struct sk_buff **skb = &rq->hw_gro_data->skb;
bool flush = cqe->shampo.flush;
bool match = cqe->shampo.match;
+ u32 page_size = BIT(rq->mpwqe.page_shift);
struct mlx5e_rq_stats *stats = rq->stats;
struct mlx5e_rx_wqe_ll *wqe;
struct mlx5e_mpw_info *wi;
struct mlx5_wq_ll *wq;
+ u32 data_offset;
+ u32 page_idx;
wi = mlx5e_get_mpw_info(rq, wqe_id);
wi->consumed_strides += cstrides;
@@ -2393,7 +2399,11 @@ static void mlx5e_handle_rx_cqe_mpwrq_shampo(struct mlx5e_rq *rq, struct mlx5_cq
goto mpwrq_cqe_out;
}
- if (*skb && (!match || !(mlx5e_hw_gro_skb_has_enough_space(*skb, data_bcnt)))) {
+ data_offset = wqe_offset & (page_size - 1);
+ page_idx = wqe_offset >> rq->mpwqe.page_shift;
+ if (*skb &&
+ !(match && mlx5e_hw_gro_skb_has_enough_space(*skb, data_bcnt,
+ page_size))) {
match = false;
mlx5e_shampo_flush_skb(rq, cqe, match);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 6.18.y 2/2] net/mlx5e: do not HW-GRO coalesce small frames
2026-09-09 17:32 ` [PATCH 6.18.y 1/2] net/mlx5e: SHAMPO, Always calculate page size Sasha Levin
@ 2026-09-09 17:32 ` Sasha Levin
0 siblings, 0 replies; 5+ messages in thread
From: Sasha Levin @ 2026-09-09 17:32 UTC (permalink / raw)
To: stable; +Cc: Glenn Judd, Tariq Toukan, Jakub Kicinski, Sasha Levin
From: Glenn Judd <gmj@meta.com>
[ Upstream commit e2466392a0b8496000e12181cb1ee1535eb0da25 ]
When hardware GRO (SHAMPO) coalesces a small IPv4/TCP segment that was
padded up to the 60-byte minimum Ethernet frame, the trailing padding is
folded into the merged payload causing padding to be delivered
to the user as payload.
Detecting and reproducing the issue: the selftest
tools/testing/selftests/drivers/net/gro.py subtest
hw_ipv4_data_lrg_1byte sends {100, 1} expecting to receive {101}.
In current code, it receives {106} (100 + 1 payload + 5 pad) instead.
This patch avoids giving the user padding as payload by simply not
coalescing small packets (which fails the subtest; the same approach
and behavior as sw gro). This gains code simplicity at the cost of
more computation (passing an extra skb up the stack) for small packets
that could be coalesced.
The threshold is chosen as ETH_ZLEN + 2 * VLAN_HLEN. This is the largest
frame that may still contain minimum-frame padding (+ 2 VLAN tags), so
anything larger is safe to consider for coalesce. (We do not include
ETH_FCS_LEN in that threshold computation as netdev_fix_features()
drops NETIF_F_GRO_HW whenever NETIF_F_RXFCS is set, so retained FCS
can't reach this path.)
Fixes: 92552d3abd32 ("net/mlx5e: HW_GRO cqe handler implementation")
Cc: stable@vger.kernel.org
Signed-off-by: Glenn Judd <gmj@meta.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
Link: https://patch.msgid.link/20260816064259.3279548-1-tariqt@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/mellanox/mlx5/core/en_rx.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
index 8a61c958c5679..17b74a97138b5 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
@@ -2401,6 +2401,11 @@ static void mlx5e_handle_rx_cqe_mpwrq_shampo(struct mlx5e_rq *rq, struct mlx5_cq
data_offset = wqe_offset & (page_size - 1);
page_idx = wqe_offset >> rq->mpwqe.page_shift;
+ if (unlikely(cqe_bcnt <= ETH_ZLEN + 2 * VLAN_HLEN)) {
+ match = false;
+ flush = true;
+ }
+
if (*skb &&
!(match && mlx5e_hw_gro_skb_has_enough_space(*skb, data_bcnt,
page_size))) {
--
2.53.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 6.18.y 1/2] net/mlx5e: SHAMPO, Always calculate page size
2026-09-03 15:09 FAILED: patch "[PATCH] net/mlx5e: do not HW-GRO coalesce small frames" failed to apply to 6.18-stable tree gregkh
2026-09-09 17:32 ` [PATCH 6.18.y 1/2] net/mlx5e: SHAMPO, Always calculate page size Sasha Levin
@ 2026-09-09 17:32 ` Sasha Levin
2026-09-09 17:32 ` [PATCH 6.18.y 2/2] net/mlx5e: do not HW-GRO coalesce small frames Sasha Levin
1 sibling, 1 reply; 5+ messages in thread
From: Sasha Levin @ 2026-09-09 17:32 UTC (permalink / raw)
To: stable; +Cc: Dragos Tatulea, Cosmin Ratiu, Tariq Toukan, Paolo Abeni,
Sasha Levin
From: Dragos Tatulea <dtatulea@nvidia.com>
[ Upstream commit dff1c3164a69284ac9fedb1c25d4c008139e9fb8 ]
Adapt the rx path in SHAMPO mode to calculate page size based on
configured page_shift when dealing with payload data.
This is necessary as an upcoming patch will add support for using
different page sizes.
This change has no functional changes.
Signed-off-by: Dragos Tatulea <dtatulea@nvidia.com>
Reviewed-by: Cosmin Ratiu <cratiu@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
Link: https://patch.msgid.link/20260223204155.1783580-9-tariqt@nvidia.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Backport to 6.18: preserve the XDP fragment accounting fix from
7d7342a18fadc ("net/mlx5e: RX, Fix XDP multi-buf frag counting for
striding RQ"). Keep new_nr_frags and the original frag_page endpoint;
only replace PAGE_SIZE with page_size in the truesize adjustment.
Reintroducing the old frag_page rewind would break page reference
accounting for fragments consumed by XDP.
Retain the page-size calculations and SHAMPO space-check changes so
e2466392a0b8496000e12181cb1ee1535eb0da25 ("net/mlx5e: do not HW-GRO
coalesce small frames") applies without modification. No functions
are added.
Stable-dep-of: e2466392a0b8 ("net/mlx5e: do not HW-GRO coalesce small frames")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../net/ethernet/mellanox/mlx5/core/en_rx.c | 34 ++++++++++++-------
1 file changed, 22 insertions(+), 12 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
index 2ffa4e6b8c373..8a61c958c5679 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
@@ -2014,11 +2014,14 @@ mlx5e_shampo_fill_skb_data(struct sk_buff *skb, struct mlx5e_rq *rq,
struct mlx5e_frag_page *frag_page,
u32 data_bcnt, u32 data_offset)
{
+ u32 page_size = BIT(rq->mpwqe.page_shift);
+
net_prefetchw(skb->data);
do {
/* Non-linear mode, hence non-XSK, which always uses PAGE_SIZE. */
- u32 pg_consumed_bytes = min_t(u32, PAGE_SIZE - data_offset, data_bcnt);
+ u32 pg_consumed_bytes = min_t(u32, page_size - data_offset,
+ data_bcnt);
unsigned int truesize = pg_consumed_bytes;
mlx5e_add_skb_frag(rq, skb, frag_page, data_offset,
@@ -2039,6 +2042,7 @@ mlx5e_skb_from_cqe_mpwrq_nonlinear(struct mlx5e_rq *rq, struct mlx5e_mpw_info *w
u16 headlen = min_t(u16, MLX5E_RX_MAX_HEAD, cqe_bcnt);
struct mlx5e_frag_page *head_page = frag_page;
struct mlx5e_xdp_buff *mxbuf = &rq->mxbuf;
+ u32 page_size = BIT(rq->mpwqe.page_shift);
u32 frag_offset = head_offset;
u32 byte_cnt = cqe_bcnt;
struct skb_shared_info *sinfo;
@@ -2084,9 +2088,9 @@ mlx5e_skb_from_cqe_mpwrq_nonlinear(struct mlx5e_rq *rq, struct mlx5e_mpw_info *w
linear_hr = skb_headroom(skb);
linear_data_len = headlen;
linear_frame_sz = MLX5_SKB_FRAG_SZ(skb_end_offset(skb));
- if (unlikely(frag_offset >= PAGE_SIZE)) {
+ if (unlikely(frag_offset >= page_size)) {
frag_page++;
- frag_offset -= PAGE_SIZE;
+ frag_offset -= page_size;
}
}
@@ -2098,7 +2102,7 @@ mlx5e_skb_from_cqe_mpwrq_nonlinear(struct mlx5e_rq *rq, struct mlx5e_mpw_info *w
while (byte_cnt) {
/* Non-linear mode, hence non-XSK, which always uses PAGE_SIZE. */
pg_consumed_bytes =
- min_t(u32, PAGE_SIZE - frag_offset, byte_cnt);
+ min_t(u32, page_size - frag_offset, byte_cnt);
if (test_bit(MLX5E_RQ_STATE_SHAMPO, &rq->state))
truesize += pg_consumed_bytes;
@@ -2135,7 +2139,7 @@ mlx5e_skb_from_cqe_mpwrq_nonlinear(struct mlx5e_rq *rq, struct mlx5e_mpw_info *w
new_nr_frags = sinfo->nr_frags;
nr_frags_free = old_nr_frags - new_nr_frags;
if (unlikely(nr_frags_free))
- truesize -= (nr_frags_free - 1) * PAGE_SIZE +
+ truesize -= (nr_frags_free - 1) * page_size +
ALIGN(pg_consumed_bytes,
BIT(rq->mpwqe.log_stride_sz));
@@ -2349,15 +2353,16 @@ mlx5e_shampo_flush_skb(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe, bool match)
rq->hw_gro_data->skb = NULL;
}
-static bool
-mlx5e_hw_gro_skb_has_enough_space(struct sk_buff *skb, u16 data_bcnt)
+static bool mlx5e_hw_gro_skb_has_enough_space(struct sk_buff *skb,
+ u16 data_bcnt,
+ u32 page_size)
{
int nr_frags = skb_shinfo(skb)->nr_frags;
- if (PAGE_SIZE >= GRO_LEGACY_MAX_SIZE)
+ if (page_size >= GRO_LEGACY_MAX_SIZE)
return skb->len + data_bcnt <= GRO_LEGACY_MAX_SIZE;
else
- return PAGE_SIZE * nr_frags + data_bcnt <= GRO_LEGACY_MAX_SIZE;
+ return page_size * nr_frags + data_bcnt <= GRO_LEGACY_MAX_SIZE;
}
static void mlx5e_handle_rx_cqe_mpwrq_shampo(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe)
@@ -2366,18 +2371,19 @@ static void mlx5e_handle_rx_cqe_mpwrq_shampo(struct mlx5e_rq *rq, struct mlx5_cq
u16 header_index = mlx5e_shampo_get_cqe_header_index(rq, cqe);
u32 wqe_offset = be32_to_cpu(cqe->shampo.data_offset);
u16 cstrides = mpwrq_get_cqe_consumed_strides(cqe);
- u32 data_offset = wqe_offset & (PAGE_SIZE - 1);
u32 cqe_bcnt = mpwrq_get_cqe_byte_cnt(cqe);
u16 wqe_id = be16_to_cpu(cqe->wqe_id);
- u32 page_idx = wqe_offset >> PAGE_SHIFT;
u16 head_size = cqe->shampo.header_size;
struct sk_buff **skb = &rq->hw_gro_data->skb;
bool flush = cqe->shampo.flush;
bool match = cqe->shampo.match;
+ u32 page_size = BIT(rq->mpwqe.page_shift);
struct mlx5e_rq_stats *stats = rq->stats;
struct mlx5e_rx_wqe_ll *wqe;
struct mlx5e_mpw_info *wi;
struct mlx5_wq_ll *wq;
+ u32 data_offset;
+ u32 page_idx;
wi = mlx5e_get_mpw_info(rq, wqe_id);
wi->consumed_strides += cstrides;
@@ -2393,7 +2399,11 @@ static void mlx5e_handle_rx_cqe_mpwrq_shampo(struct mlx5e_rq *rq, struct mlx5_cq
goto mpwrq_cqe_out;
}
- if (*skb && (!match || !(mlx5e_hw_gro_skb_has_enough_space(*skb, data_bcnt)))) {
+ data_offset = wqe_offset & (page_size - 1);
+ page_idx = wqe_offset >> rq->mpwqe.page_shift;
+ if (*skb &&
+ !(match && mlx5e_hw_gro_skb_has_enough_space(*skb, data_bcnt,
+ page_size))) {
match = false;
mlx5e_shampo_flush_skb(rq, cqe, match);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 6.18.y 2/2] net/mlx5e: do not HW-GRO coalesce small frames
2026-09-09 17:32 ` [PATCH 6.18.y 1/2] net/mlx5e: SHAMPO, Always calculate page size Sasha Levin
@ 2026-09-09 17:32 ` Sasha Levin
0 siblings, 0 replies; 5+ messages in thread
From: Sasha Levin @ 2026-09-09 17:32 UTC (permalink / raw)
To: stable; +Cc: Glenn Judd, Tariq Toukan, Jakub Kicinski, Sasha Levin
From: Glenn Judd <gmj@meta.com>
[ Upstream commit e2466392a0b8496000e12181cb1ee1535eb0da25 ]
When hardware GRO (SHAMPO) coalesces a small IPv4/TCP segment that was
padded up to the 60-byte minimum Ethernet frame, the trailing padding is
folded into the merged payload causing padding to be delivered
to the user as payload.
Detecting and reproducing the issue: the selftest
tools/testing/selftests/drivers/net/gro.py subtest
hw_ipv4_data_lrg_1byte sends {100, 1} expecting to receive {101}.
In current code, it receives {106} (100 + 1 payload + 5 pad) instead.
This patch avoids giving the user padding as payload by simply not
coalescing small packets (which fails the subtest; the same approach
and behavior as sw gro). This gains code simplicity at the cost of
more computation (passing an extra skb up the stack) for small packets
that could be coalesced.
The threshold is chosen as ETH_ZLEN + 2 * VLAN_HLEN. This is the largest
frame that may still contain minimum-frame padding (+ 2 VLAN tags), so
anything larger is safe to consider for coalesce. (We do not include
ETH_FCS_LEN in that threshold computation as netdev_fix_features()
drops NETIF_F_GRO_HW whenever NETIF_F_RXFCS is set, so retained FCS
can't reach this path.)
Fixes: 92552d3abd32 ("net/mlx5e: HW_GRO cqe handler implementation")
Cc: stable@vger.kernel.org
Signed-off-by: Glenn Judd <gmj@meta.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
Link: https://patch.msgid.link/20260816064259.3279548-1-tariqt@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/mellanox/mlx5/core/en_rx.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
index 8a61c958c5679..17b74a97138b5 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
@@ -2401,6 +2401,11 @@ static void mlx5e_handle_rx_cqe_mpwrq_shampo(struct mlx5e_rq *rq, struct mlx5_cq
data_offset = wqe_offset & (page_size - 1);
page_idx = wqe_offset >> rq->mpwqe.page_shift;
+ if (unlikely(cqe_bcnt <= ETH_ZLEN + 2 * VLAN_HLEN)) {
+ match = false;
+ flush = true;
+ }
+
if (*skb &&
!(match && mlx5e_hw_gro_skb_has_enough_space(*skb, data_bcnt,
page_size))) {
--
2.53.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-09-09 17:32 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-03 15:09 FAILED: patch "[PATCH] net/mlx5e: do not HW-GRO coalesce small frames" failed to apply to 6.18-stable tree gregkh
2026-09-09 17:32 ` [PATCH 6.18.y 1/2] net/mlx5e: SHAMPO, Always calculate page size Sasha Levin
2026-09-09 17:32 ` [PATCH 6.18.y 2/2] net/mlx5e: do not HW-GRO coalesce small frames Sasha Levin
2026-09-09 17:32 ` [PATCH 6.18.y 1/2] net/mlx5e: SHAMPO, Always calculate page size Sasha Levin
2026-09-09 17:32 ` [PATCH 6.18.y 2/2] net/mlx5e: do not HW-GRO coalesce small frames Sasha Levin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox