net: hns3: Clear client pointer when initialize client failed or unintialize finished
authorJian Shen <shenjian15@huawei.com>
Wed, 19 Sep 2018 17:29:56 +0000 (18:29 +0100)
committerDavid S. Miller <davem@davemloft.net>
Thu, 20 Sep 2018 04:20:22 +0000 (21:20 -0700)
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: 46a3df9f9718 ("net: hns3: Add HNS3 Acceleration Engine & Compatibility Layer Support")
Signed-off-by: Jian Shen <shenjian15@huawei.com>
Signed-off-by: Peng Li <lipeng321@huawei.com>
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c

index 8a50688bb8a799f1026374bf57f1092edd591b22..141da18decf14a162c6fd3547af3413aff2323f8 100644 (file)
@@ -5162,13 +5162,13 @@ static int hclge_init_client_instance(struct hnae3_client *client,
                        vport->nic.client = client;
                        ret = client->ops->init_instance(&vport->nic);
                        if (ret)
-                               return ret;
+                               goto clear_nic;
 
                        ret = hclge_init_instance_hw(hdev);
                        if (ret) {
                                client->ops->uninit_instance(&vport->nic,
                                                             0);
-                               return ret;
+                               goto clear_nic;
                        }
 
                        if (hdev->roce_client &&
@@ -5177,11 +5177,11 @@ static int hclge_init_client_instance(struct hnae3_client *client,
 
                                ret = hclge_init_roce_base_info(vport);
                                if (ret)
-                                       return ret;
+                                       goto clear_roce;
 
                                ret = rc->ops->init_instance(&vport->roce);
                                if (ret)
-                                       return ret;
+                                       goto clear_roce;
                        }
 
                        break;
@@ -5191,7 +5191,7 @@ static int hclge_init_client_instance(struct hnae3_client *client,
 
                        ret = client->ops->init_instance(&vport->nic);
                        if (ret)
-                               return ret;
+                               goto clear_nic;
 
                        break;
                case HNAE3_CLIENT_ROCE:
@@ -5203,16 +5203,25 @@ static int hclge_init_client_instance(struct hnae3_client *client,
                        if (hdev->roce_client && hdev->nic_client) {
                                ret = hclge_init_roce_base_info(vport);
                                if (ret)
-                                       return ret;
+                                       goto clear_roce;
 
                                ret = client->ops->init_instance(&vport->roce);
                                if (ret)
-                                       return ret;
+                                       goto clear_roce;
                        }
                }
        }
 
        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,
@@ -5232,7 +5241,7 @@ static void hclge_uninit_client_instance(struct hnae3_client *client,
                }
                if (client->type == HNAE3_CLIENT_ROCE)
                        return;
-               if (client->ops->uninit_instance) {
+               if (hdev->nic_client && client->ops->uninit_instance) {
                        hclge_uninit_instance_hw(hdev);
                        client->ops->uninit_instance(&vport->nic, 0);
                        hdev->nic_client = NULL;
index 320043e87fc62c8e48c5b77a9420e1c967acd8f5..88cff5ff5fafcccd8a259ac7f04960e2ec59d497 100644 (file)
@@ -1624,17 +1624,17 @@ static int hclgevf_init_client_instance(struct hnae3_client *client,
 
                ret = client->ops->init_instance(&hdev->nic);
                if (ret)
-                       return ret;
+                       goto clear_nic;
 
                if (hdev->roce_client && hnae3_dev_roce_supported(hdev)) {
                        struct hnae3_client *rc = hdev->roce_client;
 
                        ret = hclgevf_init_roce_base_info(hdev);
                        if (ret)
-                               return ret;
+                               goto clear_roce;
                        ret = rc->ops->init_instance(&hdev->roce);
                        if (ret)
-                               return ret;
+                               goto clear_roce;
                }
                break;
        case HNAE3_CLIENT_UNIC:
@@ -1643,7 +1643,7 @@ static int hclgevf_init_client_instance(struct hnae3_client *client,
 
                ret = client->ops->init_instance(&hdev->nic);
                if (ret)
-                       return ret;
+                       goto clear_nic;
                break;
        case HNAE3_CLIENT_ROCE:
                if (hnae3_dev_roce_supported(hdev)) {
@@ -1654,15 +1654,24 @@ static int hclgevf_init_client_instance(struct hnae3_client *client,
                if (hdev->roce_client && hdev->nic_client) {
                        ret = hclgevf_init_roce_base_info(hdev);
                        if (ret)
-                               return ret;
+                               goto clear_roce;
 
                        ret = client->ops->init_instance(&hdev->roce);
                        if (ret)
-                               return ret;
+                               goto clear_roce;
                }
        }
 
        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,
@@ -1671,13 +1680,19 @@ static void hclgevf_uninit_client_instance(struct hnae3_client *client,
        struct hclgevf_dev *hdev = ae_dev->priv;
 
        /* 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 = NULL;
+               hdev->roce.client = NULL;
+       }
 
        /* un-init nic/unic, if this was not called by roce client */
-       if ((client->ops->uninit_instance) &&
-           (client->type != HNAE3_CLIENT_ROCE))
+       if (client->ops->uninit_instance && hdev->nic_client &&
+           client->type != HNAE3_CLIENT_ROCE) {
                client->ops->uninit_instance(&hdev->nic, 0);
+               hdev->nic_client = NULL;
+               hdev->nic.client = NULL;
+       }
 }
 
 static int hclgevf_pci_init(struct hclgevf_dev *hdev)