All of lore.kernel.org
 help / color / mirror / Atom feed
From: Vasily Philipov <vasilyf@mellanox.com>
To: dev@dpdk.org
Cc: Vasily Philipov <vasilyf@mellanox.com>,
	Adrien Mazarguil <adrien.mazarguil@6wind.com>,
	Nelio Laranjeiro <nelio.laranjeiro@6wind.com>
Subject: [PATCH] net/mlx4: use a single drop queue for all drop flows
Date: Mon,  3 Apr 2017 12:05:15 +0300	[thread overview]
Message-ID: <a05120e777c07567210fa18f36d8da4712c0b73a.1491206959.git.vasilyf@mellanox.com> (raw)

Signed-off-by: Vasily Philipov <vasilyf@mellanox.com>
Acked-by: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>
---

This patch applies on top of [1]
[1] http://dpdk.org/dev/patchwork/patch/21415/

 drivers/net/mlx4/mlx4.h      |   1 +
 drivers/net/mlx4/mlx4_flow.c | 149 ++++++++++++++++++++++++++++---------------
 drivers/net/mlx4/mlx4_flow.h |   2 -
 3 files changed, 99 insertions(+), 53 deletions(-)

diff --git a/drivers/net/mlx4/mlx4.h b/drivers/net/mlx4/mlx4.h
index fac408b..56c2d6c 100644
--- a/drivers/net/mlx4/mlx4.h
+++ b/drivers/net/mlx4/mlx4.h
@@ -339,6 +339,7 @@ struct priv {
 	struct rxq *(*rxqs)[]; /* RX queues. */
 	struct txq *(*txqs)[]; /* TX queues. */
 	struct rte_intr_handle intr_handle; /* Interrupt handler. */
+	struct rte_flow_drop *flow_drop_queue; /* Flow drop queue. */
 	LIST_HEAD(mlx4_flows, rte_flow) flows;
 	rte_spinlock_t lock; /* Lock for control functions. */
 };
diff --git a/drivers/net/mlx4/mlx4_flow.c b/drivers/net/mlx4/mlx4_flow.c
index 65537c7..edfac03 100644
--- a/drivers/net/mlx4/mlx4_flow.c
+++ b/drivers/net/mlx4/mlx4_flow.c
@@ -103,6 +103,11 @@ struct mlx4_flow_items {
 	const enum rte_flow_item_type *const items;
 };
 
