This patch set is intended to fix several issues for hibmcge driver:
1. Holding the rtnl_lock in pci_error_handlers->reset_prepare()
may lead to a deadlock issue.
2. A division by zero issue caused by debugfs when the port is down.
3. A probabilistic false positive issue with np_link_fail.
---
ChangeLog:
v2 -> v3:
- Use READ_ONCE() to read temporary variable, suggested by Jakub Kicinski
v2: https://lore.kernel.org/all/20250805181446.3deaceb9@kernel.org/
v1 -> v2:
- Fix a concurrency issue for patch1, suggested by Simon Horman
v1: https://lore.kernel.org/all/20250731134749.4090041-1-shaojijie@huawei.com/
---
Jijie Shao (3):
net: hibmcge: fix rtnl deadlock issue
net: hibmcge: fix the division by zero issue
net: hibmcge: fix the np_link_fail error reporting issue
drivers/net/ethernet/hisilicon/hibmcge/hbg_err.c | 14 +++++---------
drivers/net/ethernet/hisilicon/hibmcge/hbg_hw.c | 15 +++++++++++++--
drivers/net/ethernet/hisilicon/hibmcge/hbg_txrx.h | 7 ++++++-
3 files changed, 24 insertions(+), 12 deletions(-)
--
2.33.0
Currently, the hibmcge netdev acquires the rtnl_lock in
pci_error_handlers.reset_prepare() and releases it in
pci_error_handlers.reset_done().
However, in the PCI framework:
pci_reset_bus - __pci_reset_slot - pci_slot_save_and_disable_locked -
pci_dev_save_and_disable - err_handler->reset_prepare(dev);
In pci_slot_save_and_disable_locked():
list_for_each_entry(dev, &slot->bus->devices, bus_list) {
if (!dev->slot || dev->slot!= slot)
continue;
pci_dev_save_and_disable(dev);
if (dev->subordinate)
pci_bus_save_and_disable_locked(dev->subordinate);
}
This will iterate through all devices under the current bus and execute
err_handler->reset_prepare(), causing two devices of the hibmcge driver
to sequentially request the rtnl_lock, leading to a deadlock.
Since the driver now executes netif_device_detach()
before the reset process, it will not concurrently with
other netdev APIs, so there is no need to hold the rtnl_lock now.
Therefore, this patch removes the rtnl_lock during the reset process and
adjusts the position of HBG_NIC_STATE_RESETTING to ensure
that multiple resets are not executed concurrently.
Fixes: 3f5a61f6d504f ("net: hibmcge: Add reset supported in this module")
Signed-off-by: Jijie Shao <shaojijie@huawei.com>
Reviewed-by: Simon Horman <horms@kernel.org>
---
ChangeLog:
v1 -> v2:
- Fix a concurrency issue, suggested by Simon Horman
v1: https://lore.kernel.org/all/20250731134749.4090041-1-shaojijie@huawei.com/
---
drivers/net/ethernet/hisilicon/hibmcge/hbg_err.c | 14 +++++---------
1 file changed, 5 insertions(+), 9 deletions(-)
@@ -53,9 +53,11 @@ static int hbg_reset_prepare(struct hbg_priv *priv, enum hbg_reset_type type){intret;-ASSERT_RTNL();+if(test_and_set_bit(HBG_NIC_STATE_RESETTING,&priv->state))+return-EBUSY;if(netif_running(priv->netdev)){+clear_bit(HBG_NIC_STATE_RESETTING,&priv->state);dev_warn(&priv->pdev->dev,"failed to reset because port is up\n");return-EBUSY;
@@ -84,29 +85,26 @@ static int hbg_reset_done(struct hbg_priv *priv, enum hbg_reset_type type)type!=priv->reset_type)return0;-ASSERT_RTNL();--clear_bit(HBG_NIC_STATE_RESETTING,&priv->state);ret=hbg_rebuild(priv);if(ret){priv->stats.reset_fail_cnt++;set_bit(HBG_NIC_STATE_RESET_FAIL,&priv->state);+clear_bit(HBG_NIC_STATE_RESETTING,&priv->state);dev_err(&priv->pdev->dev,"failed to rebuild after reset\n");returnret;}netif_device_attach(priv->netdev);+clear_bit(HBG_NIC_STATE_RESETTING,&priv->state);dev_info(&priv->pdev->dev,"reset done\n");returnret;}-/* must be protected by rtnl lock */inthbg_reset(structhbg_priv*priv){intret;-ASSERT_RTNL();ret=hbg_reset_prepare(priv,HBG_RESET_TYPE_FUNCTION);if(ret)returnret;
Currently, after modifying device port mode, the np_link_ok state
is immediately checked. At this point, the device may not yet ready,
leading to the querying of an intermediate state.
This patch will poll to check if np_link is ok after
modifying device port mode, and only report np_link_fail upon timeout.
Fixes: e0306637e85d ("net: hibmcge: Add support for mac link exception handling feature")
Signed-off-by: Jijie Shao <shaojijie@huawei.com>
Reviewed-by: Simon Horman <horms@kernel.org>
---
drivers/net/ethernet/hisilicon/hibmcge/hbg_hw.c | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
When the network port is down, the queue is released, and ring->len is 0.
In debugfs, hbg_get_queue_used_num() will be called,
which may lead to a division by zero issue.
This patch adds a check, if ring->len is 0,
hbg_get_queue_used_num() directly returns 0.
Fixes: 40735e7543f9 ("net: hibmcge: Implement .ndo_start_xmit function")
Signed-off-by: Jijie Shao <shaojijie@huawei.com>
Reviewed-by: Simon Horman <horms@kernel.org>
---
ChangeLog:
v2 -> v3:
- Use READ_ONCE() to read temporary variable, suggested by Jakub Kicinski
v2: https://lore.kernel.org/all/20250805181446.3deaceb9@kernel.org/
---
drivers/net/ethernet/hisilicon/hibmcge/hbg_txrx.h | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
Hello:
This series was applied to netdev/net.git (main)
by Jakub Kicinski [off-list ref]:
On Wed, 6 Aug 2025 18:27:55 +0800 you wrote:
This patch set is intended to fix several issues for hibmcge driver:
1. Holding the rtnl_lock in pci_error_handlers->reset_prepare()
may lead to a deadlock issue.
2. A division by zero issue caused by debugfs when the port is down.
3. A probabilistic false positive issue with np_link_fail.
[...]