mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 10:58:48 +09:00
net: hns3: fix concurrent setting vlan filter issue
[ Upstream commit 4555f8f8b6aa46940f55feb6a07704c2935b6d6e ]
The vport->req_vlan_fltr_en may be changed concurrently by function
hclge_sync_vlan_fltr_state() called in periodic work task and
function hclge_enable_vport_vlan_filter() called by user configuration.
It may cause the user configuration inoperative. Fixes it by protect
the vport->req_vlan_fltr by vport_lock.
Fixes: 2ba306627f ("net: hns3: add support for modify VLAN filter state")
Signed-off-by: Jian Shen <shenjian15@huawei.com>
Signed-off-by: Jijie Shao <shaojijie@huawei.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20250722125423.1270673-2-shaojijie@huawei.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
faf44487df
commit
3cc42004f6
@@ -9493,33 +9493,36 @@ static bool hclge_need_enable_vport_vlan_filter(struct hclge_vport *vport)
|
||||
return false;
|
||||
}
|
||||
|
||||
int hclge_enable_vport_vlan_filter(struct hclge_vport *vport, bool request_en)
|
||||
static int __hclge_enable_vport_vlan_filter(struct hclge_vport *vport,
|
||||
bool request_en)
|
||||
{
|
||||
struct hclge_dev *hdev = vport->back;
|
||||
bool need_en;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&hdev->vport_lock);
|
||||
|
||||
vport->req_vlan_fltr_en = request_en;
|
||||
|
||||
need_en = hclge_need_enable_vport_vlan_filter(vport);
|
||||
if (need_en == vport->cur_vlan_fltr_en) {
|
||||
mutex_unlock(&hdev->vport_lock);
|
||||
if (need_en == vport->cur_vlan_fltr_en)
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = hclge_set_vport_vlan_filter(vport, need_en);
|
||||
if (ret) {
|
||||
mutex_unlock(&hdev->vport_lock);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
vport->cur_vlan_fltr_en = need_en;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hclge_enable_vport_vlan_filter(struct hclge_vport *vport, bool request_en)
|
||||
{
|
||||
struct hclge_dev *hdev = vport->back;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&hdev->vport_lock);
|
||||
vport->req_vlan_fltr_en = request_en;
|
||||
ret = __hclge_enable_vport_vlan_filter(vport, request_en);
|
||||
mutex_unlock(&hdev->vport_lock);
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int hclge_enable_vlan_filter(struct hnae3_handle *handle, bool enable)
|
||||
@@ -10540,16 +10543,19 @@ static void hclge_sync_vlan_fltr_state(struct hclge_dev *hdev)
|
||||
&vport->state))
|
||||
continue;
|
||||
|
||||
ret = hclge_enable_vport_vlan_filter(vport,
|
||||
vport->req_vlan_fltr_en);
|
||||
mutex_lock(&hdev->vport_lock);
|
||||
ret = __hclge_enable_vport_vlan_filter(vport,
|
||||
vport->req_vlan_fltr_en);
|
||||
if (ret) {
|
||||
dev_err(&hdev->pdev->dev,
|
||||
"failed to sync vlan filter state for vport%u, ret = %d\n",
|
||||
vport->vport_id, ret);
|
||||
set_bit(HCLGE_VPORT_STATE_VLAN_FLTR_CHANGE,
|
||||
&vport->state);
|
||||
mutex_unlock(&hdev->vport_lock);
|
||||
return;
|
||||
}
|
||||
mutex_unlock(&hdev->vport_lock);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user