intel / intel/ethernet-linux-ice
ice: VF VLAN validation race causes infinite iavf reset loop
- Dominant language
- C
- Stars
- 60
- Forks
- 21
- PR merge metrics
- No merged PRs in 30d
Description
## Description
When using Intel E810 NICs with SR-IOV, enabling VFs and bringing up VF interfaces causes continuous iavf reset loops. The VF becomes unusable as it constantly resets.
## Environment
- Driver version: ice 2.5.4 (OOT)
- Kernel version: 6.18.21 / 6.18.22
- Hardware: Intel E810 series NICs (E810-C for SFP, E810-C for QSFP)
- SR-IOV: 7 VFs enabled
## Steps to reproduce
1. Load ice driver on E810 NIC
2. Enable SR-IOV VFs:
```bash
echo 7 > /sys/class/net/ens3f1np1/device/sriov_numvfs
```
3. Bring up VF interface:
```bash
ip link set ens3f1v0 up
```
4. Observe reset loop in dmesg
## Expected behavior
VF interface should come up normally and remain stable.
## Actual behavior
The VF continuously resets in an infinite loop. The following pattern repeats indefinitely in dmesg:
```
[ 206.275250] ice 0000:8a:00.1: PF failed to honor VF 0, opcode 53, error -22
[ 206.275335] iavf 0000:8a:05.0: PF returned error -5 (IAVF_ERR_PARAM) to our request 53
[ 206.339913] iavf 0000:8a:05.0: Removing device
[ 206.667078] iavf 0000:8a:05.0: enabling device (0000 -> 0002)
[ 206.750074] iavf 0000:8a:05.0: Multiqueue Enabled: Queue pair count = 16
[ 206.750476] iavf 0000:8a:05.0: MAC address: 22:61:bd:0b:8a:5f
[ 207.260184] 8021q: adding VLAN 0 to HW filter on device ens3f1v0
[ 207.348819] ice 0000:8a:00.1: PF failed to honor VF 0, opcode 53, error -22
[ 207.348903] iavf 0000:8a:05.0: PF returned error -5 (IAVF_ERR_PARAM) to our request 53
[ 207.414069] iavf 0000:8a:05.0: Removing device
... (repeats indefinitely)
```
Opcode 53 is `VIRTCHNL_OP_DEL_VLAN_V2`. (Note: `VIRTCHNL_OP_ADD_VLAN_V2` is opcode 52 and can exhibit similar issues.)
## Root cause analysis
In `ice_virtchnl.c`, the VLAN filter validation functions use the current VSI VLAN count as a bound:
1. `ice_vc_validate_del_vlan_filter_list()` rejects delete requests when `num_elements > ice_vsi_num_non_zero_vlans(vsi)`. During VF reset, the VSI VLAN count is transiently 0, so any delete request fails validation.
2. `ice_vc_validate_add_vlan_filter_list()` rejects add requests when `existing + requested > max_filters`. During iavf state replay after reset, iavf re-sends all VLANs, but some may still be cached on the VSI, causing double-counting and rejection.
The iavf driver responds to these `VIRTCHNL_STATUS_ERR_PARAM` errors by resetting the VF, which clears the VSI state, which causes the next VLAN request to fail again - creating an infinite loop.
## Suggested fix
Replace the dynamic VSI-based bounds with the stable `max_filters` capability negotiated at VF init time:
```c
static bool
ice_vc_validate_del_vlan_filter_list(struct virtchnl_vlan_filtering_caps *vfc,
struct virtchnl_vlan_filter_list_v2 *vfl)
{
if (!vfl->num_elements || vfl->num_elements > vfc->max_filters)
return false;
return ice_vc_validate_vlan_filter_list(vfc, vfl);
}
static bool
ice_vc_validate_add_vlan_filter_list(struct virtchnl_vlan_filtering_caps *vfc,
struct virtchnl_vlan_filter_list_v2 *vfl)
{
if (!vfl->num_elements || vfl->num_elements > vfc->max_filters)
return false;
return ice_vc_validate_vlan_filter_list(vfc, vfl);
}
```
This is safe because:
- Per-element deletion is already idempotent: `ice_vsi_del_vlan()` treats `-ENOENT`/`-EBUSY` as success
- Per-element add is already idempotent: `ice_vsi_add_vlan()` treats `-EEXIST` as success
- Real HW capacity exhaustion is propagated from `ice_fltr_add_vlan()`
See attached patch for complete implementation.
## Workaround
Apply the attached patch.
[0001-ice-fix-vlan-validation-race-causing-iavf-reset-loops.patch](https://github.com/user-attachments/files/26821663/0001-ice-fix-vlan-validation-race-causing-iavf-reset-loops.patch)
Contributor guide
Assessment
This issue has not been assessed yet.