net: hns3: fix aRFS FD rules leftover after add a user FD rule
When user had created a FD rule, all the aRFS rules should be clear up.
HNS3 process flow as below:
1.get spin lock of fd_ruls_list
2.clear up all aRFS rules
3.release lock
4.get spin lock of fd_ruls_list
5.creat a rules
6.release lock;
There is a short period of time between step 3 and step 4, which would
creatting some new aRFS FD rules if driver was receiving packet.
So refactor the fd_rule_lock to fix it.
Fixes: 4412288757
("net: hns3: refine the flow director handle")
Signed-off-by: Guojia Liao <liaoguojia@huawei.com>
Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
a6f7bfdc78
Коммит
efe3fa45f7
|
@ -5806,9 +5806,9 @@ static int hclge_add_fd_entry(struct hnae3_handle *handle,
|
|||
/* to avoid rule conflict, when user configure rule by ethtool,
|
||||
* we need to clear all arfs rules
|
||||
*/
|
||||
spin_lock_bh(&hdev->fd_rule_lock);
|
||||
hclge_clear_arfs_rules(handle);
|
||||
|
||||
spin_lock_bh(&hdev->fd_rule_lock);
|
||||
ret = hclge_fd_config_rule(hdev, rule);
|
||||
|
||||
spin_unlock_bh(&hdev->fd_rule_lock);
|
||||
|
@ -5851,6 +5851,7 @@ static int hclge_del_fd_entry(struct hnae3_handle *handle,
|
|||
return ret;
|
||||
}
|
||||
|
||||
/* make sure being called after lock up with fd_rule_lock */
|
||||
static void hclge_del_all_fd_entries(struct hnae3_handle *handle,
|
||||
bool clear_list)
|
||||
{
|
||||
|
@ -5863,7 +5864,6 @@ static void hclge_del_all_fd_entries(struct hnae3_handle *handle,
|
|||
if (!hnae3_dev_fd_supported(hdev))
|
||||
return;
|
||||
|
||||
spin_lock_bh(&hdev->fd_rule_lock);
|
||||
for_each_set_bit(location, hdev->fd_bmap,
|
||||
hdev->fd_cfg.rule_num[HCLGE_FD_STAGE_1])
|
||||
hclge_fd_tcam_config(hdev, HCLGE_FD_STAGE_1, true, location,
|
||||
|
@ -5880,8 +5880,6 @@ static void hclge_del_all_fd_entries(struct hnae3_handle *handle,
|
|||
bitmap_zero(hdev->fd_bmap,
|
||||
hdev->fd_cfg.rule_num[HCLGE_FD_STAGE_1]);
|
||||
}
|
||||
|
||||
spin_unlock_bh(&hdev->fd_rule_lock);
|
||||
}
|
||||
|
||||
static int hclge_restore_fd_entries(struct hnae3_handle *handle)
|
||||
|
@ -6263,7 +6261,7 @@ static int hclge_add_fd_entry_by_arfs(struct hnae3_handle *handle, u16 queue_id,
|
|||
u16 flow_id, struct flow_keys *fkeys)
|
||||
{
|
||||
struct hclge_vport *vport = hclge_get_vport(handle);
|
||||
struct hclge_fd_rule_tuples new_tuples;
|
||||
struct hclge_fd_rule_tuples new_tuples = {};
|
||||
struct hclge_dev *hdev = vport->back;
|
||||
struct hclge_fd_rule *rule;
|
||||
u16 tmp_queue_id;
|
||||
|
@ -6273,19 +6271,17 @@ static int hclge_add_fd_entry_by_arfs(struct hnae3_handle *handle, u16 queue_id,
|
|||
if (!hnae3_dev_fd_supported(hdev))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
memset(&new_tuples, 0, sizeof(new_tuples));
|
||||
hclge_fd_get_flow_tuples(fkeys, &new_tuples);
|
||||
|
||||
spin_lock_bh(&hdev->fd_rule_lock);
|
||||
|
||||
/* when there is already fd rule existed add by user,
|
||||
* arfs should not work
|
||||
*/
|
||||
spin_lock_bh(&hdev->fd_rule_lock);
|
||||
if (hdev->fd_active_type == HCLGE_FD_EP_ACTIVE) {
|
||||
spin_unlock_bh(&hdev->fd_rule_lock);
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
hclge_fd_get_flow_tuples(fkeys, &new_tuples);
|
||||
|
||||
/* check is there flow director filter existed for this flow,
|
||||
* if not, create a new filter for it;
|
||||
* if filter exist with different queue id, modify the filter;
|
||||
|
@ -6368,6 +6364,7 @@ static void hclge_rfs_filter_expire(struct hclge_dev *hdev)
|
|||
#endif
|
||||
}
|
||||
|
||||
/* make sure being called after lock up with fd_rule_lock */
|
||||
static void hclge_clear_arfs_rules(struct hnae3_handle *handle)
|
||||
{
|
||||
#ifdef CONFIG_RFS_ACCEL
|
||||
|
@ -6420,10 +6417,14 @@ static void hclge_enable_fd(struct hnae3_handle *handle, bool enable)
|
|||
|
||||
hdev->fd_en = enable;
|
||||
clear = hdev->fd_active_type == HCLGE_FD_ARFS_ACTIVE;
|
||||
if (!enable)
|
||||
|
||||
if (!enable) {
|
||||
spin_lock_bh(&hdev->fd_rule_lock);
|
||||
hclge_del_all_fd_entries(handle, clear);
|
||||
else
|
||||
spin_unlock_bh(&hdev->fd_rule_lock);
|
||||
} else {
|
||||
hclge_restore_fd_entries(handle);
|
||||
}
|
||||
}
|
||||
|
||||
static void hclge_cfg_mac_mode(struct hclge_dev *hdev, bool enable)
|
||||
|
@ -6886,8 +6887,9 @@ static void hclge_ae_stop(struct hnae3_handle *handle)
|
|||
int i;
|
||||
|
||||
set_bit(HCLGE_STATE_DOWN, &hdev->state);
|
||||
|
||||
spin_lock_bh(&hdev->fd_rule_lock);
|
||||
hclge_clear_arfs_rules(handle);
|
||||
spin_unlock_bh(&hdev->fd_rule_lock);
|
||||
|
||||
/* If it is not PF reset, the firmware will disable the MAC,
|
||||
* so it only need to stop phy here.
|
||||
|
|
Загрузка…
Ссылка в новой задаче