[dpdk-dev] [PATCH] mlx: fix double mbuf free in TX queue clean up function

2016-03-31 Thread Thomas Monjalon
2016-03-31 11:43, Adrien Mazarguil:
> 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 

Applied, thanks



[dpdk-dev] [PATCH] mlx: fix double mbuf free in TX queue clean up function

2016-03-31 Thread Adrien Mazarguil
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 
---
 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