Once freed, completed mbufs pointers are not set to NULL in the TX queue. Clean up function must take this into account.
Fixes: 2e22920b85d9 ("mlx5: support non-scattered Tx and Rx") Fixes: 7fae69eeff13 ("mlx4: new poll mode driver") Signed-off-by: Adrien Mazarguil <adrien.mazarguil at 6wind.com> --- drivers/net/mlx4/mlx4.c | 25 ++++++++++++++++++++----- drivers/net/mlx5/mlx5_rxtx.c | 4 ++++ drivers/net/mlx5/mlx5_txq.c | 21 ++++++++++++++++----- 3 files changed, 40 insertions(+), 10 deletions(-) diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c index f946f08..5cc995f 100644 --- a/drivers/net/mlx4/mlx4.c +++ b/drivers/net/mlx4/mlx4.c @@ -1047,14 +1047,20 @@ error: static void txq_free_elts(struct txq *txq) { - unsigned int i; unsigned int elts_n = txq->elts_n; + unsigned int elts_head = txq->elts_head; + unsigned int elts_tail = txq->elts_tail; struct txq_elt (*elts)[elts_n] = txq->elts; linear_t (*elts_linear)[elts_n] = txq->elts_linear; struct ibv_mr *mr_linear = txq->mr_linear; DEBUG("%p: freeing WRs", (void *)txq); txq->elts_n = 0; + txq->elts_head = 0; + txq->elts_tail = 0; + txq->elts_comp = 0; + txq->elts_comp_cd = 0; + txq->elts_comp_cd_init = 0; txq->elts = NULL; txq->elts_linear = NULL; txq->mr_linear = NULL; @@ -1064,12 +1070,17 @@ txq_free_elts(struct txq *txq) rte_free(elts_linear); if (elts == NULL) return; - for (i = 0; (i != elemof(*elts)); ++i) { - struct txq_elt *elt = &(*elts)[i]; + while (elts_tail != elts_head) { + struct txq_elt *elt = &(*elts)[elts_tail]; - if (elt->buf == NULL) - continue; + assert(elt->buf != NULL); rte_pktmbuf_free(elt->buf); +#ifndef NDEBUG + /* Poisoning. */ + memset(elt, 0x77, sizeof(*elt)); +#endif + if (++elts_tail == elts_n) + elts_tail = 0; } rte_free(elts); } @@ -1588,6 +1599,10 @@ mlx4_tx_burst(void *dpdk_txq, struct rte_mbuf **pkts, uint16_t pkts_n) if (likely(elt->buf != NULL)) { struct rte_mbuf *tmp = elt->buf; +#ifndef NDEBUG + /* Poisoning. */ + memset(elt, 0x66, sizeof(*elt)); +#endif /* Faster than rte_pktmbuf_free(). */ do { struct rte_mbuf *next = NEXT(tmp); diff --git a/drivers/net/mlx5/mlx5_rxtx.c b/drivers/net/mlx5/mlx5_rxtx.c index edf64aa..9d1380a 100644 --- a/drivers/net/mlx5/mlx5_rxtx.c +++ b/drivers/net/mlx5/mlx5_rxtx.c @@ -120,6 +120,10 @@ txq_complete(struct txq *txq) struct rte_mbuf *tmp = elt->buf; struct txq_elt *elt_next = &(*txq->elts)[elts_free_next]; +#ifndef NDEBUG + /* Poisoning. */ + memset(elt, 0x66, sizeof(*elt)); +#endif RTE_MBUF_PREFETCH_TO_FREE(elt_next->buf); /* Faster than rte_pktmbuf_free(). */ do { diff --git a/drivers/net/mlx5/mlx5_txq.c b/drivers/net/mlx5/mlx5_txq.c index ce2bb42..31ce53a 100644 --- a/drivers/net/mlx5/mlx5_txq.c +++ b/drivers/net/mlx5/mlx5_txq.c @@ -144,14 +144,20 @@ error: static void txq_free_elts(struct txq *txq) { - unsigned int i; unsigned int elts_n = txq->elts_n; + unsigned int elts_head = txq->elts_head; + unsigned int elts_tail = txq->elts_tail; struct txq_elt (*elts)[elts_n] = txq->elts; linear_t (*elts_linear)[elts_n] = txq->elts_linear; struct ibv_mr *mr_linear = txq->mr_linear; DEBUG("%p: freeing WRs", (void *)txq); txq->elts_n = 0; + txq->elts_head = 0; + txq->elts_tail = 0; + txq->elts_comp = 0; + txq->elts_comp_cd = 0; + txq->elts_comp_cd_init = 0; txq->elts = NULL; txq->elts_linear = NULL; txq->mr_linear = NULL; @@ -161,12 +167,17 @@ txq_free_elts(struct txq *txq) rte_free(elts_linear); if (elts == NULL) return; - for (i = 0; (i != RTE_DIM(*elts)); ++i) { - struct txq_elt *elt = &(*elts)[i]; + while (elts_tail != elts_head) { + struct txq_elt *elt = &(*elts)[elts_tail]; - if (elt->buf == NULL) - continue; + assert(elt->buf != NULL); rte_pktmbuf_free(elt->buf); +#ifndef NDEBUG + /* Poisoning. */ + memset(elt, 0x77, sizeof(*elt)); +#endif + if (++elts_tail == elts_n) + elts_tail = 0; } rte_free(elts); } -- 2.1.4