[v2,05/20] net/mlx5: add flow queue action

Message ID aa1350387b1241561ac394d662eadd411f52f141.1530111623.git.nelio.laranjeiro@6wind.com (mailing list archive)
State Superseded, archived
Delegated to: Shahaf Shuler
Headers
Series net/mlx5: flow rework |

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/Intel-compilation fail apply issues

Commit Message

Nélio Laranjeiro June 27, 2018, 3:07 p.m. UTC
  Signed-off-by: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>
---
 drivers/net/mlx5/mlx5_flow.c | 100 +++++++++++++++++++++++++++++++----
 1 file changed, 89 insertions(+), 11 deletions(-)
  

Comments

Yongseok Koh July 3, 2018, 11 p.m. UTC | #1
On Wed, Jun 27, 2018 at 05:07:37PM +0200, Nelio Laranjeiro wrote:
> Signed-off-by: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>
> ---
Acked-by: Yongseok Koh <yskoh@mellanox.com>

Thanks
  

Patch

diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index bc8c5de33..7ac1ba24c 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -50,6 +50,7 @@  extern const struct eth_dev_ops mlx5_dev_ops_isolate;
 
 /* Action fate on the packet. */
 #define MLX5_FLOW_FATE_DROP (1u << 0)
+#define MLX5_FLOW_FATE_QUEUE (1u << 1)
 
 /** Handles information leading to a drop fate. */
 struct mlx5_flow_verbs {
@@ -71,7 +72,8 @@  struct rte_flow {
 	/**< Bit-fields of present layers see MLX5_FLOW_ITEMS_*. */
 	uint32_t fate;
 	/**< Bit-fields of present fate see MLX5_FLOW_FATE_*. */
-	struct mlx5_flow_verbs verbs; /* Verbs drop flow. */
+	struct mlx5_flow_verbs verbs; /* Verbs flow. */
+	uint16_t queue; /**< Destination queue to redirect traffic to. */
 };
 
 static const struct rte_flow_ops mlx5_flow_ops = {
@@ -191,6 +193,8 @@  mlx5_flow_print(struct rte_flow *flow __rte_unused)
 		flow->layers & MLX5_FLOW_LAYER_OUTER_L4 ? "l4" : "-");
 	if (flow->fate & MLX5_FLOW_FATE_DROP)
 		fprintf(stdout, " fate: drop queue\n");
+	else if (flow->fate & MLX5_FLOW_FATE_QUEUE)
+		fprintf(stdout, " fate: target queue %u\n", flow->queue);
 	if (flow->verbs.attr) {
 		struct ibv_spec_header *hdr =
 			(struct ibv_spec_header *)flow->verbs.specs;
@@ -512,6 +516,53 @@  mlx5_flow_action_drop(const struct rte_flow_action *actions,
 	return size;
 }
 
+/**
+ * Validate action queue provided by the user.
+ *
+ * @param dev
+ *   Pointer to Ethernet device structure.
+ * @param actions
+ *   Pointer to flow actions array.
+ * @param flow
+ *   Pointer to the rte_flow structure.
+ * @param flow_size
+ *   Size in bytes of the available space for to store the flow information.
+ * @param error
+ *   Pointer to error structure.
+ *
+ * @return
+ *   0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+static int
+mlx5_flow_action_queue(struct rte_eth_dev *dev,
+		       const struct rte_flow_action *actions,
+		       struct rte_flow *flow,
+		       struct rte_flow_error *error)
+{
+	struct priv *priv = dev->data->dev_private;
+	const struct rte_flow_action_queue *queue = actions->conf;
+
+	if (flow->fate)
+		return rte_flow_error_set(error, ENOTSUP,
+					  RTE_FLOW_ERROR_TYPE_ACTION,
+					  actions,
+					  "multiple fate actions are not"
+					  " supported");
+	if (queue->index >= priv->rxqs_n)
+		return rte_flow_error_set(error, EINVAL,
+					  RTE_FLOW_ERROR_TYPE_ACTION_CONF,
+					  &queue->index,
+					  "queue index out of range");
+	if (!(*priv->rxqs)[queue->index])
+		return rte_flow_error_set(error, EINVAL,
+					  RTE_FLOW_ERROR_TYPE_ACTION_CONF,
+					  &queue->index,
+					  "queue is not configured");
+	flow->queue = queue->index;
+	flow->fate |= MLX5_FLOW_FATE_QUEUE;
+	return 0;
+}
+
 /**
  * Validate actions provided by the user.
  *
@@ -531,7 +582,7 @@  mlx5_flow_action_drop(const struct rte_flow_action *actions,
  *   otherwise and rte_errno is set.
  */
 static int
-mlx5_flow_actions(struct rte_eth_dev *dev __rte_unused,
+mlx5_flow_actions(struct rte_eth_dev *dev,
 		  const struct rte_flow_action actions[],
 		  struct rte_flow *flow, const size_t flow_size,
 		  struct rte_flow_error *error)
@@ -548,6 +599,9 @@  mlx5_flow_actions(struct rte_eth_dev *dev __rte_unused,
 			ret = mlx5_flow_action_drop(actions, flow, remain,
 						    error);
 			break;
+		case RTE_FLOW_ACTION_TYPE_QUEUE:
+			ret = mlx5_flow_action_queue(dev, actions, flow, error);
+			break;
 		default:
 			return rte_flow_error_set(error, ENOTSUP,
 						  RTE_FLOW_ERROR_TYPE_ACTION,
@@ -662,7 +716,10 @@  mlx5_flow_fate_remove(struct rte_eth_dev *dev, struct rte_flow *flow)
 		}
 	}
 	if (flow->verbs.hrxq) {
-		mlx5_hrxq_drop_release(dev, flow->verbs.hrxq);
+		if (flow->fate & MLX5_FLOW_FATE_DROP)
+			mlx5_hrxq_drop_release(dev, flow->verbs.hrxq);
+		else if (flow->fate & MLX5_FLOW_FATE_QUEUE)
+			mlx5_hrxq_release(dev, flow->verbs.hrxq);
 		flow->verbs.hrxq = NULL;
 	}
 }
@@ -684,17 +741,38 @@  static int
 mlx5_flow_fate_apply(struct rte_eth_dev *dev, struct rte_flow *flow,
 		     struct rte_flow_error *error)
 {
-	flow->verbs.hrxq = mlx5_hrxq_drop_new(dev);
-	if (!flow->verbs.hrxq)
-		return rte_flow_error_set
-			(error, errno,
-			 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
-			 NULL,
-			 "cannot allocate Drop queue");
+	if (flow->fate & MLX5_FLOW_FATE_DROP) {
+		flow->verbs.hrxq = mlx5_hrxq_drop_new(dev);
+		if (!flow->verbs.hrxq)
+			return rte_flow_error_set
+				(error, errno,
+				 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+				 NULL,
+				 "cannot allocate Drop queue");
+	} else if (flow->fate & MLX5_FLOW_FATE_QUEUE) {
+		struct mlx5_hrxq *hrxq;
+
+		hrxq = mlx5_hrxq_get(dev, rss_hash_default_key,
+				     rss_hash_default_key_len, 0,
+				     &flow->queue, 1, 0, 0);
+		if (!hrxq)
+			hrxq = mlx5_hrxq_new(dev, rss_hash_default_key,
+					     rss_hash_default_key_len, 0,
+					     &flow->queue, 1, 0, 0);
+		if (!hrxq)
+			return rte_flow_error_set(error, rte_errno,
+					RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+					NULL,
+					"cannot create flow");
+		flow->verbs.hrxq = hrxq;
+	}
 	flow->verbs.flow =
 		mlx5_glue->create_flow(flow->verbs.hrxq->qp, flow->verbs.attr);
 	if (!flow->verbs.flow) {
-		mlx5_hrxq_drop_release(dev, flow->verbs.hrxq);
+		if (flow->fate & MLX5_FLOW_FATE_DROP)
+			mlx5_hrxq_drop_release(dev, flow->verbs.hrxq);
+		else
+			mlx5_hrxq_release(dev, flow->verbs.hrxq);
 		flow->verbs.hrxq = NULL;
 		return rte_flow_error_set(error, errno,
 					  RTE_FLOW_ERROR_TYPE_UNSPECIFIED,