Commit 1ed87e8a authored by Jian Shen's avatar Jian Shen Committed by Hao Chen
Browse files

net: hns3: fix concurrent setting vlan filter issue

driver inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/IAQ6G2



----------------------------------------------------------------------

The vport->req_vlan_fltr_en may be changed concurently 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: fb19a769 ("net: hns3: add support for VF modify VLAN filter state")
Signed-off-by: default avatarJian Shen <shenjian15@huawei.com>
Signed-off-by: default avatarHao Chen <chenhao418@huawei.com>
parent a5b76fdb
Loading
Loading
Loading
Loading
+20 −15
Original line number Diff line number Diff line
@@ -10268,33 +10268,35 @@ 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)
@@ -11322,7 +11324,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,
@@ -11330,8 +11333,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);
	}
}