Skip to content

Commit f2ce65b

Browse files
orospPaolo Abeni
authored andcommitted
iavf: stop removing VLAN filters from PF on interface down
When a VF goes down, the driver currently sends DEL_VLAN to the PF for every VLAN filter (ACTIVE -> DISABLE -> send DEL -> INACTIVE), then re-adds them all on UP (INACTIVE -> ADD -> send ADD -> ADDING -> ACTIVE). This round-trip is unnecessary because: 1. The PF disables the VF's queues via VIRTCHNL_OP_DISABLE_QUEUES, which already prevents all RX/TX traffic regardless of VLAN filter state. 2. The VLAN filters remaining in PF HW while the VF is down is harmless - packets matching those filters have nowhere to go with queues disabled. 3. The DEL+ADD cycle during down/up creates race windows where the VLAN filter list is incomplete. With spoofcheck enabled, the PF enables TX VLAN filtering on the first non-zero VLAN add, blocking traffic for any VLANs not yet re-added. Remove the entire DISABLE/INACTIVE state machinery: - Remove IAVF_VLAN_DISABLE and IAVF_VLAN_INACTIVE enum values - Remove iavf_restore_filters() and its call from iavf_open() - Remove VLAN filter handling from iavf_clear_mac_vlan_filters(), rename it to iavf_clear_mac_filters() - Remove DEL_VLAN_FILTER scheduling from iavf_down() - Remove all DISABLE/INACTIVE handling from iavf_del_vlans() VLAN filters now stay ACTIVE across down/up cycles. Only explicit user removal (ndo_vlan_rx_kill_vid) or PF/VF reset triggers VLAN filter deletion/re-addition. Fixes: ed1f5b5 ("i40evf: remove VLAN filters on close") Signed-off-by: Petr Oros <poros@redhat.com> Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com> Tested-by: Rafal Romanowski <rafal.romanowski@intel.com> Reviewed-by: Simon Horman <horms@kernel.org> Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com> Signed-off-by: Jacob Keller <jacob.e.keller@intel.com> Link: https://patch.msgid.link/20260427-jk-iwl-net-petr-oros-fixes-v1-2-cdcb48303fd8@intel.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
1 parent 70d62b6 commit f2ce65b

3 files changed

Lines changed: 12 additions & 66 deletions

File tree

drivers/net/ethernet/intel/iavf/iavf.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -159,10 +159,8 @@ enum iavf_vlan_state_t {
159159
IAVF_VLAN_INVALID,
160160
IAVF_VLAN_ADD, /* filter needs to be added */
161161
IAVF_VLAN_ADDING, /* ADD sent to PF, waiting for response */
162-
IAVF_VLAN_ACTIVE, /* filter is accepted by PF */
163-
IAVF_VLAN_DISABLE, /* filter needs to be deleted by PF, then marked INACTIVE */
164-
IAVF_VLAN_INACTIVE, /* filter is inactive, we are in IFF_DOWN */
165-
IAVF_VLAN_REMOVE, /* filter needs to be removed from list */
162+
IAVF_VLAN_ACTIVE, /* PF confirmed, filter is in HW */
163+
IAVF_VLAN_REMOVE, /* filter queued for DEL from PF */
166164
};
167165

168166
struct iavf_vlan_filter {

drivers/net/ethernet/intel/iavf/iavf_main.c

Lines changed: 4 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -801,27 +801,6 @@ static void iavf_del_vlan(struct iavf_adapter *adapter, struct iavf_vlan vlan)
801801
spin_unlock_bh(&adapter->mac_vlan_list_lock);
802802
}
803803

804-
/**
805-
* iavf_restore_filters
806-
* @adapter: board private structure
807-
*
808-
* Restore existing non MAC filters when VF netdev comes back up
809-
**/
810-
static void iavf_restore_filters(struct iavf_adapter *adapter)
811-
{
812-
struct iavf_vlan_filter *f;
813-
814-
/* re-add all VLAN filters */
815-
spin_lock_bh(&adapter->mac_vlan_list_lock);
816-
817-
list_for_each_entry(f, &adapter->vlan_filter_list, list) {
818-
if (f->state == IAVF_VLAN_INACTIVE)
819-
f->state = IAVF_VLAN_ADD;
820-
}
821-
822-
spin_unlock_bh(&adapter->mac_vlan_list_lock);
823-
adapter->aq_required |= IAVF_FLAG_AQ_ADD_VLAN_FILTER;
824-
}
825804

826805
/**
827806
* iavf_get_num_vlans_added - get number of VLANs added
@@ -1246,13 +1225,12 @@ static void iavf_up_complete(struct iavf_adapter *adapter)
12461225
}
12471226

12481227
/**
1249-
* iavf_clear_mac_vlan_filters - Remove mac and vlan filters not sent to PF
1250-
* yet and mark other to be removed.
1228+
* iavf_clear_mac_filters - Remove MAC filters not sent to PF yet and mark
1229+
* others to be removed.
12511230
* @adapter: board private structure
12521231
**/
1253-
static void iavf_clear_mac_vlan_filters(struct iavf_adapter *adapter)
1232+
static void iavf_clear_mac_filters(struct iavf_adapter *adapter)
12541233
{
1255-
struct iavf_vlan_filter *vlf, *vlftmp;
12561234
struct iavf_mac_filter *f, *ftmp;
12571235

12581236
spin_lock_bh(&adapter->mac_vlan_list_lock);
@@ -1271,11 +1249,6 @@ static void iavf_clear_mac_vlan_filters(struct iavf_adapter *adapter)
12711249
}
12721250
}
12731251

