| From 93667e55026581bef235b7fbaa4b3b4acb1856dd Mon Sep 17 00:00:00 2001 |
| From: Cambda Zhu <cambda@linux.alibaba.com> |
| Date: Wed, 27 Nov 2019 17:03:55 +0800 |
| Subject: [PATCH] ixgbe: Fix calculation of queue with VFs and flow director on |
| interface flap |
| |
| commit 4fad78ad6422d9bca62135bbed8b6abc4cbb85b8 upstream. |
| |
| 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> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c |
| index 7fce21bf9fbb..1a0437623844 100644 |
| --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c |
| +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c |
| @@ -5238,7 +5238,7 @@ static void ixgbe_fdir_filter_restore(struct ixgbe_adapter *adapter) |
| struct ixgbe_hw *hw = &adapter->hw; |
| struct hlist_node *node2; |
| struct ixgbe_fdir_filter *filter; |
| - u64 action; |
| + u8 queue; |
| |
| spin_lock(&adapter->fdir_perfect_lock); |
| |
| @@ -5247,17 +5247,34 @@ static void ixgbe_fdir_filter_restore(struct ixgbe_adapter *adapter) |
| |
| hlist_for_each_entry_safe(filter, node2, |
| &adapter->fdir_filter_list, fdir_node) { |
| - action = filter->action; |
| - if (action != IXGBE_FDIR_DROP_QUEUE && action != 0) |
| - action = |
| - (action >> ETHTOOL_RX_FLOW_SPEC_RING_VF_OFF) - 1; |
| + if (filter->action == IXGBE_FDIR_DROP_QUEUE) { |
| + queue = IXGBE_FDIR_DROP_QUEUE; |
| + } else { |
| + u32 ring = ethtool_get_flow_spec_ring(filter->action); |
| + u8 vf = ethtool_get_flow_spec_ring_vf(filter->action); |
| + |
| + if (!vf && (ring >= adapter->num_rx_queues)) { |
| + e_err(drv, "FDIR restore failed without VF, ring: %u\n", |
| + ring); |
| + continue; |
| + } else if (vf && |
| + ((vf > adapter->num_vfs) || |
| + ring >= adapter->num_rx_queues_per_pool)) { |
| + e_err(drv, "FDIR restore failed with VF, vf: %hhu, ring: %u\n", |
| + vf, ring); |
| + continue; |
| + } |
| + |
| + /* Map the ring onto the absolute queue index */ |
| + if (!vf) |
| + queue = adapter->rx_ring[ring]->reg_idx; |
| + else |
| + queue = ((vf - 1) * |
| + adapter->num_rx_queues_per_pool) + ring; |
| + } |
| |
| ixgbe_fdir_write_perfect_filter_82599(hw, |
| - &filter->filter, |
| - filter->sw_idx, |
| - (action == IXGBE_FDIR_DROP_QUEUE) ? |
| - IXGBE_FDIR_DROP_QUEUE : |
| - adapter->rx_ring[action]->reg_idx); |
| + &filter->filter, filter->sw_idx, queue); |
| } |
| |
| spin_unlock(&adapter->fdir_perfect_lock); |
| -- |
| 2.7.4 |
| |