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(&eth_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
> 

Reply via email to