1274-
/* disable all VLAN filters */
1275-
list_for_each_entry_safe(vlf, vlftmp, &adapter->vlan_filter_list,
1276-
list)
1277-
vlf->state = IAVF_VLAN_DISABLE;
1278-
12791252
spin_unlock_bh(&adapter->mac_vlan_list_lock);
12801253
}
12811254

@@ -1371,7 +1344,7 @@ void iavf_down(struct iavf_adapter *adapter)
13711344
iavf_napi_disable_all(adapter);
13721345
iavf_irq_disable(adapter);
13731346

1374-
iavf_clear_mac_vlan_filters(adapter);
1347+
iavf_clear_mac_filters(adapter);
13751348
iavf_clear_cloud_filters(adapter);
13761349
iavf_clear_fdir_filters(adapter);
13771350
iavf_clear_adv_rss_conf(adapter);
@@ -1388,8 +1361,6 @@ void iavf_down(struct iavf_adapter *adapter)
13881361
*/
13891362
if (!list_empty(&adapter->mac_filter_list))
13901363
adapter->aq_required |= IAVF_FLAG_AQ_DEL_MAC_FILTER;
1391-
if (!list_empty(&adapter->vlan_filter_list))
1392-
adapter->aq_required |= IAVF_FLAG_AQ_DEL_VLAN_FILTER;
13931364
if (!list_empty(&adapter->cloud_filter_list))
13941365
adapter->aq_required |= IAVF_FLAG_AQ_DEL_CLOUD_FILTER;
13951366
if (!list_empty(&adapter->fdir_list_head))
@@ -4494,8 +4465,6 @@ static int iavf_open(struct net_device *netdev)
44944465
iavf_add_filter(adapter, adapter->hw.mac.addr);
44954466
spin_unlock_bh(&adapter->mac_vlan_list_lock);
44964467

4497-
/* Restore filters that were removed with IFF_DOWN */
4498-
iavf_restore_filters(adapter);
44994468
iavf_restore_fdir_filters(adapter);
45004469

45014470
iavf_configure(adapter);

drivers/net/ethernet/intel/iavf/iavf_virtchnl.c

Lines changed: 6 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -911,22 +911,12 @@ void iavf_del_vlans(struct iavf_adapter *adapter)
911911
spin_lock_bh(&adapter->mac_vlan_list_lock);
912912

913913
list_for_each_entry_safe(f, ftmp, &adapter->vlan_filter_list, list) {
914-
/* since VLAN capabilities are not allowed, we dont want to send
915-
* a VLAN delete request because it will most likely fail and
916-
* create unnecessary errors/noise, so just free the VLAN
917-
* filters marked for removal to enable bailing out before
918-
* sending a virtchnl message
919-
*/
920914
if (f->state == IAVF_VLAN_REMOVE &&
921915
!VLAN_FILTERING_ALLOWED(adapter)) {
922916
list_del(&f->list);
923917
kfree(f);
924918
adapter->num_vlan_filters--;
925-
} else if (f->state == IAVF_VLAN_DISABLE &&
926-
!VLAN_FILTERING_ALLOWED(adapter)) {
927-
f->state = IAVF_VLAN_INACTIVE;
928-
} else if (f->state == IAVF_VLAN_REMOVE ||
929-
f->state == IAVF_VLAN_DISABLE) {
919+
} else if (f->state == IAVF_VLAN_REMOVE) {
930920
count++;
931921
}
932922
}
@@ -959,13 +949,7 @@ void iavf_del_vlans(struct iavf_adapter *adapter)
959949
vvfl->vsi_id = adapter->vsi_res->vsi_id;
960950
vvfl->num_elements = count;
961951
list_for_each_entry_safe(f, ftmp, &adapter->vlan_filter_list, list) {
962-
if (f->state == IAVF_VLAN_DISABLE) {
963-
vvfl->vlan_id[i] = f->vlan.vid;
964-
f->state = IAVF_VLAN_INACTIVE;
965-
i++;
966-
if (i == count)
967-
break;
968-
} else if (f->state == IAVF_VLAN_REMOVE) {
952+
if (f->state == IAVF_VLAN_REMOVE) {
969953
vvfl->vlan_id[i] = f->vlan.vid;
970954
list_del(&f->list);
971955
kfree(f);
@@ -1007,8 +991,7 @@ void iavf_del_vlans(struct iavf_adapter *adapter)
1007991
vvfl_v2->vport_id = adapter->vsi_res->vsi_id;
1008992
vvfl_v2->num_elements = count;
1009993
list_for_each_entry_safe(f, ftmp, &adapter->vlan_filter_list, list) {
1010-
if (f->state == IAVF_VLAN_DISABLE ||
1011-
f->state == IAVF_VLAN_REMOVE) {
994+
if (f->state == IAVF_VLAN_REMOVE) {
1012995
struct virtchnl_vlan_supported_caps *filtering_support =
1013996
&adapter->vlan_v2_caps.filtering.filtering_support;
1014997
struct virtchnl_vlan *vlan;
@@ -1022,13 +1005,9 @@ void iavf_del_vlans(struct iavf_adapter *adapter)
10221005
vlan->tci = f->vlan.vid;
10231006
vlan->tpid = f->vlan.tpid;
10241007

1025-
if (f->state == IAVF_VLAN_DISABLE) {
1026-
f->state = IAVF_VLAN_INACTIVE;
1027-
} else {
1028-
list_del(&f->list);
1029-
kfree(f);
1030-
adapter->num_vlan_filters--;
1031-
}
1008+
list_del(&f->list);
1009+
kfree(f);
1010+
adapter->num_vlan_filters--;
10321011
i++;
10331012
if (i == count)
10341013
break;

0 commit comments

Comments
 (0)