[dpdk-dev] [PATCH v5] net/mlx5: support metadata as flow rule criteria

Yongseok Koh yskoh at mellanox.com
Mon Oct 22 20:47:16 CEST 2018


> On Oct 21, 2018, at 7:04 AM, Dekel Peled <dekelp at mellanox.com> wrote:
> 
> As described in series starting at [1], it adds option to set
> metadata value as match pattern when creating a new flow rule.
> 
> This patch adds metadata support in mlx5 driver, in two parts:
> - Add the validation and setting of metadata value in matcher,
>  when creating a new flow rule.
> - Add the passing of metadata value from mbuf to wqe when
>  indicated by ol_flag, in different burst functions.
> 
> [1] "ethdev: support metadata as flow rule criteria"
>    http://mails.dpdk.org/archives/dev/2018-September/113269.html
> 
> ---
> v5:
> Apply code review comments:
> Coding style (indentation, redundant blank lines, clear comments).
> txq_calc_offload() logic updated.
> rte_be32_t type used instead of uint32_t.
> v4:
> - Rebase.
> - Apply code review comments.
> v3:
> - Update meta item validation.
> v2:
> - Split the support of egress rules to a different patch.
> ---
> 
> Signed-off-by: Dekel Peled <dekelp at mellanox.com>
> ---
> drivers/net/mlx5/mlx5_flow.c          |   2 +-
> drivers/net/mlx5/mlx5_flow.h          |   8 +++
> drivers/net/mlx5/mlx5_flow_dv.c       | 107 ++++++++++++++++++++++++++++++++++
> drivers/net/mlx5/mlx5_prm.h           |   2 +-
> drivers/net/mlx5/mlx5_rxtx.c          |  32 ++++++++--
> drivers/net/mlx5/mlx5_rxtx_vec.c      |  46 +++++++++++----
> drivers/net/mlx5/mlx5_rxtx_vec.h      |   1 +
> drivers/net/mlx5/mlx5_rxtx_vec_neon.h |   9 ++-
> drivers/net/mlx5/mlx5_rxtx_vec_sse.h  |  10 ++--
> drivers/net/mlx5/mlx5_txq.c           |   5 +-
> 10 files changed, 193 insertions(+), 29 deletions(-)
> 
> diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
> index bd70fce..15262f6 100644
> --- a/drivers/net/mlx5/mlx5_flow.c
> +++ b/drivers/net/mlx5/mlx5_flow.c
> @@ -418,7 +418,7 @@ uint32_t mlx5_flow_adjust_priority(struct rte_eth_dev *dev, int32_t priority,
>  * @return
>  *   0 on success, a negative errno value otherwise and rte_errno is set.
>  */
> -static int
> +int
> mlx5_flow_item_acceptable(const struct rte_flow_item *item,
> 			  const uint8_t *mask,
> 			  const uint8_t *nic_mask,
> diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h
> index 094f666..834a6ed 100644
> --- a/drivers/net/mlx5/mlx5_flow.h
> +++ b/drivers/net/mlx5/mlx5_flow.h
> @@ -43,6 +43,9 @@
> #define MLX5_FLOW_LAYER_GRE (1u << 14)
> #define MLX5_FLOW_LAYER_MPLS (1u << 15)
> 
> +/* General pattern items bits. */
> +#define MLX5_FLOW_ITEM_METADATA (1u << 16)
> +
> /* Outer Masks. */
> #define MLX5_FLOW_LAYER_OUTER_L3 \
> 	(MLX5_FLOW_LAYER_OUTER_L3_IPV4 | MLX5_FLOW_LAYER_OUTER_L3_IPV6)
> @@ -307,6 +310,11 @@ int mlx5_flow_validate_action_rss(const struct rte_flow_action *action,
> int mlx5_flow_validate_attributes(struct rte_eth_dev *dev,
> 				  const struct rte_flow_attr *attributes,
> 				  struct rte_flow_error *error);
> +int mlx5_flow_item_acceptable(const struct rte_flow_item *item,
> +			      const uint8_t *mask,
> +			      const uint8_t *nic_mask,
> +			      unsigned int size,
> +			      struct rte_flow_error *error);
> int mlx5_flow_validate_item_eth(const struct rte_flow_item *item,
> 				uint64_t item_flags,
> 				struct rte_flow_error *error);
> diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
> index a013201..a7976d7 100644
> --- a/drivers/net/mlx5/mlx5_flow_dv.c
> +++ b/drivers/net/mlx5/mlx5_flow_dv.c
> @@ -36,6 +36,67 @@
> #ifdef HAVE_IBV_FLOW_DV_SUPPORT
> 
> /**
> + * Validate META item.
> + *
> + * @param[in] dev
> + *   Pointer to the rte_eth_dev structure.
> + * @param[in] item
> + *   Item specification.
> + * @param[in] attr
> + *   Attributes of flow that includes this item.
> + * @param[out] error
> + *   Pointer to error structure.
> + *
> + * @return
> + *   0 on success, a negative errno value otherwise and rte_errno is set.
> + */
> +static int
> +flow_dv_validate_item_meta(struct rte_eth_dev *dev,
> +			   const struct rte_flow_item *item,
> +			   const struct rte_flow_attr *attr,
> +			   struct rte_flow_error *error)
> +{
> +	const struct rte_flow_item_meta *spec = item->spec;
> +	const struct rte_flow_item_meta *mask = item->mask;
> +	const struct rte_flow_item_meta nic_mask = {
> +		.data = RTE_BE32(UINT32_MAX)
> +	};
> +	int ret;
> +	uint64_t offloads = dev->data->dev_conf.txmode.offloads;
> +
> +	if (!(offloads & DEV_TX_OFFLOAD_MATCH_METADATA))
> +		return rte_flow_error_set(error, EPERM,
> +					  RTE_FLOW_ERROR_TYPE_ITEM,
> +					  NULL,
> +					  "match on metadata offload "
> +					  "configuration is off for this port");
> +	if (!spec)
> +		return rte_flow_error_set(error, EINVAL,
> +					  RTE_FLOW_ERROR_TYPE_ITEM_SPEC,
> +					  item->spec,
> +					  "data cannot be empty");
> +	if (!spec->data)
> +		return rte_flow_error_set(error, EINVAL,
> +					  RTE_FLOW_ERROR_TYPE_ITEM_SPEC,
> +					  NULL,
> +					  "data cannot be zero");
> +	if (!mask)
> +		mask = &rte_flow_item_meta_mask;
> +	ret = mlx5_flow_item_acceptable(item, (const uint8_t *)mask,
> +					(const uint8_t *)&nic_mask,
> +					sizeof(struct rte_flow_item_meta),
> +					error);
> +	if (ret < 0)
> +		return ret;
> +	if (attr->ingress)
> +		return rte_flow_error_set(error, ENOTSUP,
> +					  RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
> +					  NULL,
> +					  "pattern not supported for ingress");
> +	return 0;
> +}
> +
> +/**
>  * Verify the @p attributes will be correctly understood by the NIC and store
>  * them in the @p flow if everything is correct.
>  *
> @@ -214,6 +275,13 @@
> 				return ret;
> 			item_flags |= MLX5_FLOW_LAYER_MPLS;
> 			break;
> +		case RTE_FLOW_ITEM_TYPE_META:
> +			ret = flow_dv_validate_item_meta(dev, items, attr,
> +							 error);
> +			if (ret < 0)
> +				return ret;
> +			item_flags |= MLX5_FLOW_ITEM_METADATA;
> +			break;
> 		default:
> 			return rte_flow_error_set(error, ENOTSUP,
> 						  RTE_FLOW_ERROR_TYPE_ITEM,
> @@ -855,6 +923,42 @@
> }
> 
> /**
> + * Add META item to matcher
> + *
> + * @param[in, out] matcher
> + *   Flow matcher.
> + * @param[in, out] key
> + *   Flow matcher value.
> + * @param[in] item
> + *   Flow pattern to translate.
> + * @param[in] inner
> + *   Item is inner pattern.
> + */
> +static void
> +flow_dv_translate_item_meta(void *matcher, void *key,
> +				const struct rte_flow_item *item)
> +{
> +	const struct rte_flow_item_meta *meta_m;
> +	const struct rte_flow_item_meta *meta_v;
> +
> +	void *misc2_m =
> +		MLX5_ADDR_OF(fte_match_param, matcher, misc_parameters_2);
> +	void *misc2_v =
> +		MLX5_ADDR_OF(fte_match_param, key, misc_parameters_2);
> +
> +	meta_m = (const void *)item->mask;
> +	if (!meta_m)
> +		meta_m = &rte_flow_item_meta_mask;
> +	meta_v = (const void *)item->spec;
> +	if (meta_v) {
> +		MLX5_SET(fte_match_set_misc2, misc2_m, metadata_reg_a,
> +			 rte_be_to_cpu_32(meta_m->data));
> +		MLX5_SET(fte_match_set_misc2, misc2_v, metadata_reg_a,
> +			 rte_be_to_cpu_32(meta_v->data));
> +	}
> +}
> +
> +/**
>  * Update the matcher and the value based the selected item.
>  *
>  * @param[in, out] matcher
> @@ -940,6 +1044,9 @@
> 		flow_dv_translate_item_vxlan(tmatcher->mask.buf, key, item,
> 					     inner);
> 		break;
> +	case RTE_FLOW_ITEM_TYPE_META:
> +		flow_dv_translate_item_meta(tmatcher->mask.buf, key, item);
> +		break;
> 	default:
> 		break;
> 	}
> diff --git a/drivers/net/mlx5/mlx5_prm.h b/drivers/net/mlx5/mlx5_prm.h
> index 69296a0..29742b1 100644
> --- a/drivers/net/mlx5/mlx5_prm.h
> +++ b/drivers/net/mlx5/mlx5_prm.h
> @@ -159,7 +159,7 @@ struct mlx5_wqe_eth_seg_small {
> 	uint8_t	cs_flags;
> 	uint8_t	rsvd1;
> 	uint16_t mss;
> -	uint32_t rsvd2;
> +	uint32_t flow_table_metadata;
> 	uint16_t inline_hdr_sz;
> 	uint8_t inline_hdr[2];
> } __rte_aligned(MLX5_WQE_DWORD_SIZE);
> diff --git a/drivers/net/mlx5/mlx5_rxtx.c b/drivers/net/mlx5/mlx5_rxtx.c
> index 558e6b6..2bd220b 100644
> --- a/drivers/net/mlx5/mlx5_rxtx.c
> +++ b/drivers/net/mlx5/mlx5_rxtx.c
> @@ -523,6 +523,7 @@
> 		uint8_t tso = txq->tso_en && (buf->ol_flags & PKT_TX_TCP_SEG);
> 		uint32_t swp_offsets = 0;
> 		uint8_t swp_types = 0;
> +		rte_be32_t metadata;
> 		uint16_t tso_segsz = 0;
> #ifdef MLX5_PMD_SOFT_COUNTERS
> 		uint32_t total_length = 0;
> @@ -566,6 +567,9 @@
> 		cs_flags = txq_ol_cksum_to_cs(buf);
> 		txq_mbuf_to_swp(txq, buf, (uint8_t *)&swp_offsets, &swp_types);
> 		raw = ((uint8_t *)(uintptr_t)wqe) + 2 * MLX5_WQE_DWORD_SIZE;
> +		/* Copy metadata from mbuf if valid */
> +		metadata = buf->ol_flags & PKT_TX_METADATA ?
> +				buf->tx_metadata : 0;

Nitpicking. :-)
Indentation. There're a few more in the rest of the patch.
Otherwise,

Acked-by: Yongseok Koh <yskoh at mellanox.com>
 
Thanks



More information about the dev mailing list