DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH 0/3] Add RSS action support in the sample sub-actions list
@ 2021-01-10  9:10 Jiawei Wang
  2021-01-10  9:10 ` [dpdk-dev] [PATCH 1/3] app/testpmd: add RSS support in sample action Jiawei Wang
                   ` (3 more replies)
  0 siblings, 4 replies; 16+ messages in thread
From: Jiawei Wang @ 2021-01-10  9:10 UTC (permalink / raw)
  To: ferruh.yigit, viacheslavo, matan, orika; +Cc: dev, rasland

Currently the sample flow only supports Queue action in NIC-Rx domain.
This patchset adds the RSS action support in the sample sub-actions list.

The examples for the sample flow with RSS action and result as below:
    set sample_actions 0 mark id  0x12 / rss queues  0 1 2 3 end  / end
    flow create 0 ingress group 1 pattern eth / end actions sample ratio 1 index 0 / jump group 2 / end

This flow will result in all the matched ingress packets will be
jumped to next table, and the each packet will be marked and sent to rss
queues of the control application.

Jiawei Wang (3):
  app/testpmd: add RSS support in sample action
  net/mlx5: handle the RSS action in the sample
  doc: update RSS support in sample action

 app/test-pmd/cmdline_flow.c            |  26 ++++
 doc/guides/nics/mlx5.rst               |   1 +
 doc/guides/rel_notes/release_21_02.rst |   5 +
 drivers/net/mlx5/mlx5_flow.c           |  24 +++-
 drivers/net/mlx5/mlx5_flow_dv.c        | 226 +++++++++++++++++++++++----------
 5 files changed, 207 insertions(+), 75 deletions(-)

-- 
1.8.3.1


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

* [dpdk-dev] [PATCH 1/3] app/testpmd: add RSS support in sample action
  2021-01-10  9:10 [dpdk-dev] [PATCH 0/3] Add RSS action support in the sample sub-actions list Jiawei Wang
@ 2021-01-10  9:10 ` Jiawei Wang
  2021-01-10  9:10 ` [dpdk-dev] [PATCH 2/3] net/mlx5: handle the RSS action in the sample Jiawei Wang
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 16+ messages in thread
From: Jiawei Wang @ 2021-01-10  9:10 UTC (permalink / raw)
  To: ferruh.yigit, viacheslavo, matan, orika; +Cc: dev, rasland

Support rss action in the sample sub-actions list.

The examples for the sample flow use case and result as below:
set sample_actions 0 mark id  0x12 / rss queues  0 1 2 3 end  / end
flow create 0 ingress group 1 pattern eth / end actions
sample ratio 1 index 0 / jump group 2 / end

This flow will result in all the matched ingress packets will be
jumped to next table, and the each packet will be marked and sent to rss
queues of the control application.

