net/bnx2x: fix DMAE timeout
In some cases, DPDK application may send packets while PMD is going through load or unload flow. This causes firmware to access invalid/unallocated memory to process transmit buffer. Which results in error on PCI bus and chip further blocks access to host, causing a DMAE timeout. Fix this issue by installing dummy empty transmit and receive handlers at the beginning of unload path (rte_eth_dev_stop()) and install actual transmit and receive handlers after successful load of the PMD port (rte_eth_dev_start()). This way, application won't be able to send packets while device is going through load/unload flow. Fixes: 540a211084a7 ("bnx2x: driver core") Cc: stable@dpdk.org Signed-off-by: Shahed Shaikh <shshaikh@marvell.com>
This commit is contained in:
parent
8bd31421c5
commit
e166e0db8c
@ -213,6 +213,7 @@ bnx2x_dev_configure(struct rte_eth_dev *dev)
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
bnx2x_dev_rxtx_init_dummy(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -242,11 +243,7 @@ bnx2x_dev_start(struct rte_eth_dev *dev)
|
||||
PMD_DRV_LOG(ERR, sc, "rte_intr_enable failed");
|
||||
}
|
||||
|
||||
ret = bnx2x_dev_rx_init(dev);
|
||||
if (ret != 0) {
|
||||
PMD_DRV_LOG(DEBUG, sc, "bnx2x_dev_rx_init returned error code");
|
||||
return -3;
|
||||
}
|
||||
bnx2x_dev_rxtx_init(dev);
|
||||
|
||||
bnx2x_print_device_info(sc);
|
||||
|
||||
@ -261,6 +258,8 @@ bnx2x_dev_stop(struct rte_eth_dev *dev)
|
||||
|
||||
PMD_INIT_FUNC_TRACE(sc);
|
||||
|
||||
bnx2x_dev_rxtx_init_dummy(dev);
|
||||
|
||||
if (IS_PF(sc)) {
|
||||
rte_intr_disable(&sc->pci_dev->intr_handle);
|
||||
rte_intr_callback_unregister(&sc->pci_dev->intr_handle,
|
||||
|
@ -311,7 +311,6 @@ bnx2x_dev_tx_queue_setup(struct rte_eth_dev *dev,
|
||||
txq->tx_bd_tail = 0;
|
||||
txq->tx_bd_head = 0;
|
||||
txq->nb_tx_avail = txq->nb_tx_desc;
|
||||
dev->tx_pkt_burst = bnx2x_xmit_pkts;
|
||||
dev->data->tx_queues[queue_idx] = txq;
|
||||
if (!sc->tx_queues) sc->tx_queues = dev->data->tx_queues;
|
||||
|
||||
@ -441,12 +440,24 @@ next_rx:
|
||||
return nb_rx;
|
||||
}
|
||||
|
||||
int
|
||||
bnx2x_dev_rx_init(struct rte_eth_dev *dev)
|
||||
static uint16_t
|
||||
bnx2x_rxtx_pkts_dummy(__rte_unused void *p_rxq,
|
||||
__rte_unused struct rte_mbuf **rx_pkts,
|
||||
__rte_unused uint16_t nb_pkts)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void bnx2x_dev_rxtx_init_dummy(struct rte_eth_dev *dev)
|
||||
{
|
||||
dev->rx_pkt_burst = bnx2x_rxtx_pkts_dummy;
|
||||
dev->tx_pkt_burst = bnx2x_rxtx_pkts_dummy;
|
||||
}
|
||||
|
||||
void bnx2x_dev_rxtx_init(struct rte_eth_dev *dev)
|
||||
{
|
||||
dev->rx_pkt_burst = bnx2x_recv_pkts;
|
||||
|
||||
return 0;
|
||||
dev->tx_pkt_burst = bnx2x_xmit_pkts;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -74,7 +74,8 @@ int bnx2x_dev_tx_queue_setup(struct rte_eth_dev *dev, uint16_t tx_queue_id,
|
||||
|
||||
void bnx2x_dev_rx_queue_release(void *rxq);
|
||||
void bnx2x_dev_tx_queue_release(void *txq);
|
||||
int bnx2x_dev_rx_init(struct rte_eth_dev *dev);
|
||||
void bnx2x_dev_rxtx_init(struct rte_eth_dev *dev);
|
||||
void bnx2x_dev_rxtx_init_dummy(struct rte_eth_dev *dev);
|
||||
void bnx2x_dev_clear_queues(struct rte_eth_dev *dev);
|
||||
|
||||
#endif /* _BNX2X_RXTX_H_ */
|
||||
|
Loading…
x
Reference in New Issue
Block a user