From nobody Fri Dec 19 16:02:38 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7388CC25B70 for ; Sat, 28 Oct 2023 03:02:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233169AbjJ1DCo (ORCPT ); Fri, 27 Oct 2023 23:02:44 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57652 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233118AbjJ1DCl (ORCPT ); Fri, 27 Oct 2023 23:02:41 -0400 Received: from szxga02-in.huawei.com (szxga02-in.huawei.com [45.249.212.188]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B292B10A; Fri, 27 Oct 2023 20:02:38 -0700 (PDT) Received: from kwepemm000007.china.huawei.com (unknown [172.30.72.55]) by szxga02-in.huawei.com (SkyGuard) with ESMTP id 4SHPPF4DbhzVkgh; Sat, 28 Oct 2023 10:58:41 +0800 (CST) Received: from localhost.localdomain (10.67.165.2) by kwepemm000007.china.huawei.com (7.193.23.189) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.31; Sat, 28 Oct 2023 11:02:36 +0800 From: Jijie Shao To: , , , , , CC: , , , , , Subject: [PATCH net 1/7] net: hns3: fix add VLAN fail issue Date: Sat, 28 Oct 2023 10:59:11 +0800 Message-ID: <20231028025917.314305-2-shaojijie@huawei.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20231028025917.314305-1-shaojijie@huawei.com> References: <20231028025917.314305-1-shaojijie@huawei.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Originating-IP: [10.67.165.2] X-ClientProxiedBy: dggems704-chm.china.huawei.com (10.3.19.181) To kwepemm000007.china.huawei.com (7.193.23.189) X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Jian Shen The hclge_sync_vlan_filter is called in periodic task, trying to remove VLAN from vlan_del_fail_bmap. It can be concurrence with VLAN adding operation from user. So once user failed to delete a VLAN id, and add it again soon, it may be removed by the periodic task, which may cause the software configuration being inconsistent with hardware. So add mutex handling to avoid this. user hns3 driver periodic task =E2=94=82 add vlan 10 =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80 hns3_vlan_rx_ad= d_vid =E2=94=82 =E2=94=82 (suppose success) =E2=94=82 =E2=94=82 =E2=94=82 del vlan 10 =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80 hns3_vlan_rx_k= ill_vid =E2=94=82 =E2=94=82 (suppose fail,add to =E2=94=82 =E2=94=82 vlan_del_fail_bmap) =E2=94=82 =E2=94=82 =E2=94=82 add vlan 10 =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80 hns3_vlan_rx_ad= d_vid =E2=94=82 (suppose success) =E2=94=82 foreach vlan_del_fail_bmp del vlan 10 Fixes: fe4144d47eef ("net: hns3: sync VLAN filter entries when kill VLAN ID= failed") Signed-off-by: Jian Shen Signed-off-by: Jijie Shao --- .../hisilicon/hns3/hns3pf/hclge_main.c | 21 +++++++++++++------ .../hisilicon/hns3/hns3vf/hclgevf_main.c | 11 ++++++++-- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/driv= ers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c index c42574e29747..a3230ac928a9 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c @@ -10026,8 +10026,6 @@ static void hclge_rm_vport_vlan_table(struct hclge_= vport *vport, u16 vlan_id, struct hclge_vport_vlan_cfg *vlan, *tmp; struct hclge_dev *hdev =3D vport->back; =20 - mutex_lock(&hdev->vport_lock); - list_for_each_entry_safe(vlan, tmp, &vport->vlan_list, node) { if (vlan->vlan_id =3D=3D vlan_id) { if (is_write_tbl && vlan->hd_tbl_status) @@ -10042,8 +10040,6 @@ static void hclge_rm_vport_vlan_table(struct hclge_= vport *vport, u16 vlan_id, break; } } - - mutex_unlock(&hdev->vport_lock); } =20 void hclge_rm_vport_all_vlan_table(struct hclge_vport *vport, bool is_del_= list) @@ -10452,11 +10448,16 @@ int hclge_set_vlan_filter(struct hnae3_handle *ha= ndle, __be16 proto, * handle mailbox. Just record the vlan id, and remove it after * reset finished. */ + mutex_lock(&hdev->vport_lock); if ((test_bit(HCLGE_STATE_RST_HANDLING, &hdev->state) || test_bit(HCLGE_STATE_RST_FAIL, &hdev->state)) && is_kill) { set_bit(vlan_id, vport->vlan_del_fail_bmap); + mutex_unlock(&hdev->vport_lock); return -EBUSY; + } else if (!is_kill && test_bit(vlan_id, vport->vlan_del_fail_bmap)) { + clear_bit(vlan_id, vport->vlan_del_fail_bmap); } + mutex_unlock(&hdev->vport_lock); =20 /* when port base vlan enabled, we use port base vlan as the vlan * filter entry. In this case, we don't update vlan filter table @@ -10481,7 +10482,9 @@ int hclge_set_vlan_filter(struct hnae3_handle *hand= le, __be16 proto, * and try to remove it from hw later, to be consistence * with stack */ + mutex_lock(&hdev->vport_lock); set_bit(vlan_id, vport->vlan_del_fail_bmap); + mutex_unlock(&hdev->vport_lock); } =20 hclge_set_vport_vlan_fltr_change(vport); @@ -10521,6 +10524,7 @@ static void hclge_sync_vlan_filter(struct hclge_dev= *hdev) int i, ret, sync_cnt =3D 0; u16 vlan_id; =20 + mutex_lock(&hdev->vport_lock); /* start from vport 1 for PF is always alive */ for (i =3D 0; i < hdev->num_alloc_vport; i++) { struct hclge_vport *vport =3D &hdev->vport[i]; @@ -10531,21 +10535,26 @@ static void hclge_sync_vlan_filter(struct hclge_d= ev *hdev) ret =3D hclge_set_vlan_filter_hw(hdev, htons(ETH_P_8021Q), vport->vport_id, vlan_id, true); - if (ret && ret !=3D -EINVAL) + if (ret && ret !=3D -EINVAL) { + mutex_unlock(&hdev->vport_lock); return; + } =20 clear_bit(vlan_id, vport->vlan_del_fail_bmap); hclge_rm_vport_vlan_table(vport, vlan_id, false); hclge_set_vport_vlan_fltr_change(vport); =20 sync_cnt++; - if (sync_cnt >=3D HCLGE_MAX_SYNC_COUNT) + if (sync_cnt >=3D HCLGE_MAX_SYNC_COUNT) { + mutex_unlock(&hdev->vport_lock); return; + } =20 vlan_id =3D find_first_bit(vport->vlan_del_fail_bmap, VLAN_N_VID); } } + mutex_unlock(&hdev->vport_lock); =20 hclge_sync_vlan_fltr_state(hdev); } diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/dr= ivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c index a4d68fb216fb..1c62e58ff6d8 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c @@ -1206,6 +1206,8 @@ static int hclgevf_set_vlan_filter(struct hnae3_handl= e *handle, test_bit(HCLGEVF_STATE_RST_FAIL, &hdev->state)) && is_kill) { set_bit(vlan_id, hdev->vlan_del_fail_bmap); return -EBUSY; + } else if (!is_kill && test_bit(vlan_id, hdev->vlan_del_fail_bmap)) { + clear_bit(vlan_id, hdev->vlan_del_fail_bmap); } =20 hclgevf_build_send_msg(&send_msg, HCLGE_MBX_SET_VLAN, @@ -1233,20 +1235,25 @@ static void hclgevf_sync_vlan_filter(struct hclgevf= _dev *hdev) int ret, sync_cnt =3D 0; u16 vlan_id; =20 + if (bitmap_empty(hdev->vlan_del_fail_bmap, VLAN_N_VID)) + return; + + rtnl_lock(); vlan_id =3D find_first_bit(hdev->vlan_del_fail_bmap, VLAN_N_VID); while (vlan_id !=3D VLAN_N_VID) { ret =3D hclgevf_set_vlan_filter(handle, htons(ETH_P_8021Q), vlan_id, true); if (ret) - return; + break; =20 clear_bit(vlan_id, hdev->vlan_del_fail_bmap); sync_cnt++; if (sync_cnt >=3D HCLGEVF_MAX_SYNC_COUNT) - return; + break; =20 vlan_id =3D find_first_bit(hdev->vlan_del_fail_bmap, VLAN_N_VID); } + rtnl_unlock(); } =20 static int hclgevf_en_hw_strip_rxvtag(struct hnae3_handle *handle, bool en= able) --=20 2.30.0