Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ixgbe: Fix calculation of queue with VFs and flow director on interface flap

This patch fixes the calculation of queue when we restore flow director
filters after resetting adapter. In ixgbe_fdir_filter_restore(), filter's
vf may be zero which makes the queue outside of the rx_ring array.

The calculation is changed to the same as ixgbe_add_ethtool_fdir_entry().

Signed-off-by: Cambda Zhu <cambda@linux.alibaba.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>

authored by

Cambda Zhu and committed by
Jeff Kirsher
4fad78ad aa604651

+27 -10
+27 -10
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
··· 5239 5239 struct ixgbe_hw *hw = &adapter->hw; 5240 5240 struct hlist_node *node2; 5241 5241 struct ixgbe_fdir_filter *filter; 5242 - u64 action; 5242 + u8 queue; 5243 5243 5244 5244 spin_lock(&adapter->fdir_perfect_lock); 5245 5245 ··· 5248 5248 5249 5249 hlist_for_each_entry_safe(filter, node2, 5250 5250 &adapter->fdir_filter_list, fdir_node) { 5251 - action = filter->action; 5252 - if (action != IXGBE_FDIR_DROP_QUEUE && action != 0) 5253 - action = 5254 - (action >> ETHTOOL_RX_FLOW_SPEC_RING_VF_OFF) - 1; 5251 + if (filter->action == IXGBE_FDIR_DROP_QUEUE) { 5252 + queue = IXGBE_FDIR_DROP_QUEUE; 5253 + } else { 5254 + u32 ring = ethtool_get_flow_spec_ring(filter->action); 5255 + u8 vf = ethtool_get_flow_spec_ring_vf(filter->action); 5256 + 5257 + if (!vf && (ring >= adapter->num_rx_queues)) { 5258 + e_err(drv, "FDIR restore failed without VF, ring: %u\n", 5259 + ring); 5260 + continue; 5261 + } else if (vf && 5262 + ((vf > adapter->num_vfs) || 5263 + ring >= adapter->num_rx_queues_per_pool)) { 5264 + e_err(drv, "FDIR restore failed with VF, vf: %hhu, ring: %u\n", 5265 + vf, ring); 5266 + continue; 5267 + } 5268 + 5269 + /* Map the ring onto the absolute queue index */ 5270 + if (!vf) 5271 + queue = adapter->rx_ring[ring]->reg_idx; 5272 + else 5273 + queue = ((vf - 1) * 5274 + adapter->num_rx_queues_per_pool) + ring; 5275 + } 5255 5276 5256 5277 ixgbe_fdir_write_perfect_filter_82599(hw, 5257 - &filter->filter, 5258 - filter->sw_idx, 5259 - (action == IXGBE_FDIR_DROP_QUEUE) ? 5260 - IXGBE_FDIR_DROP_QUEUE : 5261 - adapter->rx_ring[action]->reg_idx); 5278 + &filter->filter, filter->sw_idx, queue); 5262 5279 } 5263 5280 5264 5281 spin_unlock(&adapter->fdir_perfect_lock);