Skip to content

Commit c0f46de

Browse files
IronShenkuba-moo
authored andcommitted
net: hns3: fix port base vlan add fail when concurrent with reset
Currently, Port base vlan is initiated by PF and configured to its VFs, by using command "ip link set <pf name> vf <vf id> vlan <vlan id>". When a global reset was triggered, the hardware vlan table and the soft recorded vlan information will be cleared by PF, and restored them until VFs were ready. There is a short time window between the table had been cleared and before table restored. If configured a new port base vlan tag at this moment, driver will check the soft recorded vlan information, and find there hasn't the old tag in it, which causing a warning print. Due to the port base vlan is managed by PF, so the VFs's port base vlan restoring should be handled by PF when PF was ready. This patch fixes it. Fixes: 039ba86 ("net: hns3: optimize the filter table entries handling when resetting") Signed-off-by: Jian Shen <shenjian15@huawei.com> Signed-off-by: Guangbin Huang <huangguangbin2@huawei.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent ccb18f0 commit c0f46de

2 files changed

Lines changed: 46 additions & 19 deletions

File tree

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

Lines changed: 43 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1872,6 +1872,7 @@ static int hclge_alloc_vport(struct hclge_dev *hdev)
18721872
vport->vf_info.link_state = IFLA_VF_LINK_STATE_AUTO;
18731873
vport->mps = HCLGE_MAC_DEFAULT_FRAME;
18741874
vport->port_base_vlan_cfg.state = HNAE3_PORT_BASE_VLAN_DISABLE;
1875+
vport->port_base_vlan_cfg.tbl_sta = true;
18751876
vport->rxvlan_cfg.rx_vlan_offload_en = true;
18761877
vport->req_vlan_fltr_en = true;
18771878
INIT_LIST_HEAD(&vport->vlan_list);
@@ -9915,34 +9916,52 @@ void hclge_uninit_vport_vlan_table(struct hclge_dev *hdev)
99159916
}
99169917
}
99179918

