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