Signed-off-by: Jiawei Wang <jiaweiw@nvidia.com>
---
 app/test-pmd/cmdline_flow.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 585cab9..28c3a1b 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -560,6 +560,7 @@ struct raw_sample_conf {
 struct rte_flow_action_count sample_count[RAW_SAMPLE_CONFS_MAX_NUM];
 struct rte_flow_action_port_id sample_port_id[RAW_SAMPLE_CONFS_MAX_NUM];
 struct rte_flow_action_raw_encap sample_encap[RAW_SAMPLE_CONFS_MAX_NUM];
+struct action_rss_data sample_rss_data[RAW_SAMPLE_CONFS_MAX_NUM];
 
 /** Maximum number of subsequent tokens and arguments on the stack. */
 #define CTX_STACK_SIZE 16
@@ -1548,6 +1549,7 @@ struct parse_action_priv {
 
 static const enum index next_action_sample[] = {
 	ACTION_QUEUE,
+	ACTION_RSS,
 	ACTION_MARK,
 	ACTION_COUNT,
 	ACTION_PORT_ID,
@@ -7515,6 +7517,7 @@ static int comp_set_sample_index(struct context *, const struct token *,
 	uint32_t i = 0;
 	struct rte_flow_action *action = NULL;
 	struct rte_flow_action *data = NULL;
+	const struct rte_flow_action_rss *rss = NULL;
 	size_t size = 0;
 	uint16_t idx = in->port; /* We borrow port field as index */
 	uint32_t max_size = sizeof(struct rte_flow_action) *
@@ -7546,6 +7549,29 @@ static int comp_set_sample_index(struct context *, const struct token *,
 				(const void *)action->conf, size);
 			action->conf = &sample_queue[idx];
 			break;
+		case RTE_FLOW_ACTION_TYPE_RSS:
+			size = sizeof(struct rte_flow_action_rss);
+			rss = action->conf;
+			rte_memcpy(&sample_rss_data[idx].conf,
+				   (const void *)rss, size);
+			if (rss->key_len) {
+				sample_rss_data[idx].conf.key =
+						sample_rss_data[idx].key;
+				rte_memcpy((void *)((uintptr_t)
+					   sample_rss_data[idx].conf.key),
+					   (const void *)rss->key,
+					   sizeof(uint8_t) * rss->key_len);
+			}
+			if (rss->queue_num) {
+				sample_rss_data[idx].conf.queue =
+						sample_rss_data[idx].queue;
+				rte_memcpy((void *)((uintptr_t)
+					   sample_rss_data[idx].conf.queue),
+					   (const void *)rss->queue,
+					   sizeof(uint16_t) * rss->queue_num);
+			}
+			action->conf = &sample_rss_data[idx].conf;
+			break;
 		case RTE_FLOW_ACTION_TYPE_RAW_ENCAP:
 			size = sizeof(struct rte_flow_action_raw_encap);
 			rte_memcpy(&sample_encap[idx],
-- 
1.8.3.1


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

* [dpdk-dev] [PATCH 2/3] net/mlx5: handle the RSS action in the sample
  2021-01-10  9:10 [dpdk-dev] [PATCH 0/3] Add RSS action support in the sample sub-actions list Jiawei Wang
  2021-01-10  9:10 ` [dpdk-dev] [PATCH 1/3] app/testpmd: add RSS support in sample action Jiawei Wang
@ 2021-01-10  9:10 ` Jiawei Wang
  2021-01-10  9:10 ` [dpdk-dev] [PATCH 3/3] doc: update RSS support in sample action Jiawei Wang
  2021-01-12 10:01 ` [dpdk-dev] [PATCH v2 0/4] Add RSS action support in the sample sub-actions list Jiawei Wang
  3 siblings, 0 replies; 16+ messages in thread
From: Jiawei Wang @ 2021-01-10  9:10 UTC (permalink / raw)
  To: ferruh.yigit, viacheslavo, matan, orika; +Cc: dev, rasland

PMD validates the rss action in the sample sub-actions list,
then translate into rdma-core action and it will be used for sample
path destination.

If the RSS action both in sample sub-actions list and original flow,
the rss level and rss type in the sample sub-actions list should be
consistent with the original flow list, since the expanding items
for RSS should same in one flow.

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

diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index 2a4073c..96a7e0d 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -3174,16 +3174,28 @@ struct mlx5_flow_tunnel_info {
 static const struct rte_flow_action_rss*
 flow_get_rss_action(const struct rte_flow_action actions[])
 {
+	const struct rte_flow_action_rss *rss = NULL;
+
 	for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) {
 		switch (actions->type) {
 		case RTE_FLOW_ACTION_TYPE_RSS:
-			return (const struct rte_flow_action_rss *)
-			       actions->conf;
+			rss = actions->conf;
+			break;
+		case RTE_FLOW_ACTION_TYPE_SAMPLE:
+		{
+			const struct rte_flow_action_sample *sample =
+								actions->conf;
+			const struct rte_flow_action *act = sample->actions;
+			for (; act->type != RTE_FLOW_ACTION_TYPE_END; act++)
+				if (act->type == RTE_FLOW_ACTION_TYPE_RSS)
+					rss = act->conf;
+			break;
+		}
 		default:
 			break;
 		}
 	}
-	return NULL;
+	return rss;
 }
 
 /**
@@ -5278,7 +5290,7 @@ struct mlx5_hlist_entry *
 	struct mlx5_priv *priv = dev->data->dev_private;
 	struct rte_flow *flow = NULL;
 	struct mlx5_flow *dev_flow;
-	const struct rte_flow_action_rss *rss;
+	const struct rte_flow_action_rss *rss = NULL;
 	struct mlx5_translated_shared_action
 		shared_actions[MLX5_MAX_SHARED_ACTIONS];
 	int shared_actions_n = MLX5_MAX_SHARED_ACTIONS;
@@ -5356,7 +5368,9 @@ struct mlx5_hlist_entry *
 	MLX5_ASSERT(flow->drv_type > MLX5_FLOW_TYPE_MIN &&
 		    flow->drv_type < MLX5_FLOW_TYPE_MAX);
 	memset(rss_desc, 0, offsetof(struct mlx5_flow_rss_desc, queue));
-	rss = flow_get_rss_action(p_actions_rx);
+	/* RSS Action only works on NIC RX domain */
+	if (attr->ingress && !attr->transfer)
+		rss = flow_get_rss_action(p_actions_rx);
 	if (rss) {
 		if (flow_rss_workspace_adjust(wks, rss_desc, rss->queue_num))
 			return 0;
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index e4736ee..3fa15cf 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -4344,6 +4344,10 @@ struct mlx5_hlist_entry *
  *   Attributes of flow that includes this action.
  * @param[in] item_flags
  *   Holds the items detected.
+ * @param[in] rss
+ *   Pointer to the RSS action.
+ * @param[out] sample_rss
+ *   Pointer to the RSS action in sample action list.
  * @param[out] error
  *   Pointer to error structure.
  *
@@ -4355,7 +4359,9 @@ struct mlx5_hlist_entry *
 			       const struct rte_flow_action *action,
 			       struct rte_eth_dev *dev,
 			       const struct rte_flow_attr *attr,
-			       const uint64_t item_flags,
+			       uint64_t item_flags,
+			       const struct rte_flow_action_rss *rss,
+			       const struct rte_flow_action_rss **sample_rss,
 			       struct rte_flow_error *error)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
@@ -4415,6 +4421,28 @@ struct mlx5_hlist_entry *
 			sub_action_flags |= MLX5_FLOW_ACTION_QUEUE;
 			++actions_n;
 			break;
+		case RTE_FLOW_ACTION_TYPE_RSS:
+			*sample_rss = act->conf;
+			ret = mlx5_flow_validate_action_rss(act,
+							    sub_action_flags,
+							    dev, attr,
+							    item_flags,
+							    error);
+			if (ret < 0)
+				return ret;
+			if (rss && *sample_rss &&
+			    ((*sample_rss)->level != rss->level ||
+			    (*sample_rss)->types != rss->types))
+				return rte_flow_error_set(error, ENOTSUP,
+					RTE_FLOW_ERROR_TYPE_ACTION,
+					NULL,
+					"Can't use the different RSS types "
+					"or level in the same flow");
+			if (*sample_rss != NULL && (*sample_rss)->queue_num)
+				queue_index = (*sample_rss)->queue[0];
+			sub_action_flags |= MLX5_FLOW_ACTION_RSS;
+			++actions_n;
+			break;
 		case RTE_FLOW_ACTION_TYPE_MARK:
 			ret = flow_dv_validate_action_mark(dev, act,
 							   sub_action_flags,
@@ -4463,7 +4491,8 @@ struct mlx5_hlist_entry *
 		}
 	}
 	if (attr->ingress && !attr->transfer) {
-		if (!(sub_action_flags & MLX5_FLOW_ACTION_QUEUE))
+		if (!(sub_action_flags & (MLX5_FLOW_ACTION_QUEUE |
+					  MLX5_FLOW_ACTION_RSS)))
 			return rte_flow_error_set(error, EINVAL,
 						  RTE_FLOW_ERROR_TYPE_ACTION,
 						  NULL,
@@ -4490,6 +4519,11 @@ struct mlx5_hlist_entry *
 						  RTE_FLOW_ERROR_TYPE_ACTION,
 						  NULL,
 						  "unsupported action QUEUE");
+		if (sub_action_flags & MLX5_FLOW_ACTION_RSS)
+			return rte_flow_error_set(error, ENOTSUP,
+						  RTE_FLOW_ERROR_TYPE_ACTION,
+						  NULL,
+						  "unsupported action QUEUE");
 		if (!(sub_action_flags & MLX5_FLOW_ACTION_PORT_ID))
 			return rte_flow_error_set(error, EINVAL,
 						  RTE_FLOW_ERROR_TYPE_ACTION,
@@ -5240,7 +5274,8 @@ struct mlx5_hlist_entry *
 	const struct rte_flow_item *gre_item = NULL;
 	const struct rte_flow_action_raw_decap *decap;
 	const struct rte_flow_action_raw_encap *encap;
-	const struct rte_flow_action_rss *rss;
+	const struct rte_flow_action_rss *rss = NULL;
+	const struct rte_flow_action_rss *sample_rss = NULL;
 	const struct rte_flow_item_tcp nic_tcp_mask = {
 		.hdr = {
 			.tcp_flags = 0xFF,
@@ -5709,6 +5744,14 @@ struct mlx5_hlist_entry *
 							    error);
 			if (ret < 0)
 				return ret;
+			if (rss && sample_rss &&
+			    (sample_rss->level != rss->level ||
+			    sample_rss->types != rss->types))
+				return rte_flow_error_set(error, ENOTSUP,
+					RTE_FLOW_ERROR_TYPE_ACTION,
+					NULL,
+					"Can't use the different RSS types "
+					"or level in the same flow");
 			if (rss != NULL && rss->queue_num)
 				queue_index = rss->queue[0];
 			action_flags |= MLX5_FLOW_ACTION_RSS;
@@ -6027,6 +6070,7 @@ struct mlx5_hlist_entry *
 			ret = flow_dv_validate_action_sample(action_flags,
 							     actions, dev,
 							     attr, item_flags,
+							     rss, &sample_rss,
 							     error);
 			if (ret < 0)
 				return ret;
@@ -9053,7 +9097,7 @@ struct mlx5_cache_entry *
  * @param[in] dev
  *   Pointer to rte_eth_dev structure.
  * @param[in] action
- *   Pointer to action structure.
+ *   Pointer to sample action structure.
  * @param[in, out] dev_flow
  *   Pointer to the mlx5_flow.
  * @param[in] attr
@@ -9072,7 +9116,7 @@ struct mlx5_cache_entry *
  */
 static int
 flow_dv_translate_action_sample(struct rte_eth_dev *dev,
-				const struct rte_flow_action *action,
+				const struct rte_flow_action_sample *action,
 				struct mlx5_flow *dev_flow,
 				const struct rte_flow_attr *attr,
 				uint32_t *num_of_dest,
@@ -9081,9 +9125,7 @@ struct mlx5_cache_entry *
 				struct rte_flow_error *error)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
-	const struct rte_flow_action_sample *sample_action;
 	const struct rte_flow_action *sub_actions;
-	const struct rte_flow_action_queue *queue;
 	struct mlx5_flow_sub_actions_list *sample_act;
 	struct mlx5_flow_sub_actions_idx *sample_idx;
 	struct mlx5_flow_workspace *wks = mlx5_flow_get_thread_workspace();
@@ -9094,9 +9136,8 @@ struct mlx5_cache_entry *
 	rss_desc = &wks->rss_desc;
 	sample_act = &res->sample_act;
 	sample_idx = &res->sample_idx;
-	sample_action = (const struct rte_flow_action_sample *)action->conf;
-	res->ratio = sample_action->ratio;
-	sub_actions = sample_action->actions;
+	res->ratio = action->ratio;
+	sub_actions = action->actions;
 	for (; sub_actions->type != RTE_FLOW_ACTION_TYPE_END; sub_actions++) {
 		int type = sub_actions->type;
 		uint32_t pre_rix = 0;
@@ -9104,6 +9145,7 @@ struct mlx5_cache_entry *
 		switch (type) {
 		case RTE_FLOW_ACTION_TYPE_QUEUE:
 		{
+			const struct rte_flow_action_queue *queue;
 			struct mlx5_hrxq *hrxq;
 			uint32_t hrxq_idx;
 
@@ -9130,6 +9172,45 @@ struct mlx5_cache_entry *
 					MLX5_FLOW_FATE_QUEUE;
 			break;
 		}
+		case RTE_FLOW_ACTION_TYPE_RSS:
+		{
+			struct mlx5_hrxq *hrxq;
+			uint32_t hrxq_idx;
+			const struct rte_flow_action_rss *rss;
+			const uint8_t *rss_key;
+
+			rss = sub_actions->conf;
+			memcpy(rss_desc->queue, rss->queue,
+			       rss->queue_num * sizeof(uint16_t));
+			rss_desc->queue_num = rss->queue_num;
+			/* NULL RSS key indicates default RSS key. */
+			rss_key = !rss->key ? rss_hash_default_key : rss->key;
+			memcpy(rss_desc->key, rss_key, MLX5_RSS_HASH_KEY_LEN);
+			/*
+			 * rss->level and rss.types should be set in advance
+			 * when expanding items for RSS.
+			 */
+			flow_dv_hashfields_set(dev_flow, rss_desc);
+			hrxq = flow_dv_hrxq_prepare(dev, dev_flow,
+						    rss_desc, &hrxq_idx);
+			if (!hrxq)
+				return rte_flow_error_set
+					(error, rte_errno,
+					 RTE_FLOW_ERROR_TYPE_ACTION,
+					 NULL,
+					 "cannot create fate queue");
+			sample_act->dr_queue_action = hrxq->action;
+			sample_idx->rix_hrxq = hrxq_idx;
+			sample_actions[sample_act->actions_num++] =
+						hrxq->action;
+			(*num_of_dest)++;
+			action_flags |= MLX5_FLOW_ACTION_RSS;
+			if (action_flags & MLX5_FLOW_ACTION_MARK)
+				dev_flow->handle->rix_hrxq = hrxq_idx;
+			dev_flow->handle->fate_action =
+					MLX5_FLOW_FATE_QUEUE;
+			break;
+		}
 		case RTE_FLOW_ACTION_TYPE_MARK:
 		{
 			uint32_t tag_be = mlx5_flow_mark_set
@@ -9694,6 +9775,7 @@ struct mlx5_cache_entry *
 	struct mlx5_flow_dv_dest_array_resource mdest_res;
 	struct mlx5_flow_dv_sample_resource sample_res;
 	void *sample_actions[MLX5_DV_MAX_NUMBER_OF_ACTIONS] = {0};
+	const struct rte_flow_action_sample *sample = NULL;
 	struct mlx5_flow_sub_actions_list *sample_act;
 	uint32_t sample_act_pos = UINT32_MAX;
 	uint32_t num_of_dest = 0;
@@ -10235,15 +10317,8 @@ struct mlx5_cache_entry *
 			break;
 		case RTE_FLOW_ACTION_TYPE_SAMPLE:
 			sample_act_pos = actions_n;
-			ret = flow_dv_translate_action_sample(dev,
-							      actions,
-							      dev_flow, attr,
-							      &num_of_dest,
-							      sample_actions,
-							      &sample_res,
-							      error);
-			if (ret < 0)
-				return ret;
+			sample = (const struct rte_flow_action_sample *)
+				 action->conf;
 			actions_n++;
 			action_flags |= MLX5_FLOW_ACTION_SAMPLE;
 			/* put encap action into group if work with port id */
@@ -10279,30 +10354,6 @@ struct mlx5_cache_entry *
 					  flow->counter, NULL))->action;
 				actions_n++;
 			}
-			if (action_flags & MLX5_FLOW_ACTION_SAMPLE) {
-				ret = flow_dv_create_action_sample(dev,
-							  dev_flow,
-							  num_of_dest,
-							  &sample_res,
-							  &mdest_res,
-							  sample_actions,
-							  action_flags,
-							  error);
-				if (ret < 0)
-					return rte_flow_error_set
-						(error, rte_errno,
-						RTE_FLOW_ERROR_TYPE_ACTION,
-						NULL,
-						"cannot create sample action");
-				if (num_of_dest > 1) {
-					dev_flow->dv.actions[sample_act_pos] =
-					dev_flow->dv.dest_array_res->action;
-				} else {
-					dev_flow->dv.actions[sample_act_pos] =
-					dev_flow->dv.sample_res->verbs_action;
-				}
-			}
-			break;
 		default:
 			break;
 		}
@@ -10310,33 +10361,6 @@ struct mlx5_cache_entry *
 		    modify_action_position == UINT32_MAX)
 			modify_action_position = actions_n++;
 	}
-	/*
-	 * For multiple destination (sample action with ratio=1), the encap
-	 * action and port id action will be combined into group action.
-	 * 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) {
-		int i;
-		void *temp_actions[MLX5_DV_MAX_NUMBER_OF_ACTIONS] = {0};
-
-		for (i = 0; i < actions_n; i++) {
-			if ((sample_act->dr_encap_action &&
-				sample_act->dr_encap_action ==
-				dev_flow->dv.actions[i]) ||
-				(sample_act->dr_port_id_action &&
-				sample_act->dr_port_id_action ==
-				dev_flow->dv.actions[i]))
-				continue;
-			temp_actions[tmp_actions_n++] = dev_flow->dv.actions[i];
-		}
-		memcpy((void *)dev_flow->dv.actions,
-				(void *)temp_actions,
-				tmp_actions_n * sizeof(void *));
-		actions_n = tmp_actions_n;
-	}
-	dev_flow->dv.actions_n = actions_n;
-	dev_flow->act_flags = action_flags;
 	for (; items->type != RTE_FLOW_ITEM_TYPE_END; items++) {
 		int tunnel = !!(item_flags & MLX5_FLOW_LAYER_TUNNEL);
 		int item_type = items->type;
@@ -10588,6 +10612,68 @@ struct mlx5_cache_entry *
 	handle->layers |= item_flags;
 	if (action_flags & MLX5_FLOW_ACTION_RSS)
 		flow_dv_hashfields_set(dev_flow, rss_desc);
+	/* If has RSS action in the sample action, the Sample/Mirror resource
+	 * should be registered after the hash filed be update.
+	 */
+	if (action_flags & MLX5_FLOW_ACTION_SAMPLE) {
+		ret = flow_dv_translate_action_sample(dev,
+						      sample,
+						      dev_flow, attr,
+						      &num_of_dest,
+						      sample_actions,
+						      &sample_res,
+						      error);
+		if (ret < 0)
+			return ret;
+		ret = flow_dv_create_action_sample(dev,
+						   dev_flow,
+						   num_of_dest,
+						   &sample_res,
+						   &mdest_res,
+						   sample_actions,
+						   action_flags,
+						   error);
+		if (ret < 0)
+			return rte_flow_error_set
+						(error, rte_errno,
+						RTE_FLOW_ERROR_TYPE_ACTION,
+						NULL,
+						"cannot create sample action");
+		if (num_of_dest > 1) {
+			dev_flow->dv.actions[sample_act_pos] =
+			dev_flow->dv.dest_array_res->action;
+		} else {
+			dev_flow->dv.actions[sample_act_pos] =
+			dev_flow->dv.sample_res->verbs_action;
+		}
+	}
+	/*
+	 * For multiple destination (sample action with ratio=1), the encap
+	 * action and port id action will be combined into group action.
+	 * 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) {
+		int i;
+		void *temp_actions[MLX5_DV_MAX_NUMBER_OF_ACTIONS] = {0};
+
+		for (i = 0; i < actions_n; i++) {
+			if ((sample_act->dr_encap_action &&
+				sample_act->dr_encap_action ==
+				dev_flow->dv.actions[i]) ||
+				(sample_act->dr_port_id_action &&
+				sample_act->dr_port_id_action ==
+				dev_flow->dv.actions[i]))
+				continue;
+			temp_actions[tmp_actions_n++] = dev_flow->dv.actions[i];
+		}
+		memcpy((void *)dev_flow->dv.actions,
+				(void *)temp_actions,
+				tmp_actions_n * sizeof(void *));
+		actions_n = tmp_actions_n;
+	}
+	dev_flow->dv.actions_n = actions_n;
+	dev_flow->act_flags = action_flags;
 	/* Register matcher. */
 	matcher.crc = rte_raw_cksum((const void *)matcher.mask.buf,
 				    matcher.mask.size);
-- 
1.8.3.1


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

* [dpdk-dev] [PATCH 3/3] doc: update RSS support in sample action
  2021-01-10  9:10 [dpdk-dev] [PATCH 0/3] Add RSS action support in the sample sub-actions list Jiawei Wang
  2021-01-10  9:10 ` [dpdk-dev] [PATCH 1/3] app/testpmd: add RSS support in sample action Jiawei Wang
  2021-01-10  9:10 ` [dpdk-dev] [PATCH 2/3] net/mlx5: handle the RSS action in the sample Jiawei Wang
@ 2021-01-10  9:10 ` Jiawei Wang
  2021-01-12 10:01 ` [dpdk-dev] [PATCH v2 0/4] Add RSS action support in the sample sub-actions list Jiawei Wang
  3 siblings, 0 replies; 16+ messages in thread
From: Jiawei Wang @ 2021-01-10  9:10 UTC (permalink / raw)
  To: ferruh.yigit, viacheslavo, matan, orika; +Cc: dev, rasland

Add descrption about RSS action will be supported in the Sample
action in MLX5 PMD.

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

diff --git a/doc/guides/nics/mlx5.rst b/doc/guides/nics/mlx5.rst
index 3bda0f8..c20c0ed 100644
--- a/doc/guides/nics/mlx5.rst
+++ b/doc/guides/nics/mlx5.rst
@@ -98,6 +98,7 @@ Features
 - Hardware LRO.
 - Hairpin.
 - Multiple-thread flow insertion.
+- RSS support in sample action.
 
 Limitations
 -----------
diff --git a/doc/guides/rel_notes/release_21_02.rst b/doc/guides/rel_notes/release_21_02.rst
index 638f981..74ec91f 100644
--- a/doc/guides/rel_notes/release_21_02.rst
+++ b/doc/guides/rel_notes/release_21_02.rst
@@ -55,6 +55,11 @@ 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:
+
+  * Added support for RSS action in the sample sub-actions list.
 
 Removed Items
 -------------
-- 
1.8.3.1


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

* [dpdk-dev] [PATCH v2 0/4] Add RSS action support in the sample sub-actions list
  2021-01-10  9:10 [dpdk-dev] [PATCH 0/3] Add RSS action support in the sample sub-actions list Jiawei Wang
                   ` (2 preceding siblings ...)
  2021-01-10  9:10 ` [dpdk-dev] [PATCH 3/3] doc: update RSS support in sample action Jiawei Wang
@ 2021-01-12 10:01 ` Jiawei Wang
  2021-01-12 10:01   ` [dpdk-dev] [PATCH v2 1/4] app/testpmd: add RSS support in sample action Jiawei Wang
                     ` (4 more replies)
  3 siblings, 5 replies; 16+ messages in thread
From: Jiawei Wang @ 2021-01-12 10:01 UTC (permalink / raw)
  To: ferruh.yigit, viacheslavo, matan, orika; +Cc: dev, rasland

Currently the sample flow only supports Queue action in NIC-Rx domain.
This patchset adds the RSS action support in the sample sub-actions list.

The examples for the sample flow with RSS action and result as below:
    set sample_actions 0 mark id  0x12 / rss queues  0 1 2 3 end  / end
    flow create 0 ingress group 1 pattern eth / end actions sample ratio 1 index 0 / jump group 2 / end

This flow will result in all the matched ingress packets will be
jumped to the next table, and the each packet will be marked with 0x12
and duplicated to rss queues of the control application.

v2:
* Rebase
* Update commit message and document description
* Split the commit into one fix for rss checking and another for sample rss feature

Jiawei Wang (4):
  app/testpmd: add RSS support in sample action
  net/mlx5: fix the unnecessary checking for RSS action
  net/mlx5: handle the RSS action in the sample
  doc: update RSS support in sample action

 app/test-pmd/cmdline_flow.c            |  26 ++++
 doc/guides/nics/mlx5.rst               |   1 +
 doc/guides/rel_notes/release_21_02.rst |   5 +
 drivers/net/mlx5/mlx5_flow.c           |  24 +++-
 drivers/net/mlx5/mlx5_flow_dv.c        | 226 +++++++++++++++++++++++----------
 5 files changed, 207 insertions(+), 75 deletions(-)

-- 
1.8.3.1


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

* [dpdk-dev] [PATCH v2 1/4] app/testpmd: add RSS support in sample action
  2021-01-12 10:01 ` [dpdk-dev] [PATCH v2 0/4] Add RSS action support in the sample sub-actions list Jiawei Wang
@ 2021-01-12 10:01   ` Jiawei Wang
  2021-01-12 10:01   ` [dpdk-dev] [PATCH v2 2/4] net/mlx5: fix the unnecessary checking for RSS action Jiawei Wang
                     ` (3 subsequent siblings)
  4 siblings, 0 replies; 16+ messages in thread
From: Jiawei Wang @ 2021-01-12 10:01 UTC (permalink / raw)
  To: ferruh.yigit, viacheslavo, matan, orika; +Cc: dev, rasland

Support rss action in the sample sub-actions list.

The examples for the sample flow use case and result as below:
set sample_actions 0 mark id  0x12 / rss queues  0 1 2 3 end  / end
flow create 0 ingress group 1 pattern eth / end actions
sample ratio 1 index 0 / jump group 2 / end

This flow will result in all the matched ingress packets will be
jumped to next table, and the each packet will be marked with 0x12
and duplicated to rss queues of the control application.

Signed-off-by: Jiawei Wang <jiaweiw@nvidia.com>
Acked-by: Viacheslav Ovsiienko <viacheslavo@nvidia.com>
---
 app/test-pmd/cmdline_flow.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 585cab9..28c3a1b 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -560,6 +560,7 @@ struct raw_sample_conf {
 struct rte_flow_action_count sample_count[RAW_SAMPLE_CONFS_MAX_NUM];
 struct rte_flow_action_port_id sample_port_id[RAW_SAMPLE_CONFS_MAX_NUM];
 struct rte_flow_action_raw_encap sample_encap[RAW_SAMPLE_CONFS_MAX_NUM];
+struct action_rss_data sample_rss_data[RAW_SAMPLE_CONFS_MAX_NUM];
 
 /** Maximum number of subsequent tokens and arguments on the stack. */
 #define CTX_STACK_SIZE 16
@@ -1548,6 +1549,7 @@ struct parse_action_priv {
 
 static const enum index next_action_sample[] = {
 	ACTION_QUEUE,
+	ACTION_RSS,
 	ACTION_MARK,
 	ACTION_COUNT,
 	ACTION_PORT_ID,
@@ -7515,6 +7517,7 @@ static int comp_set_sample_index(struct context *, const struct token *,
 	uint32_t i = 0;
 	struct rte_flow_action *action = NULL;
 	struct rte_flow_action *data = NULL;
+	const struct rte_flow_action_rss *rss = NULL;
 	size_t size = 0;
 	uint16_t idx = in->port; /* We borrow port field as index */
 	uint32_t max_size = sizeof(struct rte_flow_action) *
@@ -7546,6 +7549,29 @@ static int comp_set_sample_index(struct context *, const struct token *,
 				(const void *)action->conf, size);
 			action->conf = &sample_queue[idx];
 			break;
+		case RTE_FLOW_ACTION_TYPE_RSS:
+			size = sizeof(struct rte_flow_action_rss);
+			rss = action->conf;
+			rte_memcpy(&sample_rss_data[idx].conf,
+				   (const void *)rss, size);
+			if (rss->key_len) {
+				sample_rss_data[idx].conf.key =
+						sample_rss_data[idx].key;
+				rte_memcpy((void *)((uintptr_t)
+					   sample_rss_data[idx].conf.key),
+					   (const void *)rss->key,
+					   sizeof(uint8_t) * rss->key_len);
+			}
+			if (rss->queue_num) {
+				sample_rss_data[idx].conf.queue =
+						sample_rss_data[idx].queue;
+				rte_memcpy((void *)((uintptr_t)
+					   sample_rss_data[idx].conf.queue),
+					   (const void *)rss->queue,
+					   sizeof(uint16_t) * rss->queue_num);
+			}
+			action->conf = &sample_rss_data[idx].conf;
+			break;
 		case RTE_FLOW_ACTION_TYPE_RAW_ENCAP:
 			size = sizeof(struct rte_flow_action_raw_encap);
 			rte_memcpy(&sample_encap[idx],
-- 
1.8.3.1


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

* [dpdk-dev] [PATCH v2 2/4] net/mlx5: fix the unnecessary checking for RSS action
  2021-01-12 10:01 ` [dpdk-dev] [PATCH v2 0/4] Add RSS action support in the sample sub-actions list Jiawei Wang
  2021-01-12 10:01   ` [dpdk-dev] [PATCH v2 1/4] app/testpmd: add RSS support in sample action Jiawei Wang
@ 2021-01-12 10:01   ` Jiawei Wang
  2021-01-12 10:01   ` [dpdk-dev] [PATCH v2 3/4] net/mlx5: handle the RSS action in the sample Jiawei Wang
                     ` (2 subsequent siblings)
  4 siblings, 0 replies; 16+ messages in thread
From: Jiawei Wang @ 2021-01-12 10:01 UTC (permalink / raw)
  To: ferruh.yigit, viacheslavo, matan, orika; +Cc: dev, rasland, stable

RSS action is valid only in NIC-RX domain, this fix bypass
the function that getting RSS action from the flow action list
under no NIC-RX domain.

Fixes: e745f900072e ("net/mlx5: optimize flow RSS struct")
Cc: stable@dpdk.org

Signed-off-by: Jiawei Wang <jiaweiw@nvidia.com>
Acked-by: Viacheslav Ovsiienko <viacheslavo@nvidia.com>
---
 drivers/net/mlx5/mlx5_flow.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index 2a4073c..29c6e14 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -5356,7 +5356,9 @@ struct mlx5_hlist_entry *
 	MLX5_ASSERT(flow->drv_type > MLX5_FLOW_TYPE_MIN &&
 		    flow->drv_type < MLX5_FLOW_TYPE_MAX);
 	memset(rss_desc, 0, offsetof(struct mlx5_flow_rss_desc, queue));
-	rss = flow_get_rss_action(p_actions_rx);
+	/* RSS Action only works on NIC RX domain */
+	if (attr->ingress && !attr->transfer)
+		rss = flow_get_rss_action(p_actions_rx);
 	if (rss) {
 		if (flow_rss_workspace_adjust(wks, rss_desc, rss->queue_num))
 			return 0;
-- 
1.8.3.1


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

* [dpdk-dev] [PATCH v2 3/4] net/mlx5: handle the RSS action in the sample
  2021-01-12 10:01 ` [dpdk-dev] [PATCH v2 0/4] Add RSS action support in the sample sub-actions list Jiawei Wang
  2021-01-12 10:01   ` [dpdk-dev] [PATCH v2 1/4] app/testpmd: add RSS support in sample action Jiawei Wang
  2021-01-12 10:01   ` [dpdk-dev] [PATCH v2 2/4] net/mlx5: fix the unnecessary checking for RSS action Jiawei Wang
@ 2021-01-12 10:01   ` Jiawei Wang
  2021-01-12 10:01   ` [dpdk-dev] [PATCH v2 4/4] doc: update RSS support in sample action Jiawei Wang
  2021-01-14  7:24   ` [dpdk-dev] [PATCH v3 0/4] Add RSS action support in the sample sub-actions list Jiawei Wang
  4 siblings, 0 replies; 16+ messages in thread
From: Jiawei Wang @ 2021-01-12 10:01 UTC (permalink / raw)
  To: ferruh.yigit, viacheslavo, matan, orika; +Cc: dev, rasland

PMD validates the rss action in the sample sub-actions list,
then translates into rdma-core action and it will be used for sample
path destination.

If the RSS action is in both sample sub-actions list and original flow,
the rss level and rss type in the sample sub-actions list should be
consistent with the original flow list, since the expanding items
for RSS should be the same for both actions.

Signed-off-by: Jiawei Wang <jiaweiw@nvidia.com>
Acked-by: Viacheslav Ovsiienko <viacheslavo@mellanox.com>
---
 drivers/net/mlx5/mlx5_flow.c    |  20 +++-
 drivers/net/mlx5/mlx5_flow_dv.c | 226 +++++++++++++++++++++++++++-------------
 2 files changed, 172 insertions(+), 74 deletions(-)

diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index 29c6e14..96a7e0d 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -3174,16 +3174,28 @@ struct mlx5_flow_tunnel_info {
 static const struct rte_flow_action_rss*
 flow_get_rss_action(const struct rte_flow_action actions[])
 {
+	const struct rte_flow_action_rss *rss = NULL;
+
 	for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) {
 		switch (actions->type) {
 		case RTE_FLOW_ACTION_TYPE_RSS:
-			return (const struct rte_flow_action_rss *)
-			       actions->conf;
+			rss = actions->conf;
+			break;
+		case RTE_FLOW_ACTION_TYPE_SAMPLE:
+		{
+			const struct rte_flow_action_sample *sample =
+								actions->conf;
+			const struct rte_flow_action *act = sample->actions;
+			for (; act->type != RTE_FLOW_ACTION_TYPE_END; act++)
+				if (act->type == RTE_FLOW_ACTION_TYPE_RSS)
+					rss = act->conf;
+			break;
+		}
 		default:
 			break;
 		}
 	}
-	return NULL;
+	return rss;
 }
 
 /**
@@ -5278,7 +5290,7 @@ struct mlx5_hlist_entry *
 	struct mlx5_priv *priv = dev->data->dev_private;
 	struct rte_flow *flow = NULL;
 	struct mlx5_flow *dev_flow;
-	const struct rte_flow_action_rss *rss;
+	const struct rte_flow_action_rss *rss = NULL;
 	struct mlx5_translated_shared_action
 		shared_actions[MLX5_MAX_SHARED_ACTIONS];
 	int shared_actions_n = MLX5_MAX_SHARED_ACTIONS;
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index e4736ee..3fa15cf 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -4344,6 +4344,10 @@ struct mlx5_hlist_entry *
  *   Attributes of flow that includes this action.
  * @param[in] item_flags
  *   Holds the items detected.
+ * @param[in] rss
+ *   Pointer to the RSS action.
+ * @param[out] sample_rss
+ *   Pointer to the RSS action in sample action list.
  * @param[out] error
  *   Pointer to error structure.
  *
@@ -4355,7 +4359,9 @@ struct mlx5_hlist_entry *
 			       const struct rte_flow_action *action,
 			       struct rte_eth_dev *dev,
 			       const struct rte_flow_attr *attr,
-			       const uint64_t item_flags,
+			       uint64_t item_flags,
+			       const struct rte_flow_action_rss *rss,
+			       const struct rte_flow_action_rss **sample_rss,
 			       struct rte_flow_error *error)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
@@ -4415,6 +4421,28 @@ struct mlx5_hlist_entry *
 			sub_action_flags |= MLX5_FLOW_ACTION_QUEUE;
 			++actions_n;
 			break;
+		case RTE_FLOW_ACTION_TYPE_RSS:
+			*sample_rss = act->conf;
+			ret = mlx5_flow_validate_action_rss(act,
+							    sub_action_flags,
+							    dev, attr,
+							    item_flags,
+							    error);
+			if (ret < 0)
+				return ret;
+			if (rss && *sample_rss &&
+			    ((*sample_rss)->level != rss->level ||
+			    (*sample_rss)->types != rss->types))
+				return rte_flow_error_set(error, ENOTSUP,
+					RTE_FLOW_ERROR_TYPE_ACTION,
+					NULL,
+					"Can't use the different RSS types "
+					"or level in the same flow");
+			if (*sample_rss != NULL && (*sample_rss)->queue_num)
+				queue_index = (*sample_rss)->queue[0];
+			sub_action_flags |= MLX5_FLOW_ACTION_RSS;
+			++actions_n;
+			break;
 		case RTE_FLOW_ACTION_TYPE_MARK:
 			ret = flow_dv_validate_action_mark(dev, act,
 							   sub_action_flags,
@@ -4463,7 +4491,8 @@ struct mlx5_hlist_entry *
 		}
 	}
 	if (attr->ingress && !attr->transfer) {
-		if (!(sub_action_flags & MLX5_FLOW_ACTION_QUEUE))
+		if (!(sub_action_flags & (MLX5_FLOW_ACTION_QUEUE |
+					  MLX5_FLOW_ACTION_RSS)))
 			return rte_flow_error_set(error, EINVAL,
 						  RTE_FLOW_ERROR_TYPE_ACTION,
 						  NULL,
@@ -4490,6 +4519,11 @@ struct mlx5_hlist_entry *
 						  RTE_FLOW_ERROR_TYPE_ACTION,
 						  NULL,
 						  "unsupported action QUEUE");
+		if (sub_action_flags & MLX5_FLOW_ACTION_RSS)
+			return rte_flow_error_set(error, ENOTSUP,
+						  RTE_FLOW_ERROR_TYPE_ACTION,
+						  NULL,
+						  "unsupported action QUEUE");
 		if (!(sub_action_flags & MLX5_FLOW_ACTION_PORT_ID))
 			return rte_flow_error_set(error, EINVAL,
 						  RTE_FLOW_ERROR_TYPE_ACTION,
@@ -5240,7 +5274,8 @@ struct mlx5_hlist_entry *
 	const struct rte_flow_item *gre_item = NULL;
 	const struct rte_flow_action_raw_decap *decap;
 	const struct rte_flow_action_raw_encap *encap;
-	const struct rte_flow_action_rss *rss;
+	const struct rte_flow_action_rss *rss = NULL;
+	const struct rte_flow_action_rss *sample_rss = NULL;
 	const struct rte_flow_item_tcp nic_tcp_mask = {
 		.hdr = {
 			.tcp_flags = 0xFF,
@@ -5709,6 +5744,14 @@ struct mlx5_hlist_entry *
 							    error);
 			if (ret < 0)
 				return ret;
+			if (rss && sample_rss &&
+			    (sample_rss->level != rss->level ||
+			    sample_rss->types != rss->types))
+				return rte_flow_error_set(error, ENOTSUP,
+					RTE_FLOW_ERROR_TYPE_ACTION,
+					NULL,
+					"Can't use the different RSS types "
+					"or level in the same flow");
 			if (rss != NULL && rss->queue_num)
 				queue_index = rss->queue[0];
 			action_flags |= MLX5_FLOW_ACTION_RSS;
@@ -6027,6 +6070,7 @@ struct mlx5_hlist_entry *
 			ret = flow_dv_validate_action_sample(action_flags,
 							     actions, dev,
 							     attr, item_flags,
+							     rss, &sample_rss,
 							     error);
 			if (ret < 0)
 				return ret;
@@ -9053,7 +9097,7 @@ struct mlx5_cache_entry *
  * @param[in] dev
  *   Pointer to rte_eth_dev structure.
  * @param[in] action
- *   Pointer to action structure.
+ *   Pointer to sample action structure.
  * @param[in, out] dev_flow
  *   Pointer to the mlx5_flow.
  * @param[in] attr
@@ -9072,7 +9116,7 @@ struct mlx5_cache_entry *
  */
 static int
 flow_dv_translate_action_sample(struct rte_eth_dev *dev,
-				const struct rte_flow_action *action,
+				const struct rte_flow_action_sample *action,
 				struct mlx5_flow *dev_flow,
 				const struct rte_flow_attr *attr,
 				uint32_t *num_of_dest,
@@ -9081,9 +9125,7 @@ struct mlx5_cache_entry *
 				struct rte_flow_error *error)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
-	const struct rte_flow_action_sample *sample_action;
 	const struct rte_flow_action *sub_actions;
-	const struct rte_flow_action_queue *queue;
 	struct mlx5_flow_sub_actions_list *sample_act;
 	struct mlx5_flow_sub_actions_idx *sample_idx;
 	struct mlx5_flow_workspace *wks = mlx5_flow_get_thread_workspace();
@@ -9094,9 +9136,8 @@ struct mlx5_cache_entry *
 	rss_desc = &wks->rss_desc;
 	sample_act = &res->sample_act;
 	sample_idx = &res->sample_idx;
-	sample_action = (const struct rte_flow_action_sample *)action->conf;
-	res->ratio = sample_action->ratio;
-	sub_actions = sample_action->actions;
+	res->ratio = action->ratio;
+	sub_actions = action->actions;
 	for (; sub_actions->type != RTE_FLOW_ACTION_TYPE_END; sub_actions++) {
 		int type = sub_actions->type;
 		uint32_t pre_rix = 0;
@@ -9104,6 +9145,7 @@ struct mlx5_cache_entry *
 		switch (type) {
 		case RTE_FLOW_ACTION_TYPE_QUEUE:
 		{
+			const struct rte_flow_action_queue *queue;
 			struct mlx5_hrxq *hrxq;
 			uint32_t hrxq_idx;
 
@@ -9130,6 +9172,45 @@ struct mlx5_cache_entry *
 					MLX5_FLOW_FATE_QUEUE;
 			break;
 		}
+		case RTE_FLOW_ACTION_TYPE_RSS:
+		{
+			struct mlx5_hrxq *hrxq;
+			uint32_t hrxq_idx;
+			const struct rte_flow_action_rss *rss;
+			const uint8_t *rss_key;
+
+			rss = sub_actions->conf;
+			memcpy(rss_desc->queue, rss->queue,
+			       rss->queue_num * sizeof(uint16_t));
+			rss_desc->queue_num = rss->queue_num;
+			/* NULL RSS key indicates default RSS key. */
+			rss_key = !rss->key ? rss_hash_default_key : rss->key;
+			memcpy(rss_desc->key, rss_key, MLX5_RSS_HASH_KEY_LEN);
+			/*
+			 * rss->level and rss.types should be set in advance
+			 * when expanding items for RSS.
+			 */
+			flow_dv_hashfields_set(dev_flow, rss_desc);
+			hrxq = flow_dv_hrxq_prepare(dev, dev_flow,
+						    rss_desc, &hrxq_idx);
+			if (!hrxq)
+				return rte_flow_error_set
+					(error, rte_errno,
+					 RTE_FLOW_ERROR_TYPE_ACTION,
+					 NULL,
+					 "cannot create fate queue");
+			sample_act->dr_queue_action = hrxq->action;
+			sample_idx->rix_hrxq = hrxq_idx;
+			sample_actions[sample_act->actions_num++] =
+						hrxq->action;
+			(*num_of_dest)++;
+			action_flags |= MLX5_FLOW_ACTION_RSS;
+			if (action_flags & MLX5_FLOW_ACTION_MARK)
+				dev_flow->handle->rix_hrxq = hrxq_idx;
+			dev_flow->handle->fate_action =
+					MLX5_FLOW_FATE_QUEUE;
+			break;
+		}
 		case RTE_FLOW_ACTION_TYPE_MARK:
 		{
 			uint32_t tag_be = mlx5_flow_mark_set
@@ -9694,6 +9775,7 @@ struct mlx5_cache_entry *
 	struct mlx5_flow_dv_dest_array_resource mdest_res;
 	struct mlx5_flow_dv_sample_resource sample_res;
 	void *sample_actions[MLX5_DV_MAX_NUMBER_OF_ACTIONS] = {0};
+	const struct rte_flow_action_sample *sample = NULL;
 	struct mlx5_flow_sub_actions_list *sample_act;
 	uint32_t sample_act_pos = UINT32_MAX;
 	uint32_t num_of_dest = 0;
@@ -10235,15 +10317,8 @@ struct mlx5_cache_entry *
 			break;
 		case RTE_FLOW_ACTION_TYPE_SAMPLE:
 			sample_act_pos = actions_n;
-			ret = flow_dv_translate_action_sample(dev,
-							      actions,
-							      dev_flow, attr,
-							      &num_of_dest,
-							      sample_actions,
-							      &sample_res,
-							      error);
-			if (ret < 0)
-				return ret;
+			sample = (const struct rte_flow_action_sample *)
+				 action->conf;
 			actions_n++;
 			action_flags |= MLX5_FLOW_ACTION_SAMPLE;
 			/* put encap action into group if work with port id */
@@ -10279,30 +10354,6 @@ struct mlx5_cache_entry *
 					  flow->counter, NULL))->action;
 				actions_n++;
 			}
-			if (action_flags & MLX5_FLOW_ACTION_SAMPLE) {
-				ret = flow_dv_create_action_sample(dev,
-							  dev_flow,
-							  num_of_dest,
-							  &sample_res,
-							  &mdest_res,
-							  sample_actions,
-							  action_flags,
-							  error);
-				if (ret < 0)
-					return rte_flow_error_set
-						(error, rte_errno,
-						RTE_FLOW_ERROR_TYPE_ACTION,
-						NULL,
-						"cannot create sample action");
-				if (num_of_dest > 1) {
-					dev_flow->dv.actions[sample_act_pos] =
-					dev_flow->dv.dest_array_res->action;
-				} else {
-					dev_flow->dv.actions[sample_act_pos] =
-					dev_flow->dv.sample_res->verbs_action;
-				}
-			}
-			break;
 		default:
 			break;
 		}
@@ -10310,33 +10361,6 @@ struct mlx5_cache_entry *
 		    modify_action_position == UINT32_MAX)
 			modify_action_position = actions_n++;
 	}
-	/*
-	 * For multiple destination (sample action with ratio=1), the encap
-	 * action and port id action will be combined into group action.
-	 * 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) {
-		int i;
-		void *temp_actions[MLX5_DV_MAX_NUMBER_OF_ACTIONS] = {0};
-
-		for (i = 0; i < actions_n; i++) {
-			if ((sample_act->dr_encap_action &&
-				sample_act->dr_encap_action ==
-				dev_flow->dv.actions[i]) ||
-				(sample_act->dr_port_id_action &&
-				sample_act->dr_port_id_action ==
-				dev_flow->dv.actions[i]))
-				continue;
-			temp_actions[tmp_actions_n++] = dev_flow->dv.actions[i];
-		}
-		memcpy((void *)dev_flow->dv.actions,
-				(void *)temp_actions,
-				tmp_actions_n * sizeof(void *));
-		actions_n = tmp_actions_n;
-	}
-	dev_flow->dv.actions_n = actions_n;
-	dev_flow->act_flags = action_flags;
 	for (; items->type != RTE_FLOW_ITEM_TYPE_END; items++) {
 		int tunnel = !!(item_flags & MLX5_FLOW_LAYER_TUNNEL);
 		int item_type = items->type;
@@ -10588,6 +10612,68 @@ struct mlx5_cache_entry *
 	handle->layers |= item_flags;
 	if (action_flags & MLX5_FLOW_ACTION_RSS)
 		flow_dv_hashfields_set(dev_flow, rss_desc);
+	/* If has RSS action in the sample action, the Sample/Mirror resource
+	 * should be registered after the hash filed be update.
+	 */
+	if (action_flags & MLX5_FLOW_ACTION_SAMPLE) {
+		ret = flow_dv_translate_action_sample(dev,
+						      sample,
+						      dev_flow, attr,
+						      &num_of_dest,
+						      sample_actions,
+						      &sample_res,
+						      error);
+		if (ret < 0)
+			return ret;
+		ret = flow_dv_create_action_sample(dev,
+						   dev_flow,
+						   num_of_dest,
+						   &sample_res,
+						   &mdest_res,
+						   sample_actions,
+						   action_flags,
+						   error);
+		if (ret < 0)
+			return rte_flow_error_set
+						(error, rte_errno,
+						RTE_FLOW_ERROR_TYPE_ACTION,
+						NULL,
+						"cannot create sample action");
+		if (num_of_dest > 1) {
+			dev_flow->dv.actions[sample_act_pos] =
+			dev_flow->dv.dest_array_res->action;
+		} else {
+			dev_flow->dv.actions[sample_act_pos] =
+			dev_flow->dv.sample_res->verbs_action;
+		}
+	}
+	/*
+	 * For multiple destination (sample action with ratio=1), the encap
+	 * action and port id action will be combined into group action.
+	 * 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) {
+		int i;
+		void *temp_actions[MLX5_DV_MAX_NUMBER_OF_ACTIONS] = {0};
+
+		for (i = 0; i < actions_n; i++) {
+			if ((sample_act->dr_encap_action &&
+				sample_act->dr_encap_action ==
+				dev_flow->dv.actions[i]) ||
+				(sample_act->dr_port_id_action &&
+				sample_act->dr_port_id_action ==
+				dev_flow->dv.actions[i]))
+				continue;
+			temp_actions[tmp_actions_n++] = dev_flow->dv.actions[i];
+		}
+		memcpy((void *)dev_flow->dv.actions,
+				(void *)temp_actions,
+				tmp_actions_n * sizeof(void *));
+		actions_n = tmp_actions_n;
+	}
+	dev_flow->dv.actions_n = actions_n;
+	dev_flow->act_flags = action_flags;
 	/* Register matcher. */
 	matcher.crc = rte_raw_cksum((const void *)matcher.mask.buf,
 				    matcher.mask.size);
-- 
1.8.3.1


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

* [dpdk-dev] [PATCH v2 4/4] doc: update RSS support in sample action
  2021-01-12 10:01 ` [dpdk-dev] [PATCH v2 0/4] Add RSS action support in the sample sub-actions list Jiawei Wang
                     ` (2 preceding siblings ...)
  2021-01-12 10:01   ` [dpdk-dev] [PATCH v2 3/4] net/mlx5: handle the RSS action in the sample Jiawei Wang
@ 2021-01-12 10:01   ` Jiawei Wang
  2021-01-19 13:13     ` Ferruh Yigit
  2021-01-14  7:24   ` [dpdk-dev] [PATCH v3 0/4] Add RSS action support in the sample sub-actions list Jiawei Wang
  4 siblings, 1 reply; 16+ messages in thread
From: Jiawei Wang @ 2021-01-12 10:01 UTC (permalink / raw)
  To: ferruh.yigit, viacheslavo, matan, orika; +Cc: dev, rasland

Add description about mlx5 PMD RSS action support for the Sample action.

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

diff --git a/doc/guides/nics/mlx5.rst b/doc/guides/nics/mlx5.rst
index 3bda0f8..c20c0ed 100644
--- a/doc/guides/nics/mlx5.rst
+++ b/doc/guides/nics/mlx5.rst
@@ -98,6 +98,7 @@ Features
 - Hardware LRO.
 - Hairpin.
 - Multiple-thread flow insertion.
+- RSS support in sample action.
 
 Limitations
 -----------
diff --git a/doc/guides/rel_notes/release_21_02.rst b/doc/guides/rel_notes/release_21_02.rst
index 706cbf8..610ddcd 100644
--- a/doc/guides/rel_notes/release_21_02.rst
+++ b/doc/guides/rel_notes/release_21_02.rst
@@ -55,6 +55,11 @@ 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:
+
+  * Added support for RSS action in the sample sub-actions list.
 
 Removed Items
 -------------
-- 
1.8.3.1


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

* [dpdk-dev] [PATCH v3 0/4] Add RSS action support in the sample sub-actions list
  2021-01-12 10:01 ` [dpdk-dev] [PATCH v2 0/4] Add RSS action support in the sample sub-actions list Jiawei Wang
                     ` (3 preceding siblings ...)
  2021-01-12 10:01   ` [dpdk-dev] [PATCH v2 4/4] doc: update RSS support in sample action Jiawei Wang
@ 2021-01-14  7:24   ` Jiawei Wang
  2021-01-14  7:24     ` [dpdk-dev] [PATCH v3 1/4] app/testpmd: add RSS support in sample action Jiawei Wang
                       ` (4 more replies)
  4 siblings, 5 replies; 16+ messages in thread
From: Jiawei Wang @ 2021-01-14  7:24 UTC (permalink / raw)
  To: ferruh.yigit, viacheslavo, matan, orika; +Cc: dev, rasland

Currently the sample flow only supports Queue action in NIC-Rx domain.
This patchset adds the RSS action support in the sample sub-actions list.

The examples for the sample flow with RSS action and result as below:
    set sample_actions 0 mark id  0x12 / rss queues  0 1 2 3 end  / end
    flow create 0 ingress group 1 pattern eth / end actions sample ratio 1 index 0 / jump group 2 / end

This flow will result in all the matched ingress packets will be
jumped to the next table, and the each packet will be marked with 0x12
and duplicated to rss queues of the control application.

v3:
* Fix the 'maybe-uninitialized' build error in commit 'net/mlx5: fix the unnecessary checking for RSS action'

v2:
* Rebase
* Update commit message and document description
* Split the commit into one fix for rss checking and another for sample rss feature

Jiawei Wang (4):
  app/testpmd: add RSS support in sample action
  net/mlx5: fix the unnecessary checking for RSS action
  net/mlx5: handle the RSS action in the sample
  doc: update RSS support in sample action

 app/test-pmd/cmdline_flow.c            |  26 ++++
 doc/guides/nics/mlx5.rst               |   1 +
 doc/guides/rel_notes/release_21_02.rst |   5 +
 drivers/net/mlx5/mlx5_flow.c           |  24 +++-
 drivers/net/mlx5/mlx5_flow_dv.c        | 226 +++++++++++++++++++++++----------
 5 files changed, 207 insertions(+), 75 deletions(-)

-- 
1.8.3.1


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

* [dpdk-dev] [PATCH v3 1/4] app/testpmd: add RSS support in sample action
  2021-01-14  7:24   ` [dpdk-dev] [PATCH v3 0/4] Add RSS action support in the sample sub-actions list Jiawei Wang
@ 2021-01-14  7:24     ` Jiawei Wang
  2021-01-14  7:24     ` [dpdk-dev] [PATCH v3 2/4] net/mlx5: fix the unnecessary checking for RSS action Jiawei Wang
                       ` (3 subsequent siblings)
  4 siblings, 0 replies; 16+ messages in thread
From: Jiawei Wang @ 2021-01-14  7:24 UTC (permalink / raw)
  To: ferruh.yigit, viacheslavo, matan, orika; +Cc: dev, rasland

Support rss action in the sample sub-actions list.

The examples for the sample flow use case and result as below:
set sample_actions 0 mark id  0x12 / rss queues  0 1 2 3 end  / end
flow create 0 ingress group 1 pattern eth / end actions
sample ratio 1 index 0 / jump group 2 / end

This flow will result in all the matched ingress packets will be
jumped to next table, and the each packet will be marked with 0x12
and duplicated to rss queues of the control application.

Signed-off-by: Jiawei Wang <jiaweiw@nvidia.com>
Acked-by: Viacheslav Ovsiienko <viacheslavo@nvidia.com>
---
 app/test-pmd/cmdline_flow.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 585cab9..28c3a1b 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -560,6 +560,7 @@ struct raw_sample_conf {
 struct rte_flow_action_count sample_count[RAW_SAMPLE_CONFS_MAX_NUM];
 struct rte_flow_action_port_id sample_port_id[RAW_SAMPLE_CONFS_MAX_NUM];
 struct rte_flow_action_raw_encap sample_encap[RAW_SAMPLE_CONFS_MAX_NUM];
+struct action_rss_data sample_rss_data[RAW_SAMPLE_CONFS_MAX_NUM];
 
 /** Maximum number of subsequent tokens and arguments on the stack. */
 #define CTX_STACK_SIZE 16
@@ -1548,6 +1549,7 @@ struct parse_action_priv {
 
 static const enum index next_action_sample[] = {
 	ACTION_QUEUE,
+	ACTION_RSS,
 	ACTION_MARK,
 	ACTION_COUNT,
 	ACTION_PORT_ID,
@@ -7515,6 +7517,7 @@ static int comp_set_sample_index(struct context *, const struct token *,
 	uint32_t i = 0;
 	struct rte_flow_action *action = NULL;
 	struct rte_flow_action *data = NULL;
+	const struct rte_flow_action_rss *rss = NULL;
 	size_t size = 0;
 	uint16_t idx = in->port; /* We borrow port field as index */
 	uint32_t max_size = sizeof(struct rte_flow_action) *
@@ -7546,6 +7549,29 @@ static int comp_set_sample_index(struct context *, const struct token *,
 				(const void *)action->conf, size);
 			action->conf = &sample_queue[idx];
 			break;
+		case RTE_FLOW_ACTION_TYPE_RSS:
+			size = sizeof(struct rte_flow_action_rss);
+			rss = action->conf;
+			rte_memcpy(&sample_rss_data[idx].conf,
+				   (const void *)rss, size);
+			if (rss->key_len) {
+				sample_rss_data[idx].conf.key =
+						sample_rss_data[idx].key;
+				rte_memcpy((void *)((uintptr_t)
+					   sample_rss_data[idx].conf.key),
+					   (const void *)rss->key,
+					   sizeof(uint8_t) * rss->key_len);
+			}
+			if (rss->queue_num) {
+				sample_rss_data[idx].conf.queue =
+						sample_rss_data[idx].queue;
+				rte_memcpy((void *)((uintptr_t)
+					   sample_rss_data[idx].conf.queue),
+					   (const void *)rss->queue,
+					   sizeof(uint16_t) * rss->queue_num);
+			}
+			action->conf = &sample_rss_data[idx].conf;
+			break;
 		case RTE_FLOW_ACTION_TYPE_RAW_ENCAP:
 			size = sizeof(struct rte_flow_action_raw_encap);
 			rte_memcpy(&sample_encap[idx],
-- 
1.8.3.1


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

* [dpdk-dev] [PATCH v3 2/4] net/mlx5: fix the unnecessary checking for RSS action
  2021-01-14  7:24   ` [dpdk-dev] [PATCH v3 0/4] Add RSS action support in the sample sub-actions list Jiawei Wang
  2021-01-14  7:24     ` [dpdk-dev] [PATCH v3 1/4] app/testpmd: add RSS support in sample action Jiawei Wang
@ 2021-01-14  7:24     ` Jiawei Wang
  2021-01-14  7:24     ` [dpdk-dev] [PATCH v3 3/4] net/mlx5: handle the RSS action in the sample Jiawei Wang
                       ` (2 subsequent siblings)
  4 siblings, 0 replies; 16+ messages in thread
From: Jiawei Wang @ 2021-01-14  7:24 UTC (permalink / raw)
  To: ferruh.yigit, viacheslavo, matan, orika; +Cc: dev, rasland, stable

RSS action is valid only in NIC-RX domain, this fix bypass
the function that getting RSS action from the flow action list
under no NIC-RX domain.

Fixes: e745f90 ("net/mlx5: optimize flow RSS struct")
Cc: stable@dpdk.org

Signed-off-by: Jiawei Wang <jiaweiw@nvidia.com>
Acked-by: Viacheslav Ovsiienko <viacheslavo@nvidia.com>
---
 drivers/net/mlx5/mlx5_flow.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index 2a4073c..0670447 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -5278,7 +5278,7 @@ struct mlx5_hlist_entry *
 	struct mlx5_priv *priv = dev->data->dev_private;
 	struct rte_flow *flow = NULL;
 	struct mlx5_flow *dev_flow;
-	const struct rte_flow_action_rss *rss;
+	const struct rte_flow_action_rss *rss = NULL;
 	struct mlx5_translated_shared_action
 		shared_actions[MLX5_MAX_SHARED_ACTIONS];
 	int shared_actions_n = MLX5_MAX_SHARED_ACTIONS;
@@ -5356,7 +5356,9 @@ struct mlx5_hlist_entry *
 	MLX5_ASSERT(flow->drv_type > MLX5_FLOW_TYPE_MIN &&
 		    flow->drv_type < MLX5_FLOW_TYPE_MAX);
 	memset(rss_desc, 0, offsetof(struct mlx5_flow_rss_desc, queue));
-	rss = flow_get_rss_action(p_actions_rx);
+	/* RSS Action only works on NIC RX domain */
+	if (attr->ingress && !attr->transfer)
+		rss = flow_get_rss_action(p_actions_rx);
 	if (rss) {
 		if (flow_rss_workspace_adjust(wks, rss_desc, rss->queue_num))
 			return 0;
-- 
1.8.3.1


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

* [dpdk-dev] [PATCH v3 3/4] net/mlx5: handle the RSS action in the sample
  2021-01-14  7:24   ` [dpdk-dev] [PATCH v3 0/4] Add RSS action support in the sample sub-actions list Jiawei Wang
  2021-01-14  7:24     ` [dpdk-dev] [PATCH v3 1/4] app/testpmd: add RSS support in sample action Jiawei Wang
  2021-01-14  7:24     ` [dpdk-dev] [PATCH v3 2/4] net/mlx5: fix the unnecessary checking for RSS action Jiawei Wang
@ 2021-01-14  7:24     ` Jiawei Wang
  2021-01-14  7:24     ` [dpdk-dev] [PATCH v3 4/4] doc: update RSS support in sample action Jiawei Wang
  2021-01-18 20:30     ` [dpdk-dev] [PATCH v3 0/4] Add RSS action support in the sample sub-actions list Raslan Darawsheh
  4 siblings, 0 replies; 16+ messages in thread
From: Jiawei Wang @ 2021-01-14  7:24 UTC (permalink / raw)
  To: ferruh.yigit, viacheslavo, matan, orika; +Cc: dev, rasland

PMD validates the rss action in the sample sub-actions list,
then translates into rdma-core action and it will be used for sample
path destination.

If the RSS action is in both sample sub-actions list and original flow,
the rss level and rss type in the sample sub-actions list should be
consistent with the original flow list, since the expanding items
for RSS should be the same for both actions.

Signed-off-by: Jiawei Wang <jiaweiw@nvidia.com>
Acked-by: Viacheslav Ovsiienko <viacheslavo@mellanox.com>
---
 drivers/net/mlx5/mlx5_flow.c    |  18 +++-
 drivers/net/mlx5/mlx5_flow_dv.c | 226 +++++++++++++++++++++++++++-------------
 2 files changed, 171 insertions(+), 73 deletions(-)

diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index 0670447..96a7e0d 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -3174,16 +3174,28 @@ struct mlx5_flow_tunnel_info {
 static const struct rte_flow_action_rss*
 flow_get_rss_action(const struct rte_flow_action actions[])
 {
+	const struct rte_flow_action_rss *rss = NULL;
+
 	for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) {
 		switch (actions->type) {
 		case RTE_FLOW_ACTION_TYPE_RSS:
-			return (const struct rte_flow_action_rss *)
-			       actions->conf;
+			rss = actions->conf;
+			break;
+		case RTE_FLOW_ACTION_TYPE_SAMPLE:
+		{
+			const struct rte_flow_action_sample *sample =
+								actions->conf;
+			const struct rte_flow_action *act = sample->actions;
+			for (; act->type != RTE_FLOW_ACTION_TYPE_END; act++)
+				if (act->type == RTE_FLOW_ACTION_TYPE_RSS)
+					rss = act->conf;
+			break;
+		}
 		default:
 			break;
 		}
 	}
-	return NULL;
+	return rss;
 }
 
 /**
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index e4736ee..3fa15cf 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -4344,6 +4344,10 @@ struct mlx5_hlist_entry *
  *   Attributes of flow that includes this action.
  * @param[in] item_flags
  *   Holds the items detected.
+ * @param[in] rss
+ *   Pointer to the RSS action.
+ * @param[out] sample_rss
+ *   Pointer to the RSS action in sample action list.
  * @param[out] error
  *   Pointer to error structure.
  *
@@ -4355,7 +4359,9 @@ struct mlx5_hlist_entry *
 			       const struct rte_flow_action *action,
 			       struct rte_eth_dev *dev,
 			       const struct rte_flow_attr *attr,
-			       const uint64_t item_flags,
+			       uint64_t item_flags,
+			       const struct rte_flow_action_rss *rss,
+			       const struct rte_flow_action_rss **sample_rss,
 			       struct rte_flow_error *error)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
@@ -4415,6 +4421,28 @@ struct mlx5_hlist_entry *
 			sub_action_flags |= MLX5_FLOW_ACTION_QUEUE;
 			++actions_n;
 			break;
+		case RTE_FLOW_ACTION_TYPE_RSS:
+			*sample_rss = act->conf;
+			ret = mlx5_flow_validate_action_rss(act,
+							    sub_action_flags,
+							    dev, attr,
+							    item_flags,
+							    error);
+			if (ret < 0)
+				return ret;
+			if (rss && *sample_rss &&
+			    ((*sample_rss)->level != rss->level ||
+			    (*sample_rss)->types != rss->types))
+				return rte_flow_error_set(error, ENOTSUP,
+					RTE_FLOW_ERROR_TYPE_ACTION,
+					NULL,
+					"Can't use the different RSS types "
+					"or level in the same flow");
+			if (*sample_rss != NULL && (*sample_rss)->queue_num)
+				queue_index = (*sample_rss)->queue[0];
+			sub_action_flags |= MLX5_FLOW_ACTION_RSS;
+			++actions_n;
+			break;
 		case RTE_FLOW_ACTION_TYPE_MARK:
 			ret = flow_dv_validate_action_mark(dev, act,
 							   sub_action_flags,
@@ -4463,7 +4491,8 @@ struct mlx5_hlist_entry *
 		}
 	}
 	if (attr->ingress && !attr->transfer) {
-		if (!(sub_action_flags & MLX5_FLOW_ACTION_QUEUE))
+		if (!(sub_action_flags & (MLX5_FLOW_ACTION_QUEUE |
+					  MLX5_FLOW_ACTION_RSS)))
 			return rte_flow_error_set(error, EINVAL,
 						  RTE_FLOW_ERROR_TYPE_ACTION,
 						  NULL,
@@ -4490,6 +4519,11 @@ struct mlx5_hlist_entry *
 						  RTE_FLOW_ERROR_TYPE_ACTION,
 						  NULL,
 						  "unsupported action QUEUE");
+		if (sub_action_flags & MLX5_FLOW_ACTION_RSS)
+			return rte_flow_error_set(error, ENOTSUP,
+						  RTE_FLOW_ERROR_TYPE_ACTION,
+						  NULL,
+						  "unsupported action QUEUE");
 		if (!(sub_action_flags & MLX5_FLOW_ACTION_PORT_ID))
 			return rte_flow_error_set(error, EINVAL,
 						  RTE_FLOW_ERROR_TYPE_ACTION,
@@ -5240,7 +5274,8 @@ struct mlx5_hlist_entry *
 	const struct rte_flow_item *gre_item = NULL;
 	const struct rte_flow_action_raw_decap *decap;
 	const struct rte_flow_action_raw_encap *encap;
-	const struct rte_flow_action_rss *rss;
+	const struct rte_flow_action_rss *rss = NULL;
+	const struct rte_flow_action_rss *sample_rss = NULL;
 	const struct rte_flow_item_tcp nic_tcp_mask = {
 		.hdr = {
 			.tcp_flags = 0xFF,
@@ -5709,6 +5744,14 @@ struct mlx5_hlist_entry *
 							    error);
 			if (ret < 0)
 				return ret;
+			if (rss && sample_rss &&
+			    (sample_rss->level != rss->level ||
+			    sample_rss->types != rss->types))
+				return rte_flow_error_set(error, ENOTSUP,
+					RTE_FLOW_ERROR_TYPE_ACTION,
+					NULL,
+					"Can't use the different RSS types "
+					"or level in the same flow");
 			if (rss != NULL && rss->queue_num)
 				queue_index = rss->queue[0];
 			action_flags |= MLX5_FLOW_ACTION_RSS;
@@ -6027,6 +6070,7 @@ struct mlx5_hlist_entry *
 			ret = flow_dv_validate_action_sample(action_flags,
 							     actions, dev,
 							     attr, item_flags,
+							     rss, &sample_rss,
 							     error);
 			if (ret < 0)
 				return ret;
@@ -9053,7 +9097,7 @@ struct mlx5_cache_entry *
  * @param[in] dev
  *   Pointer to rte_eth_dev structure.
  * @param[in] action
- *   Pointer to action structure.
+ *   Pointer to sample action structure.
  * @param[in, out] dev_flow
  *   Pointer to the mlx5_flow.
  * @param[in] attr
@@ -9072,7 +9116,7 @@ struct mlx5_cache_entry *
  */
 static int
 flow_dv_translate_action_sample(struct rte_eth_dev *dev,
-				const struct rte_flow_action *action,
+				const struct rte_flow_action_sample *action,
 				struct mlx5_flow *dev_flow,
 				const struct rte_flow_attr *attr,
 				uint32_t *num_of_dest,
@@ -9081,9 +9125,7 @@ struct mlx5_cache_entry *
 				struct rte_flow_error *error)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
-	const struct rte_flow_action_sample *sample_action;
 	const struct rte_flow_action *sub_actions;
-	const struct rte_flow_action_queue *queue;
 	struct mlx5_flow_sub_actions_list *sample_act;
 	struct mlx5_flow_sub_actions_idx *sample_idx;
 	struct mlx5_flow_workspace *wks = mlx5_flow_get_thread_workspace();
@@ -9094,9 +9136,8 @@ struct mlx5_cache_entry *
 	rss_desc = &wks->rss_desc;
 	sample_act = &res->sample_act;
 	sample_idx = &res->sample_idx;
-	sample_action = (const struct rte_flow_action_sample *)action->conf;
-	res->ratio = sample_action->ratio;
-	sub_actions = sample_action->actions;
+	res->ratio = action->ratio;
+	sub_actions = action->actions;
 	for (; sub_actions->type != RTE_FLOW_ACTION_TYPE_END; sub_actions++) {
 		int type = sub_actions->type;
 		uint32_t pre_rix = 0;
@@ -9104,6 +9145,7 @@ struct mlx5_cache_entry *
 		switch (type) {
 		case RTE_FLOW_ACTION_TYPE_QUEUE:
 		{
+			const struct rte_flow_action_queue *queue;
 			struct mlx5_hrxq *hrxq;
 			uint32_t hrxq_idx;
 
@@ -9130,6 +9172,45 @@ struct mlx5_cache_entry *
 					MLX5_FLOW_FATE_QUEUE;
 			break;
 		}
+		case RTE_FLOW_ACTION_TYPE_RSS:
+		{
+			struct mlx5_hrxq *hrxq;
+			uint32_t hrxq_idx;
+			const struct rte_flow_action_rss *rss;
+			const uint8_t *rss_key;
+
+			rss = sub_actions->conf;
+			memcpy(rss_desc->queue, rss->queue,
+			       rss->queue_num * sizeof(uint16_t));
+			rss_desc->queue_num = rss->queue_num;
+			/* NULL RSS key indicates default RSS key. */
+			rss_key = !rss->key ? rss_hash_default_key : rss->key;
+			memcpy(rss_desc->key, rss_key, MLX5_RSS_HASH_KEY_LEN);
+			/*
+			 * rss->level and rss.types should be set in advance
+			 * when expanding items for RSS.
+			 */
+			flow_dv_hashfields_set(dev_flow, rss_desc);
+			hrxq = flow_dv_hrxq_prepare(dev, dev_flow,
+						    rss_desc, &hrxq_idx);
+			if (!hrxq)
+				return rte_flow_error_set
+					(error, rte_errno,
+					 RTE_FLOW_ERROR_TYPE_ACTION,
+					 NULL,
+					 "cannot create fate queue");
+			sample_act->dr_queue_action = hrxq->action;
+			sample_idx->rix_hrxq = hrxq_idx;
+			sample_actions[sample_act->actions_num++] =
+						hrxq->action;
+			(*num_of_dest)++;
+			action_flags |= MLX5_FLOW_ACTION_RSS;
+			if (action_flags & MLX5_FLOW_ACTION_MARK)
+				dev_flow->handle->rix_hrxq = hrxq_idx;
+			dev_flow->handle->fate_action =
+					MLX5_FLOW_FATE_QUEUE;
+			break;
+		}
 		case RTE_FLOW_ACTION_TYPE_MARK:
 		{
 			uint32_t tag_be = mlx5_flow_mark_set
@@ -9694,6 +9775,7 @@ struct mlx5_cache_entry *
 	struct mlx5_flow_dv_dest_array_resource mdest_res;
 	struct mlx5_flow_dv_sample_resource sample_res;
 	void *sample_actions[MLX5_DV_MAX_NUMBER_OF_ACTIONS] = {0};
+	const struct rte_flow_action_sample *sample = NULL;
 	struct mlx5_flow_sub_actions_list *sample_act;
 	uint32_t sample_act_pos = UINT32_MAX;
 	uint32_t num_of_dest = 0;
@@ -10235,15 +10317,8 @@ struct mlx5_cache_entry *
 			break;
 		case RTE_FLOW_ACTION_TYPE_SAMPLE:
 			sample_act_pos = actions_n;
-			ret = flow_dv_translate_action_sample(dev,
-							      actions,
-							      dev_flow, attr,
-							      &num_of_dest,
-							      sample_actions,
-							      &sample_res,
-							      error);
-			if (ret < 0)
-				return ret;
+			sample = (const struct rte_flow_action_sample *)
+				 action->conf;
 			actions_n++;
 			action_flags |= MLX5_FLOW_ACTION_SAMPLE;
 			/* put encap action into group if work with port id */
@@ -10279,30 +10354,6 @@ struct mlx5_cache_entry *
 					  flow->counter, NULL))->action;
 				actions_n++;
 			}
-			if (action_flags & MLX5_FLOW_ACTION_SAMPLE) {
-				ret = flow_dv_create_action_sample(dev,
-							  dev_flow,
-							  num_of_dest,
-							  &sample_res,
-							  &mdest_res,
-							  sample_actions,
-							  action_flags,
-							  error);
-				if (ret < 0)
-					return rte_flow_error_set
-						(error, rte_errno,
-						RTE_FLOW_ERROR_TYPE_ACTION,
-						NULL,
-						"cannot create sample action");
-				if (num_of_dest > 1) {
-					dev_flow->dv.actions[sample_act_pos] =
-					dev_flow->dv.dest_array_res->action;
-				} else {
-					dev_flow->dv.actions[sample_act_pos] =
-					dev_flow->dv.sample_res->verbs_action;
-				}
-			}
-			break;
 		default:
 			break;
 		}
@@ -10310,33 +10361,6 @@ struct mlx5_cache_entry *
 		    modify_action_position == UINT32_MAX)
 			modify_action_position = actions_n++;
 	}
-	/*
-	 * For multiple destination (sample action with ratio=1), the encap
-	 * action and port id action will be combined into group action.
-	 * 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) {
-		int i;
-		void *temp_actions[MLX5_DV_MAX_NUMBER_OF_ACTIONS] = {0};
-
-		for (i = 0; i < actions_n; i++) {
-			if ((sample_act->dr_encap_action &&
-				sample_act->dr_encap_action ==
-				dev_flow->dv.actions[i]) ||
-				(sample_act->dr_port_id_action &&
-				sample_act->dr_port_id_action ==
-				dev_flow->dv.actions[i]))
-				continue;
-			temp_actions[tmp_actions_n++] = dev_flow->dv.actions[i];
-		}
-		memcpy((void *)dev_flow->dv.actions,
-				(void *)temp_actions,
-				tmp_actions_n * sizeof(void *));
-		actions_n = tmp_actions_n;
-	}
-	dev_flow->dv.actions_n = actions_n;
-	dev_flow->act_flags = action_flags;
 	for (; items->type != RTE_FLOW_ITEM_TYPE_END; items++) {
 		int tunnel = !!(item_flags & MLX5_FLOW_LAYER_TUNNEL);
 		int item_type = items->type;
@@ -10588,6 +10612,68 @@ struct mlx5_cache_entry *
 	handle->layers |= item_flags;
 	if (action_flags & MLX5_FLOW_ACTION_RSS)
 		flow_dv_hashfields_set(dev_flow, rss_desc);
+	/* If has RSS action in the sample action, the Sample/Mirror resource
+	 * should be registered after the hash filed be update.
+	 */
+	if (action_flags & MLX5_FLOW_ACTION_SAMPLE) {
+		ret = flow_dv_translate_action_sample(dev,
+						      sample,
+						      dev_flow, attr,
+						      &num_of_dest,
+						      sample_actions,
+						      &sample_res,
+						      error);
+		if (ret < 0)
+			return ret;
+		ret = flow_dv_create_action_sample(dev,
+						   dev_flow,
+						   num_of_dest,
+						   &sample_res,
+						   &mdest_res,
+						   sample_actions,
+						   action_flags,
+						   error);
+		if (ret < 0)
+			return rte_flow_error_set
+						(error, rte_errno,
+						RTE_FLOW_ERROR_TYPE_ACTION,
+						NULL,
+						"cannot create sample action");
+		if (num_of_dest > 1) {
+			dev_flow->dv.actions[sample_act_pos] =
+			dev_flow->dv.dest_array_res->action;
+		} else {
+			dev_flow->dv.actions[sample_act_pos] =
+			dev_flow->dv.sample_res->verbs_action;
+		}
+	}
+	/*
+	 * For multiple destination (sample action with ratio=1), the encap
+	 * action and port id action will be combined into group action.
+	 * 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) {
+		int i;
+		void *temp_actions[MLX5_DV_MAX_NUMBER_OF_ACTIONS] = {0};
+
+		for (i = 0; i < actions_n; i++) {
+			if ((sample_act->dr_encap_action &&
+				sample_act->dr_encap_action ==
+				dev_flow->dv.actions[i]) ||
+				(sample_act->dr_port_id_action &&
+				sample_act->dr_port_id_action ==
+				dev_flow->dv.actions[i]))
+				continue;
+			temp_actions[tmp_actions_n++] = dev_flow->dv.actions[i];
+		}
+		memcpy((void *)dev_flow->dv.actions,
+				(void *)temp_actions,
+				tmp_actions_n * sizeof(void *));
+		actions_n = tmp_actions_n;
+	}
+	dev_flow->dv.actions_n = actions_n;
+	dev_flow->act_flags = action_flags;
 	/* Register matcher. */
 	matcher.crc = rte_raw_cksum((const void *)matcher.mask.buf,
 				    matcher.mask.size);
-- 
1.8.3.1


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

* [dpdk-dev] [PATCH v3 4/4] doc: update RSS support in sample action
  2021-01-14  7:24   ` [dpdk-dev] [PATCH v3 0/4] Add RSS action support in the sample sub-actions list Jiawei Wang
                       ` (2 preceding siblings ...)
  2021-01-14  7:24     ` [dpdk-dev] [PATCH v3 3/4] net/mlx5: handle the RSS action in the sample Jiawei Wang
@ 2021-01-14  7:24     ` Jiawei Wang
  2021-01-18 20:30     ` [dpdk-dev] [PATCH v3 0/4] Add RSS action support in the sample sub-actions list Raslan Darawsheh
  4 siblings, 0 replies; 16+ messages in thread
From: Jiawei Wang @ 2021-01-14  7:24 UTC (permalink / raw)
  To: ferruh.yigit, viacheslavo, matan, orika; +Cc: dev, rasland

Add description about mlx5 PMD RSS action support for the Sample action.

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

diff --git a/doc/guides/nics/mlx5.rst b/doc/guides/nics/mlx5.rst
index 3bda0f8..c20c0ed 100644
--- a/doc/guides/nics/mlx5.rst
+++ b/doc/guides/nics/mlx5.rst
@@ -98,6 +98,7 @@ Features
 - Hardware LRO.
 - Hairpin.
 - Multiple-thread flow insertion.
+- RSS support in sample action.
 
 Limitations
 -----------
diff --git a/doc/guides/rel_notes/release_21_02.rst b/doc/guides/rel_notes/release_21_02.rst
index 706cbf8..610ddcd 100644
--- a/doc/guides/rel_notes/release_21_02.rst
+++ b/doc/guides/rel_notes/release_21_02.rst
@@ -55,6 +55,11 @@ 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:
+
+  * Added support for RSS action in the sample sub-actions list.
 
 Removed Items
 -------------
-- 
1.8.3.1


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

* Re: [dpdk-dev] [PATCH v3 0/4] Add RSS action support in the sample sub-actions list
  2021-01-14  7:24   ` [dpdk-dev] [PATCH v3 0/4] Add RSS action support in the sample sub-actions list Jiawei Wang
                       ` (3 preceding siblings ...)
  2021-01-14  7:24     ` [dpdk-dev] [PATCH v3 4/4] doc: update RSS support in sample action Jiawei Wang
@ 2021-01-18 20:30     ` Raslan Darawsheh
  4 siblings, 0 replies; 16+ messages in thread
From: Raslan Darawsheh @ 2021-01-18 20:30 UTC (permalink / raw)
  To: Jiawei(Jonny) Wang, ferruh.yigit, Slava Ovsiienko, Matan Azrad, Ori Kam
  Cc: dev

Hi,
> -----Original Message-----
> From: Jiawei Wang <jiaweiw@nvidia.com>
> Sent: Thursday, January 14, 2021 9:25 AM
> To: ferruh.yigit@intel.com; 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 v3 0/4] Add RSS action support in the sample sub-actions list
> 
> Currently the sample flow only supports Queue action in NIC-Rx domain.
> This patchset adds the RSS action support in the sample sub-actions list.
> 
> The examples for the sample flow with RSS action and result as below:
>     set sample_actions 0 mark id  0x12 / rss queues  0 1 2 3 end  / end
>     flow create 0 ingress group 1 pattern eth / end actions sample ratio 1 index
> 0 / jump group 2 / end
> 
> This flow will result in all the matched ingress packets will be
> jumped to the next table, and the each packet will be marked with 0x12
> and duplicated to rss queues of the control application.
> 
> v3:
> * Fix the 'maybe-uninitialized' build error in commit 'net/mlx5: fix the
> unnecessary checking for RSS action'
> 
> v2:
> * Rebase
> * Update commit message and document description
> * Split the commit into one fix for rss checking and another for sample rss
> feature
> 
> Jiawei Wang (4):
>   app/testpmd: add RSS support in sample action
>   net/mlx5: fix the unnecessary checking for RSS action
>   net/mlx5: handle the RSS action in the sample
>   doc: update RSS support in sample action
> 
>  app/test-pmd/cmdline_flow.c            |  26 ++++
>  doc/guides/nics/mlx5.rst               |   1 +
>  doc/guides/rel_notes/release_21_02.rst |   5 +
>  drivers/net/mlx5/mlx5_flow.c           |  24 +++-
>  drivers/net/mlx5/mlx5_flow_dv.c        | 226 +++++++++++++++++++++++---
> -------
>  5 files changed, 207 insertions(+), 75 deletions(-)
> 
> --
> 1.8.3.1

Series applied to next-net-mlx,

Kindest regards,
Raslan Darawsheh

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

* Re: [dpdk-dev] [PATCH v2 4/4] doc: update RSS support in sample action
  2021-01-12 10:01   ` [dpdk-dev] [PATCH v2 4/4] doc: update RSS support in sample action Jiawei Wang
@ 2021-01-19 13:13     ` Ferruh Yigit
  0 siblings, 0 replies; 16+ messages in thread
From: Ferruh Yigit @ 2021-01-19 13:13 UTC (permalink / raw)
  To: Jiawei Wang, viacheslavo, matan, orika; +Cc: dev, rasland

On 1/12/2021 10:01 AM, Jiawei Wang wrote:
> Add description about mlx5 PMD RSS action support for the Sample action.
> 
> Signed-off-by: Jiawei Wang <jiaweiw@nvidia.com>
> Acked-by: Viacheslav Ovsiienko <viacheslavo@mellanox.com>

Squashed into relevant commit [1] in next-net, thanks.

[1] https://patches.dpdk.org/patch/86396/

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

end of thread, other threads:[~2021-01-19 13:13 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-01-10  9:10 [dpdk-dev] [PATCH 0/3] Add RSS action support in the sample sub-actions list Jiawei Wang
2021-01-10  9:10 ` [dpdk-dev] [PATCH 1/3] app/testpmd: add RSS support in sample action Jiawei Wang
2021-01-10  9:10 ` [dpdk-dev] [PATCH 2/3] net/mlx5: handle the RSS action in the sample Jiawei Wang
2021-01-10  9:10 ` [dpdk-dev] [PATCH 3/3] doc: update RSS support in sample action Jiawei Wang
2021-01-12 10:01 ` [dpdk-dev] [PATCH v2 0/4] Add RSS action support in the sample sub-actions list Jiawei Wang
2021-01-12 10:01   ` [dpdk-dev] [PATCH v2 1/4] app/testpmd: add RSS support in sample action Jiawei Wang
2021-01-12 10:01   ` [dpdk-dev] [PATCH v2 2/4] net/mlx5: fix the unnecessary checking for RSS action Jiawei Wang
2021-01-12 10:01   ` [dpdk-dev] [PATCH v2 3/4] net/mlx5: handle the RSS action in the sample Jiawei Wang
2021-01-12 10:01   ` [dpdk-dev] [PATCH v2 4/4] doc: update RSS support in sample action Jiawei Wang
2021-01-19 13:13     ` Ferruh Yigit
2021-01-14  7:24   ` [dpdk-dev] [PATCH v3 0/4] Add RSS action support in the sample sub-actions list Jiawei Wang
2021-01-14  7:24     ` [dpdk-dev] [PATCH v3 1/4] app/testpmd: add RSS support in sample action Jiawei Wang
2021-01-14  7:24     ` [dpdk-dev] [PATCH v3 2/4] net/mlx5: fix the unnecessary checking for RSS action Jiawei Wang
2021-01-14  7:24     ` [dpdk-dev] [PATCH v3 3/4] net/mlx5: handle the RSS action in the sample Jiawei Wang
2021-01-14  7:24     ` [dpdk-dev] [PATCH v3 4/4] doc: update RSS support in sample action Jiawei Wang
2021-01-18 20:30     ` [dpdk-dev] [PATCH v3 0/4] Add RSS action support in the sample sub-actions list Raslan Darawsheh

DPDK patches and discussions

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://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/ https://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