The vectorized MPRQ path uses the software counter consumed_strd as the
stride index, resetting it only when it equals strd_n. The per-packet
stride count comes from pkt_len, which may not match the strides the
device consumed, so under load consumed_strd can drift past strd_n. The
stale index then makes mprq_buf_to_pkt() read buf->shinfos[] and the
stride offset out of bounds, corrupting mbuf metadata or accessing past
the buffer.
Drop the packet and realign to the next WQE when the stride index would
leave the buffer.
Bugzilla ID: 1369
Fixes: 0f20acbf5eda ("net/mlx5: implement vectorized MPRQ burst")
Cc: [email protected]
Reported-by: Kamil Vojanec <[email protected]>
Signed-off-by: Stephen Hemminger <[email protected]>
---
This patch looks right, it was generated by Claude based on
the bug report. I don't have mlx5 or any way to reproduce
original problem.
drivers/net/mlx5/mlx5_rxtx_vec.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/drivers/net/mlx5/mlx5_rxtx_vec.c b/drivers/net/mlx5/mlx5_rxtx_vec.c
index 79e92811d5..eebce160fd 100644
--- a/drivers/net/mlx5/mlx5_rxtx_vec.c
+++ b/drivers/net/mlx5/mlx5_rxtx_vec.c
@@ -232,6 +232,20 @@ rxq_copy_mprq_mbuf_v(struct mlx5_rxq_data *rxq,
}
strd_cnt = (elts[i]->pkt_len / strd_sz) +
((elts[i]->pkt_len % strd_sz) ? 1 : 0);
+ /* Drop and realign if the stride index drifted past the
+ * buffer, rather than letting mprq_buf_to_pkt() index
+ * past shinfos[] and the stride region (bug 1369).
+ */
+ if (unlikely(rxq->consumed_strd + strd_cnt > strd_n)) {
+ rxq->consumed_strd = strd_n;
+ rte_pktmbuf_free_seg(elts[i]);
+#ifdef MLX5_PMD_SOFT_COUNTERS
+ rxq->stats.ipackets -= 1;
+ rxq->stats.ibytes -= elts[i]->pkt_len;
+#endif
+ ++rxq->stats.idropped;
+ continue;
+ }
rxq_code = mprq_buf_to_pkt(rxq, elts[i], elts[i]->pkt_len,
buf, rxq->consumed_strd, strd_cnt);
rxq->consumed_strd += strd_cnt;
--
2.53.0