[PATCH v1 5/6] net/ice: use caller-owned pattern match storage

Anatoly Burakov anatoly.burakov at intel.com
Tue Oct 20 14:11:08 CEST 2026


Pattern lookup allocates a match item just to copy an entry from the
engine's supported-pattern table. Each engine must then free this
temporary object after parsing.

Make `ice_search_pattern_match_item()` fill caller-provided storage
and return a status code. Use stack-local match items in all four
engines, removing the allocation and corresponding cleanup paths.

Signed-off-by: Anatoly Burakov <anatoly.burakov at intel.com>
---
 drivers/net/intel/ice/ice_acl_filter.c    | 22 ++++++++------------
 drivers/net/intel/ice/ice_fdir_filter.c   | 18 ++++++++--------
 drivers/net/intel/ice/ice_generic_flow.c  | 25 +++++------------------
 drivers/net/intel/ice/ice_generic_flow.h  |  3 ++-
 drivers/net/intel/ice/ice_hash.c          | 13 +++++-------
 drivers/net/intel/ice/ice_switch_filter.c | 14 +++++--------
 6 files changed, 34 insertions(+), 61 deletions(-)

diff --git a/drivers/net/intel/ice/ice_acl_filter.c b/drivers/net/intel/ice/ice_acl_filter.c
index 91f684c9b9..fe1d03556c 100644
--- a/drivers/net/intel/ice/ice_acl_filter.c
+++ b/drivers/net/intel/ice/ice_acl_filter.c
@@ -998,7 +998,7 @@ ice_acl_parse(struct ice_adapter *ad,
 	};
 	struct ice_pf *pf = &ad->pf;
 	struct ice_acl_conf *filter = &pf->acl.conf;
-	struct ice_pattern_match_item *item = NULL;
+	struct ice_pattern_match_item item;
 	uint64_t input_set;
 	int ret;
 
