net/bnxt: fix memory leak during queue restart
authorRahul Gupta <rahul.gupta@broadcom.com>
Thu, 23 Apr 2020 15:02:23 +0000 (20:32 +0530)
committerFerruh Yigit <ferruh.yigit@intel.com>
Sat, 25 Apr 2020 21:09:29 +0000 (23:09 +0200)
During port 0 rxq 1 start ie queue start,
bnxt_free_hwrm_rx_ring() we are clearing the pointers to mbuf array.
Due to this we overwrite the queue with fresh mbuf allocations
causing previously allocated mbufs to leak.
Add a check before allocating mbuf to replenish only empty mbuf slots
in the RxQ.

Fixes: 2eb53b134aae ("net/bnxt: add initial Rx code")
Cc: stable@dpdk.org
Signed-off-by: Rahul Gupta <rahul.gupta@broadcom.com>
Reviewed-by: Somnath Kotur <somnath.kotur@broadcom.com>
Reviewed-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
drivers/net/bnxt/bnxt_hwrm.c
drivers/net/bnxt/bnxt_rxr.c

index ebf73e4..b0a7835 100644 (file)
@@ -2476,13 +2476,6 @@ void bnxt_free_hwrm_rx_ring(struct bnxt *bp, int queue_index)
                if (BNXT_HAS_RING_GRPS(bp))
                        bp->grp_info[queue_index].rx_fw_ring_id =
                                                        INVALID_HW_RING_ID;
-               memset(rxr->rx_desc_ring, 0,
-                      rxr->rx_ring_struct->ring_size *
-                      sizeof(*rxr->rx_desc_ring));
-               memset(rxr->rx_buf_ring, 0,
-                      rxr->rx_ring_struct->ring_size *
-                      sizeof(*rxr->rx_buf_ring));
-               rxr->rx_prod = 0;
        }
        ring = rxr->ag_ring_struct;
        if (ring->fw_ring_id != INVALID_HW_RING_ID) {
@@ -2490,11 +2483,6 @@ void bnxt_free_hwrm_rx_ring(struct bnxt *bp, int queue_index)
                                    BNXT_CHIP_THOR(bp) ?
                                    HWRM_RING_FREE_INPUT_RING_TYPE_RX_AGG :
                                    HWRM_RING_FREE_INPUT_RING_TYPE_RX);
-               ring->fw_ring_id = INVALID_HW_RING_ID;
-               memset(rxr->ag_buf_ring, 0,
-                      rxr->ag_ring_struct->ring_size *
-                      sizeof(*rxr->ag_buf_ring));
-               rxr->ag_prod = 0;
                if (BNXT_HAS_RING_GRPS(bp))
                        bp->grp_info[queue_index].ag_fw_ring_id =
                                                        INVALID_HW_RING_ID;
index 40da2f2..a657150 100644 (file)
@@ -963,14 +963,16 @@ int bnxt_init_one_rx_ring(struct bnxt_rx_queue *rxq)
 
        prod = rxr->rx_prod;
        for (i = 0; i < ring->ring_size; i++) {
-               if (bnxt_alloc_rx_data(rxq, rxr, prod) != 0) {
-                       PMD_DRV_LOG(WARNING,
-                               "init'ed rx ring %d with %d/%d mbufs only\n",
-                               rxq->queue_id, i, ring->ring_size);
-                       break;
+               if (unlikely(!rxr->rx_buf_ring[i].mbuf)) {
+                       if (bnxt_alloc_rx_data(rxq, rxr, prod) != 0) {
+                               PMD_DRV_LOG(WARNING,
+                                           "init'ed rx ring %d with %d/%d mbufs only\n",
+                                           rxq->queue_id, i, ring->ring_size);
+                               break;
+                       }
+                       rxr->rx_prod = prod;
+                       prod = RING_NEXT(rxr->rx_ring_struct, prod);
                }
-               rxr->rx_prod = prod;
-               prod = RING_NEXT(rxr->rx_ring_struct, prod);
        }
 
        ring = rxr->ag_ring_struct;
@@ -979,14 +981,16 @@ int bnxt_init_one_rx_ring(struct bnxt_rx_queue *rxq)
        prod = rxr->ag_prod;
 
        for (i = 0; i < ring->ring_size; i++) {
-               if (bnxt_alloc_ag_data(rxq, rxr, prod) != 0) {
-                       PMD_DRV_LOG(WARNING,
-                       "init'ed AG ring %d with %d/%d mbufs only\n",
-                       rxq->queue_id, i, ring->ring_size);
-                       break;
+               if (unlikely(!rxr->ag_buf_ring[i].mbuf)) {
+                       if (bnxt_alloc_ag_data(rxq, rxr, prod) != 0) {
+                               PMD_DRV_LOG(WARNING,
+                                           "init'ed AG ring %d with %d/%d mbufs only\n",
+                                           rxq->queue_id, i, ring->ring_size);
+                               break;
+                       }
+                       rxr->ag_prod = prod;
+                       prod = RING_NEXT(rxr->ag_ring_struct, prod);
                }
-               rxr->ag_prod = prod;
-               prod = RING_NEXT(rxr->ag_ring_struct, prod);
        }
        PMD_DRV_LOG(DEBUG, "AGG Done!\n");
 
@@ -994,11 +998,13 @@ int bnxt_init_one_rx_ring(struct bnxt_rx_queue *rxq)
                unsigned int max_aggs = BNXT_TPA_MAX_AGGS(rxq->bp);
 
                for (i = 0; i < max_aggs; i++) {
-                       rxr->tpa_info[i].mbuf =
-                               __bnxt_alloc_rx_data(rxq->mb_pool);
-                       if (!rxr->tpa_info[i].mbuf) {
-                               rte_atomic64_inc(&rxq->rx_mbuf_alloc_fail);
-                               return -ENOMEM;
+                       if (unlikely(!rxr->tpa_info[i].mbuf)) {
+                               rxr->tpa_info[i].mbuf =
+                                       __bnxt_alloc_rx_data(rxq->mb_pool);
+                               if (!rxr->tpa_info[i].mbuf) {
+                                       rte_atomic64_inc(&rxq->rx_mbuf_alloc_fail);
+                                       return -ENOMEM;
+                               }
                        }
                }
        }