From: Sunil Kumar Kori Date: Mon, 21 Dec 2020 14:03:08 +0000 (+0530) Subject: net/octeontx2: fix corruption in segments list X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=54b79ac220b16465bf67d2bd65e3098379a5ce25;p=dpdk.git net/octeontx2: fix corruption in segments list On Tx, lastseg->next is not being reset to null for multi segmented packet and same mbuf can be used on Rx which has a stale mbuf entry into mbuf->next. On Rx, application receives mbuf with mbuf->next uninitialized though mbuf->nb_segs is correct. Application iterates over all segments using mbuf->next ignoring mbuf->nb_segs which leads to undefined behavior. So earlier assumption of just having right value in mbuf->nb_segs is enough, is incorrect. Mbuf must contain valid and synced value in nb_segs and next pointer. Fixes: 364eb0e46683 ("net/octeontx2: avoid per packet barrier with multi segment") Cc: stable@dpdk.org Signed-off-by: Sunil Kumar Kori Acked-by: Nithin Dabilpuram --- diff --git a/drivers/net/octeontx2/otx2_rx.c b/drivers/net/octeontx2/otx2_rx.c index 2da8efe77c..ffeade5952 100644 --- a/drivers/net/octeontx2/otx2_rx.c +++ b/drivers/net/octeontx2/otx2_rx.c @@ -279,6 +279,12 @@ nix_recv_pkts_vector(void *rx_queue, struct rte_mbuf **rx_pkts, vst1q_u64((uint64_t *)mbuf2->rearm_data, rearm2); vst1q_u64((uint64_t *)mbuf3->rearm_data, rearm3); + /* Update that no more segments */ + mbuf0->next = NULL; + mbuf1->next = NULL; + mbuf2->next = NULL; + mbuf3->next = NULL; + /* Store the mbufs to rx_pkts */ vst1q_u64((uint64_t *)&rx_pkts[packets], mbuf01); vst1q_u64((uint64_t *)&rx_pkts[packets + 2], mbuf23); diff --git a/drivers/net/octeontx2/otx2_rx.h b/drivers/net/octeontx2/otx2_rx.h index 926f614a4e..0ba3d3d96c 100644 --- a/drivers/net/octeontx2/otx2_rx.h +++ b/drivers/net/octeontx2/otx2_rx.h @@ -215,6 +215,7 @@ nix_cqe_xtract_mseg(const struct nix_rx_parse_s *rx, iova_list = (const rte_iova_t *)(iova_list + 1); } } + mbuf->next = NULL; } static __rte_always_inline uint16_t @@ -330,10 +331,12 @@ otx2_nix_cqe_to_mbuf(const struct nix_cqe_hdr_s *cq, const uint32_t tag, *(uint64_t *)(&mbuf->rearm_data) = val; mbuf->pkt_len = len; - if (flag & NIX_RX_MULTI_SEG_F) + if (flag & NIX_RX_MULTI_SEG_F) { nix_cqe_xtract_mseg(rx, mbuf, val); - else + } else { mbuf->data_len = len; + mbuf->next = NULL; + } } #define CKSUM_F NIX_RX_OFFLOAD_CHECKSUM_F