From: Keegan Freyhof <[email protected]>

When exiting dpdk while having still having members in a bonded
port, the program would experience a segmentation fault due to the
bonding driver relying on the ethdev driver to free the rx and tx
queues of the bond members. The member ports would then try and
close using the bnxt driver, which would then try and access memory
freed by the ethdev driver causing the seen issue. The bnxt stuct's
rx and tx queues pointers would still point to the freed memory,
while the ethdev pointer would reflect the status changes to the rx
and tx queues array and be nulled.
- Changed net/bnxt/bnxt_stats.c and net/bnxt/bnxt_rxr.c to check
that the rx queues had not already been freed by the ethdev driver
and changed net/bnxt/bnxt_stats.c and net/bnxt/bnxt_txr.c to check
that the tx queues had not already been freed by the ethdev driver.

Fixes: 898248fc4287 ("net/bnxt: support statistics query when port is stopped")
Cc: [email protected]
Signed-off-by: Keegan Freyhof <[email protected]>
Signed-off-by: Mohammad Shuab Siddique <[email protected]>
---
 drivers/net/bnxt/bnxt_rxr.c   |  2 +-
 drivers/net/bnxt/bnxt_stats.c | 17 +++++++++++------
 drivers/net/bnxt/bnxt_txr.c   |  3 +++
 3 files changed, 15 insertions(+), 7 deletions(-)

diff --git a/drivers/net/bnxt/bnxt_rxr.c b/drivers/net/bnxt/bnxt_rxr.c
index 293b5c03b6..ab2175d21a 100644
--- a/drivers/net/bnxt/bnxt_rxr.c
+++ b/drivers/net/bnxt/bnxt_rxr.c
@@ -1491,7 +1491,7 @@ void bnxt_free_rx_rings(struct bnxt *bp)
        int i;
        struct bnxt_rx_queue *rxq;
 
-       if (!bp->rx_queues)
+       if (!bp->rx_queues || !bp->eth_dev->data->rx_queues)
                return;
 
        for (i = 0; i < (int)bp->rx_nr_rings; i++) {
diff --git a/drivers/net/bnxt/bnxt_stats.c b/drivers/net/bnxt/bnxt_stats.c
index 7b96cf0df9..49367588e4 100644
--- a/drivers/net/bnxt/bnxt_stats.c
+++ b/drivers/net/bnxt/bnxt_stats.c
@@ -547,15 +547,20 @@ void bnxt_free_stats(struct bnxt *bp)
 {
        int i;
 
-       for (i = 0; i < (int)bp->tx_cp_nr_rings; i++) {
-               struct bnxt_tx_queue *txq = bp->tx_queues[i];
+       if (bp->tx_queues && bp->eth_dev->data->tx_queues) {
+               for (i = 0; i < (int)bp->tx_cp_nr_rings; i++) {
+                       struct bnxt_tx_queue *txq = bp->tx_queues[i];
 
-               bnxt_free_txq_stats(txq);
+                       bnxt_free_txq_stats(txq);
+               }
        }
-       for (i = 0; i < (int)bp->rx_cp_nr_rings; i++) {
-               struct bnxt_rx_queue *rxq = bp->rx_queues[i];
 
-               bnxt_free_rxq_stats(rxq);
+       if (bp->rx_queues && bp->eth_dev->data->rx_queues) {
+               for (i = 0; i < (int)bp->rx_cp_nr_rings; i++) {
+                       struct bnxt_rx_queue *rxq = bp->rx_queues[i];
+
+                       bnxt_free_rxq_stats(rxq);
+               }
        }
 }
 
diff --git a/drivers/net/bnxt/bnxt_txr.c b/drivers/net/bnxt/bnxt_txr.c
index 83d18e220b..d37a38735c 100644
--- a/drivers/net/bnxt/bnxt_txr.c
+++ b/drivers/net/bnxt/bnxt_txr.c
@@ -24,6 +24,9 @@ void bnxt_free_tx_rings(struct bnxt *bp)
 {
        int i;
 
+       if (!bp->tx_queues || !bp->eth_dev->data->tx_queues)
+               return;
+
        for (i = 0; i < (int)bp->tx_nr_rings; i++) {
                struct bnxt_tx_queue *txq = bp->tx_queues[i];
 
-- 
2.47.3

Reply via email to