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