提交 8b206623 编写于 作者: H Huazhong Tan 提交者: Xie XiuQi

net: hns3: fix race conditions between reset and module loading & unloading

driver inclusion
category: bugfix
bugzilla: NA
CVE: NA

When loading or unloading module, it should wait for the reset task
done before it un-initializes the client, otherwise the reset task
may cause a NULL pointer reference.

Fixes: 31218a981f90 ("net: hns3: fix race conditions between reset and module loading & unloading")

Feature or Bugfix:Bugfix
Signed-off-by: NHuazhong Tan <tanhuazhong@huawei.com>
Reviewed-by: Nlipeng <lipeng321@huawei.com>
Reviewed-by: NYang Yingliang <yangyingliang@huawei.com>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
上级 812ffba3
...@@ -8463,6 +8463,9 @@ static int hclge_init_nic_client_instance(struct hnae3_ae_dev *ae_dev, ...@@ -8463,6 +8463,9 @@ static int hclge_init_nic_client_instance(struct hnae3_ae_dev *ae_dev,
init_nic_err: init_nic_err:
clear_bit(HCLGE_STATE_NIC_REGISTERED, &hdev->state); clear_bit(HCLGE_STATE_NIC_REGISTERED, &hdev->state);
while (test_bit(HCLGE_STATE_RST_HANDLING, &hdev->state))
msleep(HCLGE_WAIT_RESET_DONE);
client->ops->uninit_instance(&vport->nic, 0); client->ops->uninit_instance(&vport->nic, 0);
return ret; return ret;
...@@ -8509,6 +8512,9 @@ static int hclge_init_roce_client_instance(struct hnae3_ae_dev *ae_dev, ...@@ -8509,6 +8512,9 @@ static int hclge_init_roce_client_instance(struct hnae3_ae_dev *ae_dev,
init_roce_err: init_roce_err:
clear_bit(HCLGE_STATE_ROCE_REGISTERED, &hdev->state); clear_bit(HCLGE_STATE_ROCE_REGISTERED, &hdev->state);
while (test_bit(HCLGE_STATE_RST_HANDLING, &hdev->state))
msleep(HCLGE_WAIT_RESET_DONE);
hdev->roce_client->ops->uninit_instance(&vport->roce, 0); hdev->roce_client->ops->uninit_instance(&vport->roce, 0);
return ret; return ret;
...@@ -8576,6 +8582,9 @@ static void hclge_uninit_client_instance(struct hnae3_client *client, ...@@ -8576,6 +8582,9 @@ static void hclge_uninit_client_instance(struct hnae3_client *client,
vport = &hdev->vport[i]; vport = &hdev->vport[i];
if (hdev->roce_client) { if (hdev->roce_client) {
clear_bit(HCLGE_STATE_ROCE_REGISTERED, &hdev->state); clear_bit(HCLGE_STATE_ROCE_REGISTERED, &hdev->state);
while (test_bit(HCLGE_STATE_RST_HANDLING, &hdev->state))
msleep(HCLGE_WAIT_RESET_DONE);
hdev->roce_client->ops->uninit_instance(&vport->roce, hdev->roce_client->ops->uninit_instance(&vport->roce,
0); 0);
hdev->roce_client = NULL; hdev->roce_client = NULL;
...@@ -8585,6 +8594,8 @@ static void hclge_uninit_client_instance(struct hnae3_client *client, ...@@ -8585,6 +8594,8 @@ static void hclge_uninit_client_instance(struct hnae3_client *client,
return; return;
if (hdev->nic_client && client->ops->uninit_instance) { if (hdev->nic_client && client->ops->uninit_instance) {
clear_bit(HCLGE_STATE_NIC_REGISTERED, &hdev->state); clear_bit(HCLGE_STATE_NIC_REGISTERED, &hdev->state);
while (test_bit(HCLGE_STATE_RST_HANDLING, &hdev->state))
msleep(HCLGE_WAIT_RESET_DONE);
client->ops->uninit_instance(&vport->nic, 0); client->ops->uninit_instance(&vport->nic, 0);
hdev->nic_client = NULL; hdev->nic_client = NULL;
......
...@@ -646,6 +646,7 @@ struct hclge_mac_tnl_stats { ...@@ -646,6 +646,7 @@ struct hclge_mac_tnl_stats {
}; };
#define HCLGE_RESET_INTERVAL (12 * HZ) #define HCLGE_RESET_INTERVAL (12 * HZ)
#define HCLGE_WAIT_RESET_DONE 100
/* For each bit of TCAM entry, it uses a pair of 'x' and /* For each bit of TCAM entry, it uses a pair of 'x' and
* 'y' to indicate which value to match, like below: * 'y' to indicate which value to match, like below:
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册