The VF reset may fail for some probabilistic reasons,
such as wait for hardware reset timeout, wait for mailbox
response timeout, so this patch tries to re-schedule the
reset task when the number of reset failing is under
HCLGEVF_RESET_MAX_FAIL_CNT. This patch also add a function
hclgevf_reset_err_handle() to handle the reset failing.

Signed-off-by: Huazhong Tan <tanhuazh...@huawei.com>
Signed-off-by: Peng Li <lipeng...@huawei.com>
---
 .../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c  | 30 ++++++++++++++++------
 .../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h  |  1 +
 2 files changed, 23 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
index 21736e5..42006cc 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
@@ -11,6 +11,8 @@
 
 #define HCLGEVF_NAME   "hclgevf"
 
+#define HCLGEVF_RESET_MAX_FAIL_CNT     5
+
 static int hclgevf_reset_hdev(struct hclgevf_dev *hdev);
 static struct hnae3_ae_algo ae_algovf;
 
@@ -1481,6 +1483,24 @@ static int hclgevf_reset_prepare_wait(struct hclgevf_dev 
*hdev)
        return ret;
 }
 
+static void hclgevf_reset_err_handle(struct hclgevf_dev *hdev)
+{
+       hdev->rst_stats.rst_fail_cnt++;
+       dev_err(&hdev->pdev->dev, "failed to reset VF(%d)\n",
+               hdev->rst_stats.rst_fail_cnt);
+
+       if (hdev->rst_stats.rst_fail_cnt < HCLGEVF_RESET_MAX_FAIL_CNT)
+               set_bit(hdev->reset_type, &hdev->reset_pending);
+
+       if (hclgevf_is_reset_pending(hdev)) {
+               set_bit(HCLGEVF_RESET_PENDING, &hdev->reset_state);
+               hclgevf_reset_task_schedule(hdev);
+       } else {
+               hclgevf_write_dev(&hdev->hw, HCLGEVF_NIC_CSQ_DEPTH_REG,
+                                 HCLGEVF_NIC_CMQ_ENABLE);
+       }
+}
+
 static int hclgevf_reset(struct hclgevf_dev *hdev)
 {
        struct hnae3_ae_dev *ae_dev = pci_get_drvdata(hdev->pdev);
@@ -1537,19 +1557,13 @@ static int hclgevf_reset(struct hclgevf_dev *hdev)
        hdev->last_reset_time = jiffies;
        ae_dev->reset_type = HNAE3_NONE_RESET;
        hdev->rst_stats.rst_done_cnt++;
+       hdev->rst_stats.rst_fail_cnt = 0;
 
        return ret;
 err_reset_lock:
        rtnl_unlock();
 err_reset:
-       /* When VF reset failed, only the higher level reset asserted by PF
-        * can restore it, so re-initialize the command queue to receive
-        * this higher reset event.
-        */
-       hclgevf_cmd_init(hdev);
-       dev_err(&hdev->pdev->dev, "failed to reset VF\n");
-       if (hclgevf_is_reset_pending(hdev))
-               hclgevf_reset_task_schedule(hdev);
+       hclgevf_reset_err_handle(hdev);
 
        return ret;
 }
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h
index b0ee986..5a9e309 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h
@@ -226,6 +226,7 @@ struct hclgevf_rst_stats {
        u32 vf_rst_cnt;                 /* the number of VF reset */
        u32 rst_done_cnt;               /* the number of reset completed */
        u32 hw_rst_done_cnt;            /* the number of HW reset completed */
+       u32 rst_fail_cnt;               /* the number of VF reset fail */
 };
 
 struct hclgevf_dev {
-- 
2.7.4

Reply via email to