]> git.droids-corp.org - dpdk.git/commitdiff
net/bnxt: fix crash after removing and adding slaves
authorSantoshkumar Karanappa Rastapur <santosh.rastapur@broadcom.com>
Thu, 24 Oct 2019 07:44:27 +0000 (13:14 +0530)
committerFerruh Yigit <ferruh.yigit@intel.com>
Fri, 25 Oct 2019 17:23:23 +0000 (19:23 +0200)
On removing the slave interface, slave_remove in bonding module calls
_rte_eth_dev_reset which in turn frees both Tx and Rx queues.
1. segfault is seen after removing/adding the slave interface and starting
bond interface.
In this below path, when mtu is set for the slave interface, queues are
not created yet and driver reference to queue[0] causes the segfault.
slave_configure:
rte_eth_dev_set_mtu
rte_eth_dev_configure
rte_eth_rx_queue_setup

2. segfault is seen on starting the port after removing from bond device.
This is a testpmd bug where in, on starting the port, testpmd is supposed
to recreate the queues before starting the port.

Fixed these by adding check for queues created before accessing them.

Fixes: daef48efe5e5 ("net/bnxt: support set MTU")
Cc: stable@dpdk.org
Signed-off-by: Santoshkumar Karanappa Rastapur <santosh.rastapur@broadcom.com>
Signed-off-by: Somnath Kotur <somnath.kotur@broadcom.com>
Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
drivers/net/bnxt/bnxt.h
drivers/net/bnxt/bnxt_ethdev.c
drivers/net/bnxt/bnxt_rxq.c

index 975bcf9c6beb3df84b9641ddbe04367e0f4b980d..ffc37ea2d86a2d2cb54d549b26f86a03fbb8592e 100644 (file)
@@ -639,6 +639,7 @@ struct bnxt {
        struct bnxt_error_recovery_info *recovery_info;
 };
 
+int bnxt_mtu_set_op(struct rte_eth_dev *eth_dev, uint16_t new_mtu);
 int bnxt_link_update_op(struct rte_eth_dev *eth_dev, int wait_to_complete);
 int bnxt_rcv_msg_from_vf(struct bnxt *bp, uint16_t vf_id, void *msg);
 int is_bnxt_in_error(struct bnxt *bp);
index e24fd41202fa875b2ccf81fb139ed492e27f17d0..41872471ed40a0ddd99331b9c101f17e4a37077c 100644 (file)
@@ -121,7 +121,6 @@ static const struct rte_pci_id bnxt_pci_id_map[] = {
 
 static int bnxt_vlan_offload_set_op(struct rte_eth_dev *dev, int mask);
 static void bnxt_print_link_info(struct rte_eth_dev *eth_dev);
-static int bnxt_mtu_set_op(struct rte_eth_dev *eth_dev, uint16_t new_mtu);
 static int bnxt_dev_uninit(struct rte_eth_dev *eth_dev);
 static int bnxt_init_resources(struct bnxt *bp, bool reconfig_dev);
 static int bnxt_uninit_resources(struct bnxt *bp, bool reconfig_dev);
@@ -831,6 +830,11 @@ static int bnxt_dev_start_op(struct rte_eth_dev *eth_dev)
        int vlan_mask = 0;
        int rc;
 
+       if (!eth_dev->data->nb_tx_queues || !eth_dev->data->nb_rx_queues) {
+               PMD_DRV_LOG(ERR, "Queues are not configured yet!\n");
+               return -EINVAL;
+       }
+
        if (bp->rx_cp_nr_rings > RTE_ETHDEV_QUEUE_STAT_CNTRS) {
                PMD_DRV_LOG(ERR,
                        "RxQ cnt %d > CONFIG_RTE_ETHDEV_QUEUE_STAT_CNTRS %d\n",
@@ -2126,7 +2130,7 @@ bnxt_txq_info_get_op(struct rte_eth_dev *dev, uint16_t queue_id,
        qinfo->conf.tx_deferred_start = txq->tx_deferred_start;
 }
 
-static int bnxt_mtu_set_op(struct rte_eth_dev *eth_dev, uint16_t new_mtu)
+int bnxt_mtu_set_op(struct rte_eth_dev *eth_dev, uint16_t new_mtu)
 {
        struct bnxt *bp = eth_dev->data->dev_private;
        uint32_t new_pkt_size;
@@ -2137,6 +2141,10 @@ static int bnxt_mtu_set_op(struct rte_eth_dev *eth_dev, uint16_t new_mtu)
        if (rc)
                return rc;
 
+       /* Exit if receive queues are not configured yet */
+       if (!eth_dev->data->nb_rx_queues)
+               return rc;
+
        new_pkt_size = new_mtu + RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN +
                       VLAN_TAG_SIZE * BNXT_NUM_VLANS;
 
@@ -2167,7 +2175,9 @@ static int bnxt_mtu_set_op(struct rte_eth_dev *eth_dev, uint16_t new_mtu)
                bp->flags &= ~BNXT_FLAG_JUMBO;
        }
 
-       eth_dev->data->dev_conf.rxmode.max_rx_pkt_len = new_pkt_size;
+       /* Is there a change in mtu setting? */
+       if (eth_dev->data->dev_conf.rxmode.max_rx_pkt_len == new_pkt_size)
+               return rc;
 
        for (i = 0; i < bp->nr_vnics; i++) {
                struct bnxt_vnic_info *vnic = &bp->vnic_info[i];
@@ -2188,6 +2198,9 @@ static int bnxt_mtu_set_op(struct rte_eth_dev *eth_dev, uint16_t new_mtu)
                }
        }
 
+       if (!rc)
+               eth_dev->data->dev_conf.rxmode.max_rx_pkt_len = new_pkt_size;
+
        PMD_DRV_LOG(INFO, "New MTU is %d\n", new_mtu);
 
        return rc;
index e1ed360eff6d72eeac5b497412749fb38f3707cd..d55adc33acae0a5dc2fc1e43e19bb2c411f1c963 100644 (file)
@@ -366,6 +366,10 @@ int bnxt_rx_queue_setup_op(struct rte_eth_dev *eth_dev,
        eth_dev->data->rx_queue_state[queue_idx] = queue_state;
        rte_spinlock_init(&rxq->lock);
 
+       /* Configure mtu if it is different from what was configured before */
+       if (!queue_idx)
+               bnxt_mtu_set_op(eth_dev, eth_dev->data->mtu);
+
 out:
        return rc;
 }