net: hibmcge: fix wrong ndo.open() after reset fail issue.
authorJijie Shao <shaojijie@huawei.com>
Sat, 17 May 2025 09:58:28 +0000 (17:58 +0800)
committerJakub Kicinski <kuba@kernel.org>
Wed, 21 May 2025 22:53:51 +0000 (15:53 -0700)
If the driver reset fails, it may not work properly.
Therefore, the ndo.open() operation should be rejected.

In this patch, the driver calls netif_device_detach()
before the reset and calls netif_device_attach()
after the reset succeeds. If the reset fails,
netif_device_attach() is not called. Therefore,
netdev does not present and cannot be opened.

If reset fails, only the PCI reset (via sysfs)
can be used to attempt recovery.

Fixes: 3f5a61f6d504 ("net: hibmcge: Add reset supported in this module")
Signed-off-by: Jijie Shao <shaojijie@huawei.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20250517095828.1763126-3-shaojijie@huawei.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/hisilicon/hibmcge/hbg_err.c

index a0bcfb5a713d13f9f21e47ea49d1d84a889d365d..ff3295b60a69a81260cd4ebeb90a3addf7fd2568 100644 (file)
@@ -61,6 +61,8 @@ static int hbg_reset_prepare(struct hbg_priv *priv, enum hbg_reset_type type)
                return -EBUSY;
        }
 
+       netif_device_detach(priv->netdev);
+
        priv->reset_type = type;
        set_bit(HBG_NIC_STATE_RESETTING, &priv->state);
        clear_bit(HBG_NIC_STATE_RESET_FAIL, &priv->state);
@@ -91,6 +93,8 @@ static int hbg_reset_done(struct hbg_priv *priv, enum hbg_reset_type type)
                return ret;
        }
 
+       netif_device_attach(priv->netdev);
+
        dev_info(&priv->pdev->dev, "reset done\n");
        return ret;
 }
@@ -117,16 +121,13 @@ void hbg_err_reset(struct hbg_priv *priv)
        if (running)
                dev_close(priv->netdev);
 
-       hbg_reset(priv);
-
-       /* in hbg_pci_err_detected(), we will detach first,
-        * so we need to attach before open
-        */
-       if (!netif_device_present(priv->netdev))
-               netif_device_attach(priv->netdev);
+       if (hbg_reset(priv))
+               goto err_unlock;
 
        if (running)
                dev_open(priv->netdev, NULL);
+
+err_unlock:
        rtnl_unlock();
 }
 
@@ -160,7 +161,6 @@ static pci_ers_result_t hbg_pci_err_slot_reset(struct pci_dev *pdev)
        pci_save_state(pdev);
 
        hbg_err_reset(priv);
-       netif_device_attach(netdev);
        return PCI_ERS_RESULT_RECOVERED;
 }