@@ -1012,33 +1012,29 @@ ice_acl_parse(struct ice_adapter *ad,
 	if (ret)
 		return ret;
 
-	item = ice_search_pattern_match_item(ad, pattern, array, array_len,
-					     error);
-	if (!item)
-		return -rte_errno;
+	ret = ice_search_pattern_match_item(ad, pattern, array, array_len,
+					     &item, error);
+	if (ret != 0)
+		return ret;
 
 	ret = ice_acl_parse_pattern(ad, pattern, error, filter);
 	if (ret)
-		goto error;
+		return ret;
 	input_set = filter->input_set;
-	if (!input_set || input_set & ~item->input_set_mask_o) {
-		rte_flow_error_set(error, EINVAL,
+	if (!input_set || input_set & ~item.input_set_mask_o) {
+		return rte_flow_error_set(error, EINVAL,
 				   RTE_FLOW_ERROR_TYPE_ITEM_SPEC,
 				   pattern,
 				   "Invalid input set");
-		ret = -rte_errno;
-		goto error;
 	}
 
 	ret = ice_acl_parse_action(&parsed_actions, filter, error);
 	if (ret)
-		goto error;
+		return ret;
 
 	if (meta)
 		*meta = filter;
 
-error:
-	free(item);
 	return ret;
 }
 
diff --git a/drivers/net/intel/ice/ice_fdir_filter.c b/drivers/net/intel/ice/ice_fdir_filter.c
index b1a8753e90..a4bb33264c 100644
--- a/drivers/net/intel/ice/ice_fdir_filter.c
+++ b/drivers/net/intel/ice/ice_fdir_filter.c
@@ -3023,7 +3023,7 @@ ice_fdir_parse(struct ice_adapter *ad,
 	};
 	struct ice_pf *pf = &ad->pf;
 	struct ice_fdir_filter_conf *filter = &pf->fdir.conf;
-	struct ice_pattern_match_item *item = NULL;
+	struct ice_pattern_match_item item;
 	uint64_t input_set;
 	bool raw = false;
 	int ret;
@@ -3038,17 +3038,17 @@ ice_fdir_parse(struct ice_adapter *ad,
 	if (ret)
 		return ret;
 
-	item = ice_search_pattern_match_item(ad, pattern, array, array_len,
-					     error);
+	ret = ice_search_pattern_match_item(ad, pattern, array, array_len,
+					     &item, error);
 
-	if (!item)
-		return -rte_errno;
+	if (ret != 0)
+		return ret;
 
 	ret = ice_fdir_parse_pattern(ad, pattern, error, filter);
 	if (ret)
 		goto error;
 
-	if (item->pattern_list[0] == RTE_FLOW_ITEM_TYPE_RAW)
+	if (item.pattern_list[0] == RTE_FLOW_ITEM_TYPE_RAW)
 		raw = true;
 
 	input_set = filter->input_set_o | filter->input_set_i;
@@ -3056,8 +3056,8 @@ ice_fdir_parse(struct ice_adapter *ad,
 
 	if (!input_set ||
 	    (filter->input_set_o &
-	     ~(item->input_set_mask_o | ICE_INSET_ETHERTYPE)) ||
-	    (filter->input_set_i & ~item->input_set_mask_i)) {
+	     ~(item.input_set_mask_o | ICE_INSET_ETHERTYPE)) ||
+	    (filter->input_set_i & ~item.input_set_mask_i)) {
 		rte_flow_error_set(error, EINVAL,
 				   RTE_FLOW_ERROR_TYPE_ITEM_SPEC,
 				   pattern,
@@ -3077,11 +3077,9 @@ ice_fdir_parse(struct ice_adapter *ad,
 		rte_free(filter->pkt_buf);
 	}
 
-	free(item);
 	return ret;
 error:
 	rte_free(filter->pkt_buf);
-	free(item);
 	return ret;
 }
 
diff --git a/drivers/net/intel/ice/ice_generic_flow.c b/drivers/net/intel/ice/ice_generic_flow.c
index ebe986c469..1a30327293 100644
--- a/drivers/net/intel/ice/ice_generic_flow.c
+++ b/drivers/net/intel/ice/ice_generic_flow.c
@@ -2209,45 +2209,30 @@ ice_pattern_is_supported(__rte_unused struct ice_adapter *ad,
 	return false;
 }
 
-struct ice_pattern_match_item *
+int
 ice_search_pattern_match_item(struct ice_adapter *ad,
 			      const struct rte_flow_item pattern[],
 			      struct ice_pattern_match_item *array,
 			      uint32_t array_len,
+			      struct ice_pattern_match_item *match,
 			      struct rte_flow_error *error)
 {
-	struct ice_pattern_match_item *pattern_match_item;
 	uint16_t i = 0;
 
-	pattern_match_item = calloc(1, sizeof(struct ice_pattern_match_item));
-	if (!pattern_match_item) {
-		rte_flow_error_set(error, ENOMEM, RTE_FLOW_ERROR_TYPE_HANDLE,
-				NULL, "Failed to allocate memory.");
-		return NULL;
-	}
-
 	if (!ice_pattern_is_supported(ad, pattern))
 		goto unsupported;
 
 	for (i = 0; i < array_len; i++) {
 		if (ice_match_pattern(array[i].pattern_list,
 				      pattern)) {
-			pattern_match_item->input_set_mask_o =
-				array[i].input_set_mask_o;
-			pattern_match_item->input_set_mask_i =
-				array[i].input_set_mask_i;
-			pattern_match_item->pattern_list =
-				array[i].pattern_list;
-			pattern_match_item->meta = array[i].meta;
-			return pattern_match_item;
+			*match = array[i];
+			return 0;
 		}
 	}
 
 unsupported:
-	rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM,
+	return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM,
 			   pattern, "Unsupported pattern");
-	free(pattern_match_item);
-	return NULL;
 }
 
 static bool
diff --git a/drivers/net/intel/ice/ice_generic_flow.h b/drivers/net/intel/ice/ice_generic_flow.h
index 983f86a5ab..a801e0c704 100644
--- a/drivers/net/intel/ice/ice_generic_flow.h
+++ b/drivers/net/intel/ice/ice_generic_flow.h
@@ -583,11 +583,12 @@ ice_pattern_skip_void(const struct rte_flow_item *item)
 	     (item)->type != RTE_FLOW_ITEM_TYPE_END; \
 	     (item) = ice_pattern_skip_void((item) + 1))
 
-struct ice_pattern_match_item *
+int
 ice_search_pattern_match_item(struct ice_adapter *ad,
 			      const struct rte_flow_item pattern[],
 			      struct ice_pattern_match_item *array,
 			      uint32_t array_len,
+			      struct ice_pattern_match_item *match,
 			      struct rte_flow_error *error);
 int
 ice_flow_redirect(struct ice_adapter *ad,
diff --git a/drivers/net/intel/ice/ice_hash.c b/drivers/net/intel/ice/ice_hash.c
index 13bedfe90c..21545efefd 100644
--- a/drivers/net/intel/ice/ice_hash.c
+++ b/drivers/net/intel/ice/ice_hash.c
@@ -1201,7 +1201,7 @@ ice_hash_parse_pattern_action(__rte_unused struct ice_adapter *ad,
 		.check = ice_hash_parse_action_check,
 	};
 	const struct rte_flow_action_rss *rss;
-	struct ice_pattern_match_item *pattern_match_item;
+	struct ice_pattern_match_item pattern_match_item;
 	struct ice_rss_meta *rss_meta_ptr;
 	uint64_t phint = ICE_PHINT_NONE;
 	int ret = 0;
@@ -1223,12 +1223,10 @@ ice_hash_parse_pattern_action(__rte_unused struct ice_adapter *ad,
 	}
 
 	/* Check rss supported pattern and find matched pattern. */
-	pattern_match_item = ice_search_pattern_match_item(ad, pattern, array,
-							   array_len, error);
-	if (!pattern_match_item) {
-		ret = -rte_errno;
+	ret = ice_search_pattern_match_item(ad, pattern, array, array_len,
+					   &pattern_match_item, error);
+	if (ret != 0)
 		goto error;
-	}
 
 	ret = ice_hash_parse_pattern(pattern, &phint, error);
 	if (ret)
@@ -1248,7 +1246,7 @@ ice_hash_parse_pattern_action(__rte_unused struct ice_adapter *ad,
 	}
 
 	rss = parsed_actions.actions[0]->conf;
-	ret = ice_hash_parse_rss_action(pattern_match_item, rss, phint,
+	ret = ice_hash_parse_rss_action(&pattern_match_item, rss, phint,
 				rss_meta_ptr, error);
 
 error:
@@ -1256,7 +1254,6 @@ ice_hash_parse_pattern_action(__rte_unused struct ice_adapter *ad,
 		*meta = rss_meta_ptr;
 	else
 		rte_free(rss_meta_ptr);
-	free(pattern_match_item);
 
 	return ret;
 }
diff --git a/drivers/net/intel/ice/ice_switch_filter.c b/drivers/net/intel/ice/ice_switch_filter.c
index 6bc1bdd09f..5c34089b40 100644
--- a/drivers/net/intel/ice/ice_switch_filter.c
+++ b/drivers/net/intel/ice/ice_switch_filter.c
@@ -1755,7 +1755,7 @@ ice_switch_parse_pattern_action(struct ice_adapter *ad,
 	uint16_t vlan_num = 0;
 	enum ice_sw_tunnel_type tun_type =
 			ICE_NON_TUN;
-	struct ice_pattern_match_item *pattern_match_item = NULL;
+	struct ice_pattern_match_item pattern_match_item;
 	struct ci_flow_attr_check_param attr_param = {
 		.allow_priority = true,
 	};
@@ -1848,10 +1848,9 @@ ice_switch_parse_pattern_action(struct ice_adapter *ad,
 		goto error;
 	}
 
-	pattern_match_item =
-		ice_search_pattern_match_item(ad, pattern, array, array_len,
-					      error);
-	if (!pattern_match_item) {
+	ret = ice_search_pattern_match_item(ad, pattern, array, array_len,
+					    &pattern_match_item, error);
+	if (ret != 0) {
 		rte_flow_error_set(error, EINVAL,
 				   RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
 				   "Invalid input pattern");
@@ -1859,7 +1858,7 @@ ice_switch_parse_pattern_action(struct ice_adapter *ad,
 	}
 
 	if (!ice_switch_parse_pattern(pattern, error, list, &lkups_num,
-				   &tun_type, pattern_match_item)) {
+				   &tun_type, &pattern_match_item)) {
 		rte_flow_error_set(error, EINVAL,
 				   RTE_FLOW_ERROR_TYPE_ITEM_SPEC,
 				   pattern,
@@ -1890,14 +1889,11 @@ ice_switch_parse_pattern_action(struct ice_adapter *ad,
 		rte_free(sw_meta_ptr);
 	}
 
-	free(pattern_match_item);
-
 	return 0;
 
 error:
 	rte_free(list);
 	rte_free(sw_meta_ptr);
-	free(pattern_match_item);
 
 	return -rte_errno;
 }
-- 
2.52.0



More information about the dev mailing list