[PATCH 16/19] net/txgbe: switch to use FDIR when ntuple filter is full

Jiawen Wu jiawenwu at trustnetic.com
Mon Oct 27 04:15:39 CET 2025


Using ntuple filter has less performance loss on the hardware compared
to FDIR filter. So when the flow rule both match ntuple filter and FDIR
filter, ntuple filter will be created first. But there are only maximum
128 flow rules can be created on ntuple filter, it is far less than the
requirements of many users. So switch to use FDIR when ntuple filters
are full.

Fixes: 77a72b4d9dc0 ("net/txgbe: support ntuple filter add and delete")
Cc: stable at dpdk.org
Signed-off-by: Jiawen Wu <jiawenwu at trustnetic.com>
---
 drivers/net/txgbe/txgbe_ethdev.c | 5 ++++-
 drivers/net/txgbe/txgbe_ethdev.h | 1 +
 drivers/net/txgbe/txgbe_flow.c   | 8 ++++++++
 3 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/net/txgbe/txgbe_ethdev.c b/drivers/net/txgbe/txgbe_ethdev.c
index f650c5b7a4..21f0711762 100644
--- a/drivers/net/txgbe/txgbe_ethdev.c
+++ b/drivers/net/txgbe/txgbe_ethdev.c
@@ -893,6 +893,7 @@ int txgbe_ntuple_filter_uninit(struct rte_eth_dev *eth_dev)
 	}
 	memset(filter_info->fivetuple_mask, 0,
 	       sizeof(uint32_t) * TXGBE_5TUPLE_ARRAY_SIZE);
+	filter_info->ntuple_is_full = false;
 
 	return 0;
 }
@@ -4495,7 +4496,8 @@ txgbe_add_5tuple_filter(struct rte_eth_dev *dev,
 		}
 	}
 	if (i >= TXGBE_MAX_FTQF_FILTERS) {
-		PMD_DRV_LOG(ERR, "5tuple filters are full.");
+		PMD_DRV_LOG(INFO, "5tuple filters are full, switch to FDIR");
+		filter_info->ntuple_is_full = true;
 		return -ENOSYS;
 	}
 
@@ -4526,6 +4528,7 @@ txgbe_remove_5tuple_filter(struct rte_eth_dev *dev,
 				~(1 << (index % (sizeof(uint32_t) * NBBY)));
 	TAILQ_REMOVE(&filter_info->fivetuple_list, filter, entries);
 	rte_free(filter);
+	filter_info->ntuple_is_full = false;
 
 	if (!txgbe_is_pf(TXGBE_DEV_HW(dev))) {
 		txgbevf_remove_5tuple_filter(dev, index);
diff --git a/drivers/net/txgbe/txgbe_ethdev.h b/drivers/net/txgbe/txgbe_ethdev.h
index 053aa1645f..1e7cc5ea80 100644
--- a/drivers/net/txgbe/txgbe_ethdev.h
+++ b/drivers/net/txgbe/txgbe_ethdev.h
@@ -245,6 +245,7 @@ struct txgbe_filter_info {
 	/* Bit mask for every used 5tuple filter */
 	uint32_t fivetuple_mask[TXGBE_5TUPLE_ARRAY_SIZE];
 	struct txgbe_5tuple_filter_list fivetuple_list;
+	bool ntuple_is_full;
 	/* store the SYN filter info */
 	uint32_t syn_info;
 	/* store the rss filter info */
diff --git a/drivers/net/txgbe/txgbe_flow.c b/drivers/net/txgbe/txgbe_flow.c
index d3113b6fc8..cd05ceffed 100644
--- a/drivers/net/txgbe/txgbe_flow.c
+++ b/drivers/net/txgbe/txgbe_flow.c
@@ -580,8 +580,12 @@ txgbe_parse_ntuple_filter(struct rte_eth_dev *dev,
 			  struct rte_eth_ntuple_filter *filter,
 			  struct rte_flow_error *error)
 {
+	struct txgbe_filter_info *filter_info = TXGBE_DEV_FILTER(dev);
 	int ret;
 
+	if (filter_info->ntuple_is_full)
+		return -ENOSYS;
+
 	ret = cons_parse_ntuple_filter(attr, pattern, actions, filter, error);
 
 	if (ret)
@@ -3200,6 +3204,7 @@ txgbe_flow_create(struct rte_eth_dev *dev,
 	struct txgbe_fdir_rule_ele *fdir_rule_ptr;
 	struct txgbe_rss_conf_ele *rss_filter_ptr;
 	struct txgbe_flow_mem *txgbe_flow_mem_ptr;
+	struct txgbe_filter_info *filter_info = TXGBE_DEV_FILTER(dev);
 	uint8_t first_mask = FALSE;
 
 	flow = rte_zmalloc("txgbe_rte_flow", sizeof(struct rte_flow), 0);
@@ -3245,6 +3250,8 @@ txgbe_flow_create(struct rte_eth_dev *dev,
 			flow->rule = ntuple_filter_ptr;
 			flow->filter_type = RTE_ETH_FILTER_NTUPLE;
 			return flow;
+		} else if (filter_info->ntuple_is_full) {
+			goto next;
 		}
 		goto out;
 	}
@@ -3254,6 +3261,7 @@ txgbe_flow_create(struct rte_eth_dev *dev,
 		goto out;
 	}
 
+next:
 	memset(&ethertype_filter, 0, sizeof(struct rte_eth_ethertype_filter));
 	ret = txgbe_parse_ethertype_filter(dev, attr, pattern,
 				actions, &ethertype_filter, error);
-- 
2.48.1



More information about the stable mailing list