Currently, FDIR code will use emptiness of its flow list as an indicator
that there are no flows (and that we can install a mask). That usage is the
only thing preventing us from getting rid of the FDIR flow list
altogether, so introduce a new mechanism for flow count tracking.

Signed-off-by: Anatoly Burakov <[email protected]>
---
 drivers/net/intel/ixgbe/ixgbe_ethdev.c | 1 +
 drivers/net/intel/ixgbe/ixgbe_ethdev.h | 1 +
 drivers/net/intel/ixgbe/ixgbe_fdir.c   | 8 +++++---
 drivers/net/intel/ixgbe/ixgbe_flow.c   | 3 ++-
 4 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/net/intel/ixgbe/ixgbe_ethdev.c 
b/drivers/net/intel/ixgbe/ixgbe_ethdev.c
index 1c4a2e1177..ee1b499b49 100644
--- a/drivers/net/intel/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/intel/ixgbe/ixgbe_ethdev.c
@@ -1465,6 +1465,7 @@ static int ixgbe_fdir_filter_init(struct rte_eth_dev 
*eth_dev)
                rte_hash_free(fdir_info->hash_handle);
                return -ENOMEM;
        }
+       fdir_info->n_flows = 0;
        fdir_info->mask_added = FALSE;
 
        return 0;
diff --git a/drivers/net/intel/ixgbe/ixgbe_ethdev.h 
b/drivers/net/intel/ixgbe/ixgbe_ethdev.h
index 2fb6d55387..6147cd6bdf 100644
--- a/drivers/net/intel/ixgbe/ixgbe_ethdev.h
+++ b/drivers/net/intel/ixgbe/ixgbe_ethdev.h
@@ -199,6 +199,7 @@ struct ixgbe_hw_fdir_info {
        struct ixgbe_fdir_filter **hash_map;
        struct rte_hash *hash_handle; /* cuckoo hash handler */
        bool mask_added; /* If already got mask from consistent filter */
+       uint32_t    n_flows;
 };
 
 struct ixgbe_rte_flow_rss_conf {
diff --git a/drivers/net/intel/ixgbe/ixgbe_fdir.c 
b/drivers/net/intel/ixgbe/ixgbe_fdir.c
index f51582a4bf..5f7159abf2 100644
--- a/drivers/net/intel/ixgbe/ixgbe_fdir.c
+++ b/drivers/net/intel/ixgbe/ixgbe_fdir.c
@@ -1362,20 +1362,22 @@ ixgbe_clear_all_fdir_filter(struct rte_eth_dev *dev)
        struct ixgbe_hw_fdir_info *fdir_info =
                IXGBE_DEV_PRIVATE_TO_FDIR_INFO(dev->data->dev_private);
        struct ixgbe_fdir_filter *fdir_filter;
-       struct ixgbe_fdir_filter *filter_flag;
+       bool had_flows;
        int ret = 0;
 
+       had_flows = (fdir_info->n_flows != 0);
+
        /* flush flow director */
        rte_hash_reset(fdir_info->hash_handle);
        memset(fdir_info->hash_map, 0,
               sizeof(struct ixgbe_fdir_filter *) * IXGBE_MAX_FDIR_FILTER_NUM);
-       filter_flag = TAILQ_FIRST(&fdir_info->fdir_list);
        while ((fdir_filter = TAILQ_FIRST(&fdir_info->fdir_list))) {
                TAILQ_REMOVE(&fdir_info->fdir_list,
                             fdir_filter,
                             entries);
                rte_free(fdir_filter);
        }
+       fdir_info->n_flows = 0;
 
        /* reset internal FDIR state */
        fdir_info->mask = (struct ixgbe_hw_fdir_mask){0};
@@ -1383,7 +1385,7 @@ ixgbe_clear_all_fdir_filter(struct rte_eth_dev *dev)
        fdir_info->mask_added = FALSE;
        fdir_conf->mode = RTE_FDIR_MODE_NONE;
 
-       if (filter_flag != NULL)
+       if (had_flows)
                ret = ixgbe_fdir_flush(dev);
 
        return ret;
diff --git a/drivers/net/intel/ixgbe/ixgbe_flow.c 
b/drivers/net/intel/ixgbe/ixgbe_flow.c
index e641a9d405..b68934e911 100644
--- a/drivers/net/intel/ixgbe/ixgbe_flow.c
+++ b/drivers/net/intel/ixgbe/ixgbe_flow.c
@@ -3241,6 +3241,7 @@ ixgbe_flow_create(struct rte_eth_dev *dev,
                                        &fdir_rule_ptr->base, entries);
                                flow->rule = fdir_rule_ptr;
                                flow->filter_type = RTE_ETH_FILTER_FDIR;
+                               fdir_info->n_flows++;
 
                                return flow;
                        }
@@ -3477,7 +3478,7 @@ ixgbe_flow_destroy(struct rte_eth_dev *dev,
                        TAILQ_REMOVE(&flow_lists->fdir_list,
                                &fdir_rule_ptr->base, entries);
                        rte_free(fdir_rule_ptr);
-                       if (TAILQ_EMPTY(&flow_lists->fdir_list)) {
+                       if (fdir_info->n_flows > 0 && --(fdir_info->n_flows) == 
0) {
                                fdir_info->mask_added = false;
                                fdir_info->mask = (struct 
ixgbe_hw_fdir_mask){0};
                                fdir_info->flex_bytes_offset = 0;
-- 
2.47.3

Reply via email to