rte_dpaa_remove() closed the port twice:
ret = dpaa_eth_dev_close(eth_dev);
if (eth_dev->state != RTE_ETH_DEV_UNUSED) {
dpaa_eth_dev_close(eth_dev);
The first call ran unconditionally, the second ran again on a port
that had just been torn down. The unconditional call also dereferenced
eth_dev without checking that rte_eth_dev_allocated() found anything,
so removing a device that was never probed crashed.
Close the port once, only when it is still in use, and log the close
result before releasing the port. The release status is returned,
since the port must be released regardless of how close ended.
Fixes: 78ea4b4fcb52 ("bus/dpaa: improve cleanup")
Cc: [email protected]
Signed-off-by: Hemant Agrawal <[email protected]>
---
drivers/net/dpaa/dpaa_ethdev.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/net/dpaa/dpaa_ethdev.c b/drivers/net/dpaa/dpaa_ethdev.c
index 1aaf97f175..a5b02cc9a8 100644
--- a/drivers/net/dpaa/dpaa_ethdev.c
+++ b/drivers/net/dpaa/dpaa_ethdev.c
@@ -2679,11 +2679,14 @@ rte_dpaa_remove(struct rte_dpaa_device *dpaa_dev)
PMD_INIT_FUNC_TRACE();
eth_dev = rte_eth_dev_allocated(dpaa_dev->device.name);
- ret = dpaa_eth_dev_close(eth_dev);
- if (eth_dev->state != RTE_ETH_DEV_UNUSED) {
- dpaa_eth_dev_close(eth_dev);
+ if (eth_dev != NULL && eth_dev->state != RTE_ETH_DEV_UNUSED) {
+ ret = dpaa_eth_dev_close(eth_dev);
+ if (ret != 0)
+ DPAA_PMD_WARN("%s: close failed(%d), releasing port",
+ dpaa_dev->device.name, ret);
ret = rte_eth_dev_release_port(eth_dev);
}
+
dpaa_valid_dev--;
if (!dpaa_valid_dev)
rte_mempool_free(dpaa_tx_sg_pool);
--
2.25.1