From: Adrien Mazarguil Date: Thu, 31 Mar 2016 09:43:43 +0000 (+0200) Subject: mlx: fix double mbuf free in Tx queue clean up X-Git-Tag: spdx-start~7142 X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=b185e63fdf7a5ae83d2c702a03172e8ac8765fe3;p=dpdk.git mlx: fix double mbuf free in Tx queue clean up 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 --- diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c index f946f0857a..5cc995f00c 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 edf64aa8ca..9d1380a021 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 ce2bb421ce..31ce53ad20 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); }