From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <dev-bounces@dpdk.org>
Received: from dpdk.org (dpdk.org [92.243.14.124])
	by inbox.dpdk.org (Postfix) with ESMTP id 0EAD8A0529;
	Tue, 30 Jun 2020 20:18:15 +0200 (CEST)
Received: from [92.243.14.124] (localhost [127.0.0.1])
	by dpdk.org (Postfix) with ESMTP id 632391BE9D;
	Tue, 30 Jun 2020 20:18:14 +0200 (CEST)
Received: from EUR01-DB5-obe.outbound.protection.outlook.com
 (mail-eopbgr150058.outbound.protection.outlook.com [40.107.15.58])
 by dpdk.org (Postfix) with ESMTP id A9B042B9C
 for <dev@dpdk.org>; Tue, 30 Jun 2020 20:18:12 +0200 (CEST)
ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none;
 b=aiamegN6OVAQSeRVrA/1euIhkXGrqXjabEbt3S2Lhl5bxwLRgT1iv95mYmFk2q0DS0B2RBYSA7U0jhgBy5qaQIq6b1eK1khrPr8ywsuu6l8cqI0zsi7uO28twqjXbilugVTZxdEqG0U0MwWjfcs1nvN2aLOfTvptHSFp3DOdLkOWPqr5n/U1AxSoAhJyn8ESqKnI1s2jfrkOK4nHPuOYuwrMybxS4PGbIKYiojqMDyP3kIaTiTPWMiW7//MomzJAJnl6eG6T+X2vhalQhg3mVrnbjs4p9TqvfI5dt3/z2VJQkseoLep4lWAMh/ZKkVo7SEhS8gTsR57pbUiB/OH2fg==
ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; 
 s=arcselector9901;
 h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;
 bh=gUJq4pc2CuwEMk8es0Lf6J34bIAMkTGrQWVv6m60ULI=;
 b=bAW1OhdunnbwL+atjjPTakl+QlfoXKkb/u1th1wW+pAnQNw3W5o4BFN3VJQT/ms6XFqIOpLewYOvgGcPOMz4RI6B4XDqr0J2dvyq2U/F3g3N6EGqC7Kt5uoGGCuTUgKJK3P+v1D7Y6+2rTB5AvuQ8cmA8RyG+A61UgWA96kSGl3GCAiWwKvaAT/WZc0QFPp+Yg17c9sSl2jAYLieom6lzT7nMbaljlL1NlN3XdpMj+yJnsud3Ym6yL1bWyaHH2zEcAVvPZaM1be4VjhJwSdO+OOnR9UYT89O5bDUpan4MQMjHwH94iIsQPQCc+dvGpwJsTw+wYaIpUOPfkLL6FBdCQ==
ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass
 smtp.mailfrom=mellanox.com; dmarc=pass action=none header.from=mellanox.com;
 dkim=pass header.d=mellanox.com; arc=none
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Mellanox.com;
 s=selector1;
 h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;
 bh=gUJq4pc2CuwEMk8es0Lf6J34bIAMkTGrQWVv6m60ULI=;
 b=l7USJKUjt8pc71MRVRzgUhfdDqwkJvS1nd+Z8eKoeybd88l0b9RBAZKgliYEEpvRbw3u3kdCLaIOxzj2/6jsaUvBup+9lb+KaLVZ+RDjBplRri8kLdN2d6Q9P1/q8QUNPSkOQB3V+8kw0s2AO8lWODs18Z13XDQTUl7ltb/4Uyo=