+struct rte_flow_drop {
+	struct ibv_qp *qp; /**< Verbs queue pair. */
+	struct ibv_cq *cq; /**< Verbs completion queue. */
+};
+
 /** Valid action for this PMD. */
 static const enum rte_flow_action_type valid_actions[] = {
 	RTE_FLOW_ACTION_TYPE_DROP,
@@ -711,6 +716,87 @@ struct mlx4_flow_items {
 }
 
 /**
+ * Destroy a drop queue.
+ *
+ * @param priv
+ *   Pointer to private structure.
+ */
+static void
+mlx4_flow_destroy_drop_queue(struct priv *priv)
+{
+	if (priv->flow_drop_queue) {
+		struct rte_flow_drop *fdq = priv->flow_drop_queue;
+
+		priv->flow_drop_queue = NULL;
+		claim_zero(ibv_destroy_qp(fdq->qp));
+		claim_zero(ibv_destroy_cq(fdq->cq));
+		rte_free(fdq);
+	}
+}
+
+/**
+ * Create a single drop queue for all drop flows.
+ *
+ * @param priv
+ *   Pointer to private structure.
+ *
+ * @return
+ *   0 on success, negative value otherwise.
+ */
+static int
+mlx4_flow_create_drop_queue(struct priv *priv)
+{
+	struct ibv_qp *qp;
+	struct ibv_cq *cq;
+	struct rte_flow_drop *fdq;
+
+	fdq = rte_calloc(__func__, 1, sizeof(*fdq), 0);
+	if (!fdq) {
+		ERROR("Cannot allocate memory for drop struct");
+		goto err;
+	}
+	cq = ibv_exp_create_cq(priv->ctx, 1, NULL, NULL, 0,
+			      &(struct ibv_exp_cq_init_attr){
+					.comp_mask = 0,
+			      });
+	if (!cq) {
+		ERROR("Cannot create drop CQ");
+		goto err_create_cq;
+	}
+	qp = ibv_exp_create_qp(priv->ctx,
+			      &(struct ibv_exp_qp_init_attr){
+					.send_cq = cq,
+					.recv_cq = cq,
+					.cap = {
+						.max_recv_wr = 1,
+						.max_recv_sge = 1,
+					},
+					.qp_type = IBV_QPT_RAW_PACKET,
+					.comp_mask =
+						IBV_EXP_QP_INIT_ATTR_PD |
+						IBV_EXP_QP_INIT_ATTR_PORT,
+					.pd = priv->pd,
+					.port_num = priv->port,
+			      });
+	if (!qp) {
+		ERROR("Cannot create drop QP");
+		goto err_create_qp;
+	}
+	*fdq = (struct rte_flow_drop){
+		.qp = qp,
+		.cq = cq,
+	};
+	priv->flow_drop_queue = fdq;
+	return 0;
+err_create_qp:
+	claim_zero(ibv_destroy_cq(cq));
+err_create_cq:
+	rte_free(fdq);
+err:
+	return -1;
+}
+
+/**
  * Complete flow rule creation.
  *
  * @param priv
@@ -731,7 +817,6 @@ struct mlx4_flow_items {
 			      struct mlx4_flow_action *action,
 			      struct rte_flow_error *error)
 {
-	struct rxq *rxq;
 	struct ibv_qp *qp;
 	struct rte_flow *rte_flow;
 
@@ -743,47 +828,13 @@ struct mlx4_flow_items {
 				   NULL, "cannot allocate flow memory");
 		return NULL;
 	}
-	rxq = (*priv->rxqs)[action->queue_id];
 	if (action->drop) {
-		rte_flow->cq =
-			ibv_exp_create_cq(priv->ctx, 1, NULL, NULL, 0,
-					  &(struct ibv_exp_cq_init_attr){
-						  .comp_mask = 0,
-					  });
-		if (!rte_flow->cq) {
-			rte_flow_error_set(error, ENOMEM,
-					   RTE_FLOW_ERROR_TYPE_HANDLE,
-					   NULL, "cannot allocate CQ");
-			goto error;
-		}
-		rte_flow->qp = ibv_exp_create_qp(
-			priv->ctx,
-			&(struct ibv_exp_qp_init_attr){
-				.send_cq = rte_flow->cq,
-				.recv_cq = rte_flow->cq,
-				.cap = {
-					.max_recv_wr = 1,
-					.max_recv_sge = 1,
-				},
-				.qp_type = IBV_QPT_RAW_PACKET,
-				.comp_mask =
-					IBV_EXP_QP_INIT_ATTR_PD |
-					IBV_EXP_QP_INIT_ATTR_PORT |
-					IBV_EXP_QP_INIT_ATTR_RES_DOMAIN,
-				.pd = priv->pd,
-				.res_domain = rxq->rd,
-				.port_num = priv->port,
-			});
-		if (!rte_flow->qp) {
-			rte_flow_error_set(error, ENOMEM,
-					   RTE_FLOW_ERROR_TYPE_HANDLE,
-					   NULL, "cannot allocate QP");
-			goto error;
-		}
-		qp = rte_flow->qp;
+		qp = priv->flow_drop_queue->qp;
 	} else {
-		rte_flow->rxq = rxq;
+		struct rxq *rxq = (*priv->rxqs)[action->queue_id];
+
 		qp = rxq->qp;
+		rte_flow->qp = qp;
 	}
 	rte_flow->ibv_attr = ibv_attr;
 	rte_flow->ibv_flow = ibv_create_flow(qp, rte_flow->ibv_attr);
@@ -795,12 +846,6 @@ struct mlx4_flow_items {
 	return rte_flow;
 
 error:
-	assert(rte_flow);
-	if (rte_flow->cq)
-		ibv_destroy_cq(rte_flow->cq);
-	if (rte_flow->qp)
-		ibv_destroy_qp(rte_flow->qp);
-	rte_free(rte_flow->ibv_attr);
 	rte_free(rte_flow);
 	return NULL;
 }
@@ -878,7 +923,8 @@ struct mlx4_flow_items {
 	}
 	rte_flow = priv_flow_create_action_queue(priv, flow.ibv_attr,
 						 &action, error);
-	return rte_flow;
+	if (rte_flow)
+		return rte_flow;
 exit:
 	rte_free(flow.ibv_attr);
 	return NULL;
@@ -925,10 +971,6 @@ struct rte_flow *
 	LIST_REMOVE(flow, next);
 	if (flow->ibv_flow)
 		claim_zero(ibv_destroy_flow(flow->ibv_flow));
-	if (flow->qp)
-		claim_zero(ibv_destroy_qp(flow->qp));
-	if (flow->cq)
-		claim_zero(ibv_destroy_cq(flow->cq));
 	rte_free(flow->ibv_attr);
 	DEBUG("Flow destroyed %p", (void *)flow);
 	rte_free(flow);
@@ -1010,6 +1052,7 @@ struct rte_flow *
 		flow->ibv_flow = NULL;
 		DEBUG("Flow %p removed", (void *)flow);
 	}
+	mlx4_flow_destroy_drop_queue(priv);
 }
 
 /**
@@ -1024,13 +1067,17 @@ struct rte_flow *
 int
 mlx4_priv_flow_start(struct priv *priv)
 {
+	int ret;
 	struct ibv_qp *qp;
 	struct rte_flow *flow;
 
+	ret = mlx4_flow_create_drop_queue(priv);
+	if (ret)
+		return -1;
 	for (flow = LIST_FIRST(&priv->flows);
 	     flow;
 	     flow = LIST_NEXT(flow, next)) {
-		qp = flow->qp ? flow->qp : flow->rxq->qp;
+		qp = flow->qp ? flow->qp : priv->flow_drop_queue->qp;
 		flow->ibv_flow = ibv_create_flow(qp, flow->ibv_attr);
 		if (!flow->ibv_flow) {
 			DEBUG("Flow %p cannot be applied", (void *)flow);
diff --git a/drivers/net/mlx4/mlx4_flow.h b/drivers/net/mlx4/mlx4_flow.h
index 66c5be6..12a293e 100644
--- a/drivers/net/mlx4/mlx4_flow.h
+++ b/drivers/net/mlx4/mlx4_flow.h
@@ -56,11 +56,9 @@
 
 struct rte_flow {
 	LIST_ENTRY(rte_flow) next; /**< Pointer to the next flow structure. */
-	struct rxq *rxq; /**< Pointer to the queue, NULL if drop queue. */
 	struct ibv_flow *ibv_flow; /**< Verbs flow. */
 	struct ibv_flow_attr *ibv_attr; /**< Pointer to Verbs attributes. */
 	struct ibv_qp *qp; /**< Verbs queue pair. */
-	struct ibv_cq *cq; /**< Verbs completion queue. */
 };
 
 int
-- 
1.8.3.1

             reply	other threads:[~2017-04-03  9:05 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-04-03  9:05 Vasily Philipov [this message]
2017-04-03 13:05 ` [PATCH] net/mlx4: use a single drop queue for all drop flows Ferruh Yigit

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=a05120e777c07567210fa18f36d8da4712c0b73a.1491206959.git.vasilyf@mellanox.com \
    --to=vasilyf@mellanox.com \
    --cc=adrien.mazarguil@6wind.com \
    --cc=dev@dpdk.org \
    --cc=nelio.laranjeiro@6wind.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.