Skip to content

Commit 12cda92

Browse files
liuyonglong86davem330
authored andcommitted
net: hns3: fix kernel crash problem in concurrent scenario
When link status change, the nic driver need to notify the roce driver to handle this event, but at this time, the roce driver may uninit, then cause kernel crash. To fix the problem, when link status change, need to check whether the roce registered, and when uninit, need to wait link update finish. Fixes: 45e92b7 ("net: hns3: add calling roce callback function when link status change") Signed-off-by: Yonglong Liu <[email protected]> Signed-off-by: Jijie Shao <[email protected]> Reviewed-by: Simon Horman <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent b472b99 commit 12cda92

File tree

1 file changed

+16
-5
lines changed

1 file changed

+16
-5
lines changed

drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3086,9 +3086,7 @@ static void hclge_push_link_status(struct hclge_dev *hdev)
30863086

30873087
static void hclge_update_link_status(struct hclge_dev *hdev)
30883088
{
3089-
struct hnae3_handle *rhandle = &hdev->vport[0].roce;
30903089
struct hnae3_handle *handle = &hdev->vport[0].nic;
3091-
struct hnae3_client *rclient = hdev->roce_client;
30923090
struct hnae3_client *client = hdev->nic_client;
30933091
int state;
30943092
int ret;
@@ -3112,8 +3110,15 @@ static void hclge_update_link_status(struct hclge_dev *hdev)
31123110

31133111
client->ops->link_status_change(handle, state);
31143112
hclge_config_mac_tnl_int(hdev, state);
3115-
if (rclient && rclient->ops->link_status_change)
3116-
rclient->ops->link_status_change(rhandle, state);
3113+
3114+
if (test_bit(HCLGE_STATE_ROCE_REGISTERED, &hdev->state)) {
3115+
struct hnae3_handle *rhandle = &hdev->vport[0].roce;
3116+
struct hnae3_client *rclient = hdev->roce_client;
3117+
3118+
if (rclient && rclient->ops->link_status_change)
3119+
rclient->ops->link_status_change(rhandle,
3120+
state);
3121+
}
31173122

31183123
hclge_push_link_status(hdev);
31193124
}
@@ -11319,6 +11324,12 @@ static int hclge_init_client_instance(struct hnae3_client *client,
1131911324
return ret;
1132011325
}
1132111326

11327+
static bool hclge_uninit_need_wait(struct hclge_dev *hdev)
11328+
{
11329+
return test_bit(HCLGE_STATE_RST_HANDLING, &hdev->state) ||
11330+
test_bit(HCLGE_STATE_LINK_UPDATING, &hdev->state);
11331+
}
11332+
1132211333
static void hclge_uninit_client_instance(struct hnae3_client *client,
1132311334
struct hnae3_ae_dev *ae_dev)
1132411335
{
@@ -11327,7 +11338,7 @@ static void hclge_uninit_client_instance(struct hnae3_client *client,
1132711338

1132811339
if (hdev->roce_client) {
1132911340
clear_bit(HCLGE_STATE_ROCE_REGISTERED, &hdev->state);
11330-
while (test_bit(HCLGE_STATE_RST_HANDLING, &hdev->state))
11341+
while (hclge_uninit_need_wait(hdev))
1133111342
msleep(HCLGE_WAIT_RESET_DONE);
1133211343

1133311344
hdev->roce_client->ops->uninit_instance(&vport->roce, 0);

0 commit comments

Comments
 (0)