Received: from AM6PR05MB5176.eurprd05.prod.outlook.com (2603:10a6:20b:63::30)
 by AM6PR05MB4183.eurprd05.prod.outlook.com (2603:10a6:209:40::28)
 with Microsoft SMTP Server (version=TLS1_2,
 cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3131.23; Tue, 30 Jun
 2020 18:18:07 +0000
Received: from AM6PR05MB5176.eurprd05.prod.outlook.com
 ([fe80::9024:accb:4d6b:805f]) by AM6PR05MB5176.eurprd05.prod.outlook.com
 ([fe80::9024:accb:4d6b:805f%3]) with mapi id 15.20.3131.027; Tue, 30 Jun 2020
 18:18:07 +0000
From: Ori Kam <orika@mellanox.com>
To: "Jiawei(Jonny) Wang" <jiaweiw@mellanox.com>, Slava Ovsiienko
 <viacheslavo@mellanox.com>, Matan Azrad <matan@mellanox.com>
CC: "dev@dpdk.org" <dev@dpdk.org>, Thomas Monjalon <thomas@monjalon.net>,
 Raslan Darawsheh <rasland@mellanox.com>, "ian.stokes@intel.com"
 <ian.stokes@intel.com>, "fbl@redhat.com" <fbl@redhat.com>, "Jiawei(Jonny)
 Wang" <jiaweiw@mellanox.com>
Thread-Topic: [PATCH 5/8] net/mlx5: split sample flow into two sub flows
Thread-Index: AQHWSxDCEvKa9BlP70GyIixoMjpwUKjxTAaA
Date: Tue, 30 Jun 2020 18:18:07 +0000
Message-ID: <AM6PR05MB517683F30627F8AB50D0BCC6DB6F0@AM6PR05MB5176.eurprd05.prod.outlook.com>
References: <1593102379-400132-1-git-send-email-jiaweiw@mellanox.com>
 <1593102379-400132-6-git-send-email-jiaweiw@mellanox.com>
In-Reply-To: <1593102379-400132-6-git-send-email-jiaweiw@mellanox.com>
Accept-Language: en-US
Content-Language: en-US
X-MS-Has-Attach: 
X-MS-TNEF-Correlator: 
authentication-results: mellanox.com; dkim=none (message not signed)
 header.d=none;mellanox.com; dmarc=none action=none header.from=mellanox.com;
x-originating-ip: [147.236.152.129]
x-ms-publictraffictype: Email
x-ms-office365-filtering-ht: Tenant
x-ms-office365-filtering-correlation-id: 61249859-889d-4dd5-764e-08d81d21f01d
x-ms-traffictypediagnostic: AM6PR05MB4183:
x-ld-processed: a652971c-7d2e-4d9b-a6a4-d149256f461b,ExtFwd,ExtAddr
x-ms-exchange-transport-forked: True
x-microsoft-antispam-prvs: <AM6PR05MB4183BDB09EAEDF7EC7000408DB6F0@AM6PR05MB4183.eurprd05.prod.outlook.com>
x-ms-oob-tlc-oobclassifiers: OLM:8882;
x-forefront-prvs: 0450A714CB
x-ms-exchange-senderadcheck: 1
x-microsoft-antispam: BCL:0;
x-microsoft-antispam-message-info: hCdAHfmHHc5ZF8O/5XMj8pjGYDQmjMFcCMAJdj/YvZ8/Yln8l3tqYSPwrVWBos0JlzybR4DNr8XdLkcrGwoZZ3xBxOfcvgU9yQh2vol4VtKNCtEPo8ecQtDxAi0BcOqMbbdMIwVKmURpatGi9zP7WbotrDzoggzzpMs77GPWkD5Y1I4FcwUb8kkFHy1X3alfTa18/9J9g/JKMiS2H03LTPcEX+BytJiq9JS/A8FlzomDuYXb5W9/nryU/FLVujV4kdAZaS/PwMCzxXRPUFtPzdqB88h28dhLHVoE+by57VRwaZj7YdnyFhlswkhNbRxcLDJCiBK/SzCmz4HZ0YgpJQ==
x-forefront-antispam-report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:;
 IPV:NLI; SFV:NSPM; H:AM6PR05MB5176.eurprd05.prod.outlook.com; PTR:; CAT:NONE;
 SFTY:;
 SFS:(4636009)(366004)(346002)(136003)(376002)(39860400002)(396003)(66946007)(478600001)(186003)(45080400002)(8676002)(76116006)(55016002)(9686003)(52536014)(30864003)(5660300002)(33656002)(6636002)(8936002)(71200400001)(4326008)(83380400001)(86362001)(107886003)(316002)(2906002)(110136005)(66476007)(66556008)(64756008)(66446008)(54906003)(7696005)(6506007)(53546011)(26005);
 DIR:OUT; SFP:1101; 
x-ms-exchange-antispam-messagedata: JXN1OgQqnjN13dKAvF69POXKDSoZqari5Dl4JWTJZWqDnjOfZmBMAm9St1vKtfUlBxjHGXc5QKYZUvnBWuOHNtqkvGtFBGTeTPXBNB+Cq6RUahxHnj2UOOZXNH1iTRTk519XKR1+/sb+m8Mn/aq/hT3CKBSQvBICAIDMc32dz0gETVxHSyTSDrnfynaPdCsUix/KB9SlYd5hlbGf5GlL/ZHYjoky2yaQlgTf6Do6VUZpfUYTMQRFdQi30a2qDn/Oy9e/80GnqHF4yZ1GscXZMdApEitUqpmKWZNj9RuOrupVmWFfMjFCbn7/nkI94HOCHq9S85PSkywxTC73j5tZNdQ7oih7wloduOd5Nnxjb1i3hV/d1XgerxyUp0q2TEocFWmP/J0lOZexKK58Icj+ReY375rlbjcxOuMY4zR/BSOZAPoD1r3Np5gP9X9g1V5N/e0HlM8TXbbWUKnmYo0HzpGdzMYJGQMZJEXaAe5/VBnNoDoAiyC84AoTCZCGK4AV
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: quoted-printable
MIME-Version: 1.0
X-OriginatorOrg: Mellanox.com
X-MS-Exchange-CrossTenant-AuthAs: Internal
X-MS-Exchange-CrossTenant-AuthSource: AM6PR05MB5176.eurprd05.prod.outlook.com
X-MS-Exchange-CrossTenant-Network-Message-Id: 61249859-889d-4dd5-764e-08d81d21f01d
X-MS-Exchange-CrossTenant-originalarrivaltime: 30 Jun 2020 18:18:07.1714 (UTC)
X-MS-Exchange-CrossTenant-fromentityheader: Hosted
X-MS-Exchange-CrossTenant-id: a652971c-7d2e-4d9b-a6a4-d149256f461b
X-MS-Exchange-CrossTenant-mailboxtype: HOSTED
X-MS-Exchange-CrossTenant-userprincipalname: x4/c9as14GgTiICNZL+agz0mhOyMthHHmidfgYEOSaq6SEkwohup5BWrw1jH6/MQvmOsO4epLBXlxcu45cXO7g==
X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM6PR05MB4183
Subject: Re: [dpdk-dev] [PATCH 5/8] net/mlx5: split sample flow into two sub
	flows
X-BeenThere: dev@dpdk.org
X-Mailman-Version: 2.1.15
Precedence: list
List-Id: DPDK patches and discussions <dev.dpdk.org>
List-Unsubscribe: <https://mails.dpdk.org/options/dev>,
 <mailto:dev-request@dpdk.org?subject=unsubscribe>
List-Archive: <http://mails.dpdk.org/archives/dev/>
List-Post: <mailto:dev@dpdk.org>
List-Help: <mailto:dev-request@dpdk.org?subject=help>
List-Subscribe: <https://mails.dpdk.org/listinfo/dev>,
 <mailto:dev-request@dpdk.org?subject=subscribe>
Errors-To: dev-bounces@dpdk.org
Sender: "dev" <dev-bounces@dpdk.org>

Hi Jiawei,

Please fix the small comment below and send with my ack
Acked-by: Ori Kam <orika@mellanox.com>

Best,
Ori

> -----Original Message-----
> From: Jiawei Wang <jiaweiw@mellanox.com>
> Sent: Thursday, June 25, 2020 7:26 PM
> To: Ori Kam <orika@mellanox.com>; Slava Ovsiienko
> <viacheslavo@mellanox.com>; Matan Azrad <matan@mellanox.com>
> Cc: dev@dpdk.org; Thomas Monjalon <thomas@monjalon.net>; Raslan
> Darawsheh <rasland@mellanox.com>; ian.stokes@intel.com; fbl@redhat.com;
> Jiawei(Jonny) Wang <jiaweiw@mellanox.com>
> Subject: [PATCH 5/8] net/mlx5: split sample flow into two sub flows
>=20
> Add the sampler action resource structs definition.
>=20
> The flow with sample action will be splited into two sub flows,
> the prefix flow with sample action, the suffix flow with the left
> actions.
>=20
> For the prefix flow, add the extra the tag action with unique id
> to metadata register, and suffix flow will add the extra tag item
> to match that unique id.
>=20
> Signed-off-by: Jiawei Wang <jiaweiw@mellanox.com>
> ---
>  drivers/net/mlx5/mlx5.c      |  11 ++
>  drivers/net/mlx5/mlx5.h      |   3 +
>  drivers/net/mlx5/mlx5_flow.c | 254
> ++++++++++++++++++++++++++++++++++++++++++-
>  drivers/net/mlx5/mlx5_flow.h |  37 +++++++
>  4 files changed, 301 insertions(+), 4 deletions(-)
>=20
> diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
> index ddbe29d..4a52462 100644
> --- a/drivers/net/mlx5/mlx5.c
> +++ b/drivers/net/mlx5/mlx5.c
> @@ -238,6 +238,17 @@ static LIST_HEAD(, mlx5_dev_ctx_shared)
> mlx5_dev_ctx_list =3D
>  		.free =3D rte_free,
>  		.type =3D "mlx5_jump_ipool",
>  	},
> +	{
> +		.size =3D sizeof(struct mlx5_flow_dv_sample_resource),
> +		.trunk_size =3D 64,
> +		.grow_trunk =3D 3,
> +		.grow_shift =3D 2,
> +		.need_lock =3D 0,
> +		.release_mem_en =3D 1,
> +		.malloc =3D rte_malloc_socket,
> +		.free =3D rte_free,
> +		.type =3D "mlx5_sample_ipool",
> +	},
>  #endif
>  	{
>  		.size =3D sizeof(struct mlx5_flow_meter),
> diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
> index c2a875c..7394753 100644
> --- a/drivers/net/mlx5/mlx5.h
> +++ b/drivers/net/mlx5/mlx5.h
> @@ -51,6 +51,7 @@ enum mlx5_ipool_index {
>  	MLX5_IPOOL_TAG, /* Pool for tag resource. */
>  	MLX5_IPOOL_PORT_ID, /* Pool for port id resource. */
>  	MLX5_IPOOL_JUMP, /* Pool for jump resource. */
> +	MLX5_IPOOL_SAMPLE, /* Pool for sample resource. */
>  #endif
>  	MLX5_IPOOL_MTR, /* Pool for meter resource. */
>  	MLX5_IPOOL_MCP, /* Pool for metadata resource. */
> @@ -510,6 +511,7 @@ struct mlx5_flow_tbl_resource {
>  /* Tables for metering splits should be added here. */
>  #define MLX5_MAX_TABLES_EXTERNAL (MLX5_MAX_TABLES - 3)
>  #define MLX5_MAX_TABLES_FDB UINT16_MAX
> +#define MLX5_FLOW_TABLE_FACTOR 10
>=20
>  /* ID generation structure. */
>  struct mlx5_flow_id_pool {
> @@ -558,6 +560,7 @@ struct mlx5_dev_ctx_shared {
>  	struct mlx5_hlist *tag_table;
>  	uint32_t port_id_action_list; /* List of port ID actions. */
>  	uint32_t push_vlan_action_list; /* List of push VLAN actions. */
> +	uint32_t sample_action_list; /* List of sample actions. */
>  	struct mlx5_flow_counter_mng cmng; /* Counters management
> structure. */
>  	struct mlx5_indexed_pool *ipool[MLX5_IPOOL_MAX];
>  	/* Memory Pool for mlx5 flow resources. */
> diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
> index 3a48b89..7c65a9a 100644
> --- a/drivers/net/mlx5/mlx5_flow.c
> +++ b/drivers/net/mlx5/mlx5_flow.c
> @@ -360,6 +360,8 @@ struct mlx5_flow_tunnel_info {
>  		return REG_B;
>  	case MLX5_HAIRPIN_TX:
>  		return REG_A;
> +	case MLX5_SAMPLE_FDB:
> +		return REG_C_0;
>  	case MLX5_METADATA_RX:
>  		switch (config->dv_xmeta_en) {
>  		case MLX5_XMETA_MODE_LEGACY:
> @@ -3878,6 +3880,137 @@ uint32_t mlx5_flow_adjust_priority(struct
> rte_eth_dev *dev, int32_t priority,
>  	return 0;
>  }
>=20
> +
> +/**
> + * Check the match action from the action list.
> + *
> + * @param[in] actions
> + *   Pointer to the list of actions.
> + * @param[in] action
> + *   The action to be check if exist.
> + *
> + * @return
> + *   > 0 the total number of actions.
> + *   0 if not found match action in action list.
> + */
> +static int
> +flow_check_match_action(const struct rte_flow_action actions[],
> +					enum rte_flow_action_type action)
> +{
> +	int actions_n =3D 0;
> +	int flag =3D 0;
> +
> +	for (; actions->type !=3D RTE_FLOW_ACTION_TYPE_END; actions++) {
> +		if (actions->type =3D=3D action)
> +			flag =3D 1;
> +		actions_n++;
> +	}
> +	/* Count RTE_FLOW_ACTION_TYPE_END. */
> +	return flag ? actions_n + 1 : 0;
> +}
> +
> +/**
> + * Split the sample flow.
> + *
> + * As sample flow will split to two sub flow, sample flow with
> + * sample action, the other actions will move to new suffix flow.
> + *
> + * Also add unique tag id with tag action in the sample flow,
> + * the same tag id will be as match in the suffix flow.
> + *
> + * @param dev
> + *   Pointer to Ethernet device.
> + * @param[in] attr
> + *   Flow rule attributes.
> + * @param[out] sfx_items
> + *   Suffix flow match items (list terminated by the END pattern item).
> + * @param[in] actions
> + *   Associated actions (list terminated by the END action).
> + * @param[out] actions_sfx
> + *   Suffix flow actions.
> + * @param[out] actions_pre
> + *   Prefix flow actions.
> + *
> + * @return
> + *   0 on success.


It looks like the function also returns the tag id.

> + */
> +static int
> +flow_sample_split_prep(struct rte_eth_dev *dev,
> +		 const struct rte_flow_attr *attr,
> +		 struct rte_flow_item sfx_items[],
> +		 const struct rte_flow_action actions[],
> +		 struct rte_flow_action actions_sfx[],
> +		 struct rte_flow_action actions_pre[])
> +{
> +	struct mlx5_rte_flow_action_set_tag *set_tag;
> +	struct mlx5_rte_flow_item_tag *tag_spec;
> +	struct mlx5_rte_flow_item_tag *tag_mask;
> +	struct rte_flow_item *tag_item;
> +	struct rte_flow_action *tag_action =3D NULL;
> +	bool pre_sample =3D true;
> +	struct rte_flow_error error;
> +	uint32_t tag_id;
> +
> +	/* Prepare the actions for prefix and suffix flow. */
> +	for (; actions->type !=3D RTE_FLOW_ACTION_TYPE_END; actions++) {
> +		struct rte_flow_action **action_cur =3D NULL;
> +
> +		switch (actions->type) {
> +		case RTE_FLOW_ACTION_TYPE_SAMPLE:
> +			/* Add the extra tag action first. */
> +			tag_action =3D actions_pre;
> +			tag_action->type =3D (enum rte_flow_action_type)
> +
> 	MLX5_RTE_FLOW_ACTION_TYPE_TAG;
> +			actions_pre++;
> +			break;
> +		case RTE_FLOW_ACTION_TYPE_JUMP:
> +		case RTE_FLOW_ACTION_TYPE_METER:
> +			action_cur =3D &actions_sfx;
> +			break;
> +		default:
> +			break;
> +		}
> +		if (pre_sample && !action_cur)
> +			action_cur =3D &actions_pre;
> +		else
> +			action_cur =3D &actions_sfx;
> +		memcpy(*action_cur, actions, sizeof(struct rte_flow_action));
> +		(*action_cur)++;
> +		if (actions->type =3D=3D RTE_FLOW_ACTION_TYPE_SAMPLE)
> +			pre_sample =3D false;
> +	}
> +	/* Add end action to the actions. */
> +	actions_sfx->type =3D RTE_FLOW_ACTION_TYPE_END;
> +	actions_pre->type =3D RTE_FLOW_ACTION_TYPE_END;
> +	actions_pre++;
> +	/* Set the tag. */
> +	set_tag =3D (void *)actions_pre;
> +	set_tag->id =3D mlx5_flow_get_reg_id(dev, attr->transfer ?
> +			MLX5_SAMPLE_FDB : MLX5_APP_TAG, 0, &error);
> +	tag_id =3D flow_qrss_get_id(dev);
> +	set_tag->data =3D tag_id;
> +	assert(tag_action);
> +	tag_action->conf =3D set_tag;
> +	/* Prepare the suffix subflow items. */
> +	if (sfx_items) {
> +		tag_item =3D sfx_items++;
> +		sfx_items->type =3D RTE_FLOW_ITEM_TYPE_END;
> +		sfx_items++;
> +		tag_spec =3D (struct mlx5_rte_flow_item_tag *)sfx_items;
> +		tag_spec->data =3D tag_id;
> +		tag_spec->id =3D set_tag->id;
> +		tag_mask =3D tag_spec + 1;
> +		tag_mask->data =3D UINT32_MAX;
> +		tag_mask->id =3D UINT16_MAX;
> +		tag_item->type =3D (enum rte_flow_item_type)
> +				MLX5_RTE_FLOW_ITEM_TYPE_TAG;
> +		tag_item->spec =3D tag_spec;
> +		tag_item->last =3D NULL;
> +		tag_item->mask =3D tag_mask;
> +	}
> +	return tag_id;
> +}
> +
>  /**
>   * The splitting for metadata feature.
>   *
> @@ -4137,6 +4270,7 @@ uint32_t mlx5_flow_adjust_priority(struct
> rte_eth_dev *dev, int32_t priority,
>  static int
>  flow_create_split_meter(struct rte_eth_dev *dev,
>  			   struct rte_flow *flow,
> +			   uint64_t prefix_layers,
>  			   const struct rte_flow_attr *attr,
>  			   const struct rte_flow_item items[],
>  			   const struct rte_flow_action actions[],
> @@ -4183,8 +4317,9 @@ uint32_t mlx5_flow_adjust_priority(struct
> rte_eth_dev *dev, int32_t priority,
>  			goto exit;
>  		}
>  		/* Add the prefix subflow. */
> -		ret =3D flow_create_split_inner(dev, flow, &dev_flow, 0, attr,
> -					      items, pre_actions, external,
> +		ret =3D flow_create_split_inner(dev, flow, &dev_flow,
> +					      prefix_layers, attr, items,
> +					      pre_actions, external,
>  					      flow_idx, error);
>  		if (ret) {
>  			ret =3D -rte_errno;
> @@ -4199,7 +4334,7 @@ uint32_t mlx5_flow_adjust_priority(struct
> rte_eth_dev *dev, int32_t priority,
>  	/* Add the prefix subflow. */
>  	ret =3D flow_create_split_metadata(dev, flow, dev_flow ?
>=20
> flow_get_prefix_layer_flags(dev_flow) :
> -					 0, &sfx_attr,
> +					 prefix_layers, &sfx_attr,
>  					 sfx_items ? sfx_items : items,
>  					 sfx_actions ? sfx_actions : actions,
>  					 external, flow_idx, error);
> @@ -4210,6 +4345,117 @@ uint32_t mlx5_flow_adjust_priority(struct
> rte_eth_dev *dev, int32_t priority,
>  }
>=20
>  /**
> + * The splitting for sample feature.
> + *
> + * The sample flow will be split to two flows as prefix and
> + * suffix flow.
> + *
> + * @param dev
> + *   Pointer to Ethernet device.
> + * @param[in] flow
> + *   Parent flow structure pointer.
> + * @param[in] attr
> + *   Flow rule attributes.
> + * @param[in] items
> + *   Pattern specification (list terminated by the END pattern item).
> + * @param[in] actions
> + *   Associated actions (list terminated by the END action).
> + * @param[in] external
> + *   This flow rule is created by request external to PMD.
> + * @param[in] flow_idx
> + *   This memory pool index to the flow.
> + * @param[out] error
> + *   Perform verbose error reporting if not NULL.
> + * @return
> + *   0 on success, negative value otherwise
> + */
> +static int
> +flow_create_split_sample(struct rte_eth_dev *dev,
> +			   struct rte_flow *flow,
> +			   const struct rte_flow_attr *attr,
> +			   const struct rte_flow_item items[],
> +			   const struct rte_flow_action actions[],
> +			   bool external, uint32_t flow_idx,
> +			   struct rte_flow_error *error)
> +{
> +	struct mlx5_priv *priv =3D dev->data->dev_private;
> +	struct rte_flow_action *sfx_actions =3D NULL;
> +	struct rte_flow_action *pre_actions =3D NULL;
> +	struct rte_flow_item *sfx_items =3D NULL;
> +	struct mlx5_flow *dev_flow =3D NULL;
> +	struct rte_flow_attr sfx_attr =3D *attr;
> +	struct mlx5_flow_dv_sample_resource *sample_res;
> +	struct mlx5_flow_tbl_data_entry *sfx_tbl_data;
> +	struct mlx5_flow_tbl_resource *sfx_tbl;
> +	union mlx5_flow_tbl_key sfx_table_key;
> +	size_t act_size;
> +	size_t item_size;
> +	uint32_t tag_id =3D 0;
> +	int actions_n =3D 0;
> +	int ret =3D 0;
> +
> +	if (priv->sampler_en)
> +		actions_n =3D flow_check_match_action(actions,
> +					RTE_FLOW_ACTION_TYPE_SAMPLE);
> +	if (actions_n) {
> +		/* The prefix actions must includes sample, tag, end. */
> +		act_size =3D sizeof(struct rte_flow_action) * (actions_n * 2) +
> +			   sizeof(struct mlx5_rte_flow_action_set_tag);
> +		/* tag, end. */
> +#define SAMPLE_SUFFIX_ITEM 2
> +		item_size =3D sizeof(struct rte_flow_item) *
> SAMPLE_SUFFIX_ITEM +
> +			    sizeof(struct mlx5_rte_flow_item_tag) * 2;
> +		sfx_actions =3D rte_zmalloc(__func__, (act_size + item_size), 0);
> +		if (!sfx_actions)
> +			return rte_flow_error_set(error, ENOMEM,
> +
> RTE_FLOW_ERROR_TYPE_ACTION,
> +						  NULL, "no memory to split "
> +						  "sample flow");
> +		if (!attr->transfer)
> +			sfx_items =3D (struct rte_flow_item *)((char
> *)sfx_actions
> +					+ act_size);
> +		pre_actions =3D sfx_actions + actions_n;
> +		tag_id =3D flow_sample_split_prep(dev, attr, sfx_items,
> +						   actions, sfx_actions,
> +						   pre_actions);
> +		if (!tag_id) {
> +			ret =3D -rte_errno;
> +			goto exit;
> +		}
> +		/* Add the prefix subflow. */
> +		ret =3D flow_create_split_inner(dev, flow, &dev_flow, 0, attr,
> +					      items, pre_actions, external,
> +					      flow_idx, error);
> +		if (ret) {
> +			ret =3D -rte_errno;
> +			goto exit;
> +		}
> +		dev_flow->handle->split_flow_id =3D tag_id;
> +		/* Set the sfx group attr. */
> +		sample_res =3D (struct mlx5_flow_dv_sample_resource *)
> +					dev_flow->dv.sample_res;
> +		sfx_tbl =3D (struct mlx5_flow_tbl_resource *)
> +					sample_res->normal_path_tbl;
> +		sfx_tbl_data =3D container_of(sfx_tbl,
> +					struct mlx5_flow_tbl_data_entry, tbl);
> +		sfx_table_key.v64 =3D sfx_tbl_data->entry.key;
> +		sfx_attr.group =3D sfx_attr.transfer ?
> +					(sfx_table_key.table_id - 1) :
> +					sfx_table_key.table_id;
> +	}
> +	/* Add the suffix subflow. */
> +	ret =3D flow_create_split_meter(dev, flow, dev_flow ?
> +				 flow_get_prefix_layer_flags(dev_flow) : 0,
> +				 &sfx_attr, sfx_items ? sfx_items : items,
> +				 sfx_actions ? sfx_actions : actions,
> +				 external, flow_idx, error);
> +exit:
> +	if (sfx_actions)
> +		rte_free(sfx_actions);
> +	return ret;
> +}
> +
> +/**
>   * Split the flow to subflow set. The splitters might be linked
>   * in the chain, like this:
>   * flow_create_split_outer() calls:
> @@ -4257,7 +4503,7 @@ uint32_t mlx5_flow_adjust_priority(struct
> rte_eth_dev *dev, int32_t priority,
>  {
>  	int ret;
>=20
> -	ret =3D flow_create_split_meter(dev, flow, attr, items,
> +	ret =3D flow_create_split_sample(dev, flow, attr, items,
>  					 actions, external, flow_idx, error);
>  	MLX5_ASSERT(ret <=3D 0);
>  	return ret;
> diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h
> index 902380b..941de5f 100644
> --- a/drivers/net/mlx5/mlx5_flow.h
> +++ b/drivers/net/mlx5/mlx5_flow.h
> @@ -79,6 +79,7 @@ enum mlx5_feature_name {
>  	MLX5_COPY_MARK,
>  	MLX5_MTR_COLOR,
>  	MLX5_MTR_SFX,
> +	MLX5_SAMPLE_FDB,
>  };
>=20
>  /* Pattern outer Layer bits. */
> @@ -498,6 +499,38 @@ struct mlx5_flow_tbl_data_entry {
>  	uint32_t idx; /**< index for the indexed mempool. */
>  };
>=20
> +/* Sub rdma-core actions list. */
> +struct mlx5_flow_sub_actions_list {
> +	uint32_t actions_num; /**< Number of sample actions. */
> +	uint64_t action_flags;
> +	void *dr_queue_action;
> +	void *dr_tag_action;
> +	void *dr_cnt_action;
> +};
> +
> +/* Sample sub-actions resource list. */
> +struct mlx5_flow_sub_actions_idx {
> +	uint32_t rix_hrxq; /**< Hash Rx queue object index. */
> +	uint32_t rix_tag; /**< Index to the tag action. */
> +	uint32_t cnt;
> +};
> +
> +/* Sample action resource structure. */
> +struct mlx5_flow_dv_sample_resource {
> +	ILIST_ENTRY(uint32_t)next; /**< Pointer to next element. */
> +	rte_atomic32_t refcnt; /**< Reference counter. */
> +	void *verbs_action; /**< Verbs sample action object. */
> +	uint8_t ft_type; /** Flow Table Type */
> +	uint32_t ft_id; /** Flow Table Level */
> +	void *normal_path_tbl; /** Flow Table pointer */
> +	void *default_miss; /** default_miss dr_action. */
> +	uint32_t ratio;   /** Sample Ratio */
> +	struct mlx5_flow_sub_actions_idx sample_idx;
> +	/**< Action index resources. */
> +	struct mlx5_flow_sub_actions_list sample_act;
> +	/**< Action resources. */
> +};
> +
>  /* Verbs specification header. */
>  struct ibv_spec_header {
>  	enum ibv_flow_spec_type type;
> @@ -526,6 +559,8 @@ struct mlx5_flow_handle_dv {
>  	/**< Index to push VLAN action resource in cache. */
>  	uint32_t rix_tag;
>  	/**< Index to the tag action. */
> +	uint32_t rix_sample;
> +	/**< Index to sample action resource in cache. */
>  } __rte_packed;
>=20
>  /** Device flow handle structure: used both for creating & destroying. *=
/
> @@ -589,6 +624,8 @@ struct mlx5_flow_dv_workspace {
>  	/**< Pointer to the jump action resource. */
>  	struct mlx5_flow_dv_match_params value;
>  	/**< Holds the value that the packet is compared to. */
> +	struct mlx5_flow_dv_sample_resource *sample_res;
> +	/**< Pointer to the sample action resource. */
>  };
>=20
>  /*
> --
> 1.8.3.1