rte_dpaa_remove() called dpaa_eth_dev_close() and then
rte_eth_dev_release_port(), which calls the close op again through
rte_eth_dev_destroy(). The second close ran on an already torn down
port. It also dereferenced eth_dev without checking that
rte_eth_dev_allocated() found anything.
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