iavf: Check for duplicate TC flower filter before parsing
authorAvinash Dayanand <avinash.dayanand@intel.com>
Tue, 21 Jun 2022 18:39:33 +0000 (14:39 -0400)
committerTony Nguyen <anthony.l.nguyen@intel.com>
Fri, 22 Jul 2022 17:25:51 +0000 (10:25 -0700)
Record of all the TC flower filters are kept for local book keeping, so
take advantage of that and check for duplicate filter even before sending
a request to the PF driver.

Signed-off-by: Avinash Dayanand <avinash.dayanand@intel.com>
Signed-off-by: Jun Zhang <xuejun.zhang@intel.com>
Tested-by: Bharathi Sreenivas <bharathi.sreenivas@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
drivers/net/ethernet/intel/iavf/iavf_main.c

index 7dddf98..e78c38d 100644 (file)
@@ -3832,6 +3832,29 @@ static int iavf_handle_tclass(struct iavf_adapter *adapter, u32 tc,
 }
 
 /**
+ * iavf_find_cf - Find the cloud filter in the list
+ * @adapter: Board private structure
+ * @cookie: filter specific cookie
+ *
+ * Returns ptr to the filter object or NULL. Must be called while holding the
+ * cloud_filter_list_lock.
+ */
+static struct iavf_cloud_filter *iavf_find_cf(struct iavf_adapter *adapter,
+                                             unsigned long *cookie)
+{
+       struct iavf_cloud_filter *filter = NULL;
+
+       if (!cookie)
+               return NULL;
+
+       list_for_each_entry(filter, &adapter->cloud_filter_list, list) {
+               if (!memcmp(cookie, &filter->cookie, sizeof(filter->cookie)))
+                       return filter;
+       }
+       return NULL;
+}
+
+/**
  * iavf_configure_clsflower - Add tc flower filters
  * @adapter: board private structure
  * @cls_flower: Pointer to struct flow_cls_offload
@@ -3862,6 +3885,15 @@ static int iavf_configure_clsflower(struct iavf_adapter *adapter,
 
        filter->cookie = cls_flower->cookie;
 
+       /* bail out here if filter already exists */
+       spin_lock_bh(&adapter->cloud_filter_list_lock);
+       if (iavf_find_cf(adapter, &cls_flower->cookie)) {
+               dev_err(&adapter->pdev->dev, "Failed to add TC Flower filter, it already exists\n");
+               err = -EEXIST;
+               goto spin_unlock;
+       }
+       spin_unlock_bh(&adapter->cloud_filter_list_lock);
+
        /* set the mask to all zeroes to begin with */
        memset(&filter->f.mask.tcp_spec, 0, sizeof(struct virtchnl_l4_spec));
        /* start out with flow type and eth type IPv4 to begin with */
@@ -3880,6 +3912,7 @@ static int iavf_configure_clsflower(struct iavf_adapter *adapter,
        adapter->num_cloud_filters++;
        filter->add = true;
        adapter->aq_required |= IAVF_FLAG_AQ_ADD_CLOUD_FILTER;
+spin_unlock:
        spin_unlock_bh(&adapter->cloud_filter_list_lock);
 err:
        if (err)
@@ -3889,28 +3922,6 @@ err:
        return err;
 }
 
-/* iavf_find_cf - Find the cloud filter in the list
- * @adapter: Board private structure
- * @cookie: filter specific cookie
- *
- * Returns ptr to the filter object or NULL. Must be called while holding the
- * cloud_filter_list_lock.
- */
-static struct iavf_cloud_filter *iavf_find_cf(struct iavf_adapter *adapter,
-                                             unsigned long *cookie)
-{
-       struct iavf_cloud_filter *filter = NULL;
-
-       if (!cookie)
-               return NULL;
-
-       list_for_each_entry(filter, &adapter->cloud_filter_list, list) {
-               if (!memcmp(cookie, &filter->cookie, sizeof(filter->cookie)))
-                       return filter;
-       }
-       return NULL;
-}
-
 /**
  * iavf_delete_clsflower - Remove tc flower filters
  * @adapter: board private structure