Commit 4555f8f8 authored by Jian Shen's avatar Jian Shen Committed by Paolo Abeni
Browse files

net: hns3: fix concurrent setting vlan filter issue



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: 2ba30662 ("net: hns3: add support for modify VLAN filter state")
Signed-off-by: default avatarJian Shen <shenjian15@huawei.com>
Signed-off-by: default avatarJijie Shao <shaojijie@huawei.com>
Reviewed-by: default avatarSimon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20250722125423.1270673-2-shaojijie@huawei.com


Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parent 897e8601
Loading
Loading
Loading
Loading
+21 −15
Original line number Diff line number Diff line
@@ -9576,33 +9576,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)
@@ -10623,7 +10626,8 @@ static void hclge_sync_vlan_fltr_state(struct hclge_dev *hdev)
					&vport->state))
			continue;

		ret = hclge_enable_vport_vlan_filter(vport,
		mutex_lock(&hdev->vport_lock);
		ret = __hclge_enable_vport_vlan_filter(vport,
						       vport->req_vlan_fltr_en);
		if (ret) {
			dev_err(&hdev->pdev->dev,
@@ -10631,8 +10635,10 @@ static void hclge_sync_vlan_fltr_state(struct hclge_dev *hdev)
				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);
	}
}