i40e: track filter type statistics when deleting invalid filters
authorJacob Keller <jacob.e.keller@intel.com>
Thu, 8 Mar 2018 22:52:08 +0000 (14:52 -0800)
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>
Wed, 14 Mar 2018 19:29:08 +0000 (12:29 -0700)
When hardware has trouble with a particular filter, we delete it from
the list. Unfortunately, we did not properly update the per-filter
statistic when doing so.

Create a helper function to handle this, and properly reduce the
necessary counter so that it tracks the number of active filters
properly.

Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
drivers/net/ethernet/intel/i40e/i40e_main.c

index 1469698..848c8f1 100644 (file)
@@ -8136,6 +8136,51 @@ u32 i40e_get_global_fd_count(struct i40e_pf *pf)
 }
 
 /**
+ * i40e_delete_invalid_filter - Delete an invalid FDIR filter
+ * @pf: board private structure
+ * @filter: FDir filter to remove
+ */
+static void i40e_delete_invalid_filter(struct i40e_pf *pf,
+                                      struct i40e_fdir_filter *filter)
+{
+       /* Update counters */
+       pf->fdir_pf_active_filters--;
+       pf->fd_inv = 0;
+
+       switch (filter->flow_type) {
+       case TCP_V4_FLOW:
+               pf->fd_tcp4_filter_cnt--;
+               break;
+       case UDP_V4_FLOW:
+               pf->fd_udp4_filter_cnt--;
+               break;
+       case SCTP_V4_FLOW:
+               pf->fd_sctp4_filter_cnt--;
+               break;
+       case IP_USER_FLOW:
+               switch (filter->ip4_proto) {
+               case IPPROTO_TCP:
+                       pf->fd_tcp4_filter_cnt--;
+                       break;
+               case IPPROTO_UDP:
+                       pf->fd_udp4_filter_cnt--;
+                       break;
+               case IPPROTO_SCTP:
+                       pf->fd_sctp4_filter_cnt--;
+                       break;
+               case IPPROTO_IP:
+                       pf->fd_ip4_filter_cnt--;
+                       break;
+               }
+               break;
+       }
+
+       /* Remove the filter from the list and free memory */
+       hlist_del(&filter->fdir_node);
+       kfree(filter);
+}
+
+/**
  * i40e_fdir_check_and_reenable - Function to reenabe FD ATR or SB if disabled
  * @pf: board private structure
  **/
@@ -8179,14 +8224,9 @@ void i40e_fdir_check_and_reenable(struct i40e_pf *pf)
        /* 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--;
-                               pf->fd_inv = 0;
-                       }
-               }
+                                         &pf->fdir_filter_list, fdir_node)
+                       if (filter->fd_id == pf->fd_inv)
+                               i40e_delete_invalid_filter(pf, filter);
        }
 }