]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
i40e: Fix for extra Flow Director filter in table after error
authorCarolyn Wyborny <carolyn.wyborny@intel.com>
Thu, 27 Aug 2015 15:42:38 +0000 (11:42 -0400)
committerChuck Anderson <chuck.anderson@oracle.com>
Thu, 10 Mar 2016 16:32:25 +0000 (08:32 -0800)
Orabug: 22342532

This patch fixes a problem where the PF's fdir filter table would have an
entry that the hw was unable to add. This notification happens in the hot
path, so instead of trying to fix it then, we note the location in the
failure case and delete it during regular fdir subtask callback. Without
this patch, a case can occur where an invalid entry gets replayed and a
valid one is not.

Change-ID: I67831c183b5d0309876de807cc434809b74c9cb7
Signed-off-by: Carolyn Wyborny <carolyn.wyborny@intel.com>
Signed-off-by: Shannon Nelson <shannon.nelson@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
(cherry picked from commit 3487b6c30c0dd2204dc31e14330097dff02d9a58)
Signed-off-by: Brian Maly <brian.maly@oracle.com>
drivers/net/ethernet/intel/i40e/i40e.h
drivers/net/ethernet/intel/i40e/i40e_main.c
drivers/net/ethernet/intel/i40e/i40e_txrx.c

index df9a8ab8f18edd288475069700487766e4c38734..5b652594f1bbd2d31c8ba20780396bcbdd009c3e 100644 (file)
@@ -409,6 +409,7 @@ struct i40e_pf {
        u32 npar_min_bw;
 
        u32 ioremap_len;
+       u32 fd_inv;
 };
 
 struct i40e_mac_filter {
index 1da33fbf7a731e657d0c946892e5825e3d615ab2..3ce199d87b9dc2e5dc04ce9be17a0acceb6d783b 100644 (file)
@@ -5584,7 +5584,9 @@ u32 i40e_get_global_fd_count(struct i40e_pf *pf)
  **/
 void i40e_fdir_check_and_reenable(struct i40e_pf *pf)
 {
+       struct i40e_fdir_filter *filter;
        u32 fcnt_prog, fcnt_avail;
+       struct hlist_node *node;
 
        if (test_bit(__I40E_FD_FLUSH_REQUESTED, &pf->state))
                return;
@@ -5613,6 +5615,18 @@ void i40e_fdir_check_and_reenable(struct i40e_pf *pf)
                                dev_info(&pf->pdev->dev, "ATR is being enabled since we have space in the table now\n");
                }
        }
+
+       /* if hw had a problem adding a filter, delete it */
+       if (pf->fd_inv > 0) {
+               hlist_for_each_entry_safe(filter, node,
+                                         &pf->fdir_filter_list, fdir_node) {
+                       if (filter->fd_id == pf->fd_inv) {
+                               hlist_del(&filter->fdir_node);
+                               kfree(filter);
+                               pf->fdir_pf_active_filters--;
+                       }
+               }
+       }
 }
 
 #define I40E_MIN_FD_FLUSH_INTERVAL 10
index c0829b8386a919cba235717a480e51582b4030aa..0ba71247fc0045b8a2ae35c8830a50562aecc507 100644 (file)
@@ -465,10 +465,11 @@ static void i40e_fd_handle_status(struct i40e_ring *rx_ring,
                I40E_RX_PROG_STATUS_DESC_QW1_ERROR_SHIFT;
 
        if (error == BIT(I40E_RX_PROG_STATUS_DESC_FD_TBL_FULL_SHIFT)) {
+               pf->fd_inv = le32_to_cpu(rx_desc->wb.qword0.hi_dword.fd_id);
                if ((rx_desc->wb.qword0.hi_dword.fd_id != 0) ||
                    (I40E_DEBUG_FD & pf->hw.debug_mask))
                        dev_warn(&pdev->dev, "ntuple filter loc = %d, could not be added\n",
-                                rx_desc->wb.qword0.hi_dword.fd_id);
+                                pf->fd_inv);
 
                /* Check if the programming error is for ATR.
                 * If so, auto disable ATR and set a state for