Commit 49dd8054 authored by Jian Shen's avatar Jian Shen Committed by David S. Miller

net: hns3: Clear client pointer when initialize client failed or unintialize finished

If initialize client failed or finish uninitializing client, we should
clear the client pointer. It may cause unexpected result when use
uninitialized client. Meanwhile, we also should check whether client
exist when uninitialize it.

Fixes: 46a3df9f ("net: hns3: Add HNS3 Acceleration Engine & Compatibility Layer Support")
Signed-off-by: default avatarJian Shen <shenjian15@huawei.com>
Signed-off-by: default avatarPeng Li <lipeng321@huawei.com>
Signed-off-by: default avatarSalil Mehta <salil.mehta@huawei.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 37dc9cdb
...@@ -5162,13 +5162,13 @@ static int hclge_init_client_instance(struct hnae3_client *client, ...@@ -5162,13 +5162,13 @@ static int hclge_init_client_instance(struct hnae3_client *client,
vport->nic.client = client; vport->nic.client = client;
ret = client->ops->init_instance(&vport->nic); ret = client->ops->init_instance(&vport->nic);
if (ret) if (ret)
return ret; goto clear_nic;
ret = hclge_init_instance_hw(hdev); ret = hclge_init_instance_hw(hdev);
if (ret) { if (ret) {
client->ops->uninit_instance(&vport->nic, client->ops->uninit_instance(&vport->nic,
0); 0);
return ret; goto clear_nic;
} }
if (hdev->roce_client && if (hdev->roce_client &&
...@@ -5177,11 +5177,11 @@ static int hclge_init_client_instance(struct hnae3_client *client, ...@@ -5177,11 +5177,11 @@ static int hclge_init_client_instance(struct hnae3_client *client,
ret = hclge_init_roce_base_info(vport); ret = hclge_init_roce_base_info(vport);
if (ret) if (ret)
return ret; goto clear_roce;
ret = rc->ops->init_instance(&vport->roce); ret = rc->ops->init_instance(&vport->roce);
if (ret) if (ret)
return ret; goto clear_roce;
} }
break; break;
...@@ -5191,7 +5191,7 @@ static int hclge_init_client_instance(struct hnae3_client *client, ...@@ -5191,7 +5191,7 @@ static int hclge_init_client_instance(struct hnae3_client *client,
ret = client->ops->init_instance(&vport->nic); ret = client->ops->init_instance(&vport->nic);
if (ret) if (ret)
return ret; goto clear_nic;
break; break;
case HNAE3_CLIENT_ROCE: case HNAE3_CLIENT_ROCE:
...@@ -5203,16 +5203,25 @@ static int hclge_init_client_instance(struct hnae3_client *client, ...@@ -5203,16 +5203,25 @@ static int hclge_init_client_instance(struct hnae3_client *client,
if (hdev->roce_client && hdev->nic_client) { if (hdev->roce_client && hdev->nic_client) {
ret = hclge_init_roce_base_info(vport); ret = hclge_init_roce_base_info(vport);
if (ret) if (ret)
return ret; goto clear_roce;
ret = client->ops->init_instance(&vport->roce); ret = client->ops->init_instance(&vport->roce);
if (ret) if (ret)
return ret; goto clear_roce;
} }
} }
} }
return 0; return 0;
clear_nic:
hdev->nic_client = NULL;
vport->nic.client = NULL;
return ret;
clear_roce:
hdev->roce_client = NULL;
vport->roce.client = NULL;
return ret;
} }
static void hclge_uninit_client_instance(struct hnae3_client *client, static void hclge_uninit_client_instance(struct hnae3_client *client,
...@@ -5232,7 +5241,7 @@ static void hclge_uninit_client_instance(struct hnae3_client *client, ...@@ -5232,7 +5241,7 @@ static void hclge_uninit_client_instance(struct hnae3_client *client,
} }
if (client->type == HNAE3_CLIENT_ROCE) if (client->type == HNAE3_CLIENT_ROCE)
return; return;
if (client->ops->uninit_instance) { if (hdev->nic_client && client->ops->uninit_instance) {
hclge_uninit_instance_hw(hdev); hclge_uninit_instance_hw(hdev);
client->ops->uninit_instance(&vport->nic, 0); client->ops->uninit_instance(&vport->nic, 0);
hdev->nic_client = NULL; hdev->nic_client = NULL;
......
...@@ -1624,17 +1624,17 @@ static int hclgevf_init_client_instance(struct hnae3_client *client, ...@@ -1624,17 +1624,17 @@ static int hclgevf_init_client_instance(struct hnae3_client *client,
ret = client->ops->init_instance(&hdev->nic); ret = client->ops->init_instance(&hdev->nic);
if (ret) if (ret)
return ret; goto clear_nic;
if (hdev->roce_client && hnae3_dev_roce_supported(hdev)) { if (hdev->roce_client && hnae3_dev_roce_supported(hdev)) {
struct hnae3_client *rc = hdev->roce_client; struct hnae3_client *rc = hdev->roce_client;
ret = hclgevf_init_roce_base_info(hdev); ret = hclgevf_init_roce_base_info(hdev);
if (ret) if (ret)
return ret; goto clear_roce;
ret = rc->ops->init_instance(&hdev->roce); ret = rc->ops->init_instance(&hdev->roce);
if (ret) if (ret)
return ret; goto clear_roce;
} }
break; break;
case HNAE3_CLIENT_UNIC: case HNAE3_CLIENT_UNIC:
...@@ -1643,7 +1643,7 @@ static int hclgevf_init_client_instance(struct hnae3_client *client, ...@@ -1643,7 +1643,7 @@ static int hclgevf_init_client_instance(struct hnae3_client *client,
ret = client->ops->init_instance(&hdev->nic); ret = client->ops->init_instance(&hdev->nic);
if (ret) if (ret)
return ret; goto clear_nic;
break; break;
case HNAE3_CLIENT_ROCE: case HNAE3_CLIENT_ROCE:
if (hnae3_dev_roce_supported(hdev)) { if (hnae3_dev_roce_supported(hdev)) {
...@@ -1654,15 +1654,24 @@ static int hclgevf_init_client_instance(struct hnae3_client *client, ...@@ -1654,15 +1654,24 @@ static int hclgevf_init_client_instance(struct hnae3_client *client,
if (hdev->roce_client && hdev->nic_client) { if (hdev->roce_client && hdev->nic_client) {
ret = hclgevf_init_roce_base_info(hdev); ret = hclgevf_init_roce_base_info(hdev);
if (ret) if (ret)
return ret; goto clear_roce;
ret = client->ops->init_instance(&hdev->roce); ret = client->ops->init_instance(&hdev->roce);
if (ret) if (ret)
return ret; goto clear_roce;
} }
} }
return 0; return 0;
clear_nic:
hdev->nic_client = NULL;
hdev->nic.client = NULL;
return ret;
clear_roce:
hdev->roce_client = NULL;
hdev->roce.client = NULL;
return ret;
} }
static void hclgevf_uninit_client_instance(struct hnae3_client *client, static void hclgevf_uninit_client_instance(struct hnae3_client *client,
...@@ -1671,13 +1680,19 @@ static void hclgevf_uninit_client_instance(struct hnae3_client *client, ...@@ -1671,13 +1680,19 @@ static void hclgevf_uninit_client_instance(struct hnae3_client *client,
struct hclgevf_dev *hdev = ae_dev->priv; struct hclgevf_dev *hdev = ae_dev->priv;
/* un-init roce, if it exists */ /* un-init roce, if it exists */
if (hdev->roce_client) if (hdev->roce_client) {
hdev->roce_client->ops->uninit_instance(&hdev->roce, 0); hdev->roce_client->ops->uninit_instance(&hdev->roce, 0);
hdev->roce_client = NULL;
hdev->roce.client = NULL;
}
/* un-init nic/unic, if this was not called by roce client */ /* un-init nic/unic, if this was not called by roce client */
if ((client->ops->uninit_instance) && if (client->ops->uninit_instance && hdev->nic_client &&
(client->type != HNAE3_CLIENT_ROCE)) client->type != HNAE3_CLIENT_ROCE) {
client->ops->uninit_instance(&hdev->nic, 0); client->ops->uninit_instance(&hdev->nic, 0);
hdev->nic_client = NULL;
hdev->nic.client = NULL;
}
} }
static int hclgevf_pci_init(struct hclgevf_dev *hdev) static int hclgevf_pci_init(struct hclgevf_dev *hdev)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment