Skip to content

Commit d9dc444

Browse files
orospgregkh
authored andcommitted
iavf: stop removing VLAN filters from PF on interface down
[ Upstream commit f2ce65b ] 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> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent 611d500 commit d9dc444

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
@@ -818,27 +818,6 @@ static void iavf_del_vlan(struct iavf_adapter *adapter, struct iavf_vlan vlan)
818818
spin_unlock_bh(&adapter->mac_vlan_list_lock);
819819
}
820820

821-
/**
822-
* iavf_restore_filters
823-
* @adapter: board private structure
824-
*
825-
* Restore existing non MAC filters when VF netdev comes back up
826-
**/
827-
static void iavf_restore_filters(struct iavf_adapter *adapter)
828-
{
829-
struct iavf_vlan_filter *f;
830-
831-
/* re-add all VLAN filters */
832-
spin_lock_bh(&adapter->mac_vlan_list_lock);
833-
834-
list_for_each_entry(f, &adapter->vlan_filter_list, list) {
835-
if (f->state == IAVF_VLAN_INACTIVE)
836-
f->state = IAVF_VLAN_ADD;
837-
}
838-
839-
spin_unlock_bh(&adapter->mac_vlan_list_lock);
840-
adapter->aq_required |= IAVF_FLAG_AQ_ADD_VLAN_FILTER;
841-
}
842821

843822
/**
844823
* iavf_get_num_vlans_added - get number of VLANs added
@@ -1257,13 +1236,12 @@ static void iavf_up_complete(struct iavf_adapter *adapter)
12571236
}
12581237

12591238
/**
1260-
* iavf_clear_mac_vlan_filters - Remove mac and vlan filters not sent to PF
1261-
* yet and mark other to be removed.
1239+
* iavf_clear_mac_filters - Remove MAC filters not sent to PF yet and mark
1240+
* others to be removed.
12621241
* @adapter: board private structure
12631242
**/
1264-
static void iavf_clear_mac_vlan_filters(struct iavf_adapter *adapter)
1243+
static void iavf_clear_mac_filters(struct iavf_adapter *adapter)
12651244
{
1266-
struct iavf_vlan_filter *vlf, *vlftmp;
12671245
struct iavf_mac_filter *f, *ftmp;
12681246

12691247
spin_lock_bh(&adapter->mac_vlan_list_lock);
@@ -1282,11 +1260,6 @@ static void iavf_clear_mac_vlan_filters(struct iavf_adapter *adapter)
12821260
}
12831261
}
12841262

1285-
/* disable all VLAN filters */
1286-
list_for_each_entry_safe(vlf, vlftmp, &adapter->vlan_filter_list,
1287-
list)
1288-
vlf->state = IAVF_VLAN_DISABLE;
1289-
12901263
spin_unlock_bh(&adapter->mac_vlan_list_lock);
12911264
}
12921265

@@ -1382,7 +1355,7 @@ void iavf_down(struct iavf_adapter *adapter)
13821355
iavf_napi_disable_all(adapter);
13831356
iavf_irq_disable(adapter);
13841357

1385-
iavf_clear_mac_vlan_filters(adapter);
1358+
iavf_clear_mac_filters(adapter);
13861359
iavf_clear_cloud_filters(adapter);
13871360
iavf_clear_fdir_filters(adapter);
13881361
iavf_clear_adv_rss_conf(adapter);
@@ -1399,8 +1372,6 @@ void iavf_down(struct iavf_adapter *adapter)
13991372
*/
14001373
if (!list_empty(&adapter->mac_filter_list))
14011374
adapter->aq_required |= IAVF_FLAG_AQ_DEL_MAC_FILTER;
1402-
if (!list_empty(&adapter->vlan_filter_list))
1403-
adapter->aq_required |= IAVF_FLAG_AQ_DEL_VLAN_FILTER;
14041375
if (!list_empty(&adapter->cloud_filter_list))
14051376
adapter->aq_required |= IAVF_FLAG_AQ_DEL_CLOUD_FILTER;
14061377
if (!list_empty(&adapter->fdir_list_head))
@@ -4363,8 +4334,6 @@ static int iavf_open(struct net_device *netdev)
43634334

