[10/13] net/ionic: fix device close sequence to avoid crash
Checks
Commit Message
The close routine should release all resources, but not
call rte_eth_dev_destroy(). As written this code will call
rte_eth_dev_release_port() twice and segfault.
Instead, move rte_eth_dev_destroy() to the remove routine.
eth_ionic_dev_uninit() will call close if necessary.
Fixes: 175e4e7ed760 ("net/ionic: complete release on close")
Cc: stable@dpdk.org
Signed-off-by: Andrew Boyer <andrew.boyer@amd.com>
---
drivers/net/ionic/ionic_ethdev.c | 30 +++++++++++++++---------------
1 file changed, 15 insertions(+), 15 deletions(-)
@@ -1009,19 +1009,21 @@ ionic_dev_close(struct rte_eth_dev *eth_dev)
ionic_lif_stop(lif);
- ionic_lif_free_queues(lif);
-
IONIC_PRINT(NOTICE, "Removing device %s", eth_dev->device->name);
if (adapter->intf->unconfigure_intr)
(*adapter->intf->unconfigure_intr)(adapter);
- rte_eth_dev_destroy(eth_dev, eth_ionic_dev_uninit);
-
ionic_port_reset(adapter);
ionic_reset(adapter);
+
+ ionic_lif_free_queues(lif);
+ ionic_lif_deinit(lif);
+ ionic_lif_free(lif); /* Does not free LIF object */
+
if (adapter->intf->unmap_bars)
(*adapter->intf->unmap_bars)(adapter);
+ lif->adapter = NULL;
rte_free(adapter);
return 0;
@@ -1098,21 +1100,18 @@ eth_ionic_dev_init(struct rte_eth_dev *eth_dev, void *init_params)
static int
eth_ionic_dev_uninit(struct rte_eth_dev *eth_dev)
{
- struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
- struct ionic_adapter *adapter = lif->adapter;
-
IONIC_PRINT_CALL();
if (rte_eal_process_type() != RTE_PROC_PRIMARY)
return 0;
- adapter->lif = NULL;
-
- ionic_lif_deinit(lif);
- ionic_lif_free(lif);
+ if (eth_dev->state != RTE_ETH_DEV_UNUSED)
+ ionic_dev_close(eth_dev);
- if (!(lif->state & IONIC_LIF_F_FW_RESET))
- ionic_lif_reset(lif);
+ eth_dev->dev_ops = NULL;
+ eth_dev->rx_pkt_burst = NULL;
+ eth_dev->tx_pkt_burst = NULL;
+ eth_dev->tx_pkt_prepare = NULL;
return 0;
}
@@ -1267,17 +1266,18 @@ eth_ionic_dev_remove(struct rte_device *rte_dev)
{
char name[RTE_ETH_NAME_MAX_LEN];
struct rte_eth_dev *eth_dev;
+ int ret = 0;
/* Adapter lookup is using the eth_dev name */
snprintf(name, sizeof(name), "%s_lif", rte_dev->name);
eth_dev = rte_eth_dev_allocated(name);
if (eth_dev)
- ionic_dev_close(eth_dev);
+ ret = rte_eth_dev_destroy(eth_dev, eth_ionic_dev_uninit);
else
IONIC_PRINT(DEBUG, "Cannot find device %s", rte_dev->name);
- return 0;
+ return ret;
}
RTE_LOG_REGISTER_DEFAULT(ionic_logtype, NOTICE);