Skip to content

Commit 5951a2b

Browse files
bcreeley13anguy11
authored andcommitted
iavf: Fix VLAN feature flags after VFR
When a VF goes through a reset, it's possible for the VF's feature set to change. For example it may lose the VIRTCHNL_VF_OFFLOAD_VLAN capability after VF reset. Unfortunately, the driver doesn't correctly deal with this situation and errors are seen from downing/upping the interface and/or moving the interface in/out of a network namespace. When setting the interface down/up we see the following errors after the VIRTCHNL_VF_OFFLOAD_VLAN capability was taken away from the VF: ice 0000:51:00.1: VF 1 failed opcode 12, retval: -64 iavf 0000:51:09.1: Failed to add VLAN filter, error IAVF_NOT_SUPPORTED ice 0000:51:00.1: VF 1 failed opcode 13, retval: -64 iavf 0000:51:09.1: Failed to delete VLAN filter, error IAVF_NOT_SUPPORTED These add/delete errors are happening because the VLAN filters are tracked internally to the driver and regardless of the VLAN_ALLOWED() setting the driver tries to delete/re-add them over virtchnl. Fix the delete failure by making sure to delete any VLAN filter tracking in the driver when a removal request is made, while preventing the virtchnl request. This makes it so the driver's VLAN list is up to date and the errors are Fix the add failure by making sure the check for VLAN_ALLOWED() during reset is done after the VF receives its capability list from the PF via VIRTCHNL_OP_GET_VF_RESOURCES. If VLAN functionality is not allowed, then prevent requesting re-adding the filters over virtchnl. When moving the interface into a network namespace we see the following errors after the VIRTCHNL_VF_OFFLOAD_VLAN capability was taken away from the VF: iavf 0000:51:09.1 enp81s0f1v1: NIC Link is Up Speed is 25 Gbps Full Duplex iavf 0000:51:09.1 temp_27: renamed from enp81s0f1v1 iavf 0000:51:09.1 mgmt: renamed from temp_27 iavf 0000:51:09.1 dev27: set_features() failed (-22); wanted 0x020190001fd54833, left 0x020190001fd54bb3 These errors are happening because we aren't correctly updating the netdev capabilities and dealing with ndo_fix_features() and ndo_set_features() correctly. Fix this by only reporting errors in the driver's ndo_set_features() callback when VIRTCHNL_VF_OFFLOAD_VLAN is not allowed and any attempt to enable the VLAN features is made. Also, make sure to disable VLAN insertion, filtering, and stripping since the VIRTCHNL_VF_OFFLOAD_VLAN flag applies to all of them and not just VLAN stripping. Also, after we process the capabilities in the VF reset path, make sure to call netdev_update_features() in case the capabilities have changed in order to update the netdev's feature set to match the VF's actual capabilities. Lastly, make sure to always report success on VLAN filter delete when VIRTCHNL_VF_OFFLOAD_VLAN is not supported. The changed flow in iavf_del_vlans() allows the stack to delete previosly existing VLAN filters even if VLAN filtering is not allowed. This makes it so the VLAN filter list is up to date. Fixes: 8774370 ("i40e/i40evf: support for VF VLAN tag stripping control") Signed-off-by: Brett Creeley <[email protected]> Tested-by: Konrad Jankowski <[email protected]> Signed-off-by: Tony Nguyen <[email protected]>
1 parent 3b5bdd1 commit 5951a2b

File tree

3 files changed

+56
-23
lines changed

3 files changed