9918-
void hclge_restore_vport_vlan_table(struct hclge_vport *vport)
9919+
void hclge_restore_vport_port_base_vlan_config(struct hclge_dev *hdev)
99199920
{
9920-
struct hclge_vport_vlan_cfg *vlan, *tmp;
9921-
struct hclge_dev *hdev = vport->back;
9921+
struct hclge_vlan_info *vlan_info;
9922+
struct hclge_vport *vport;
99229923
u16 vlan_proto;
99239924
u16 vlan_id;
99249925
u16 state;
9926+
int vf_id;
99259927
int ret;
99269928

9927-
vlan_proto = vport->port_base_vlan_cfg.vlan_info.vlan_proto;
9928-
vlan_id = vport->port_base_vlan_cfg.vlan_info.vlan_tag;
9929-
state = vport->port_base_vlan_cfg.state;
9929+
/* PF should restore all vfs port base vlan */
9930+
for (vf_id = 0; vf_id < hdev->num_alloc_vfs; vf_id++) {
9931+
vport = &hdev->vport[vf_id + HCLGE_VF_VPORT_START_NUM];
9932+
vlan_info = vport->port_base_vlan_cfg.tbl_sta ?
9933+
&vport->port_base_vlan_cfg.vlan_info :
9934+
&vport->port_base_vlan_cfg.old_vlan_info;
99309935

9931-
if (state != HNAE3_PORT_BASE_VLAN_DISABLE) {
9932-
clear_bit(vport->vport_id, hdev->vlan_table[vlan_id]);
9933-
hclge_set_vlan_filter_hw(hdev, htons(vlan_proto),
9934-
vport->vport_id, vlan_id,
9935-
false);
9936-
return;
9936+
vlan_id = vlan_info->vlan_tag;
9937+
vlan_proto = vlan_info->vlan_proto;
9938+
state = vport->port_base_vlan_cfg.state;
9939+
9940+
if (state != HNAE3_PORT_BASE_VLAN_DISABLE) {
9941+
clear_bit(vport->vport_id, hdev->vlan_table[vlan_id]);
9942+
ret = hclge_set_vlan_filter_hw(hdev, htons(vlan_proto),
9943+
vport->vport_id,
9944+
vlan_id, false);
9945+
vport->port_base_vlan_cfg.tbl_sta = ret == 0;
9946+
}
99379947
}
9948+
}
99389949

9939-
list_for_each_entry_safe(vlan, tmp, &vport->vlan_list, node) {
9940-
ret = hclge_set_vlan_filter_hw(hdev, htons(ETH_P_8021Q),
9941-
vport->vport_id,
9942-
vlan->vlan_id, false);
9943-
if (ret)
9944-
break;
9945-
vlan->hd_tbl_status = true;
9950+
void hclge_restore_vport_vlan_table(struct hclge_vport *vport)
9951+
{
9952+
struct hclge_vport_vlan_cfg *vlan, *tmp;
9953+
struct hclge_dev *hdev = vport->back;
9954+
int ret;
9955+
9956+
if (vport->port_base_vlan_cfg.state == HNAE3_PORT_BASE_VLAN_DISABLE) {
9957+
list_for_each_entry_safe(vlan, tmp, &vport->vlan_list, node) {
9958+
ret = hclge_set_vlan_filter_hw(hdev, htons(ETH_P_8021Q),
9959+
vport->vport_id,
9960+
vlan->vlan_id, false);
9961+
if (ret)
9962+
break;
9963+
vlan->hd_tbl_status = true;
9964+
}
99469965
}
99479966
}
99489967

@@ -9983,6 +10002,7 @@ static void hclge_restore_hw_table(struct hclge_dev *hdev)
998310002
struct hnae3_handle *handle = &vport->nic;
998410003

998510004
hclge_restore_mac_table_common(vport);
10005+
hclge_restore_vport_port_base_vlan_config(hdev);
998610006
hclge_restore_vport_vlan_table(vport);
998710007
set_bit(HCLGE_STATE_FD_USER_DEF_CHANGED, &hdev->state);
998810008
hclge_restore_fd_entries(handle);
@@ -10039,6 +10059,8 @@ static int hclge_update_vlan_filter_entries(struct hclge_vport *vport,
1003910059
false);
1004010060
}
1004110061

10062+
vport->port_base_vlan_cfg.tbl_sta = false;
10063+
1004210064
/* force add VLAN 0 */
1004310065
ret = hclge_set_vf_vlan_common(hdev, vport->vport_id, false, 0);
1004410066
if (ret)
@@ -10128,7 +10150,9 @@ int hclge_update_port_base_vlan_cfg(struct hclge_vport *vport, u16 state,
1012810150
else
1012910151
nic->port_base_vlan_state = HNAE3_PORT_BASE_VLAN_ENABLE;
1013010152

10153+
vport->port_base_vlan_cfg.old_vlan_info = *old_vlan_info;
1013110154
vport->port_base_vlan_cfg.vlan_info = *vlan_info;
10155+
vport->port_base_vlan_cfg.tbl_sta = true;
1013210156
hclge_set_vport_vlan_fltr_change(vport);
1013310157

1013410158
return 0;

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -985,7 +985,9 @@ struct hclge_vlan_info {
985985

986986
struct hclge_port_base_vlan_config {
987987
u16 state;
988+
bool tbl_sta;
988989
struct hclge_vlan_info vlan_info;
990+
struct hclge_vlan_info old_vlan_info;
989991
};
990992

991993
struct hclge_vf_info {
@@ -1100,6 +1102,7 @@ void hclge_rm_vport_all_mac_table(struct hclge_vport *vport, bool is_del_list,
11001102
void hclge_rm_vport_all_vlan_table(struct hclge_vport *vport, bool is_del_list);
11011103
void hclge_uninit_vport_vlan_table(struct hclge_dev *hdev);
11021104
void hclge_restore_mac_table_common(struct hclge_vport *vport);
1105+
void hclge_restore_vport_port_base_vlan_config(struct hclge_dev *hdev);
11031106
void hclge_restore_vport_vlan_table(struct hclge_vport *vport);
11041107
int hclge_update_port_base_vlan_cfg(struct hclge_vport *vport, u16 state,
11051108
struct hclge_vlan_info *vlan_info);

0 commit comments

Comments
 (0)