]> git.dujemihanovic.xyz Git - linux.git/commitdiff
net: hns3: ignore reset event before initialization process is done
authorGuangbin Huang <huangguangbin2@huawei.com>
Wed, 27 Oct 2021 12:11:45 +0000 (20:11 +0800)
committerDavid S. Miller <davem@davemloft.net>
Wed, 27 Oct 2021 13:47:33 +0000 (14:47 +0100)
Currently, if there is a reset event triggered by RAS during device in
initialization process, driver may run reset process concurrently with
initialization process. In this case, it may cause problem. For example,
the RSS indirection table may has not been alloc memory in initialization
process yet, but it is used in reset process, it will cause a call trace
like this:

[61228.744836] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000
...
[61228.897677] Workqueue: hclgevf hclgevf_service_task [hclgevf]
[61228.911390] pstate: 40400009 (nZcv daif +PAN -UAO -TCO BTYPE=--)
[61228.918670] pc : hclgevf_set_rss_indir_table+0xb4/0x190 [hclgevf]
[61228.927812] lr : hclgevf_set_rss_indir_table+0x90/0x190 [hclgevf]
[61228.937248] sp : ffff8000162ebb50
[61228.941087] x29: ffff8000162ebb50 x28: ffffb77add72dbc0 x27: ffff0820c7dc8080
[61228.949516] x26: 0000000000000000 x25: ffff0820ad4fc880 x24: ffff0820c7dc8080
[61228.958220] x23: ffff0820c7dc8090 x22: 00000000ffffffff x21: 0000000000000040
[61228.966360] x20: ffffb77add72b9c0 x19: 0000000000000000 x18: 0000000000000030
[61228.974646] x17: 0000000000000000 x16: ffffb77ae713feb0 x15: ffff0820ad4fcce8
[61228.982808] x14: ffffffffffffffff x13: ffff8000962eb7f7 x12: 00003834ec70c960
[61228.991990] x11: 00e0fafa8c206982 x10: 9670facc78a8f9a8 x9 : ffffb77add717530
[61229.001123] x8 : ffff0820ad4fd6b8 x7 : 0000000000000000 x6 : 0000000000000011
[61229.010249] x5 : 00000000000cb1b0 x4 : 0000000000002adb x3 : 0000000000000049
[61229.018662] x2 : ffff8000162ebbb8 x1 : 0000000000000000 x0 : 0000000000000480
[61229.027002] Call trace:
[61229.030177]  hclgevf_set_rss_indir_table+0xb4/0x190 [hclgevf]
[61229.039009]  hclgevf_rss_init_hw+0x128/0x1b4 [hclgevf]
[61229.046809]  hclgevf_reset_rebuild+0x17c/0x69c [hclgevf]
[61229.053862]  hclgevf_reset_service_task+0x4cc/0xa80 [hclgevf]
[61229.061306]  hclgevf_service_task+0x6c/0x630 [hclgevf]
[61229.068491]  process_one_work+0x1dc/0x48c
[61229.074121]  worker_thread+0x15c/0x464
[61229.078562]  kthread+0x168/0x16c
[61229.082873]  ret_from_fork+0x10/0x18
[61229.088221] Code: 7900e7f6 f904a683 d503201f 9101a3e2 (38616b43)
[61229.095357] ---[ end trace 153661a538f6768c ]---

To fix this problem, don't schedule reset task before initialization
process is done.

Signed-off-by: Guangbin Huang <huangguangbin2@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
drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h

index 3dbde04965453d2f0290ee1d45167cbfadfa06a6..269e579762b21e28fc9d398c2313ef76ead6ac1c 100644 (file)
@@ -2853,6 +2853,7 @@ static void hclge_mbx_task_schedule(struct hclge_dev *hdev)
 static void hclge_reset_task_schedule(struct hclge_dev *hdev)
 {
        if (!test_bit(HCLGE_STATE_REMOVING, &hdev->state) &&
+           test_bit(HCLGE_STATE_SERVICE_INITED, &hdev->state) &&
            !test_and_set_bit(HCLGE_STATE_RST_SERVICE_SCHED, &hdev->state))
                mod_delayed_work(hclge_wq, &hdev->service_task, 0);
 }
index 5efa5420297d243bf5323e2c5fce07270db3f4d0..cf00ad7bb881f31502d95277da55906cae71bc82 100644 (file)
@@ -2232,6 +2232,7 @@ static void hclgevf_get_misc_vector(struct hclgevf_dev *hdev)
 void hclgevf_reset_task_schedule(struct hclgevf_dev *hdev)
 {
        if (!test_bit(HCLGEVF_STATE_REMOVING, &hdev->state) &&
+           test_bit(HCLGEVF_STATE_SERVICE_INITED, &hdev->state) &&
            !test_and_set_bit(HCLGEVF_STATE_RST_SERVICE_SCHED,
                              &hdev->state))
                mod_delayed_work(hclgevf_wq, &hdev->service_task, 0);
@@ -3449,6 +3450,8 @@ static int hclgevf_init_hdev(struct hclgevf_dev *hdev)
 
        hclgevf_init_rxd_adv_layout(hdev);
 
+       set_bit(HCLGEVF_STATE_SERVICE_INITED, &hdev->state);
+
        hdev->last_reset_time = jiffies;
        dev_info(&hdev->pdev->dev, "finished initializing %s driver\n",
                 HCLGEVF_DRIVER_NAME);
index 883130a9b48f2b24a77a147781bd7bf2abf0edc6..28288d7e33032c33d679d3667591e30a345793b0 100644 (file)
@@ -146,6 +146,7 @@ enum hclgevf_states {
        HCLGEVF_STATE_REMOVING,
        HCLGEVF_STATE_NIC_REGISTERED,
        HCLGEVF_STATE_ROCE_REGISTERED,
+       HCLGEVF_STATE_SERVICE_INITED,
        /* task states */
        HCLGEVF_STATE_RST_SERVICE_SCHED,
        HCLGEVF_STATE_RST_HANDLING,