+56
-23
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -503,4 +503,5 @@ void iavf_add_adv_rss_cfg(struct iavf_adapter *adapter);
503503
void iavf_del_adv_rss_cfg(struct iavf_adapter *adapter);
504504
struct iavf_mac_filter *iavf_add_filter(struct iavf_adapter *adapter,
505505
const u8 *macaddr);
506+
int iavf_lock_timeout(struct mutex *lock, unsigned int msecs);
506507
#endif /* _IAVF_H_ */

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

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ enum iavf_status iavf_free_virt_mem_d(struct iavf_hw *hw,
147147
*
148148
* Returns 0 on success, negative on failure
149149
**/
150-
static int iavf_lock_timeout(struct mutex *lock, unsigned int msecs)
150+
int iavf_lock_timeout(struct mutex *lock, unsigned int msecs)
151151
{
152152
unsigned int wait, delay = 10;
153153

@@ -717,13 +717,11 @@ static void iavf_del_vlan(struct iavf_adapter *adapter, u16 vlan)
717717
**/
718718
static void iavf_restore_filters(struct iavf_adapter *adapter)
719719
{
720-
/* re-add all VLAN filters */
721-
if (VLAN_ALLOWED(adapter)) {
722-
u16 vid;
720+
u16 vid;
723721

724-
for_each_set_bit(vid, adapter->vsi.active_vlans, VLAN_N_VID)
725-
iavf_add_vlan(adapter, vid);
726-
}
722+
/* re-add all VLAN filters */
723+
for_each_set_bit(vid, adapter->vsi.active_vlans, VLAN_N_VID)
724+
iavf_add_vlan(adapter, vid);
727725
}
728726

729727
/**
@@ -758,9 +756,6 @@ static int iavf_vlan_rx_kill_vid(struct net_device *netdev,
758756
{
759757
struct iavf_adapter *adapter = netdev_priv(netdev);
760758

761-
if (!VLAN_ALLOWED(adapter))
762-
return -EIO;
763-
764759
iavf_del_vlan(adapter, vid);
765760
clear_bit(vid, adapter->vsi.active_vlans);
766761

@@ -2191,7 +2186,6 @@ static void iavf_reset_task(struct work_struct *work)
21912186
struct net_device *netdev = adapter->netdev;
21922187
struct iavf_hw *hw = &adapter->hw;
21932188
struct iavf_mac_filter *f, *ftmp;
2194-
struct iavf_vlan_filter *vlf;
21952189
struct iavf_cloud_filter *cf;
21962190
u32 reg_val;
21972191
int i = 0, err;
@@ -2332,11 +2326,6 @@ static void iavf_reset_task(struct work_struct *work)
23322326
list_for_each_entry(f, &adapter->mac_filter_list, list) {
23332327
f->add = true;
23342328
}
2335-
/* re-add all VLAN filters */
2336-
list_for_each_entry(vlf, &adapter->vlan_filter_list, list) {
2337-
vlf->add = true;
2338-
}
2339-
23402329
spin_unlock_bh(&adapter->mac_vlan_list_lock);
23412330

23422331
/* check if TCs are running and re-add all cloud filters */
@@ -2350,7 +2339,6 @@ static void iavf_reset_task(struct work_struct *work)
23502339
spin_unlock_bh(&adapter->cloud_filter_list_lock);
23512340

23522341
adapter->aq_required |= IAVF_FLAG_AQ_ADD_MAC_FILTER;
2353-
adapter->aq_required |= IAVF_FLAG_AQ_ADD_VLAN_FILTER;
23542342
adapter->aq_required |= IAVF_FLAG_AQ_ADD_CLOUD_FILTER;
23552343
iavf_misc_irq_enable(adapter);
23562344

@@ -3462,11 +3450,16 @@ static int iavf_set_features(struct net_device *netdev,
34623450
{
34633451
struct iavf_adapter *adapter = netdev_priv(netdev);
34643452

3465-
/* Don't allow changing VLAN_RX flag when adapter is not capable
3466-
* of VLAN offload
3453+
/* Don't allow enabling VLAN features when adapter is not capable
3454+
* of VLAN offload/filtering
34673455
*/
34683456
if (!VLAN_ALLOWED(adapter)) {
3469-
if ((netdev->features ^ features) & NETIF_F_HW_VLAN_CTAG_RX)
3457+
netdev->hw_features &= ~(NETIF_F_HW_VLAN_CTAG_RX |
3458+
NETIF_F_HW_VLAN_CTAG_TX |
3459+
NETIF_F_HW_VLAN_CTAG_FILTER);
3460+
if (features & (NETIF_F_HW_VLAN_CTAG_RX |
3461+
NETIF_F_HW_VLAN_CTAG_TX |
3462+
NETIF_F_HW_VLAN_CTAG_FILTER))
34703463
return -EINVAL;
34713464
} else if ((netdev->features ^ features) & NETIF_F_HW_VLAN_CTAG_RX) {
34723465
if (features & NETIF_F_HW_VLAN_CTAG_RX)

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

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -607,7 +607,7 @@ void iavf_add_vlans(struct iavf_adapter *adapter)
607607
if (f->add)
608608
count++;
609609
}
610-
if (!count) {
610+
if (!count || !VLAN_ALLOWED(adapter)) {
611611
adapter->aq_required &= ~IAVF_FLAG_AQ_ADD_VLAN_FILTER;
612612
spin_unlock_bh(&adapter->mac_vlan_list_lock);
613613
return;
@@ -673,9 +673,19 @@ void iavf_del_vlans(struct iavf_adapter *adapter)
673673

674674
spin_lock_bh(&adapter->mac_vlan_list_lock);
675675

676-
list_for_each_entry(f, &adapter->vlan_filter_list, list) {
677-
if (f->remove)
676+
list_for_each_entry_safe(f, ftmp, &adapter->vlan_filter_list, list) {
677+
/* since VLAN capabilities are not allowed, we dont want to send
678+
* a VLAN delete request because it will most likely fail and
679+
* create unnecessary errors/noise, so just free the VLAN
680+
* filters marked for removal to enable bailing out before
681+
* sending a virtchnl message
682+
*/
683+
if (f->remove && !VLAN_ALLOWED(adapter)) {
684+
list_del(&f->list);
685+
kfree(f);
686+
} else if (f->remove) {
678687
count++;
688+
}
679689
}
680690
if (!count) {
681691
adapter->aq_required &= ~IAVF_FLAG_AQ_DEL_VLAN_FILTER;
@@ -1724,8 +1734,37 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter,
17241734
}
17251735
spin_lock_bh(&adapter->mac_vlan_list_lock);
17261736
iavf_add_filter(adapter, adapter->hw.mac.addr);
1737+
1738+
if (VLAN_ALLOWED(adapter)) {
1739+
if (!list_empty(&adapter->vlan_filter_list)) {
1740+
struct iavf_vlan_filter *vlf;
1741+
1742+
/* re-add all VLAN filters over virtchnl */
1743+
list_for_each_entry(vlf,
1744+
&adapter->vlan_filter_list,
1745+
list)
1746+
vlf->add = true;
1747+
1748+
adapter->aq_required |=
1749+
IAVF_FLAG_AQ_ADD_VLAN_FILTER;
1750+
}
1751+
}
1752+
17271753
spin_unlock_bh(&adapter->mac_vlan_list_lock);
17281754
iavf_process_config(adapter);
1755+
1756+
/* unlock crit_lock before acquiring rtnl_lock as other
1757+
* processes holding rtnl_lock could be waiting for the same
1758+
* crit_lock
1759+
*/
1760+
mutex_unlock(&adapter->crit_lock);
1761+
rtnl_lock();
1762+
netdev_update_features(adapter->netdev);
1763+
rtnl_unlock();
1764+
if (iavf_lock_timeout(&adapter->crit_lock, 10000))
1765+
dev_warn(&adapter->pdev->dev, "failed to acquire crit_lock in %s\n",
1766+
__FUNCTION__);
1767+
17291768
}
17301769
break;
17311770
case VIRTCHNL_OP_ENABLE_QUEUES:

0 commit comments

Comments
 (0)