]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
net: hns3: fix oops when unload drivers paralleling
authorJian Shen <shenjian15@huawei.com>
Sat, 18 Jan 2025 09:47:41 +0000 (17:47 +0800)
committerJakub Kicinski <kuba@kernel.org>
Thu, 23 Jan 2025 04:00:34 +0000 (20:00 -0800)
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: 0dd8a25f355b ("net: hns3: disable sriov before unload hclge layer")
Signed-off-by: Jian Shen <shenjian15@huawei.com>
Signed-off-by: Jijie Shao <shaojijie@huawei.com>
Link: https://patch.msgid.link/20250118094741.3046663-1-shaojijie@huawei.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/hisilicon/hns3/hnae3.c
drivers/net/ethernet/hisilicon/hns3/hnae3.h
drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c

index 9a63fbc6940831d16d90fb89df4ec76d132f502f..b25fb400f4767e5044b8fa665cc8b57e48bc1d8c 100644 (file)
@@ -40,6 +40,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 ||
index 12ba380eb7019afcc1cde913c43087170e1b1e66..4e44f28288f9023aec03a91e578183ab90f56de2 100644 (file)
@@ -963,4 +963,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
index a7e3b22f641c855186722d745cd28eaef02b4a08..9ff797fb36c4564fb15abb3888dba58f6b61b2a6 100644 (file)
@@ -6002,9 +6002,11 @@ module_init(hns3_init_module);
  */
 static void __exit hns3_exit_module(void)
 {
+       hnae3_acquire_unload_lock();
        pci_unregister_driver(&hns3_driver);
        hnae3_unregister_client(&client);
        hns3_dbg_unregister_debugfs();
+       hnae3_release_unload_lock();
 }
 module_exit(hns3_exit_module);
 
index db784500925261dfec13d663330ab49a99c06ab0..3f17b3073e50fd743f3e57955298f9358a90c6d9 100644 (file)
@@ -12919,9 +12919,11 @@ static int __init hclge_init(void)
 
 static void __exit 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);
index 163c6e59ea4c15e372cbcfbfa9b4571df1eaa1aa..9ba767740a043f9c8fe3201717f46372888c99c7 100644 (file)
@@ -3410,8 +3410,10 @@ static int __init hclgevf_init(void)
 
 static void __exit 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);