All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jiawei Wang <jiaweiw@nvidia.com>
To: ferruh.yigit@intel.com, viacheslavo@nvidia.com, matan@nvidia.com,
	orika@nvidia.com
Cc: dev@dpdk.org, rasland@nvidia.com
Subject: [dpdk-dev] [PATCH v2 3/4] net/mlx5: handle the RSS action in the sample
Date: Tue, 12 Jan 2021 12:01:28 +0200	[thread overview]
Message-ID: <1610445689-389472-4-git-send-email-jiaweiw@nvidia.com> (raw)
In-Reply-To: <1610445689-389472-1-git-send-email-jiaweiw@nvidia.com>

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


  parent reply	other threads:[~2021-01-12 10:01 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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   ` Jiawei Wang [this message]
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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1610445689-389472-4-git-send-email-jiaweiw@nvidia.com \
    --to=jiaweiw@nvidia.com \
    --cc=dev@dpdk.org \
    --cc=ferruh.yigit@intel.com \
    --cc=matan@nvidia.com \
    --cc=orika@nvidia.com \
    --cc=rasland@nvidia.com \
    --cc=viacheslavo@nvidia.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.