Commit c2002cc8 authored by Jian Shen's avatar Jian Shen Committed by Hao Chen
Browse files

net: hns3: fix oops when unload drivers paralleling

maillist inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/IBQKQF
CVE: NA

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git/commit/?id=92e599577377



----------------------------------------------------------------------

When unload hclge driver, it tries to disable sriov first for each
ae_dev node from hnae3_ae_dev_list. If user unloads hns3 driver at
the time, because it removes all the ae_dev nodes, and it may cause
oops.

But we can't simply use hnae3_common_lock for this. Because in the
process flow of pci_disable_sriov(), it will trigger the remove flow
of VF, which will also take hnae3_common_lock.

To fixes it, introduce a new mutex to protect the unload process.

Fixes: 0dd8a25f ("net: hns3: disable sriov before unload hclge layer")
Signed-off-by: default avatarJian Shen <shenjian15@huawei.com>
Signed-off-by: default avatarJijie Shao <shaojijie@huawei.com>
Link: https://patch.msgid.link/20250118094741.3046663-1-shaojijie@huawei.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
Signed-off-by: default avatarHao Chen <chenhao418@huawei.com>
parent 22f72139
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -37,6 +37,21 @@ EXPORT_SYMBOL(hnae3_unregister_ae_algo_prepare);
 */
static DEFINE_MUTEX(hnae3_common_lock);

/* ensure the drivers being unloaded one by one */
static DEFINE_MUTEX(hnae3_unload_lock);

void hnae3_acquire_unload_lock(void)
{
	mutex_lock(&hnae3_unload_lock);
}
EXPORT_SYMBOL(hnae3_acquire_unload_lock);

void hnae3_release_unload_lock(void)
{
	mutex_unlock(&hnae3_unload_lock);
}
EXPORT_SYMBOL(hnae3_release_unload_lock);

static bool hnae3_client_match(enum hnae3_client_type client_type)
{
	if (client_type == HNAE3_CLIENT_KNIC ||
+2 −0
Original line number Diff line number Diff line
@@ -1106,4 +1106,6 @@ int hnae3_register_client(struct hnae3_client *client);
void hnae3_set_client_init_flag(struct hnae3_client *client,
				struct hnae3_ae_dev *ae_dev,
				unsigned int inited);
void hnae3_acquire_unload_lock(void);
void hnae3_release_unload_lock(void);
#endif
+2 −0
Original line number Diff line number Diff line
@@ -6527,12 +6527,14 @@ module_init(hns3_init_module);
 */
static void __exit hns3_exit_module(void)
{
	hnae3_acquire_unload_lock();
#ifdef CONFIG_HNS3_UBL
	unregister_ipaddr_notifier();
#endif
	pci_unregister_driver(&hns3_driver);
	hnae3_unregister_client(&client);
	hns3_dbg_unregister_debugfs();
	hnae3_release_unload_lock();
}
module_exit(hns3_exit_module);

+2 −0
Original line number Diff line number Diff line
@@ -13842,9 +13842,11 @@ static int hclge_init(void)

static void hclge_exit(void)
{
	hnae3_acquire_unload_lock();
	hnae3_unregister_ae_algo_prepare(&ae_algo);
	hnae3_unregister_ae_algo(&ae_algo);
	destroy_workqueue(hclge_wq);
	hnae3_release_unload_lock();
}
module_init(hclge_init);
module_exit(hclge_exit);
+2 −0
Original line number Diff line number Diff line
@@ -3735,8 +3735,10 @@ static int hclgevf_init(void)

static void hclgevf_exit(void)
{
	hnae3_acquire_unload_lock();
	hnae3_unregister_ae_algo(&ae_algovf);
	destroy_workqueue(hclgevf_wq);
	hnae3_release_unload_lock();
}
module_init(hclgevf_init);
module_exit(hclgevf_exit);