DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH 0/5] Add the E-Switch mirroring and jump supports
@ 2021-01-10 11:06 Jiawei Wang
  2021-01-10 11:06 ` [dpdk-dev] [PATCH 1/5] common/mlx5: query register c preserve capability via DevX Jiawei Wang
                   ` (5 more replies)
  0 siblings, 6 replies; 14+ messages in thread
From: Jiawei Wang @ 2021-01-10 11:06 UTC (permalink / raw)
  To: viacheslavo, matan, orika; +Cc: dev, rasland

MLX5 E-Switch mirroring is implemented as multiple destination array in
one steering table. The array currently supports only port ID as
destination actions.

This patchset adds the below supports for MLX5 PMD driver:
  - Supports the metadata register Cx preserve capability query.
  - Supports the jump action support as one of destination of array.
  - Supports the modify action only impact on the one of destination.

The examples for the E-Switch flow use case and result as below:
    set sample_actions 0 port_id id 1 / end
    flow create 0 ingress transfer pattern eth / end actions sample ratio 1 index 0 / jump group 1 / end
    flow create 1 ingress transfer group 1 pattern eth / end actions set_mac_dst mac_addr 00:aa:bb:cc:dd:ee / port_id id 2 / end

The flow results all the matched ingress packets are mirrored
to port id 1 and go to group 1. In the group 1, packets are modified
with the destination mac and sent to port id 2.

Jiawei Wang (5):
  common/mlx5: query register c preserve capability via DevX
  net/mlx5: support E-Switch mirroring and jump in one flow
  net/mlx5: extend the skip scale flag
  net/mlx5: supports modify one port in E-Switch mirroring
  doc: update the advanced E-switch mirroring supports

 doc/guides/nics/mlx5.rst               |   2 +
 doc/guides/rel_notes/release_21_02.rst |   6 +
 drivers/common/mlx5/mlx5_devx_cmds.c   |   2 +
 drivers/common/mlx5/mlx5_devx_cmds.h   |   1 +
 drivers/common/mlx5/mlx5_prm.h         |   4 +-
 drivers/net/mlx5/mlx5_flow.c           | 203 +++++++++++++++++++++++----------
 drivers/net/mlx5/mlx5_flow.h           |  23 +++-
 drivers/net/mlx5/mlx5_flow_dv.c        |  92 +++++++++------
 8 files changed, 234 insertions(+), 99 deletions(-)

-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [dpdk-dev] [PATCH 1/5] common/mlx5: query register c preserve capability via DevX
  2021-01-10 11:06 [dpdk-dev] [PATCH 0/5] Add the E-Switch mirroring and jump supports Jiawei Wang
@ 2021-01-10 11:06 ` Jiawei Wang
  2021-01-10 11:06 ` [dpdk-dev] [PATCH 2/5] net/mlx5: support E-Switch mirroring and jump in one flow Jiawei Wang
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 14+ messages in thread
From: Jiawei Wang @ 2021-01-10 11:06 UTC (permalink / raw)
  To: viacheslavo, matan, orika; +Cc: dev, rasland

Update function mlx5_devx_cmd_query_hca_attr() to add the
reg_c_preserve bit query.

The stored metadata in register C may be lost in NIC Tx and
FDB egress while doing one one of the following operations:
 - packet encapsulation.
 - packet mirroring (multiple processing paths).
 - packet sampling (using Flow Sampler).

If the reg_c_preserve bit is set to 1, then the above
limitation is obsolete, the all metadata registers Cx
preserve their values even through the operations mentioned
above.

Signed-off-by: Jiawei Wang <jiaweiw@nvidia.com>
---
 drivers/common/mlx5/mlx5_devx_cmds.c | 2 ++
 drivers/common/mlx5/mlx5_devx_cmds.h | 1 +
 drivers/common/mlx5/mlx5_prm.h       | 4 +++-
 3 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/common/mlx5/mlx5_devx_cmds.c b/drivers/common/mlx5/mlx5_devx_cmds.c
index 12f51a9..b2d8a9e 100644
--- a/drivers/common/mlx5/mlx5_devx_cmds.c
+++ b/drivers/common/mlx5/mlx5_devx_cmds.c
@@ -728,6 +728,8 @@ struct mlx5_devx_obj *
 	attr->log_max_pd = MLX5_GET(cmd_hca_cap, hcattr, log_max_pd);
 	attr->log_max_srq = MLX5_GET(cmd_hca_cap, hcattr, log_max_srq);
 	attr->log_max_srq_sz = MLX5_GET(cmd_hca_cap, hcattr, log_max_srq_sz);
