On Tue, Oct 20, 2026 at 01:11:06PM +0100, Anatoly Burakov wrote: > VOID handling differs between pattern matching and engine parsing. > Pattern matching relies on a temporary copy with VOID items removed, > while engines handle them independently. This temporary copy makes memory > management complicated, so we want to get rid of it. > > However, before we can do that, we first need to standardize traversal of > the pattern so that all engines can skip over VOID items. Add shared > helpers to skip VOID items and iterate over non-VOID items, and use them > in pattern matching and all engines; also use them for item counting, > lookahead and RAW item lookup. > > Signed-off-by: Anatoly Burakov <[email protected]> > ---
This loop macro looks a very nice cleanup. Acked-by: Bruce Richardson <[email protected]> > drivers/net/intel/ice/ice_acl_filter.c | 4 +--- > drivers/net/intel/ice/ice_fdir_filter.c | 8 +++----- > drivers/net/intel/ice/ice_generic_flow.c | 11 +++++------ > drivers/net/intel/ice/ice_generic_flow.h | 14 ++++++++++++++ > drivers/net/intel/ice/ice_hash.c | 6 ++++-- > drivers/net/intel/ice/ice_switch_filter.c | 8 ++------ > 6 files changed, 29 insertions(+), 22 deletions(-) > > diff --git a/drivers/net/intel/ice/ice_acl_filter.c > b/drivers/net/intel/ice/ice_acl_filter.c > index eb5d88ccc5..91f684c9b9 100644 > --- a/drivers/net/intel/ice/ice_acl_filter.c > +++ b/drivers/net/intel/ice/ice_acl_filter.c > @@ -664,7 +664,7 @@ ice_acl_parse_pattern(__rte_unused struct ice_adapter *ad, > uint64_t input_set = ICE_INSET_NONE; > uint8_t flow_type = ICE_FLTR_PTYPE_NONF_NONE; > > - for (item = pattern; item->type != RTE_FLOW_ITEM_TYPE_END; item++) { > + ICE_FLOW_FOREACH_ITEM(item, pattern) { > item_type = item->type; > > switch (item_type) { > @@ -897,8 +897,6 @@ ice_acl_parse_pattern(__rte_unused struct ice_adapter *ad, > } > } > break; > - case RTE_FLOW_ITEM_TYPE_VOID: > - break; > default: > rte_flow_error_set(error, EINVAL, > RTE_FLOW_ERROR_TYPE_ITEM, > diff --git a/drivers/net/intel/ice/ice_fdir_filter.c > b/drivers/net/intel/ice/ice_fdir_filter.c > index 63a0d9fb1f..b1a8753e90 100644 > --- a/drivers/net/intel/ice/ice_fdir_filter.c > +++ b/drivers/net/intel/ice/ice_fdir_filter.c > @@ -1904,7 +1904,7 @@ ice_fdir_parse_pattern(__rte_unused struct ice_adapter > *ad, > struct ice_parser_result rslt; > uint8_t item_num = 0; > > - for (item = pattern; item->type != RTE_FLOW_ITEM_TYPE_END; item++) { > + ICE_FLOW_FOREACH_ITEM(item, pattern) { > if (item->type == RTE_FLOW_ITEM_TYPE_VXLAN) > tunnel_type = ICE_FDIR_TUNNEL_TYPE_VXLAN; > if (item->type == RTE_FLOW_ITEM_TYPE_L2TPV2) > @@ -1922,7 +1922,7 @@ ice_fdir_parse_pattern(__rte_unused struct ice_adapter > *ad, > /* This loop parse flow pattern and distinguish Non-tunnel and tunnel > * flow. input_set_i is used for inner part. > */ > - for (item = pattern; item->type != RTE_FLOW_ITEM_TYPE_END; item++) { > + ICE_FLOW_FOREACH_ITEM(item, pattern) { > item_type = item->type; > > if (item->last && !(item_type == RTE_FLOW_ITEM_TYPE_IPV4 || > @@ -2065,7 +2065,7 @@ ice_fdir_parse_pattern(__rte_unused struct ice_adapter > *ad, > if (!rte_is_zero_ether_addr(ð_mask->hdr.src_addr)) > *input_set |= ICE_INSET_SMAC; > > - next_type = (item + 1)->type; > + next_type = ice_pattern_skip_void(item + 1)->type; > /* Ignore this field except for > ICE_FLTR_PTYPE_NON_IP_L2 */ > if (eth_mask->hdr.ether_type == RTE_BE16(0xffff) && > next_type == RTE_FLOW_ITEM_TYPE_END) { > @@ -2471,8 +2471,6 @@ ice_fdir_parse_pattern(__rte_unused struct ice_adapter > *ad, > p_v6->src_port = sctp_spec->hdr.src_port; > } > break; > - case RTE_FLOW_ITEM_TYPE_VOID: > - break; > case RTE_FLOW_ITEM_TYPE_VXLAN: > l3 = RTE_FLOW_ITEM_TYPE_END; > vxlan_spec = item->spec; > diff --git a/drivers/net/intel/ice/ice_generic_flow.c > b/drivers/net/intel/ice/ice_generic_flow.c > index 76b3800545..fee048e456 100644 > --- a/drivers/net/intel/ice/ice_generic_flow.c > +++ b/drivers/net/intel/ice/ice_generic_flow.c > @@ -2109,16 +2109,15 @@ static bool > ice_match_pattern(enum rte_flow_item_type *item_array, > const struct rte_flow_item *pattern) > { > - const struct rte_flow_item *item = pattern; > + const struct rte_flow_item *item; > > - while ((*item_array == item->type) && > - (*item_array != RTE_FLOW_ITEM_TYPE_END)) { > + ICE_FLOW_FOREACH_ITEM(item, pattern) { > + if (*item_array != item->type) > + return false; > item_array++; > - item++; > } > > - return (*item_array == RTE_FLOW_ITEM_TYPE_END && > - item->type == RTE_FLOW_ITEM_TYPE_END); > + return *item_array == RTE_FLOW_ITEM_TYPE_END; > } > > struct ice_ptype_match { > diff --git a/drivers/net/intel/ice/ice_generic_flow.h > b/drivers/net/intel/ice/ice_generic_flow.h > index 650b43633f..983f86a5ab 100644 > --- a/drivers/net/intel/ice/ice_generic_flow.h > +++ b/drivers/net/intel/ice/ice_generic_flow.h > @@ -569,6 +569,20 @@ struct ice_flow_parser_node { > void ice_register_flow_engine(struct ice_flow_engine *engine); > int ice_flow_init(struct ice_adapter *ad); > void ice_flow_uninit(struct ice_adapter *ad); > + > +static inline const struct rte_flow_item * > +ice_pattern_skip_void(const struct rte_flow_item *item) > +{ > + while (item->type == RTE_FLOW_ITEM_TYPE_VOID) > + item++; > + return item; > +} > + > +#define ICE_FLOW_FOREACH_ITEM(item, pattern) \ > + for ((item) = ice_pattern_skip_void(pattern); \ > + (item)->type != RTE_FLOW_ITEM_TYPE_END; \ > + (item) = ice_pattern_skip_void((item) + 1)) > + > struct ice_pattern_match_item * > ice_search_pattern_match_item(struct ice_adapter *ad, > const struct rte_flow_item pattern[], > diff --git a/drivers/net/intel/ice/ice_hash.c > b/drivers/net/intel/ice/ice_hash.c > index 7a9a4f1a04..13bedfe90c 100644 > --- a/drivers/net/intel/ice/ice_hash.c > +++ b/drivers/net/intel/ice/ice_hash.c > @@ -624,7 +624,7 @@ ice_hash_parse_pattern(const struct rte_flow_item > pattern[], uint64_t *phint, > const struct rte_flow_item *item = pattern; > const struct rte_flow_item_gtp_psc *psc; > > - for (item = pattern; item->type != RTE_FLOW_ITEM_TYPE_END; item++) { > + ICE_FLOW_FOREACH_ITEM(item, pattern) { > if (item->last) { > rte_flow_error_set(error, EINVAL, > RTE_FLOW_ERROR_TYPE_ITEM, item, > @@ -1235,8 +1235,10 @@ ice_hash_parse_pattern_action(__rte_unused struct > ice_adapter *ad, > goto error; > > if (phint == ICE_PHINT_RAW) { > + const struct rte_flow_item *raw_item = > ice_pattern_skip_void(pattern); > + > rss_meta_ptr->raw.raw_ena = true; > - ret = ice_hash_parse_raw_pattern(ad, pattern, error, > rss_meta_ptr); > + ret = ice_hash_parse_raw_pattern(ad, raw_item, error, > rss_meta_ptr); > if (ret) { > rte_flow_error_set(error, EINVAL, > RTE_FLOW_ERROR_TYPE_ITEM, NULL, > diff --git a/drivers/net/intel/ice/ice_switch_filter.c > b/drivers/net/intel/ice/ice_switch_filter.c > index 6f5af03f6a..6bc1bdd09f 100644 > --- a/drivers/net/intel/ice/ice_switch_filter.c > +++ b/drivers/net/intel/ice/ice_switch_filter.c > @@ -489,8 +489,7 @@ ice_switch_parse_pattern(const struct rte_flow_item > pattern[], > *tun_type == ICE_NON_TUN_QINQ) > qinq_valid = 1; > > - for (item = pattern; item->type != > - RTE_FLOW_ITEM_TYPE_END; item++) { > + ICE_FLOW_FOREACH_ITEM(item, pattern) { > if (item->last) { > rte_flow_error_set(error, EINVAL, > RTE_FLOW_ERROR_TYPE_ITEM, > @@ -1378,9 +1377,6 @@ ice_switch_parse_pattern(const struct rte_flow_item > pattern[], > gtpu_psc_valid = 1; > break; > > - case RTE_FLOW_ITEM_TYPE_VOID: > - break; > - > default: > rte_flow_error_set(error, EINVAL, > RTE_FLOW_ERROR_TYPE_ITEM, pattern, > @@ -1805,7 +1801,7 @@ ice_switch_parse_pattern_action(struct ice_adapter *ad, > return -rte_errno; > } > > - for (; item->type != RTE_FLOW_ITEM_TYPE_END; item++) { > + ICE_FLOW_FOREACH_ITEM(item, pattern) { > item_num++; > if (item->type == RTE_FLOW_ITEM_TYPE_ETH) { > const struct rte_flow_item_eth *eth_mask; > -- > 2.52.0 >