43644335
spin_unlock_bh(&adapter->mac_vlan_list_lock);
43654336

4366-
/* Restore filters that were removed with IFF_DOWN */
4367-
iavf_restore_filters(adapter);
43684337
iavf_restore_fdir_filters(adapter);
43694338

43704339
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
@@ -799,22 +799,12 @@ void iavf_del_vlans(struct iavf_adapter *adapter)
799799
spin_lock_bh(&adapter->mac_vlan_list_lock);
800800

801801
list_for_each_entry_safe(f, ftmp, &adapter->vlan_filter_list, list) {
802-
/* since VLAN capabilities are not allowed, we dont want to send
803-
* a VLAN delete request because it will most likely fail and
804-
* create unnecessary errors/noise, so just free the VLAN
805-
* filters marked for removal to enable bailing out before
806-
* sending a virtchnl message
807-
*/
808802
if (f->state == IAVF_VLAN_REMOVE &&
809803
!VLAN_FILTERING_ALLOWED(adapter)) {
810804
list_del(&f->list);
811805
kfree(f);
812806
adapter->num_vlan_filters--;
813-
} else if (f->state == IAVF_VLAN_DISABLE &&
814-
!VLAN_FILTERING_ALLOWED(adapter)) {
815-
f->state = IAVF_VLAN_INACTIVE;
816-
} else if (f->state == IAVF_VLAN_REMOVE ||
817-
f->state == IAVF_VLAN_DISABLE) {
807+
} else if (f->state == IAVF_VLAN_REMOVE) {
818808
count++;
819809
}
820810
}
@@ -846,13 +836,7 @@ void iavf_del_vlans(struct iavf_adapter *adapter)
846836
vvfl->vsi_id = adapter->vsi_res->vsi_id;
847837
vvfl->num_elements = count;
848838
list_for_each_entry_safe(f, ftmp, &adapter->vlan_filter_list, list) {
849-
if (f->state == IAVF_VLAN_DISABLE) {
850-
vvfl->vlan_id[i] = f->vlan.vid;
851-
f->state = IAVF_VLAN_INACTIVE;
852-
i++;
853-
if (i == count)
854-
break;
855-
} else if (f->state == IAVF_VLAN_REMOVE) {
839+
if (f->state == IAVF_VLAN_REMOVE) {
856840
vvfl->vlan_id[i] = f->vlan.vid;
857841
list_del(&f->list);
858842
kfree(f);
@@ -893,8 +877,7 @@ void iavf_del_vlans(struct iavf_adapter *adapter)
893877
vvfl_v2->vport_id = adapter->vsi_res->vsi_id;
894878
vvfl_v2->num_elements = count;
895879
list_for_each_entry_safe(f, ftmp, &adapter->vlan_filter_list, list) {
896-
if (f->state == IAVF_VLAN_DISABLE ||
897-
f->state == IAVF_VLAN_REMOVE) {
880+
if (f->state == IAVF_VLAN_REMOVE) {
898881
struct virtchnl_vlan_supported_caps *filtering_support =
899882
&adapter->vlan_v2_caps.filtering.filtering_support;
900883
struct virtchnl_vlan *vlan;
@@ -908,13 +891,9 @@ void iavf_del_vlans(struct iavf_adapter *adapter)
908891
vlan->tci = f->vlan.vid;
909892
vlan->tpid = f->vlan.tpid;
910893

911-
if (f->state == IAVF_VLAN_DISABLE) {
912-
f->state = IAVF_VLAN_INACTIVE;
913-
} else {
914-
list_del(&f->list);
915-
kfree(f);
916-
adapter->num_vlan_filters--;
917-
}
894+
list_del(&f->list);
895+
kfree(f);
896+
adapter->num_vlan_filters--;
918897
i++;
919898
if (i == count)
920899
break;

0 commit comments

Comments
 (0)