+	attr->reg_c_preserve =
+		MLX5_GET(cmd_hca_cap, hcattr, reg_c_preserve);
 	if (attr->qos.sup) {
 		MLX5_SET(query_hca_cap_in, in, op_mod,
 			 MLX5_GET_HCA_CAP_OP_MOD_QOS_CAP |
diff --git a/drivers/common/mlx5/mlx5_devx_cmds.h b/drivers/common/mlx5/mlx5_devx_cmds.h
index b335b7c..3b243b6 100644
--- a/drivers/common/mlx5/mlx5_devx_cmds.h
+++ b/drivers/common/mlx5/mlx5_devx_cmds.h
@@ -114,6 +114,7 @@ struct mlx5_hca_attr {
 	uint32_t scatter_fcs_w_decap_disable:1;
 	uint32_t flow_hit_aso:1; /* General obj type FLOW_HIT_ASO supported. */
 	uint32_t regex:1;
+	uint32_t reg_c_preserve:1;
 	uint32_t regexp_num_of_engines;
 	uint32_t log_max_ft_sampler_num:8;
 	struct mlx5_hca_qos_attr qos;
diff --git a/drivers/common/mlx5/mlx5_prm.h b/drivers/common/mlx5/mlx5_prm.h
index 8c9b53c..53dab91 100644
--- a/drivers/common/mlx5/mlx5_prm.h
+++ b/drivers/common/mlx5/mlx5_prm.h
@@ -1130,7 +1130,9 @@ struct mlx5_ifc_cmd_hca_cap_bits {
 	u8 regexp[0x1];
 	u8 reserved_at_a1[0x3];
 	u8 regexp_num_of_engines[0x4];
-	u8 reserved_at_a8[0x3];
+	u8 reserved_at_a8[0x1];
+	u8 reg_c_preserve[0x1];
+	u8 reserved_at_aa[0x1];
 	u8 log_max_srq[0x5];
 	u8 reserved_at_b0[0x3];
 	u8 regexp_log_crspace_size[0x5];
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [dpdk-dev] [PATCH 2/5] net/mlx5: support E-Switch mirroring and jump in one flow
  2021-01-10 11:06 [dpdk-dev] [PATCH 0/5] Add the E-Switch mirroring and jump supports Jiawei Wang
  2021-01-10 11:06 ` [dpdk-dev] [PATCH 1/5] common/mlx5: query register c preserve capability via DevX Jiawei Wang
@ 2021-01-10 11:06 ` Jiawei Wang
  2021-01-10 11:06 ` [dpdk-dev] [PATCH 3/5] net/mlx5: extend the skip scale flag Jiawei Wang
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 14+ messages in thread
From: Jiawei Wang @ 2021-01-10 11:06 UTC (permalink / raw)
  To: viacheslavo, matan, orika; +Cc: dev, rasland

mlx5 E-Switch mirroring is implemented as multiple destination array in
one steering table. The array currently supports only port ID as
destination actions.

This patch adds the jump action support to the array as one of
destination.
The packets can be mirrored to the port and jump to next table in the
same
destination array allowing to continue handling in the new table.

For example:
    set sample_actions 0 port_id id 1 / end
    flow create 0 ingress transfer pattern eth / end actions
    sample ratio 1 index 0 / jump group 1 / end
    flow create 1 ingress transfer group 1 pattern eth / end actions
    set_mac_dst mac_addr 00:aa:bb:cc:dd:ee / port_id id 2 / end

The flow results all the matched ingress packets are mirrored
to port id 1 and go to group 1. In the group 1, packets are modified
with the destination mac and sent to port id 2.

Signed-off-by: Jiawei Wang <jiaweiw@nvidia.com>
---
 drivers/net/mlx5/mlx5_flow.c    | 36 ++++++++++--------
 drivers/net/mlx5/mlx5_flow.h    |  2 +
 drivers/net/mlx5/mlx5_flow_dv.c | 81 +++++++++++++++++++++++++++++------------
 3 files changed, 80 insertions(+), 39 deletions(-)

diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index 2a4073c..217090a 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -4503,7 +4503,6 @@ struct mlx5_hlist_entry *
 {
 	const struct rte_flow_action_sample *sample;
 	int actions_n = 0;
-	int jump_flag = 0;
 	uint32_t ratio = 0;
 	int sub_type = 0;
 	int flag = 0;
@@ -4518,8 +4517,6 @@ struct mlx5_hlist_entry *
 		if (actions->type == RTE_FLOW_ACTION_TYPE_QUEUE ||
 		    actions->type == RTE_FLOW_ACTION_TYPE_RSS)
 			*qrss_action_pos = actions_n;
-		if (actions->type == RTE_FLOW_ACTION_TYPE_JUMP)
-			jump_flag = 1;
 		if (actions->type == RTE_FLOW_ACTION_TYPE_SAMPLE) {
 			sample = actions->conf;
 			ratio = sample->ratio;
@@ -4530,10 +4527,10 @@ struct mlx5_hlist_entry *
 	}
 	if (flag && action == RTE_FLOW_ACTION_TYPE_SAMPLE && attr->transfer) {
 		if (ratio == 1) {
-			/* JUMP Action not support for Mirroring;
-			 * Mirroring support multi-destination;
+			/* FDB mirroring uses the destination array to implement
+			 * instead of FLOW_SAMPLER object.
 			 */
-			if (!jump_flag && sub_type != RTE_FLOW_ACTION_TYPE_END)
+			if (sub_type != RTE_FLOW_ACTION_TYPE_END)
 				flag = 0;
 		}
 	}
@@ -4554,8 +4551,8 @@ struct mlx5_hlist_entry *
  *
  * @param dev
  *   Pointer to Ethernet device.
- * @param[in] fdb_tx
- *   FDB egress flow flag.
+ * @param[in] add_tag
+ *   Add extra tag action flag.
  * @param[out] sfx_items
  *   Suffix flow match items (list terminated by the END pattern item).
  * @param[in] actions
@@ -4579,7 +4576,7 @@ struct mlx5_hlist_entry *
  */
 static int
 flow_sample_split_prep(struct rte_eth_dev *dev,
-		       uint32_t fdb_tx,
+		       int add_tag,
 		       struct rte_flow_item sfx_items[],
 		       const struct rte_flow_action actions[],
 		       struct rte_flow_action actions_sfx[],
@@ -4602,7 +4599,11 @@ struct mlx5_hlist_entry *
 					  RTE_FLOW_ERROR_TYPE_ACTION,
 					  NULL, "invalid position of sample "
 					  "action in list");
-	if (!fdb_tx) {
+	/* For CX5, add an extra tag action for NIC-RX and E-Switch ingress.
+	 * For CX6DX and above, metadata registers Cx preserve their value,
+	 * add an extra tag action for NIC-RX and E-Switch ingress and egress.
+	 */
+	if (add_tag) {
 		/* Prepare the prefix tag action. */
 		set_tag = (void *)(actions_pre + actions_n + 1);
 		ret = mlx5_flow_get_reg_id(dev, MLX5_APP_TAG, 0, error);
@@ -4653,8 +4654,7 @@ struct mlx5_hlist_entry *
 			memcpy(actions_pre, actions,
 			       sizeof(struct rte_flow_action) * index);
 	}
-	/* Add the extra tag action for NIC-RX and E-Switch ingress. */
-	if (!fdb_tx) {
+	if (add_tag) {
 		actions_pre[index++] =
 			(struct rte_flow_action){
 			.type = (enum rte_flow_action_type)
@@ -5067,6 +5067,7 @@ struct mlx5_hlist_entry *
 	int actions_n = 0;
 	int sample_action_pos;
 	int qrss_action_pos;
+	int add_tag = 0;
 	int ret = 0;
 
 	if (priv->sampler_en)
@@ -5088,16 +5089,21 @@ struct mlx5_hlist_entry *
 						  "sample flow");
 		/* The representor_id is -1 for uplink. */
 		fdb_tx = (attr->transfer && priv->representor_id != -1);
-		if (!fdb_tx)
+		/*
+		 * When reg_c_preserve is set, metadata registers Cx preserve
+		 * their value even through packet duplication.
+		 */
+		add_tag = (!fdb_tx || priv->config.hca_attr.reg_c_preserve);
+		if (add_tag)
 			sfx_items = (struct rte_flow_item *)((char *)sfx_actions
 					+ act_size);
 		pre_actions = sfx_actions + actions_n;
-		tag_id = flow_sample_split_prep(dev, fdb_tx, sfx_items,
+		tag_id = flow_sample_split_prep(dev, add_tag, sfx_items,
 						actions, sfx_actions,
 						pre_actions, actions_n,
 						sample_action_pos,
 						qrss_action_pos, error);
-		if (tag_id < 0 || (!fdb_tx && !tag_id)) {
+		if (tag_id < 0 || (add_tag && !tag_id)) {
 			ret = -rte_errno;
 			goto exit;
 		}
diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h
index ee85c9d..18d5cfc 100644
--- a/drivers/net/mlx5/mlx5_flow.h
+++ b/drivers/net/mlx5/mlx5_flow.h
@@ -552,6 +552,7 @@ struct mlx5_flow_sub_actions_list {
 	void *dr_cnt_action;
 	void *dr_port_id_action;
 	void *dr_encap_action;
+	void *dr_jump_action;
 };
 
 /* Sample sub-actions resource list. */
@@ -561,6 +562,7 @@ struct mlx5_flow_sub_actions_idx {
 	uint32_t cnt;
 	uint32_t rix_port_id_action; /**< Index to port ID action resource. */
 	uint32_t rix_encap_decap; /**< Index to encap/decap resource. */
+	uint32_t rix_jump; /**< Index to the jump action resource. */
 };
 
 /* Sample action resource structure. */
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index e4736ee..d82d22e 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -76,7 +76,7 @@
 
 static int
 flow_dv_encap_decap_resource_release(struct rte_eth_dev *dev,
-				      uint32_t encap_decap_idx);
+				     uint32_t encap_decap_idx);
 
 static int
 flow_dv_port_id_action_resource_release(struct rte_eth_dev *dev,
@@ -84,6 +84,10 @@
 static void
 flow_dv_shared_rss_action_release(struct rte_eth_dev *dev, uint32_t srss);
 
+static int
+flow_dv_jump_tbl_resource_release(struct rte_eth_dev *dev,
+				  uint32_t rix_jump);
+
 /**
  * Initialize flow attributes structure according to flow items' types.
  *
@@ -3596,7 +3600,7 @@ struct mlx5_cache_entry *
 					    (dev, &res, dev_flow, error);
 }
 
-static int fdb_mirror;
+static int fdb_mirror_limit;
 
 /**
  * Validate the modify-header actions.
@@ -3625,7 +3629,7 @@ struct mlx5_cache_entry *
 					  RTE_FLOW_ERROR_TYPE_ACTION, NULL,
 					  "can't have encap action before"
 					  " modify action");
-	if ((action_flags & MLX5_FLOW_ACTION_SAMPLE) && fdb_mirror)
+	if ((action_flags & MLX5_FLOW_ACTION_SAMPLE) && fdb_mirror_limit)
 		return rte_flow_error_set(error, EINVAL,
 					  RTE_FLOW_ERROR_TYPE_ACTION, NULL,
 					  "can't support sample action before"
@@ -3961,12 +3965,6 @@ struct mlx5_cache_entry *
 		return rte_flow_error_set(error, ENOTSUP,
 					  RTE_FLOW_ERROR_TYPE_ACTION, NULL,
 					  "jump with meter not support");
-	if ((action_flags & MLX5_FLOW_ACTION_SAMPLE) && fdb_mirror)
-		return rte_flow_error_set(error, EINVAL,
-					  RTE_FLOW_ERROR_TYPE_ACTION, NULL,
-					  "E-Switch mirroring can't support"
-					  " Sample action and jump action in"
-					  " same flow now");
 	if (!action->conf)
 		return rte_flow_error_set(error, EINVAL,
 					  RTE_FLOW_ERROR_TYPE_ACTION_CONF,
@@ -4366,8 +4364,8 @@ struct mlx5_hlist_entry *
 	uint16_t queue_index = 0xFFFF;
 	int actions_n = 0;
 	int ret;
-	fdb_mirror = 0;
 
+	fdb_mirror_limit = 0;
 	if (!sample)
 		return rte_flow_error_set(error, EINVAL,
 					  RTE_FLOW_ERROR_TYPE_ACTION, action,
@@ -4484,7 +4482,7 @@ struct mlx5_hlist_entry *
 						  "E-Switch doesn't support "
 						  "any optional action "
 						  "for sampling");
-		fdb_mirror = 1;
+		fdb_mirror_limit = 1;
 		if (sub_action_flags & MLX5_FLOW_ACTION_QUEUE)
 			return rte_flow_error_set(error, ENOTSUP,
 						  RTE_FLOW_ERROR_TYPE_ACTION,
@@ -8706,6 +8704,10 @@ struct mlx5_hlist_entry *
 		flow_dv_counter_free(dev, act_res->cnt);
 		act_res->cnt = 0;
 	}
+	if (act_res->rix_jump) {
+		flow_dv_jump_tbl_resource_release(dev, act_res->rix_jump);
+		act_res->rix_jump = 0;
+	}
 }
 
 int
@@ -8918,6 +8920,7 @@ struct mlx5_cache_entry *
 	struct mlx5dv_dr_domain *domain;
 	uint32_t idx = 0, res_idx = 0;
 	struct rte_flow_error *error = ctx->error;
+	uint64_t action_flags;
 	int ret;
 
 	/* Register new destination array resource. */
@@ -8951,19 +8954,31 @@ struct mlx5_cache_entry *
 		}
 		dest_attr[idx]->type = MLX5DV_DR_ACTION_DEST;
 		sample_act = &resource->sample_act[idx];
-		if (sample_act->action_flags == MLX5_FLOW_ACTION_QUEUE) {
+		action_flags = sample_act->action_flags;
+		switch (action_flags) {
+		case MLX5_FLOW_ACTION_QUEUE:
 			dest_attr[idx]->dest = sample_act->dr_queue_action;
-		} else if (sample_act->action_flags ==
-			  (MLX5_FLOW_ACTION_PORT_ID | MLX5_FLOW_ACTION_ENCAP)) {
+			break;
+		case (MLX5_FLOW_ACTION_PORT_ID | MLX5_FLOW_ACTION_ENCAP):
 			dest_attr[idx]->type = MLX5DV_DR_ACTION_DEST_REFORMAT;
 			dest_attr[idx]->dest_reformat = &dest_reformat[idx];
 			dest_attr[idx]->dest_reformat->reformat =
 					sample_act->dr_encap_action;
 			dest_attr[idx]->dest_reformat->dest =
 					sample_act->dr_port_id_action;
-		} else if (sample_act->action_flags ==
-			   MLX5_FLOW_ACTION_PORT_ID) {
+			break;
+		case MLX5_FLOW_ACTION_PORT_ID:
 			dest_attr[idx]->dest = sample_act->dr_port_id_action;
+			break;
+		case MLX5_FLOW_ACTION_JUMP:
+			dest_attr[idx]->dest = sample_act->dr_jump_action;
+			break;
+		default:
+			rte_flow_error_set(error, EINVAL,
+					   RTE_FLOW_ERROR_TYPE_ACTION,
+					   NULL,
+					   "unsupported actions type");
+			goto error;
 		}
 	}
 	/* create a dest array actioin */
@@ -9000,6 +9015,10 @@ struct mlx5_cache_entry *
 			!flow_dv_port_id_action_resource_release(dev,
 				act_res->rix_port_id_action))
 			act_res->rix_port_id_action = 0;
+		if (act_res->rix_jump &&
+			!flow_dv_jump_tbl_resource_release(dev,
+				act_res->rix_jump))
+			act_res->rix_jump = 0;
 		if (dest_attr[idx])
 			mlx5_free(dest_attr[idx]);
 	}
@@ -9336,6 +9355,14 @@ struct mlx5_cache_entry *
 			sample_act->dr_port_id_action =
 				dev_flow->dv.port_id_action->action;
 		}
+		if (sample_act->action_flags & MLX5_FLOW_ACTION_JUMP) {
+			normal_idx++;
+			mdest_res->sample_idx[dest_index].rix_jump =
+				dev_flow->handle->rix_jump;
+			sample_act->dr_jump_action =
+				dev_flow->dv.jump->action;
+			dev_flow->handle->rix_jump = 0;
+		}
 		sample_act->actions_num = normal_idx;
 		/* update sample action resource into first index of array */
 		mdest_res->ft_type = res->ft_type;
@@ -10094,6 +10121,8 @@ struct mlx5_cache_entry *
 					dev_flow->dv.jump->action;
 			action_flags |= MLX5_FLOW_ACTION_JUMP;
 			dev_flow->handle->fate_action = MLX5_FLOW_FATE_JUMP;
+			sample_act->action_flags |= MLX5_FLOW_ACTION_JUMP;
+			num_of_dest++;
 			break;
 		case RTE_FLOW_ACTION_TYPE_SET_MAC_SRC:
 		case RTE_FLOW_ACTION_TYPE_SET_MAC_DST:
@@ -10316,7 +10345,8 @@ struct mlx5_cache_entry *
 	 * So need remove the original these actions in the flow and only
 	 * use the sample action instead of.
 	 */
-	if (num_of_dest > 1 && sample_act->dr_port_id_action) {
+	if (num_of_dest > 1 &&
+	    (sample_act->dr_port_id_action || sample_act->dr_jump_action)) {
 		int i;
 		void *temp_actions[MLX5_DV_MAX_NUMBER_OF_ACTIONS] = {0};
 
@@ -10326,6 +10356,9 @@ struct mlx5_cache_entry *
 				dev_flow->dv.actions[i]) ||
 				(sample_act->dr_port_id_action &&
 				sample_act->dr_port_id_action ==
+				dev_flow->dv.actions[i]) ||
+				(sample_act->dr_jump_action &&
+				sample_act->dr_jump_action ==
 				dev_flow->dv.actions[i]))
 				continue;
 			temp_actions[tmp_actions_n++] = dev_flow->dv.actions[i];
@@ -10924,21 +10957,21 @@ struct mlx5_cache_entry *
  *
  * @param dev
  *   Pointer to Ethernet device.
- * @param handle
- *   Pointer to mlx5_flow_handle.
+ * @param rix_jump
+ *   Index to the jump action resource.
  *
  * @return
  *   1 while a reference on it exists, 0 when freed.
  */
 static int
 flow_dv_jump_tbl_resource_release(struct rte_eth_dev *dev,
-				  struct mlx5_flow_handle *handle)
+				  uint32_t rix_jump)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
 	struct mlx5_flow_tbl_data_entry *tbl_data;
 
 	tbl_data = mlx5_ipool_get(priv->sh->ipool[MLX5_IPOOL_JUMP],
-			     handle->rix_jump);
+				  rix_jump);
 	if (!tbl_data)
 		return 0;
 	return flow_dv_tbl_resource_release(MLX5_SH(dev), &tbl_data->tbl);
@@ -11092,7 +11125,7 @@ struct mlx5_cache_entry *
 		mlx5_hrxq_release(dev, handle->rix_hrxq);
 		break;
 	case MLX5_FLOW_FATE_JUMP:
-		flow_dv_jump_tbl_resource_release(dev, handle);
+		flow_dv_jump_tbl_resource_release(dev, handle->rix_jump);
 		break;
 	case MLX5_FLOW_FATE_PORT_ID:
 		flow_dv_port_id_action_resource_release(dev,
@@ -11188,8 +11221,8 @@ struct mlx5_cache_entry *
  *
  * @param dev
  *   Pointer to Ethernet device.
- * @param handle
- *   Pointer to mlx5_flow_handle.
+ * @param port_id
+ *   Index to port ID action resource.
  *
  * @return
  *   1 while a reference on it exists, 0 when freed.
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [dpdk-dev] [PATCH 3/5] net/mlx5: extend the skip scale flag
  2021-01-10 11:06 [dpdk-dev] [PATCH 0/5] Add the E-Switch mirroring and jump supports Jiawei Wang
  2021-01-10 11:06 ` [dpdk-dev] [PATCH 1/5] common/mlx5: query register c preserve capability via DevX Jiawei Wang
  2021-01-10 11:06 ` [dpdk-dev] [PATCH 2/5] net/mlx5: support E-Switch mirroring and jump in one flow Jiawei Wang
@ 2021-01-10 11:06 ` Jiawei Wang
  2021-01-10 11:06 ` [dpdk-dev] [PATCH 4/5] net/mlx5: supports modify one port in E-Switch mirroring Jiawei Wang
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 14+ messages in thread
From: Jiawei Wang @ 2021-01-10 11:06 UTC (permalink / raw)
  To: viacheslavo, matan, orika; +Cc: dev, rasland

The sampling feature introduces the scale flow group with factor,
then the scaled table value can be used for the normal path table
due to this table be created implicitly.

But if the input group value already be scaled, for example the
group value of sampling suffix flow, then use 'skip_scale" flag
to skip the scale twice in the translation action.

Consider the flow with jump action and this jump action could be
created implicitly, PMD may only scale the original flow group
value or scale the jump group value or both, so extend the
'skip_scale' flag to two bits:
If bit0 of 'skip_scale' flag is set to 1, then skip the scale the
original flow group;
If bit1 of 'skip_scale' flag is set to 1, then skip the scale the
jump flow group.

Signed-off-by: Jiawei Wang <jiaweiw@nvidia.com>
---
 drivers/net/mlx5/mlx5_flow.c    |  2 +-
 drivers/net/mlx5/mlx5_flow.h    | 21 ++++++++++++++++++---
 drivers/net/mlx5/mlx5_flow_dv.c |  9 +++++++--
 3 files changed, 26 insertions(+), 6 deletions(-)

diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index 217090a..055474b 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -5133,7 +5133,7 @@ struct mlx5_hlist_entry *
 		/* Suffix group level already be scaled with factor, set
 		 * skip_scale to 1 to avoid scale again in translation.
 		 */
-		flow_split_info->skip_scale = 1;
+		flow_split_info->skip_scale = 1 << MLX5_SCALE_FLOW_GROUP_BIT;
 #endif
 	}
 	/* Add the suffix subflow. */
diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h
index 18d5cfc..a054ff3 100644
--- a/drivers/net/mlx5/mlx5_flow.h
+++ b/drivers/net/mlx5/mlx5_flow.h
@@ -755,6 +755,9 @@ struct mlx5_flow_verbs_workspace {
 };
 #endif /* HAVE_INFINIBAND_VERBS_H */
 
+#define MLX5_SCALE_FLOW_GROUP_BIT 0
+#define MLX5_SCALE_JUMP_FLOW_GROUP_BIT 1
+
 /** Maximal number of device sub-flows supported. */
 #define MLX5_NUM_MAX_DEV_FLOWS 32
 
@@ -768,8 +771,20 @@ struct mlx5_flow {
 	/**< Bit-fields of detected actions, see MLX5_FLOW_ACTION_*. */
 	bool external; /**< true if the flow is created external to PMD. */
 	uint8_t ingress:1; /**< 1 if the flow is ingress. */
-	uint8_t skip_scale:1;
-	/**< 1 if skip the scale the table with factor. */
+	uint8_t skip_scale:2;
+	/**
+	 * Each Bit be set to 1 if Skip the scale the flow group with factor.
+	 * If bit0 be set to 1, then skip the scale the original flow group;
+	 * If bit1 be set to 1, then skip the scale the jump flow group if
+	 * having jump action.
+	 * 00: Enable scale in a flow, default value.
+	 * 01: Skip scale the flow group with factor, enable scale the group
+	 * of jump action.
+	 * 10: Enable scale the group with factor, skip scale the group of
+	 * jump action.
+	 * 11: Skip scale the table with factor both for flow group and jump
+	 * group.
+	 */
 	union {
 #if defined(HAVE_IBV_FLOW_DV_SUPPORT) || !defined(HAVE_INFINIBAND_VERBS_H)
 		struct mlx5_flow_dv_workspace dv;
@@ -1238,7 +1253,7 @@ struct flow_grp_info {
 	uint64_t fdb_def_rule:1;
 	/* force standard group translation */
 	uint64_t std_tbl_fix:1;
-	uint64_t skip_scale:1;
+	uint64_t skip_scale:2;
 };
 
 static inline bool
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index d82d22e..63569ad 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -9732,7 +9732,8 @@ struct mlx5_cache_entry *
 		.external = !!dev_flow->external,
 		.transfer = !!attr->transfer,
 		.fdb_def_rule = !!priv->fdb_def_rule,
-		.skip_scale = !!dev_flow->skip_scale,
+		.skip_scale = dev_flow->skip_scale &
+			(1 << MLX5_SCALE_FLOW_GROUP_BIT),
 	};
 
 	if (!wks)
@@ -10090,7 +10091,11 @@ struct mlx5_cache_entry *
 			jump_group = ((const struct rte_flow_action_jump *)
 							action->conf)->group;
 			grp_info.std_tbl_fix = 0;
-			grp_info.skip_scale = 0;
+			if (dev_flow->skip_scale &
+				(1 << MLX5_SCALE_JUMP_FLOW_GROUP_BIT))
+				grp_info.skip_scale = 1;
+			else
+				grp_info.skip_scale = 0;
 			ret = mlx5_flow_group_to_table(dev, tunnel,
 						       jump_group,
 						       &table,
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [dpdk-dev] [PATCH 4/5] net/mlx5: supports modify one port in E-Switch mirroring
  2021-01-10 11:06 [dpdk-dev] [PATCH 0/5] Add the E-Switch mirroring and jump supports Jiawei Wang
                   ` (2 preceding siblings ...)
  2021-01-10 11:06 ` [dpdk-dev] [PATCH 3/5] net/mlx5: extend the skip scale flag Jiawei Wang
@ 2021-01-10 11:06 ` Jiawei Wang
  2021-01-10 11:06 ` [dpdk-dev] [PATCH 5/5] doc: update the advanced E-switch mirroring supports Jiawei Wang
  2021-01-12 10:29 ` [dpdk-dev] [PATCH v2 0/5] Add the E-Switch mirroring and jump supports Jiawei Wang
  5 siblings, 0 replies; 14+ messages in thread
From: Jiawei Wang @ 2021-01-10 11:06 UTC (permalink / raw)
  To: viacheslavo, matan, orika; +Cc: dev, rasland

While there's the modify action and sample action with ratio=1
in the E-Switch flow, and modify action is after the sample
action, means that the modify should only impact on after sample.
MLX5 PMD will monitor the above case and split the E-Switch flow
into two sub flows, smiliar as sample flow did before:

 - the prefix sub flow with all actions preceding the sample and the
   sample action itself, also append the new jump action after sample
   in the prefix sub flow;
 - the suffix sub flow with the modify action and other actions
   following the sample action.

The flow split as below:

Original flow: items / actions pre / sample / modify / actions sfx
    prefix sub flow -
    items / actions pre / set_tag action / sample / jump
    suffix sub flow -
    tag_item / modify / actions sfx

Signed-off-by: Jiawei Wang <jiaweiw@nvidia.com>
---
 drivers/net/mlx5/mlx5_flow.c    | 175 ++++++++++++++++++++++++++++------------
 drivers/net/mlx5/mlx5_flow_dv.c |  10 ---
 2 files changed, 123 insertions(+), 62 deletions(-)

diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index 055474b..df79318 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -4490,6 +4490,8 @@ struct mlx5_hlist_entry *
  *   Pointer to the position of the matched action if exists, otherwise is -1.
  * @param[out] qrss_action_pos
  *   Pointer to the position of the Queue/RSS action if exists, otherwise is -1.
+ * @param[out] modify_after_mirror
+ *   Pointer to the flag of modify action after FDB mirroring.
  *
  * @return
  *   > 0 the total number of actions.
@@ -4499,13 +4501,15 @@ struct mlx5_hlist_entry *
 flow_check_match_action(const struct rte_flow_action actions[],
 			const struct rte_flow_attr *attr,
 			enum rte_flow_action_type action,
-			int *match_action_pos, int *qrss_action_pos)
+			int *match_action_pos, int *qrss_action_pos,
+			int *modify_after_mirror)
 {
 	const struct rte_flow_action_sample *sample;
 	int actions_n = 0;
 	uint32_t ratio = 0;
 	int sub_type = 0;
 	int flag = 0;
+	int fdb_mirror = 0;
 
 	*match_action_pos = -1;
 	*qrss_action_pos = -1;
@@ -4514,25 +4518,53 @@ struct mlx5_hlist_entry *
 			flag = 1;
 			*match_action_pos = actions_n;
 		}
-		if (actions->type == RTE_FLOW_ACTION_TYPE_QUEUE ||
-		    actions->type == RTE_FLOW_ACTION_TYPE_RSS)
+		switch (actions->type) {
+		case RTE_FLOW_ACTION_TYPE_QUEUE:
+		case RTE_FLOW_ACTION_TYPE_RSS:
 			*qrss_action_pos = actions_n;
-		if (actions->type == RTE_FLOW_ACTION_TYPE_SAMPLE) {
+			break;
+		case RTE_FLOW_ACTION_TYPE_SAMPLE:
 			sample = actions->conf;
 			ratio = sample->ratio;
 			sub_type = ((const struct rte_flow_action *)
 					(sample->actions))->type;
+			if (ratio == 1 && attr->transfer)
+				fdb_mirror = 1;
+			break;
+		case RTE_FLOW_ACTION_TYPE_SET_MAC_SRC:
+		case RTE_FLOW_ACTION_TYPE_SET_MAC_DST:
+		case RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC:
+		case RTE_FLOW_ACTION_TYPE_SET_IPV4_DST:
+		case RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC:
+		case RTE_FLOW_ACTION_TYPE_SET_IPV6_DST:
+		case RTE_FLOW_ACTION_TYPE_SET_TP_SRC:
+		case RTE_FLOW_ACTION_TYPE_SET_TP_DST:
+		case RTE_FLOW_ACTION_TYPE_DEC_TTL:
+		case RTE_FLOW_ACTION_TYPE_SET_TTL:
+		case RTE_FLOW_ACTION_TYPE_INC_TCP_SEQ:
+		case RTE_FLOW_ACTION_TYPE_DEC_TCP_SEQ:
+		case RTE_FLOW_ACTION_TYPE_INC_TCP_ACK:
+		case RTE_FLOW_ACTION_TYPE_DEC_TCP_ACK:
+		case RTE_FLOW_ACTION_TYPE_SET_IPV4_DSCP:
+		case RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP:
+		case RTE_FLOW_ACTION_TYPE_FLAG:
+		case RTE_FLOW_ACTION_TYPE_MARK:
+		case RTE_FLOW_ACTION_TYPE_SET_META:
+		case RTE_FLOW_ACTION_TYPE_SET_TAG:
+			if (fdb_mirror)
+				*modify_after_mirror = 1;
+			break;
+		default:
+			break;
 		}
 		actions_n++;
 	}
-	if (flag && action == RTE_FLOW_ACTION_TYPE_SAMPLE && attr->transfer) {
-		if (ratio == 1) {
-			/* FDB mirroring uses the destination array to implement
-			 * instead of FLOW_SAMPLER object.
-			 */
-			if (sub_type != RTE_FLOW_ACTION_TYPE_END)
-				flag = 0;
-		}
+	if (flag && fdb_mirror && !*modify_after_mirror) {
+		/* FDB mirroring uses the destination array to implement
+		 * instead of FLOW_SAMPLER object.
+		 */
+		if (sub_type != RTE_FLOW_ACTION_TYPE_END)
+			flag = 0;
 	}
 	/* Count RTE_FLOW_ACTION_TYPE_END. */
 	return flag ? actions_n + 1 : 0;
@@ -4567,6 +4599,8 @@ struct mlx5_hlist_entry *
  *   The sample action position.
  * @param[in] qrss_action_pos
  *   The Queue/RSS action position.
+ * @param[in] jump_table
+ *   Add extra jump action flag.
  * @param[out] error
  *   Perform verbose error reporting if not NULL.
  *
@@ -4584,14 +4618,17 @@ struct mlx5_hlist_entry *
 		       int actions_n,
 		       int sample_action_pos,
 		       int qrss_action_pos,
+		       int jump_table,
 		       struct rte_flow_error *error)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
 	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_action_jump *jump_action;
 	uint32_t tag_id = 0;
 	int index;
+	int append_index = 0;
 	int ret;
 
 	if (sample_action_pos < 0)
@@ -4599,13 +4636,37 @@ struct mlx5_hlist_entry *
 					  RTE_FLOW_ERROR_TYPE_ACTION,
 					  NULL, "invalid position of sample "
 					  "action in list");
+	/* Prepare the actions for prefix and suffix flow. */
+	if (qrss_action_pos >= 0 && qrss_action_pos < sample_action_pos) {
+		index = qrss_action_pos;
+		/* Put the preceding the Queue/RSS action into prefix flow. */
+		if (index != 0)
+			memcpy(actions_pre, actions,
+			       sizeof(struct rte_flow_action) * index);
+		/* Put others preceding the sample action into prefix flow. */
+		if (sample_action_pos > index + 1)
+			memcpy(actions_pre + index, actions + index + 1,
+			       sizeof(struct rte_flow_action) *
+			       (sample_action_pos - index - 1));
+		index = sample_action_pos - 1;
+		/* Put Queue/RSS action into Suffix flow. */
+		memcpy(actions_sfx, actions + qrss_action_pos,
+		       sizeof(struct rte_flow_action));
+		actions_sfx++;
+	} else {
+		index = sample_action_pos;
+		if (index != 0)
+			memcpy(actions_pre, actions,
+			       sizeof(struct rte_flow_action) * index);
+	}
 	/* For CX5, add an extra tag action for NIC-RX and E-Switch ingress.
 	 * For CX6DX and above, metadata registers Cx preserve their value,
-	 * add an extra tag action for NIC-RX and E-Switch ingress and egress.
+	 * add an extra tag action for NIC-RX and E-Switch Domain.
 	 */
 	if (add_tag) {
 		/* Prepare the prefix tag action. */
-		set_tag = (void *)(actions_pre + actions_n + 1);
+		append_index++;
+		set_tag = (void *)(actions_pre + actions_n + append_index);
 		ret = mlx5_flow_get_reg_id(dev, MLX5_APP_TAG, 0, error);
 		if (ret < 0)
 			return ret;
@@ -4630,31 +4691,7 @@ struct mlx5_hlist_entry *
 			.type = (enum rte_flow_item_type)
 				RTE_FLOW_ITEM_TYPE_END,
 		};
-	}
-	/* Prepare the actions for prefix and suffix flow. */
-	if (qrss_action_pos >= 0 && qrss_action_pos < sample_action_pos) {
-		index = qrss_action_pos;
-		/* Put the preceding the Queue/RSS action into prefix flow. */
-		if (index != 0)
-			memcpy(actions_pre, actions,
-			       sizeof(struct rte_flow_action) * index);
-		/* Put others preceding the sample action into prefix flow. */
-		if (sample_action_pos > index + 1)
-			memcpy(actions_pre + index, actions + index + 1,
-			       sizeof(struct rte_flow_action) *
-			       (sample_action_pos - index - 1));
-		index = sample_action_pos - 1;
-		/* Put Queue/RSS action into Suffix flow. */
-		memcpy(actions_sfx, actions + qrss_action_pos,
-		       sizeof(struct rte_flow_action));
-		actions_sfx++;
-	} else {
-		index = sample_action_pos;
-		if (index != 0)
-			memcpy(actions_pre, actions,
-			       sizeof(struct rte_flow_action) * index);
-	}
-	if (add_tag) {
+		/* Prepare the tag action in prefix subflow. */
 		actions_pre[index++] =
 			(struct rte_flow_action){
 			.type = (enum rte_flow_action_type)
@@ -4665,6 +4702,22 @@ struct mlx5_hlist_entry *
 	memcpy(actions_pre + index, actions + sample_action_pos,
 	       sizeof(struct rte_flow_action));
 	index += 1;
+	/* For the modify action after the sample action in E-Switch mirroring,
+	 * Add the extra jump action in prefix subflow and jump into the next
+	 * table, then do the modify action in the new table.
+	 */
+	if (jump_table) {
+		/* Prepare the prefix jump action. */
+		append_index++;
+		jump_action = (void *)(actions_pre + actions_n + append_index);
+		jump_action->group = jump_table;
+		actions_pre[index++] =
+			(struct rte_flow_action){
+			.type = (enum rte_flow_action_type)
+				RTE_FLOW_ACTION_TYPE_JUMP,
+			.conf = jump_action,
+		};
+	}
 	actions_pre[index] = (struct rte_flow_action){
 		.type = (enum rte_flow_action_type)
 			RTE_FLOW_ACTION_TYPE_END,
@@ -5068,12 +5121,16 @@ struct mlx5_hlist_entry *
 	int sample_action_pos;
 	int qrss_action_pos;
 	int add_tag = 0;
+	int modify_after_mirror = 0;
+	uint16_t jump_table = 0;
+	const uint32_t next_ft_step = 1;
 	int ret = 0;
 
 	if (priv->sampler_en)
 		actions_n = flow_check_match_action(actions, attr,
 					RTE_FLOW_ACTION_TYPE_SAMPLE,
-					&sample_action_pos, &qrss_action_pos);
+					&sample_action_pos, &qrss_action_pos,
+					&modify_after_mirror);
 	if (actions_n) {
 		/* The prefix actions must includes sample, tag, end. */
 		act_size = sizeof(struct rte_flow_action) * (actions_n * 2 + 1)
@@ -5097,16 +5154,23 @@ struct mlx5_hlist_entry *
 		if (add_tag)
 			sfx_items = (struct rte_flow_item *)((char *)sfx_actions
 					+ act_size);
+		if (modify_after_mirror)
+			jump_table = attr->group * MLX5_FLOW_TABLE_FACTOR +
+				     next_ft_step;
 		pre_actions = sfx_actions + actions_n;
 		tag_id = flow_sample_split_prep(dev, add_tag, sfx_items,
 						actions, sfx_actions,
 						pre_actions, actions_n,
 						sample_action_pos,
-						qrss_action_pos, error);
+						qrss_action_pos, jump_table,
+						error);
 		if (tag_id < 0 || (add_tag && !tag_id)) {
 			ret = -rte_errno;
 			goto exit;
 		}
+		if (modify_after_mirror)
+			flow_split_info->skip_scale =
+					1 << MLX5_SCALE_JUMP_FLOW_GROUP_BIT;
 		/* Add the prefix subflow. */
 		ret = flow_create_split_inner(dev, flow, &dev_flow, attr,
 					      items, pre_actions,
@@ -5117,21 +5181,28 @@ struct mlx5_hlist_entry *
 		}
 		dev_flow->handle->split_flow_id = tag_id;
 #ifdef HAVE_IBV_FLOW_DV_SUPPORT
-		/* Set the sfx group attr. */
-		sample_res = (struct mlx5_flow_dv_sample_resource *)
-					dev_flow->dv.sample_res;
-		sfx_tbl = (struct mlx5_flow_tbl_resource *)
-					sample_res->normal_path_tbl;
-		sfx_tbl_data = container_of(sfx_tbl,
-					struct mlx5_flow_tbl_data_entry, tbl);
-		sfx_attr.group = sfx_attr.transfer ?
-					(sfx_tbl_data->table_id - 1) :
-					 sfx_tbl_data->table_id;
+		if (!modify_after_mirror) {
+			/* Set the sfx group attr. */
+			sample_res = (struct mlx5_flow_dv_sample_resource *)
+						dev_flow->dv.sample_res;
+			sfx_tbl = (struct mlx5_flow_tbl_resource *)
+						sample_res->normal_path_tbl;
+			sfx_tbl_data = container_of(sfx_tbl,
+						struct mlx5_flow_tbl_data_entry,
+						tbl);
+			sfx_attr.group = sfx_attr.transfer ?
+						(sfx_tbl_data->table_id - 1) :
+						sfx_tbl_data->table_id;
+		} else {
+			MLX5_ASSERT(attr->transfer);
+			sfx_attr.group = jump_table;
+		}
 		flow_split_info->prefix_layers =
 				flow_get_prefix_layer_flags(dev_flow);
 		flow_split_info->prefix_mark = dev_flow->handle->mark;
 		/* Suffix group level already be scaled with factor, set
-		 * skip_scale to 1 to avoid scale again in translation.
+		 * MLX5_SCALE_FLOW_GROUP_BIT of skip_scale to 1 to avoid scale
+		 * again in translation.
 		 */
 		flow_split_info->skip_scale = 1 << MLX5_SCALE_FLOW_GROUP_BIT;
 #endif
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index 63569ad..4b191fd 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -3600,8 +3600,6 @@ struct mlx5_cache_entry *
 					    (dev, &res, dev_flow, error);
 }
 
-static int fdb_mirror_limit;
-
 /**
  * Validate the modify-header actions.
  *
@@ -3629,12 +3627,6 @@ struct mlx5_cache_entry *
 					  RTE_FLOW_ERROR_TYPE_ACTION, NULL,
 					  "can't have encap action before"
 					  " modify action");
-	if ((action_flags & MLX5_FLOW_ACTION_SAMPLE) && fdb_mirror_limit)
-		return rte_flow_error_set(error, EINVAL,
-					  RTE_FLOW_ERROR_TYPE_ACTION, NULL,
-					  "can't support sample action before"
-					  " modify action for E-Switch"
-					  " mirroring");
 	return 0;
 }
 
@@ -4365,7 +4357,6 @@ struct mlx5_hlist_entry *
 	int actions_n = 0;
 	int ret;
 
-	fdb_mirror_limit = 0;
 	if (!sample)
 		return rte_flow_error_set(error, EINVAL,
 					  RTE_FLOW_ERROR_TYPE_ACTION, action,
@@ -4482,7 +4473,6 @@ struct mlx5_hlist_entry *
 						  "E-Switch doesn't support "
 						  "any optional action "
 						  "for sampling");
-		fdb_mirror_limit = 1;
 		if (sub_action_flags & MLX5_FLOW_ACTION_QUEUE)
 			return rte_flow_error_set(error, ENOTSUP,
 						  RTE_FLOW_ERROR_TYPE_ACTION,
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [dpdk-dev] [PATCH 5/5] doc: update the advanced E-switch mirroring supports
  2021-01-10 11:06 [dpdk-dev] [PATCH 0/5] Add the E-Switch mirroring and jump supports Jiawei Wang
                   ` (3 preceding siblings ...)
  2021-01-10 11:06 ` [dpdk-dev] [PATCH 4/5] net/mlx5: supports modify one port in E-Switch mirroring Jiawei Wang
@ 2021-01-10 11:06 ` Jiawei Wang
  2021-01-12 10:29 ` [dpdk-dev] [PATCH v2 0/5] Add the E-Switch mirroring and jump supports Jiawei Wang
  5 siblings, 0 replies; 14+ messages in thread
From: Jiawei Wang @ 2021-01-10 11:06 UTC (permalink / raw)
  To: viacheslavo, matan, orika; +Cc: dev, rasland

Updates the description in MLX5 PMD and release note.
Adds the new supports for E-switch mirroring and jump in one flow,
and header modify one port in E-switch mirroring.

Signed-off-by: Jiawei Wang <jiaweiw@nvidia.com>
---
 doc/guides/nics/mlx5.rst               | 2 ++
 doc/guides/rel_notes/release_21_02.rst | 6 ++++++
 2 files changed, 8 insertions(+)

diff --git a/doc/guides/nics/mlx5.rst b/doc/guides/nics/mlx5.rst
index 3bda0f8..65922ef 100644
--- a/doc/guides/nics/mlx5.rst
+++ b/doc/guides/nics/mlx5.rst
@@ -98,6 +98,8 @@ Features
 - Hardware LRO.
 - Hairpin.
 - Multiple-thread flow insertion.
+- E-Switch mirroring and jump.
+- E-Switch mirroring and modify.
 
 Limitations
 -----------
diff --git a/doc/guides/rel_notes/release_21_02.rst b/doc/guides/rel_notes/release_21_02.rst
index 638f981..76025aa 100644
--- a/doc/guides/rel_notes/release_21_02.rst
+++ b/doc/guides/rel_notes/release_21_02.rst
@@ -55,6 +55,12 @@ New Features
      Also, make sure to start the actual text at the margin.
      =======================================================
 
+* **Updated Mellanox mlx5 driver.**
+
+  Updated the Mellanox mlx5 driver with new features and improvements, including:
+
+  * - Add support for E-Switch mirroring and jump in one flow.
+  * - Add support for header modify for one port in E-Switch mirroring flow.
 
 Removed Items
 -------------
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [dpdk-dev] [PATCH v2 0/5] Add the E-Switch mirroring and jump supports
  2021-01-10 11:06 [dpdk-dev] [PATCH 0/5] Add the E-Switch mirroring and jump supports Jiawei Wang
                   ` (4 preceding siblings ...)
  2021-01-10 11:06 ` [dpdk-dev] [PATCH 5/5] doc: update the advanced E-switch mirroring supports Jiawei Wang
@ 2021-01-12 10:29 ` Jiawei Wang
  2021-01-12 10:29   ` [dpdk-dev] [PATCH v2 1/5] common/mlx5: query register c preserve capability via DevX Jiawei Wang
                     ` (5 more replies)
  5 siblings, 6 replies; 14+ messages in thread
From: Jiawei Wang @ 2021-01-12 10:29 UTC (permalink / raw)
  To: viacheslavo, matan, orika; +Cc: dev, rasland

MLX5 E-Switch mirroring is implemented as multiple destination array in
one steering table. The array currently supports only port ID as
destination actions.

This patchset adds the below supports for MLX5 PMD driver:
  - Supports the metadata register Cx preserve capability query.
  - Supports the jump action support as one of destination of array.
  - Supports the modify action only impact on the one of destination.

The examples for the E-Switch flow use case and result as below:
    set sample_actions 0 port_id id 1 / end
    flow create 0 ingress transfer pattern eth / end actions sample ratio 1 index 0 / jump group 1 / end
    flow create 1 ingress transfer group 1 pattern eth / end actions set_mac_dst mac_addr 00:aa:bb:cc:dd:ee / port_id id 2 / end

The flow results all the matched ingress packets are mirrored
to port id 1 and go to group 1. In the group 1, packets are modified
with the destination mac and sent to port id 2.

v2:
* Rebase
* Update commit message and document description

Jiawei Wang (5):
  common/mlx5: query register c preserve capability via DevX
  net/mlx5: support E-Switch mirroring and jump in one flow
  net/mlx5: extend the skip scale flag
  net/mlx5: update modify actions support for E-Switch mirror
  doc: update the advanced E-switch mirroring supports

 doc/guides/nics/mlx5.rst               |   2 +
 doc/guides/rel_notes/release_21_02.rst |   7 ++
 drivers/common/mlx5/mlx5_devx_cmds.c   |   2 +
 drivers/common/mlx5/mlx5_devx_cmds.h   |   1 +
 drivers/common/mlx5/mlx5_prm.h         |   4 +-
 drivers/net/mlx5/mlx5_flow.c           | 203 +++++++++++++++++++++++----------
 drivers/net/mlx5/mlx5_flow.h           |  23 +++-
 drivers/net/mlx5/mlx5_flow_dv.c        |  92 +++++++++------
 8 files changed, 235 insertions(+), 99 deletions(-)

-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [dpdk-dev] [PATCH v2 1/5] common/mlx5: query register c preserve capability via DevX
  2021-01-12 10:29 ` [dpdk-dev] [PATCH v2 0/5] Add the E-Switch mirroring and jump supports Jiawei Wang
@ 2021-01-12 10:29   ` Jiawei Wang
  2021-01-12 10:29   ` [dpdk-dev] [PATCH v2 2/5] net/mlx5: support E-Switch mirroring and jump in one flow Jiawei Wang
                     ` (4 subsequent siblings)
  5 siblings, 0 replies; 14+ messages in thread
From: Jiawei Wang @ 2021-01-12 10:29 UTC (permalink / raw)
  To: viacheslavo, matan, orika; +Cc: dev, rasland

Update function mlx5_devx_cmd_query_hca_attr() to add the
reg_c_preserve bit query.

The stored metadata in register C may be lost in NIC Tx and
FDB egress while doing one of the following operations:
 - packet encapsulation.
 - packet mirroring (multiple processing paths).
 - packet sampling (using Flow Sampler).

If the reg_c_preserve bit is set to 1, then the above
limitation is obsolete, the all metadata registers Cx
preserve their values even through the operations mentioned
above.

Signed-off-by: Jiawei Wang <jiaweiw@nvidia.com>
Acked-by: Viacheslav Ovsiienko <viacheslavo@nvidia.com>
---
 drivers/common/mlx5/mlx5_devx_cmds.c | 2 ++
 drivers/common/mlx5/mlx5_devx_cmds.h | 1 +
 drivers/common/mlx5/mlx5_prm.h       | 4 +++-
 3 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/common/mlx5/mlx5_devx_cmds.c b/drivers/common/mlx5/mlx5_devx_cmds.c
index 3bf5279..a1b4910 100644
--- a/drivers/common/mlx5/mlx5_devx_cmds.c
+++ b/drivers/common/mlx5/mlx5_devx_cmds.c
@@ -728,6 +728,8 @@ struct mlx5_devx_obj *
 	attr->log_max_pd = MLX5_GET(cmd_hca_cap, hcattr, log_max_pd);
 	attr->log_max_srq = MLX5_GET(cmd_hca_cap, hcattr, log_max_srq);
 	attr->log_max_srq_sz = MLX5_GET(cmd_hca_cap, hcattr, log_max_srq_sz);
+	attr->reg_c_preserve =
+		MLX5_GET(cmd_hca_cap, hcattr, reg_c_preserve);
 	if (attr->qos.sup) {
 		MLX5_SET(query_hca_cap_in, in, op_mod,
 			 MLX5_GET_HCA_CAP_OP_MOD_QOS_CAP |
diff --git a/drivers/common/mlx5/mlx5_devx_cmds.h b/drivers/common/mlx5/mlx5_devx_cmds.h
index 94e9bbb..e0fa595 100644
--- a/drivers/common/mlx5/mlx5_devx_cmds.h
+++ b/drivers/common/mlx5/mlx5_devx_cmds.h
@@ -114,6 +114,7 @@ struct mlx5_hca_attr {
 	uint32_t scatter_fcs_w_decap_disable:1;
 	uint32_t flow_hit_aso:1; /* General obj type FLOW_HIT_ASO supported. */
 	uint32_t regex:1;
+	uint32_t reg_c_preserve:1;
 	uint32_t regexp_num_of_engines;
 	uint32_t log_max_ft_sampler_num:8;
 	struct mlx5_hca_qos_attr qos;
diff --git a/drivers/common/mlx5/mlx5_prm.h b/drivers/common/mlx5/mlx5_prm.h
index 7d5cf96..712f698 100644
--- a/drivers/common/mlx5/mlx5_prm.h
+++ b/drivers/common/mlx5/mlx5_prm.h
@@ -1130,7 +1130,9 @@ struct mlx5_ifc_cmd_hca_cap_bits {
 	u8 regexp[0x1];
 	u8 reserved_at_a1[0x3];
 	u8 regexp_num_of_engines[0x4];
-	u8 reserved_at_a8[0x3];
+	u8 reserved_at_a8[0x1];
+	u8 reg_c_preserve[0x1];
+	u8 reserved_at_aa[0x1];
 	u8 log_max_srq[0x5];
 	u8 reserved_at_b0[0x3];
 	u8 regexp_log_crspace_size[0x5];
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [dpdk-dev] [PATCH v2 2/5] net/mlx5: support E-Switch mirroring and jump in one flow
  2021-01-12 10:29 ` [dpdk-dev] [PATCH v2 0/5] Add the E-Switch mirroring and jump supports Jiawei Wang
  2021-01-12 10:29   ` [dpdk-dev] [PATCH v2 1/5] common/mlx5: query register c preserve capability via DevX Jiawei Wang
@ 2021-01-12 10:29   ` Jiawei Wang
  2021-01-12 10:29   ` [dpdk-dev] [PATCH v2 3/5] net/mlx5: extend the skip scale flag Jiawei Wang
                     ` (3 subsequent siblings)
  5 siblings, 0 replies; 14+ messages in thread
From: Jiawei Wang @ 2021-01-12 10:29 UTC (permalink / raw)
  To: viacheslavo, matan, orika; +Cc: dev, rasland

mlx5 E-Switch mirroring is implemented as multiple destination array in
one steering table. The array currently supports only port ID as
destination actions.

This patch adds the jump action support to the array as one of
destination.
The packets can be mirrored to the port and jump to the next table in the
same destination array allowing to continue handling in the new table.

For example:
    set sample_actions 0 port_id id 1 / end
    flow create 0 ingress transfer pattern eth / end actions
    sample ratio 1 index 0 / jump group 1 / end
    flow create 1 ingress transfer group 1 pattern eth / end actions
    set_mac_dst mac_addr 00:aa:bb:cc:dd:ee / port_id id 2 / end

The flow results all the matched ingress packets are mirrored
to port id 1 and go to group 1. In the group 1, packets are modified
with the destination mac and sent to port id 2.

Signed-off-by: Jiawei Wang <jiaweiw@nvidia.com>
Acked-by: Viacheslav Ovsiienko <viacheslavo@nvidia.com>
---
 drivers/net/mlx5/mlx5_flow.c    | 36 ++++++++++--------
 drivers/net/mlx5/mlx5_flow.h    |  2 +
 drivers/net/mlx5/mlx5_flow_dv.c | 81 +++++++++++++++++++++++++++++------------
 3 files changed, 80 insertions(+), 39 deletions(-)

diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index 2a4073c..217090a 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -4503,7 +4503,6 @@ struct mlx5_hlist_entry *
 {
 	const struct rte_flow_action_sample *sample;
 	int actions_n = 0;
-	int jump_flag = 0;
 	uint32_t ratio = 0;
 	int sub_type = 0;
 	int flag = 0;
@@ -4518,8 +4517,6 @@ struct mlx5_hlist_entry *
 		if (actions->type == RTE_FLOW_ACTION_TYPE_QUEUE ||
 		    actions->type == RTE_FLOW_ACTION_TYPE_RSS)
 			*qrss_action_pos = actions_n;
-		if (actions->type == RTE_FLOW_ACTION_TYPE_JUMP)
-			jump_flag = 1;
 		if (actions->type == RTE_FLOW_ACTION_TYPE_SAMPLE) {
 			sample = actions->conf;
 			ratio = sample->ratio;
@@ -4530,10 +4527,10 @@ struct mlx5_hlist_entry *
 	}
 	if (flag && action == RTE_FLOW_ACTION_TYPE_SAMPLE && attr->transfer) {
 		if (ratio == 1) {
-			/* JUMP Action not support for Mirroring;
-			 * Mirroring support multi-destination;
+			/* FDB mirroring uses the destination array to implement
+			 * instead of FLOW_SAMPLER object.
 			 */
-			if (!jump_flag && sub_type != RTE_FLOW_ACTION_TYPE_END)
+			if (sub_type != RTE_FLOW_ACTION_TYPE_END)
 				flag = 0;
 		}
 	}
@@ -4554,8 +4551,8 @@ struct mlx5_hlist_entry *
  *
  * @param dev
  *   Pointer to Ethernet device.
- * @param[in] fdb_tx
- *   FDB egress flow flag.
+ * @param[in] add_tag
+ *   Add extra tag action flag.
  * @param[out] sfx_items
  *   Suffix flow match items (list terminated by the END pattern item).
  * @param[in] actions
@@ -4579,7 +4576,7 @@ struct mlx5_hlist_entry *
  */
 static int
 flow_sample_split_prep(struct rte_eth_dev *dev,
-		       uint32_t fdb_tx,
+		       int add_tag,
 		       struct rte_flow_item sfx_items[],
 		       const struct rte_flow_action actions[],
 		       struct rte_flow_action actions_sfx[],
@@ -4602,7 +4599,11 @@ struct mlx5_hlist_entry *
 					  RTE_FLOW_ERROR_TYPE_ACTION,
 					  NULL, "invalid position of sample "
 					  "action in list");
-	if (!fdb_tx) {
+	/* For CX5, add an extra tag action for NIC-RX and E-Switch ingress.
+	 * For CX6DX and above, metadata registers Cx preserve their value,
+	 * add an extra tag action for NIC-RX and E-Switch ingress and egress.
+	 */
+	if (add_tag) {
 		/* Prepare the prefix tag action. */
 		set_tag = (void *)(actions_pre + actions_n + 1);
 		ret = mlx5_flow_get_reg_id(dev, MLX5_APP_TAG, 0, error);
@@ -4653,8 +4654,7 @@ struct mlx5_hlist_entry *
 			memcpy(actions_pre, actions,
 			       sizeof(struct rte_flow_action) * index);
 	}
-	/* Add the extra tag action for NIC-RX and E-Switch ingress. */
-	if (!fdb_tx) {
+	if (add_tag) {
 		actions_pre[index++] =
 			(struct rte_flow_action){
 			.type = (enum rte_flow_action_type)
@@ -5067,6 +5067,7 @@ struct mlx5_hlist_entry *
 	int actions_n = 0;
 	int sample_action_pos;
 	int qrss_action_pos;
+	int add_tag = 0;
 	int ret = 0;
 
 	if (priv->sampler_en)
@@ -5088,16 +5089,21 @@ struct mlx5_hlist_entry *
 						  "sample flow");
 		/* The representor_id is -1 for uplink. */
 		fdb_tx = (attr->transfer && priv->representor_id != -1);
-		if (!fdb_tx)
+		/*
+		 * When reg_c_preserve is set, metadata registers Cx preserve
+		 * their value even through packet duplication.
+		 */
+		add_tag = (!fdb_tx || priv->config.hca_attr.reg_c_preserve);
+		if (add_tag)
 			sfx_items = (struct rte_flow_item *)((char *)sfx_actions
 					+ act_size);
 		pre_actions = sfx_actions + actions_n;
-		tag_id = flow_sample_split_prep(dev, fdb_tx, sfx_items,
+		tag_id = flow_sample_split_prep(dev, add_tag, sfx_items,
 						actions, sfx_actions,
 						pre_actions, actions_n,
 						sample_action_pos,
 						qrss_action_pos, error);
-		if (tag_id < 0 || (!fdb_tx && !tag_id)) {
+		if (tag_id < 0 || (add_tag && !tag_id)) {
 			ret = -rte_errno;
 			goto exit;
 		}
diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h
index ee85c9d..18d5cfc 100644
--- a/drivers/net/mlx5/mlx5_flow.h
+++ b/drivers/net/mlx5/mlx5_flow.h
@@ -552,6 +552,7 @@ struct mlx5_flow_sub_actions_list {
 	void *dr_cnt_action;
 	void *dr_port_id_action;
 	void *dr_encap_action;
+	void *dr_jump_action;
 };
 
 /* Sample sub-actions resource list. */
@@ -561,6 +562,7 @@ struct mlx5_flow_sub_actions_idx {
 	uint32_t cnt;
 	uint32_t rix_port_id_action; /**< Index to port ID action resource. */
 	uint32_t rix_encap_decap; /**< Index to encap/decap resource. */
+	uint32_t rix_jump; /**< Index to the jump action resource. */
 };
 
 /* Sample action resource structure. */
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index e4736ee..d82d22e 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -76,7 +76,7 @@
 
 static int
 flow_dv_encap_decap_resource_release(struct rte_eth_dev *dev,
-				      uint32_t encap_decap_idx);
+				     uint32_t encap_decap_idx);
 
 static int
 flow_dv_port_id_action_resource_release(struct rte_eth_dev *dev,
@@ -84,6 +84,10 @@
 static void
 flow_dv_shared_rss_action_release(struct rte_eth_dev *dev, uint32_t srss);
 
+static int
+flow_dv_jump_tbl_resource_release(struct rte_eth_dev *dev,
+				  uint32_t rix_jump);
+
 /**
  * Initialize flow attributes structure according to flow items' types.
  *
@@ -3596,7 +3600,7 @@ struct mlx5_cache_entry *
 					    (dev, &res, dev_flow, error);
 }
 
-static int fdb_mirror;
+static int fdb_mirror_limit;
 
 /**
  * Validate the modify-header actions.
@@ -3625,7 +3629,7 @@ struct mlx5_cache_entry *
 					  RTE_FLOW_ERROR_TYPE_ACTION, NULL,
 					  "can't have encap action before"
 					  " modify action");
-	if ((action_flags & MLX5_FLOW_ACTION_SAMPLE) && fdb_mirror)
+	if ((action_flags & MLX5_FLOW_ACTION_SAMPLE) && fdb_mirror_limit)
 		return rte_flow_error_set(error, EINVAL,
 					  RTE_FLOW_ERROR_TYPE_ACTION, NULL,
 					  "can't support sample action before"
@@ -3961,12 +3965,6 @@ struct mlx5_cache_entry *
 		return rte_flow_error_set(error, ENOTSUP,
 					  RTE_FLOW_ERROR_TYPE_ACTION, NULL,
 					  "jump with meter not support");
-	if ((action_flags & MLX5_FLOW_ACTION_SAMPLE) && fdb_mirror)
-		return rte_flow_error_set(error, EINVAL,
-					  RTE_FLOW_ERROR_TYPE_ACTION, NULL,
-					  "E-Switch mirroring can't support"
-					  " Sample action and jump action in"
-					  " same flow now");
 	if (!action->conf)
 		return rte_flow_error_set(error, EINVAL,
 					  RTE_FLOW_ERROR_TYPE_ACTION_CONF,
@@ -4366,8 +4364,8 @@ struct mlx5_hlist_entry *
 	uint16_t queue_index = 0xFFFF;
 	int actions_n = 0;
 	int ret;
-	fdb_mirror = 0;
 
+	fdb_mirror_limit = 0;
 	if (!sample)
 		return rte_flow_error_set(error, EINVAL,
 					  RTE_FLOW_ERROR_TYPE_ACTION, action,
@@ -4484,7 +4482,7 @@ struct mlx5_hlist_entry *
 						  "E-Switch doesn't support "
 						  "any optional action "
 						  "for sampling");
-		fdb_mirror = 1;
+		fdb_mirror_limit = 1;
 		if (sub_action_flags & MLX5_FLOW_ACTION_QUEUE)
 			return rte_flow_error_set(error, ENOTSUP,
 						  RTE_FLOW_ERROR_TYPE_ACTION,
@@ -8706,6 +8704,10 @@ struct mlx5_hlist_entry *
 		flow_dv_counter_free(dev, act_res->cnt);
 		act_res->cnt = 0;
 	}
+	if (act_res->rix_jump) {
+		flow_dv_jump_tbl_resource_release(dev, act_res->rix_jump);
+		act_res->rix_jump = 0;
+	}
 }
 
 int
@@ -8918,6 +8920,7 @@ struct mlx5_cache_entry *
 	struct mlx5dv_dr_domain *domain;
 	uint32_t idx = 0, res_idx = 0;
 	struct rte_flow_error *error = ctx->error;
+	uint64_t action_flags;
 	int ret;
 
 	/* Register new destination array resource. */
@@ -8951,19 +8954,31 @@ struct mlx5_cache_entry *
 		}
 		dest_attr[idx]->type = MLX5DV_DR_ACTION_DEST;
 		sample_act = &resource->sample_act[idx];
-		if (sample_act->action_flags == MLX5_FLOW_ACTION_QUEUE) {
+		action_flags = sample_act->action_flags;
+		switch (action_flags) {
+		case MLX5_FLOW_ACTION_QUEUE:
 			dest_attr[idx]->dest = sample_act->dr_queue_action;
-		} else if (sample_act->action_flags ==
-			  (MLX5_FLOW_ACTION_PORT_ID | MLX5_FLOW_ACTION_ENCAP)) {
+			break;
+		case (MLX5_FLOW_ACTION_PORT_ID | MLX5_FLOW_ACTION_ENCAP):
 			dest_attr[idx]->type = MLX5DV_DR_ACTION_DEST_REFORMAT;
 			dest_attr[idx]->dest_reformat = &dest_reformat[idx];
 			dest_attr[idx]->dest_reformat->reformat =
 					sample_act->dr_encap_action;
 			dest_attr[idx]->dest_reformat->dest =
 					sample_act->dr_port_id_action;
-		} else if (sample_act->action_flags ==
-			   MLX5_FLOW_ACTION_PORT_ID) {
+			break;
+		case MLX5_FLOW_ACTION_PORT_ID:
 			dest_attr[idx]->dest = sample_act->dr_port_id_action;
+			break;
+		case MLX5_FLOW_ACTION_JUMP:
+			dest_attr[idx]->dest = sample_act->dr_jump_action;
+			break;
+		default:
+			rte_flow_error_set(error, EINVAL,
+					   RTE_FLOW_ERROR_TYPE_ACTION,
+					   NULL,
+					   "unsupported actions type");
+			goto error;
 		}
 	}
 	/* create a dest array actioin */
@@ -9000,6 +9015,10 @@ struct mlx5_cache_entry *
 			!flow_dv_port_id_action_resource_release(dev,
 				act_res->rix_port_id_action))
 			act_res->rix_port_id_action = 0;
+		if (act_res->rix_jump &&
+			!flow_dv_jump_tbl_resource_release(dev,
+				act_res->rix_jump))
+			act_res->rix_jump = 0;
 		if (dest_attr[idx])
 			mlx5_free(dest_attr[idx]);
 	}
@@ -9336,6 +9355,14 @@ struct mlx5_cache_entry *
 			sample_act->dr_port_id_action =
 				dev_flow->dv.port_id_action->action;
 		}
+		if (sample_act->action_flags & MLX5_FLOW_ACTION_JUMP) {
+			normal_idx++;
+			mdest_res->sample_idx[dest_index].rix_jump =
+				dev_flow->handle->rix_jump;
+			sample_act->dr_jump_action =
+				dev_flow->dv.jump->action;
+			dev_flow->handle->rix_jump = 0;
+		}
 		sample_act->actions_num = normal_idx;
 		/* update sample action resource into first index of array */
 		mdest_res->ft_type = res->ft_type;
@@ -10094,6 +10121,8 @@ struct mlx5_cache_entry *
 					dev_flow->dv.jump->action;
 			action_flags |= MLX5_FLOW_ACTION_JUMP;
 			dev_flow->handle->fate_action = MLX5_FLOW_FATE_JUMP;
+			sample_act->action_flags |= MLX5_FLOW_ACTION_JUMP;
+			num_of_dest++;
 			break;
 		case RTE_FLOW_ACTION_TYPE_SET_MAC_SRC:
 		case RTE_FLOW_ACTION_TYPE_SET_MAC_DST:
@@ -10316,7 +10345,8 @@ struct mlx5_cache_entry *
 	 * So need remove the original these actions in the flow and only
 	 * use the sample action instead of.
 	 */
-	if (num_of_dest > 1 && sample_act->dr_port_id_action) {
+	if (num_of_dest > 1 &&
+	    (sample_act->dr_port_id_action || sample_act->dr_jump_action)) {
 		int i;
 		void *temp_actions[MLX5_DV_MAX_NUMBER_OF_ACTIONS] = {0};
 
@@ -10326,6 +10356,9 @@ struct mlx5_cache_entry *
 				dev_flow->dv.actions[i]) ||
 				(sample_act->dr_port_id_action &&
 				sample_act->dr_port_id_action ==
+				dev_flow->dv.actions[i]) ||
+				(sample_act->dr_jump_action &&
+				sample_act->dr_jump_action ==
 				dev_flow->dv.actions[i]))
 				continue;
 			temp_actions[tmp_actions_n++] = dev_flow->dv.actions[i];
@@ -10924,21 +10957,21 @@ struct mlx5_cache_entry *
  *
  * @param dev
  *   Pointer to Ethernet device.
- * @param handle
- *   Pointer to mlx5_flow_handle.
+ * @param rix_jump
+ *   Index to the jump action resource.
  *
  * @return
  *   1 while a reference on it exists, 0 when freed.
  */
 static int
 flow_dv_jump_tbl_resource_release(struct rte_eth_dev *dev,
-				  struct mlx5_flow_handle *handle)
+				  uint32_t rix_jump)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
 	struct mlx5_flow_tbl_data_entry *tbl_data;
 
 	tbl_data = mlx5_ipool_get(priv->sh->ipool[MLX5_IPOOL_JUMP],
-			     handle->rix_jump);
+				  rix_jump);
 	if (!tbl_data)
 		return 0;
 	return flow_dv_tbl_resource_release(MLX5_SH(dev), &tbl_data->tbl);
@@ -11092,7 +11125,7 @@ struct mlx5_cache_entry *
 		mlx5_hrxq_release(dev, handle->rix_hrxq);
 		break;
 	case MLX5_FLOW_FATE_JUMP:
-		flow_dv_jump_tbl_resource_release(dev, handle);
+		flow_dv_jump_tbl_resource_release(dev, handle->rix_jump);
 		break;
 	case MLX5_FLOW_FATE_PORT_ID:
 		flow_dv_port_id_action_resource_release(dev,
@@ -11188,8 +11221,8 @@ struct mlx5_cache_entry *
  *
  * @param dev
  *   Pointer to Ethernet device.
- * @param handle
- *   Pointer to mlx5_flow_handle.
+ * @param port_id
+ *   Index to port ID action resource.
  *
  * @return
  *   1 while a reference on it exists, 0 when freed.
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [dpdk-dev] [PATCH v2 3/5] net/mlx5: extend the skip scale flag
  2021-01-12 10:29 ` [dpdk-dev] [PATCH v2 0/5] Add the E-Switch mirroring and jump supports Jiawei Wang
  2021-01-12 10:29   ` [dpdk-dev] [PATCH v2 1/5] common/mlx5: query register c preserve capability via DevX Jiawei Wang
  2021-01-12 10:29   ` [dpdk-dev] [PATCH v2 2/5] net/mlx5: support E-Switch mirroring and jump in one flow Jiawei Wang
@ 2021-01-12 10:29   ` Jiawei Wang
  2021-01-12 10:29   ` [dpdk-dev] [PATCH v2 4/5] net/mlx5: update modify actions support for E-Switch mirror Jiawei Wang
                     ` (2 subsequent siblings)
  5 siblings, 0 replies; 14+ messages in thread
From: Jiawei Wang @ 2021-01-12 10:29 UTC (permalink / raw)
  To: viacheslavo, matan, orika; +Cc: dev, rasland

The sampling feature introduces the scale flow group with factor,
then the scaled table value can be used for the normal path table
due to this table be created implicitly.

But if the input group value already be scaled, for example the
group value of sampling suffix flow, then use 'skip_scale" flag
to skip the scale twice in the translation action.

Consider the flow with jump action and this jump action could be
created implicitly, PMD may only scale the original flow group
value or scale the jump group value or both, so extend the
'skip_scale' flag to two bits:
If bit0 of 'skip_scale' flag is set to 1, then skip the scale the
original flow group;
If bit1 of 'skip_scale' flag is set to 1, then skip the scale the
jump flow group.

Signed-off-by: Jiawei Wang <jiaweiw@nvidia.com>
Acked-by: Viacheslav Ovsiienko <viacheslavo@nvidia.com>
---
 drivers/net/mlx5/mlx5_flow.c    |  2 +-
 drivers/net/mlx5/mlx5_flow.h    | 21 ++++++++++++++++++---
 drivers/net/mlx5/mlx5_flow_dv.c |  9 +++++++--
 3 files changed, 26 insertions(+), 6 deletions(-)

diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index 217090a..055474b 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -5133,7 +5133,7 @@ struct mlx5_hlist_entry *
 		/* Suffix group level already be scaled with factor, set
 		 * skip_scale to 1 to avoid scale again in translation.
 		 */
-		flow_split_info->skip_scale = 1;
+		flow_split_info->skip_scale = 1 << MLX5_SCALE_FLOW_GROUP_BIT;
 #endif
 	}
 	/* Add the suffix subflow. */
diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h
index 18d5cfc..a054ff3 100644
--- a/drivers/net/mlx5/mlx5_flow.h
+++ b/drivers/net/mlx5/mlx5_flow.h
@@ -755,6 +755,9 @@ struct mlx5_flow_verbs_workspace {
 };
 #endif /* HAVE_INFINIBAND_VERBS_H */
 
+#define MLX5_SCALE_FLOW_GROUP_BIT 0
+#define MLX5_SCALE_JUMP_FLOW_GROUP_BIT 1
+
 /** Maximal number of device sub-flows supported. */
 #define MLX5_NUM_MAX_DEV_FLOWS 32
 
@@ -768,8 +771,20 @@ struct mlx5_flow {
 	/**< Bit-fields of detected actions, see MLX5_FLOW_ACTION_*. */
 	bool external; /**< true if the flow is created external to PMD. */
 	uint8_t ingress:1; /**< 1 if the flow is ingress. */
-	uint8_t skip_scale:1;
-	/**< 1 if skip the scale the table with factor. */
+	uint8_t skip_scale:2;
+	/**
+	 * Each Bit be set to 1 if Skip the scale the flow group with factor.
+	 * If bit0 be set to 1, then skip the scale the original flow group;
+	 * If bit1 be set to 1, then skip the scale the jump flow group if
+	 * having jump action.
+	 * 00: Enable scale in a flow, default value.
+	 * 01: Skip scale the flow group with factor, enable scale the group
+	 * of jump action.
+	 * 10: Enable scale the group with factor, skip scale the group of
+	 * jump action.
+	 * 11: Skip scale the table with factor both for flow group and jump
+	 * group.
+	 */
 	union {
 #if defined(HAVE_IBV_FLOW_DV_SUPPORT) || !defined(HAVE_INFINIBAND_VERBS_H)
 		struct mlx5_flow_dv_workspace dv;
@@ -1238,7 +1253,7 @@ struct flow_grp_info {
 	uint64_t fdb_def_rule:1;
 	/* force standard group translation */
 	uint64_t std_tbl_fix:1;
-	uint64_t skip_scale:1;
+	uint64_t skip_scale:2;
 };
 
 static inline bool
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index d82d22e..63569ad 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -9732,7 +9732,8 @@ struct mlx5_cache_entry *
 		.external = !!dev_flow->external,
 		.transfer = !!attr->transfer,
 		.fdb_def_rule = !!priv->fdb_def_rule,
-		.skip_scale = !!dev_flow->skip_scale,
+		.skip_scale = dev_flow->skip_scale &
+			(1 << MLX5_SCALE_FLOW_GROUP_BIT),
 	};
 
 	if (!wks)
@@ -10090,7 +10091,11 @@ struct mlx5_cache_entry *
 			jump_group = ((const struct rte_flow_action_jump *)
 							action->conf)->group;
 			grp_info.std_tbl_fix = 0;
-			grp_info.skip_scale = 0;
+			if (dev_flow->skip_scale &
+				(1 << MLX5_SCALE_JUMP_FLOW_GROUP_BIT))
+				grp_info.skip_scale = 1;
+			else
+				grp_info.skip_scale = 0;
 			ret = mlx5_flow_group_to_table(dev, tunnel,
 						       jump_group,
 						       &table,
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [dpdk-dev] [PATCH v2 4/5] net/mlx5: update modify actions support for E-Switch mirror
  2021-01-12 10:29 ` [dpdk-dev] [PATCH v2 0/5] Add the E-Switch mirroring and jump supports Jiawei Wang
                     ` (2 preceding siblings ...)
  2021-01-12 10:29   ` [dpdk-dev] [PATCH v2 3/5] net/mlx5: extend the skip scale flag Jiawei Wang
@ 2021-01-12 10:29   ` Jiawei Wang
  2021-01-12 10:29   ` [dpdk-dev] [PATCH v2 5/5] doc: update the advanced E-switch mirroring supports Jiawei Wang
  2021-01-20 15:05   ` [dpdk-dev] [PATCH v2 0/5] Add the E-Switch mirroring and jump supports Raslan Darawsheh
  5 siblings, 0 replies; 14+ messages in thread
From: Jiawei Wang @ 2021-01-12 10:29 UTC (permalink / raw)
  To: viacheslavo, matan, orika; +Cc: dev, rasland

While there's the modify action and sample action with ratio=1
in the E-Switch flow, and modify action is after the sample
action, means that the modify should only impact on after sample.
MLX5 PMD will monitor the above case and split the E-Switch flow
into two sub flows, similar as sample flow did before:

 - the prefix sub flow with all actions preceding the sample and the
   sample action itself, also append the new jump action after sample
   in the prefix sub flow;
 - the suffix sub flow with the modify action and other actions
   following the sample action.

The flow split as below:

Original flow: items / actions pre / sample / modify / actions sfx
    prefix sub flow -
    items / actions pre / set_tag action / sample / jump
    suffix sub flow -
    tag_item / modify / actions sfx

Signed-off-by: Jiawei Wang <jiaweiw@nvidia.com>
Acked-by: Viacheslav Ovsiienko <viacheslavo@nvidia.com>
---
 drivers/net/mlx5/mlx5_flow.c    | 175 ++++++++++++++++++++++++++++------------
 drivers/net/mlx5/mlx5_flow_dv.c |  10 ---
 2 files changed, 123 insertions(+), 62 deletions(-)

diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index 055474b..df79318 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -4490,6 +4490,8 @@ struct mlx5_hlist_entry *
  *   Pointer to the position of the matched action if exists, otherwise is -1.
  * @param[out] qrss_action_pos
  *   Pointer to the position of the Queue/RSS action if exists, otherwise is -1.
+ * @param[out] modify_after_mirror
+ *   Pointer to the flag of modify action after FDB mirroring.
  *
  * @return
  *   > 0 the total number of actions.
@@ -4499,13 +4501,15 @@ struct mlx5_hlist_entry *
 flow_check_match_action(const struct rte_flow_action actions[],
 			const struct rte_flow_attr *attr,
 			enum rte_flow_action_type action,
-			int *match_action_pos, int *qrss_action_pos)
+			int *match_action_pos, int *qrss_action_pos,
+			int *modify_after_mirror)
 {
 	const struct rte_flow_action_sample *sample;
 	int actions_n = 0;
 	uint32_t ratio = 0;
 	int sub_type = 0;
 	int flag = 0;
+	int fdb_mirror = 0;
 
 	*match_action_pos = -1;
 	*qrss_action_pos = -1;
@@ -4514,25 +4518,53 @@ struct mlx5_hlist_entry *
 			flag = 1;
 			*match_action_pos = actions_n;
 		}
-		if (actions->type == RTE_FLOW_ACTION_TYPE_QUEUE ||
-		    actions->type == RTE_FLOW_ACTION_TYPE_RSS)
+		switch (actions->type) {
+		case RTE_FLOW_ACTION_TYPE_QUEUE:
+		case RTE_FLOW_ACTION_TYPE_RSS:
 			*qrss_action_pos = actions_n;
-		if (actions->type == RTE_FLOW_ACTION_TYPE_SAMPLE) {
+			break;
+		case RTE_FLOW_ACTION_TYPE_SAMPLE:
 			sample = actions->conf;
 			ratio = sample->ratio;
 			sub_type = ((const struct rte_flow_action *)
 					(sample->actions))->type;
+			if (ratio == 1 && attr->transfer)
+				fdb_mirror = 1;
+			break;
+		case RTE_FLOW_ACTION_TYPE_SET_MAC_SRC:
+		case RTE_FLOW_ACTION_TYPE_SET_MAC_DST:
+		case RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC:
+		case RTE_FLOW_ACTION_TYPE_SET_IPV4_DST:
+		case RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC:
+		case RTE_FLOW_ACTION_TYPE_SET_IPV6_DST:
+		case RTE_FLOW_ACTION_TYPE_SET_TP_SRC:
+		case RTE_FLOW_ACTION_TYPE_SET_TP_DST:
+		case RTE_FLOW_ACTION_TYPE_DEC_TTL:
+		case RTE_FLOW_ACTION_TYPE_SET_TTL:
+		case RTE_FLOW_ACTION_TYPE_INC_TCP_SEQ:
+		case RTE_FLOW_ACTION_TYPE_DEC_TCP_SEQ:
+		case RTE_FLOW_ACTION_TYPE_INC_TCP_ACK:
+		case RTE_FLOW_ACTION_TYPE_DEC_TCP_ACK:
+		case RTE_FLOW_ACTION_TYPE_SET_IPV4_DSCP:
+		case RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP:
+		case RTE_FLOW_ACTION_TYPE_FLAG:
+		case RTE_FLOW_ACTION_TYPE_MARK:
+		case RTE_FLOW_ACTION_TYPE_SET_META:
+		case RTE_FLOW_ACTION_TYPE_SET_TAG:
+			if (fdb_mirror)
+				*modify_after_mirror = 1;
+			break;
+		default:
+			break;
 		}
 		actions_n++;
 	}
-	if (flag && action == RTE_FLOW_ACTION_TYPE_SAMPLE && attr->transfer) {
-		if (ratio == 1) {
-			/* FDB mirroring uses the destination array to implement
-			 * instead of FLOW_SAMPLER object.
-			 */
-			if (sub_type != RTE_FLOW_ACTION_TYPE_END)
-				flag = 0;
-		}
+	if (flag && fdb_mirror && !*modify_after_mirror) {
+		/* FDB mirroring uses the destination array to implement
+		 * instead of FLOW_SAMPLER object.
+		 */
+		if (sub_type != RTE_FLOW_ACTION_TYPE_END)
+			flag = 0;
 	}
 	/* Count RTE_FLOW_ACTION_TYPE_END. */
 	return flag ? actions_n + 1 : 0;
@@ -4567,6 +4599,8 @@ struct mlx5_hlist_entry *
  *   The sample action position.
  * @param[in] qrss_action_pos
  *   The Queue/RSS action position.
+ * @param[in] jump_table
+ *   Add extra jump action flag.
  * @param[out] error
  *   Perform verbose error reporting if not NULL.
  *
@@ -4584,14 +4618,17 @@ struct mlx5_hlist_entry *
 		       int actions_n,
 		       int sample_action_pos,
 		       int qrss_action_pos,
+		       int jump_table,
 		       struct rte_flow_error *error)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
 	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_action_jump *jump_action;
 	uint32_t tag_id = 0;
 	int index;
+	int append_index = 0;
 	int ret;
 
 	if (sample_action_pos < 0)
@@ -4599,13 +4636,37 @@ struct mlx5_hlist_entry *
 					  RTE_FLOW_ERROR_TYPE_ACTION,
 					  NULL, "invalid position of sample "
 					  "action in list");
+	/* Prepare the actions for prefix and suffix flow. */
+	if (qrss_action_pos >= 0 && qrss_action_pos < sample_action_pos) {
+		index = qrss_action_pos;
+		/* Put the preceding the Queue/RSS action into prefix flow. */
+		if (index != 0)
+			memcpy(actions_pre, actions,
+			       sizeof(struct rte_flow_action) * index);
+		/* Put others preceding the sample action into prefix flow. */
+		if (sample_action_pos > index + 1)
+			memcpy(actions_pre + index, actions + index + 1,
+			       sizeof(struct rte_flow_action) *
+			       (sample_action_pos - index - 1));
+		index = sample_action_pos - 1;
+		/* Put Queue/RSS action into Suffix flow. */
+		memcpy(actions_sfx, actions + qrss_action_pos,
+		       sizeof(struct rte_flow_action));
+		actions_sfx++;
+	} else {
+		index = sample_action_pos;
+		if (index != 0)
+			memcpy(actions_pre, actions,
+			       sizeof(struct rte_flow_action) * index);
+	}
 	/* For CX5, add an extra tag action for NIC-RX and E-Switch ingress.
 	 * For CX6DX and above, metadata registers Cx preserve their value,
-	 * add an extra tag action for NIC-RX and E-Switch ingress and egress.
+	 * add an extra tag action for NIC-RX and E-Switch Domain.
 	 */
 	if (add_tag) {
 		/* Prepare the prefix tag action. */
-		set_tag = (void *)(actions_pre + actions_n + 1);
+		append_index++;
+		set_tag = (void *)(actions_pre + actions_n + append_index);
 		ret = mlx5_flow_get_reg_id(dev, MLX5_APP_TAG, 0, error);
 		if (ret < 0)
 			return ret;
@@ -4630,31 +4691,7 @@ struct mlx5_hlist_entry *
 			.type = (enum rte_flow_item_type)
 				RTE_FLOW_ITEM_TYPE_END,
 		};
-	}
-	/* Prepare the actions for prefix and suffix flow. */
-	if (qrss_action_pos >= 0 && qrss_action_pos < sample_action_pos) {
-		index = qrss_action_pos;
-		/* Put the preceding the Queue/RSS action into prefix flow. */
-		if (index != 0)
-			memcpy(actions_pre, actions,
-			       sizeof(struct rte_flow_action) * index);
-		/* Put others preceding the sample action into prefix flow. */
-		if (sample_action_pos > index + 1)
-			memcpy(actions_pre + index, actions + index + 1,
-			       sizeof(struct rte_flow_action) *
-			       (sample_action_pos - index - 1));
-		index = sample_action_pos - 1;
-		/* Put Queue/RSS action into Suffix flow. */
-		memcpy(actions_sfx, actions + qrss_action_pos,
-		       sizeof(struct rte_flow_action));
-		actions_sfx++;
-	} else {
-		index = sample_action_pos;
-		if (index != 0)
-			memcpy(actions_pre, actions,
-			       sizeof(struct rte_flow_action) * index);
-	}
-	if (add_tag) {
+		/* Prepare the tag action in prefix subflow. */
 		actions_pre[index++] =
 			(struct rte_flow_action){
 			.type = (enum rte_flow_action_type)
@@ -4665,6 +4702,22 @@ struct mlx5_hlist_entry *
 	memcpy(actions_pre + index, actions + sample_action_pos,
 	       sizeof(struct rte_flow_action));
 	index += 1;
+	/* For the modify action after the sample action in E-Switch mirroring,
+	 * Add the extra jump action in prefix subflow and jump into the next
+	 * table, then do the modify action in the new table.
+	 */
+	if (jump_table) {
+		/* Prepare the prefix jump action. */
+		append_index++;
+		jump_action = (void *)(actions_pre + actions_n + append_index);
+		jump_action->group = jump_table;
+		actions_pre[index++] =
+			(struct rte_flow_action){
+			.type = (enum rte_flow_action_type)
+				RTE_FLOW_ACTION_TYPE_JUMP,
+			.conf = jump_action,
+		};
+	}
 	actions_pre[index] = (struct rte_flow_action){
 		.type = (enum rte_flow_action_type)
 			RTE_FLOW_ACTION_TYPE_END,
@@ -5068,12 +5121,16 @@ struct mlx5_hlist_entry *
 	int sample_action_pos;
 	int qrss_action_pos;
 	int add_tag = 0;
+	int modify_after_mirror = 0;
+	uint16_t jump_table = 0;
+	const uint32_t next_ft_step = 1;
 	int ret = 0;
 
 	if (priv->sampler_en)
 		actions_n = flow_check_match_action(actions, attr,
 					RTE_FLOW_ACTION_TYPE_SAMPLE,
-					&sample_action_pos, &qrss_action_pos);
+					&sample_action_pos, &qrss_action_pos,
+					&modify_after_mirror);
 	if (actions_n) {
 		/* The prefix actions must includes sample, tag, end. */
 		act_size = sizeof(struct rte_flow_action) * (actions_n * 2 + 1)
@@ -5097,16 +5154,23 @@ struct mlx5_hlist_entry *
 		if (add_tag)
 			sfx_items = (struct rte_flow_item *)((char *)sfx_actions
 					+ act_size);
+		if (modify_after_mirror)
+			jump_table = attr->group * MLX5_FLOW_TABLE_FACTOR +
+				     next_ft_step;
 		pre_actions = sfx_actions + actions_n;
 		tag_id = flow_sample_split_prep(dev, add_tag, sfx_items,
 						actions, sfx_actions,
 						pre_actions, actions_n,
 						sample_action_pos,
-						qrss_action_pos, error);
+						qrss_action_pos, jump_table,
+						error);
 		if (tag_id < 0 || (add_tag && !tag_id)) {
 			ret = -rte_errno;
 			goto exit;
 		}
+		if (modify_after_mirror)
+			flow_split_info->skip_scale =
+					1 << MLX5_SCALE_JUMP_FLOW_GROUP_BIT;
 		/* Add the prefix subflow. */
 		ret = flow_create_split_inner(dev, flow, &dev_flow, attr,
 					      items, pre_actions,
@@ -5117,21 +5181,28 @@ struct mlx5_hlist_entry *
 		}
 		dev_flow->handle->split_flow_id = tag_id;
 #ifdef HAVE_IBV_FLOW_DV_SUPPORT
-		/* Set the sfx group attr. */
-		sample_res = (struct mlx5_flow_dv_sample_resource *)
-					dev_flow->dv.sample_res;
-		sfx_tbl = (struct mlx5_flow_tbl_resource *)
-					sample_res->normal_path_tbl;
-		sfx_tbl_data = container_of(sfx_tbl,
-					struct mlx5_flow_tbl_data_entry, tbl);
-		sfx_attr.group = sfx_attr.transfer ?
-					(sfx_tbl_data->table_id - 1) :
-					 sfx_tbl_data->table_id;
+		if (!modify_after_mirror) {
+			/* Set the sfx group attr. */
+			sample_res = (struct mlx5_flow_dv_sample_resource *)
+						dev_flow->dv.sample_res;
+			sfx_tbl = (struct mlx5_flow_tbl_resource *)
+						sample_res->normal_path_tbl;
+			sfx_tbl_data = container_of(sfx_tbl,
+						struct mlx5_flow_tbl_data_entry,
+						tbl);
+			sfx_attr.group = sfx_attr.transfer ?
+						(sfx_tbl_data->table_id - 1) :
+						sfx_tbl_data->table_id;
+		} else {
+			MLX5_ASSERT(attr->transfer);
+			sfx_attr.group = jump_table;
+		}
 		flow_split_info->prefix_layers =
 				flow_get_prefix_layer_flags(dev_flow);
 		flow_split_info->prefix_mark = dev_flow->handle->mark;
 		/* Suffix group level already be scaled with factor, set
-		 * skip_scale to 1 to avoid scale again in translation.
+		 * MLX5_SCALE_FLOW_GROUP_BIT of skip_scale to 1 to avoid scale
+		 * again in translation.
 		 */
 		flow_split_info->skip_scale = 1 << MLX5_SCALE_FLOW_GROUP_BIT;
 #endif
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index 63569ad..4b191fd 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -3600,8 +3600,6 @@ struct mlx5_cache_entry *
 					    (dev, &res, dev_flow, error);
 }
 
-static int fdb_mirror_limit;
-
 /**
  * Validate the modify-header actions.
  *
@@ -3629,12 +3627,6 @@ struct mlx5_cache_entry *
 					  RTE_FLOW_ERROR_TYPE_ACTION, NULL,
 					  "can't have encap action before"
 					  " modify action");
-	if ((action_flags & MLX5_FLOW_ACTION_SAMPLE) && fdb_mirror_limit)
-		return rte_flow_error_set(error, EINVAL,
-					  RTE_FLOW_ERROR_TYPE_ACTION, NULL,
-					  "can't support sample action before"
-					  " modify action for E-Switch"
-					  " mirroring");
 	return 0;
 }
 
@@ -4365,7 +4357,6 @@ struct mlx5_hlist_entry *
 	int actions_n = 0;
 	int ret;
 
-	fdb_mirror_limit = 0;
 	if (!sample)
 		return rte_flow_error_set(error, EINVAL,
 					  RTE_FLOW_ERROR_TYPE_ACTION, action,
@@ -4482,7 +4473,6 @@ struct mlx5_hlist_entry *
 						  "E-Switch doesn't support "
 						  "any optional action "
 						  "for sampling");
-		fdb_mirror_limit = 1;
 		if (sub_action_flags & MLX5_FLOW_ACTION_QUEUE)
 			return rte_flow_error_set(error, ENOTSUP,
 						  RTE_FLOW_ERROR_TYPE_ACTION,
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [dpdk-dev] [PATCH v2 5/5] doc: update the advanced E-switch mirroring supports
  2021-01-12 10:29 ` [dpdk-dev] [PATCH v2 0/5] Add the E-Switch mirroring and jump supports Jiawei Wang
                     ` (3 preceding siblings ...)
  2021-01-12 10:29   ` [dpdk-dev] [PATCH v2 4/5] net/mlx5: update modify actions support for E-Switch mirror Jiawei Wang
@ 2021-01-12 10:29   ` Jiawei Wang
  2021-01-22 12:37     ` Ferruh Yigit
  2021-01-20 15:05   ` [dpdk-dev] [PATCH v2 0/5] Add the E-Switch mirroring and jump supports Raslan Darawsheh
  5 siblings, 1 reply; 14+ messages in thread
From: Jiawei Wang @ 2021-01-12 10:29 UTC (permalink / raw)
  To: viacheslavo, matan, orika; +Cc: dev, rasland

Updates the description in MLX5 PMD and release note.

Adds the new supports for E-switch mirroring and jump action in
the same flow, and handle modify action in correct order regarding the
mirroring action on E-Switch.

Signed-off-by: Jiawei Wang <jiaweiw@nvidia.com>
Acked-by: Viacheslav Ovsiienko <viacheslavo@nvidia.com>
---
 doc/guides/nics/mlx5.rst               | 2 ++
 doc/guides/rel_notes/release_21_02.rst | 7 +++++++
 2 files changed, 9 insertions(+)

diff --git a/doc/guides/nics/mlx5.rst b/doc/guides/nics/mlx5.rst
index 3bda0f8..65922ef 100644
--- a/doc/guides/nics/mlx5.rst
+++ b/doc/guides/nics/mlx5.rst
@@ -98,6 +98,8 @@ Features
 - Hardware LRO.
 - Hairpin.
 - Multiple-thread flow insertion.
+- E-Switch mirroring and jump.
+- E-Switch mirroring and modify.
 
 Limitations
 -----------
diff --git a/doc/guides/rel_notes/release_21_02.rst b/doc/guides/rel_notes/release_21_02.rst
index 706cbf8..c5ba46e 100644
--- a/doc/guides/rel_notes/release_21_02.rst
+++ b/doc/guides/rel_notes/release_21_02.rst
@@ -55,6 +55,13 @@ New Features
      Also, make sure to start the actual text at the margin.
      =======================================================
 
+* **Updated Mellanox mlx5 driver.**
+
+  Updated the Mellanox mlx5 driver with new features and improvements, including:
+
+  * Add support for E-Switch mirroring and jump action in the same flow.
+  * Add support to handle modify action in correct order regarding the
+    mirroring action on E-Switch.
 
 Removed Items
 -------------
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [dpdk-dev] [PATCH v2 0/5] Add the E-Switch mirroring and jump supports
  2021-01-12 10:29 ` [dpdk-dev] [PATCH v2 0/5] Add the E-Switch mirroring and jump supports Jiawei Wang
                     ` (4 preceding siblings ...)
  2021-01-12 10:29   ` [dpdk-dev] [PATCH v2 5/5] doc: update the advanced E-switch mirroring supports Jiawei Wang
@ 2021-01-20 15:05   ` Raslan Darawsheh
  5 siblings, 0 replies; 14+ messages in thread
From: Raslan Darawsheh @ 2021-01-20 15:05 UTC (permalink / raw)
  To: Jiawei(Jonny) Wang, Slava Ovsiienko, Matan Azrad, Ori Kam; +Cc: dev

Hi,

> -----Original Message-----
> From: Jiawei Wang <jiaweiw@nvidia.com>
> Sent: Tuesday, January 12, 2021 12:29 PM
> To: Slava Ovsiienko <viacheslavo@nvidia.com>; Matan Azrad
> <matan@nvidia.com>; Ori Kam <orika@nvidia.com>
> Cc: dev@dpdk.org; Raslan Darawsheh <rasland@nvidia.com>
> Subject: [PATCH v2 0/5] Add the E-Switch mirroring and jump supports
> 
> MLX5 E-Switch mirroring is implemented as multiple destination array in
> one steering table. The array currently supports only port ID as
> destination actions.
> 
> This patchset adds the below supports for MLX5 PMD driver:
>   - Supports the metadata register Cx preserve capability query.
>   - Supports the jump action support as one of destination of array.
>   - Supports the modify action only impact on the one of destination.
> 
> The examples for the E-Switch flow use case and result as below:
>     set sample_actions 0 port_id id 1 / end
>     flow create 0 ingress transfer pattern eth / end actions sample ratio 1 index
> 0 / jump group 1 / end
>     flow create 1 ingress transfer group 1 pattern eth / end actions
> set_mac_dst mac_addr 00:aa:bb:cc:dd:ee / port_id id 2 / end
> 
> The flow results all the matched ingress packets are mirrored
> to port id 1 and go to group 1. In the group 1, packets are modified
> with the destination mac and sent to port id 2.
> 
> v2:
> * Rebase
> * Update commit message and document description
> 
> Jiawei Wang (5):
>   common/mlx5: query register c preserve capability via DevX
>   net/mlx5: support E-Switch mirroring and jump in one flow
>   net/mlx5: extend the skip scale flag
>   net/mlx5: update modify actions support for E-Switch mirror
>   doc: update the advanced E-switch mirroring supports
> 
>  doc/guides/nics/mlx5.rst               |   2 +
>  doc/guides/rel_notes/release_21_02.rst |   7 ++
>  drivers/common/mlx5/mlx5_devx_cmds.c   |   2 +
>  drivers/common/mlx5/mlx5_devx_cmds.h   |   1 +
>  drivers/common/mlx5/mlx5_prm.h         |   4 +-
>  drivers/net/mlx5/mlx5_flow.c           | 203 +++++++++++++++++++++++------
> ----
>  drivers/net/mlx5/mlx5_flow.h           |  23 +++-
>  drivers/net/mlx5/mlx5_flow_dv.c        |  92 +++++++++------
>  8 files changed, 235 insertions(+), 99 deletions(-)
> 
> --
> 1.8.3.1

Series rebased and applied to next-net-mlx,

Kindest regards,
Raslan Darawsheh

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [dpdk-dev] [PATCH v2 5/5] doc: update the advanced E-switch mirroring supports
  2021-01-12 10:29   ` [dpdk-dev] [PATCH v2 5/5] doc: update the advanced E-switch mirroring supports Jiawei Wang
@ 2021-01-22 12:37     ` Ferruh Yigit
  0 siblings, 0 replies; 14+ messages in thread
From: Ferruh Yigit @ 2021-01-22 12:37 UTC (permalink / raw)
  To: Jiawei Wang, viacheslavo, matan, orika; +Cc: dev, rasland

On 1/12/2021 10:29 AM, Jiawei Wang wrote:
> Updates the description in MLX5 PMD and release note.
> 
> Adds the new supports for E-switch mirroring and jump action in
> the same flow, and handle modify action in correct order regarding the
> mirroring action on E-Switch.
> 
> Signed-off-by: Jiawei Wang <jiaweiw@nvidia.com>
> Acked-by: Viacheslav Ovsiienko <viacheslavo@nvidia.com>

Squashed into relevant commits in next-net, thanks.


^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2021-01-22 12:37 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-01-10 11:06 [dpdk-dev] [PATCH 0/5] Add the E-Switch mirroring and jump supports Jiawei Wang
2021-01-10 11:06 ` [dpdk-dev] [PATCH 1/5] common/mlx5: query register c preserve capability via DevX Jiawei Wang
2021-01-10 11:06 ` [dpdk-dev] [PATCH 2/5] net/mlx5: support E-Switch mirroring and jump in one flow Jiawei Wang
2021-01-10 11:06 ` [dpdk-dev] [PATCH 3/5] net/mlx5: extend the skip scale flag Jiawei Wang
2021-01-10 11:06 ` [dpdk-dev] [PATCH 4/5] net/mlx5: supports modify one port in E-Switch mirroring Jiawei Wang
2021-01-10 11:06 ` [dpdk-dev] [PATCH 5/5] doc: update the advanced E-switch mirroring supports Jiawei Wang
2021-01-12 10:29 ` [dpdk-dev] [PATCH v2 0/5] Add the E-Switch mirroring and jump supports Jiawei Wang
2021-01-12 10:29   ` [dpdk-dev] [PATCH v2 1/5] common/mlx5: query register c preserve capability via DevX Jiawei Wang
2021-01-12 10:29   ` [dpdk-dev] [PATCH v2 2/5] net/mlx5: support E-Switch mirroring and jump in one flow Jiawei Wang
2021-01-12 10:29   ` [dpdk-dev] [PATCH v2 3/5] net/mlx5: extend the skip scale flag Jiawei Wang
2021-01-12 10:29   ` [dpdk-dev] [PATCH v2 4/5] net/mlx5: update modify actions support for E-Switch mirror Jiawei Wang
2021-01-12 10:29   ` [dpdk-dev] [PATCH v2 5/5] doc: update the advanced E-switch mirroring supports Jiawei Wang
2021-01-22 12:37     ` Ferruh Yigit
2021-01-20 15:05   ` [dpdk-dev] [PATCH v2 0/5] Add the E-Switch mirroring and jump supports Raslan Darawsheh

DPDK patches and discussions

This inbox may be cloned and mirrored by anyone:

	git clone --mirror http://inbox.dpdk.org/dev/0 dev/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 dev dev/ http://inbox.dpdk.org/dev \
		dev@dpdk.org
	public-inbox-index dev

Example config snippet for mirrors.
Newsgroup available over NNTP:
	nntp://inbox.dpdk.org/inbox.dpdk.dev


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git