When a queue is stopped all buffers are meant to released from it, and
then a new set of buffers reallocated on start. For the iavf code when
using vector Tx, some buffers were left in the ring, and so those
buffers were leaked. The buffers were missed as the release code only
handled one side of a wrap-around case in the ring.

Fix the issue by doing a single iteration of the ring freeing all
buffers in it, handling wraparound through a simple post-increment
check.

Fixes: 319c421f3890 ("net/avf: enable SSE Rx Tx")
Fixes: 9ab9514c150e ("net/iavf: enable AVX512 for Tx")
Cc: wenzhuo...@intel.com
Cc: jingjing...@intel.com
Cc: sta...@dpdk.org

Signed-off-by: Bruce Richardson <bruce.richard...@intel.com>
---
 drivers/net/iavf/iavf_rxtx_vec_avx512.c | 17 ++++++++---------
 drivers/net/iavf/iavf_rxtx_vec_common.h | 11 +++++------
 2 files changed, 13 insertions(+), 15 deletions(-)

diff --git a/drivers/net/iavf/iavf_rxtx_vec_avx512.c 
b/drivers/net/iavf/iavf_rxtx_vec_avx512.c
index 3e66df5341..48337d5e03 100644
--- a/drivers/net/iavf/iavf_rxtx_vec_avx512.c
+++ b/drivers/net/iavf/iavf_rxtx_vec_avx512.c
@@ -2460,20 +2460,19 @@ iavf_tx_queue_release_mbufs_avx512(struct iavf_tx_queue 
*txq)
 {
        unsigned int i;
        const uint16_t max_desc = (uint16_t)(txq->nb_tx_desc - 1);
+       const uint16_t end_desc = txq->tx_tail >> txq->use_ctx; /* next empty 
slot */
+       const uint16_t wrap_point = txq->nb_tx_desc >> txq->use_ctx;  /* end of 
SW ring */
        struct iavf_tx_vec_entry *swr = (void *)txq->sw_ring;
 
        if (!txq->sw_ring || txq->nb_free == max_desc)
                return;
 
-       i = (txq->next_dd >> txq->use_ctx) + 1 -
-                       (txq->rs_thresh >> txq->use_ctx);
-
-       if (txq->tx_tail < i) {
-               for (; i < (unsigned int)(txq->nb_tx_desc >> txq->use_ctx); 
i++) {
-                       rte_pktmbuf_free_seg(swr[i].mbuf);
-                       swr[i].mbuf = NULL;
-               }
-               i = 0;
+       i = (txq->next_dd - txq->rs_thresh + 1) >> txq->use_ctx;
+       while (i != end_desc) {
+               rte_pktmbuf_free_seg(swr[i].mbuf);
+               swr[i].mbuf = NULL;
+               if (++i == wrap_point)
+                       i = 0;
        }
 }
 
diff --git a/drivers/net/iavf/iavf_rxtx_vec_common.h 
b/drivers/net/iavf/iavf_rxtx_vec_common.h
index ddb13ce8c3..1fac957fe1 100644
--- a/drivers/net/iavf/iavf_rxtx_vec_common.h
+++ b/drivers/net/iavf/iavf_rxtx_vec_common.h
@@ -186,12 +186,11 @@ _iavf_tx_queue_release_mbufs_vec(struct iavf_tx_queue 
*txq)
                return;
 
        i = txq->next_dd - txq->rs_thresh + 1;
-       if (txq->tx_tail < i) {
-               for (; i < txq->nb_tx_desc; i++) {
-                       rte_pktmbuf_free_seg(txq->sw_ring[i].mbuf);
-                       txq->sw_ring[i].mbuf = NULL;
-               }
-               i = 0;
+       while (i != txq->tx_tail) {
+               rte_pktmbuf_free_seg(txq->sw_ring[i].mbuf);
+               txq->sw_ring[i].mbuf = NULL;
+               if (++i == txq->nb_tx_desc)
+                       i = 0;
        }
 }
 
-- 
2.39.2

Reply via email to