Cleanup was not done on this PMD if a error is seen during the init:
- possible memory leak due to a missing free
- interrupt handler was not disabled: if an IRQ is received after the
  init, a SIGSEGV can be seen (private data stored in
  rte_eth_devices[port_id] is pointing to NULL)

Fixes: a6061d9e7075 ("fm10k: register PF driver")
Fixes: 4c287332c39a ("fm10k: add PF and VF interrupt handling")
Cc: sta...@dpdk.org

Signed-off-by: Julien Meunier <julien.meun...@nokia.com>
---
 drivers/net/fm10k/fm10k_ethdev.c | 39 +++++++++++++++++++++++++++-----
 1 file changed, 33 insertions(+), 6 deletions(-)

diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c
index fa0d16277e..7b490bea17 100644
--- a/drivers/net/fm10k/fm10k_ethdev.c
+++ b/drivers/net/fm10k/fm10k_ethdev.c
@@ -3058,7 +3058,7 @@ eth_fm10k_dev_init(struct rte_eth_dev *dev)
        struct fm10k_hw *hw = FM10K_DEV_PRIVATE_TO_HW(dev->data->dev_private);
        struct rte_pci_device *pdev = RTE_ETH_DEV_TO_PCI(dev);
        struct rte_intr_handle *intr_handle = pdev->intr_handle;
-       int diag, i;
+       int diag, i, ret;
        struct fm10k_macvlan_filter_info *macvlan;
 
        PMD_INIT_FUNC_TRACE();
@@ -3147,21 +3147,24 @@ eth_fm10k_dev_init(struct rte_eth_dev *dev)
        diag = fm10k_stats_reset(dev);
        if (diag != 0) {
                PMD_INIT_LOG(ERR, "Stats reset failed: %d", diag);
-               return diag;
+               ret = diag;
+               goto err_stat;
        }
 
        /* Reset the hw */
        diag = fm10k_reset_hw(hw);
        if (diag != FM10K_SUCCESS) {
                PMD_INIT_LOG(ERR, "Hardware reset failed: %d", diag);
-               return -EIO;
+               ret = -EIO;
+               goto err_reset_hw;
        }
 
        /* Setup mailbox service */
        diag = fm10k_setup_mbx_service(hw);
        if (diag != FM10K_SUCCESS) {
                PMD_INIT_LOG(ERR, "Failed to setup mailbox: %d", diag);
-               return -EIO;
+               ret = -EIO;
+               goto err_mbx;
        }
 
        /*PF/VF has different interrupt handling mechanism */
@@ -3200,7 +3203,8 @@ eth_fm10k_dev_init(struct rte_eth_dev *dev)
 
                if (switch_ready == false) {
                        PMD_INIT_LOG(ERR, "switch is not ready");
-                       return -1;
+                       ret = -1;
+                       goto err_switch_ready;
                }
        }
 
@@ -3235,7 +3239,8 @@ eth_fm10k_dev_init(struct rte_eth_dev *dev)
 
                if (!hw->mac.default_vid) {
                        PMD_INIT_LOG(ERR, "default VID is not ready");
-                       return -1;
+                       ret = -1;
+                       goto err_vid;
                }
        }
 
@@ -3244,6 +3249,28 @@ eth_fm10k_dev_init(struct rte_eth_dev *dev)
                MAIN_VSI_POOL_NUMBER);
 
        return 0;
+
+err_vid:
+err_switch_ready:
+       rte_intr_disable(intr_handle);
+
+       if (hw->mac.type == fm10k_mac_pf) {
+               fm10k_dev_disable_intr_pf(dev);
+               rte_intr_callback_unregister(intr_handle,
+                       fm10k_dev_interrupt_handler_pf, (void *)dev);
+       } else {
+               fm10k_dev_disable_intr_vf(dev);
+               rte_intr_callback_unregister(intr_handle,
+                       fm10k_dev_interrupt_handler_vf, (void *)dev);
+       }
+
+err_mbx:
+err_reset_hw:
+err_stat:
+       rte_free(dev->data->mac_addrs);
+       dev->data->mac_addrs = NULL;
+
+       return ret;
 }
 
 static int
-- 
2.34.1

Reply via email to