[ofa-general][PATCH v2 2/2] mlx4: Default value for automatic completion vector selection

Yevgeny Petrilin yevgenyp at mellanox.co.il
Tue May 27 08:35:00 PDT 2008


>From 71b7fbb81b46f992986b2b278eea7c61d7e0372a Mon Sep 17 00:00:00 2001
From: Yevgeny Petrilin <yevgenyp at mellanox.co.il>
Date: Tue, 27 May 2008 18:15:36 +0300
Subject: [PATCH] mlx4: Default value for automatic completion vector selection

When the vector number passed to mlx4_cq_alloc is IB_CQ_VECTOR_LEAST_ATTACHED (0xff),
the driver selects the completion vector that has the least CQ's attached
to it and attaches the CQ to the chosen vector.
IB_CQ_VECTOR_LEAST_ATTACHED is redefined in device.h as MLX4_ANY_VECTOR
because we don't want all mlx4_core clients (Ethernet and FCoE) to
include <rdma/ib_verbs.h>

Signed-off-by: Yevgeny Petrilin <yevgenyp at mellanox.co.il>
---
Changes since V1:
1. Added IB_CQ_VECTOR_LEAST_ATTACHED to rdma/ib_verbs.h
2. Set MLX4_ANY_VECTOR to IB_CQ_VECTOR_LEAST_ATTACHED

 drivers/net/mlx4/cq.c       |   22 +++++++++++++++++++++-
 drivers/net/mlx4/mlx4.h     |    1 +
 include/linux/mlx4/device.h |    4 ++++
 include/rdma/ib_verbs.h     |   10 +++++++++-
 4 files changed, 35 insertions(+), 2 deletions(-)

diff --git a/drivers/net/mlx4/cq.c b/drivers/net/mlx4/cq.c
index 9be895f..7f0bdf6 100644
--- a/drivers/net/mlx4/cq.c
+++ b/drivers/net/mlx4/cq.c
@@ -187,6 +187,22 @@ int mlx4_cq_resize(struct mlx4_dev *dev, struct mlx4_cq *cq,
 }
 EXPORT_SYMBOL_GPL(mlx4_cq_resize);

+static int mlx4_find_least_loaded_vector(struct mlx4_priv *priv)
+{
+	int i;
+	int index = 0;
+	int min = priv->eq_table.eq[MLX4_EQ_COMP_CPU0].load;
+
+	for (i = 1; i < priv->dev.caps.num_comp_vectors; i++) {
+		if (priv->eq_table.eq[MLX4_EQ_COMP_CPU0 + i].load < min) {
+			index = i;
+			min = priv->eq_table.eq[MLX4_EQ_COMP_CPU0 + i].load;
+		}
+	}
+
+	return index;
+}
+
 int mlx4_cq_alloc(struct mlx4_dev *dev, int nent, struct mlx4_mtt *mtt,
 		  struct mlx4_uar *uar, u64 db_rec, struct mlx4_cq *cq,
 		  unsigned vector, int collapsed)
@@ -228,7 +244,9 @@ int mlx4_cq_alloc(struct mlx4_dev *dev, int nent, struct mlx4_mtt *mtt,
 	cq_context->flags	    = cpu_to_be32(!!collapsed << 18);
 	cq_context->logsize_usrpage = cpu_to_be32((ilog2(nent) << 24) | uar->index);

-	if (vector >= dev->caps.num_comp_vectors) {
+	if (vector == MLX4_ANY_VECTOR)
+		vector = mlx4_find_least_loaded_vector(priv);
+	else if (vector >= dev->caps.num_comp_vectors) {
 		err = -EINVAL;
 		goto err_radix;
 	}
@@ -248,6 +266,7 @@ int mlx4_cq_alloc(struct mlx4_dev *dev, int nent, struct mlx4_mtt *mtt,
 	if (err)
 		goto err_radix;

+	priv->eq_table.eq[cq->comp_eq_idx].load++;
 	cq->cons_index = 0;
 	cq->arm_sn     = 1;
 	cq->uar        = uar;
@@ -285,6 +304,7 @@ void mlx4_cq_free(struct mlx4_dev *dev, struct mlx4_cq *cq)
 		mlx4_warn(dev, "HW2SW_CQ failed (%d) for CQN %06x\n", err, cq->cqn);

 	synchronize_irq(priv->eq_table.eq[cq->comp_eq_idx].irq);
+	priv->eq_table.eq[cq->comp_eq_idx].load--;

 	spin_lock_irq(&cq_table->lock);
 	radix_tree_delete(&cq_table->tree, cq->cqn);
diff --git a/drivers/net/mlx4/mlx4.h b/drivers/net/mlx4/mlx4.h
index 8e5fbe0..df16f05 100644
--- a/drivers/net/mlx4/mlx4.h
+++ b/drivers/net/mlx4/mlx4.h
@@ -143,6 +143,7 @@ struct mlx4_eq {
 	u16			irq;
 	u16			have_irq;
 	int			nent;
+	int			load;
 	struct mlx4_buf_list   *page_list;
 	struct mlx4_mtt		mtt;
 };
diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h
index accc1ee..fd93546 100644
--- a/include/linux/mlx4/device.h
+++ b/include/linux/mlx4/device.h
@@ -37,6 +37,8 @@
 #include <linux/completion.h>
 #include <linux/radix-tree.h>

+#include <rdma/ib_verbs.h>
+
 #include <asm/atomic.h>

 enum {
@@ -133,6 +135,8 @@ enum {
 	MLX4_STAT_RATE_OFFSET	= 5
 };

+#define MLX4_ANY_VECTOR		IB_CQ_VECTOR_LEAST_ATTACHED
+
 static inline u64 mlx4_fw_ver(u64 major, u64 minor, u64 subminor)
 {
 	return (major << 32) | (minor << 16) | subminor;
diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
index 911a661..2462d83 100644
--- a/include/rdma/ib_verbs.h
+++ b/include/rdma/ib_verbs.h
@@ -1364,6 +1364,13 @@ static inline int ib_post_recv(struct ib_qp *qp,
 	return qp->device->post_recv(qp, recv_wr, bad_recv_wr);
 }

+/*
+ * IB_CQ_VECTOR_LEAST_ATTACHED: The constatnt specifies that
+ *	teh cq will be attached to the least attached
+ *	completion vector
+ */
+#define IB_CQ_VECTOR_LEAST_ATTACHED	0xff
+
 /**
  * ib_create_cq - Creates a CQ on the specified device.
  * @device: The device on which to create the CQ.
@@ -1375,7 +1382,8 @@ static inline int ib_post_recv(struct ib_qp *qp,
  *   the associated completion and event handlers.
  * @cqe: The minimum size of the CQ.
  * @comp_vector - Completion vector used to signal completion events.
- *     Must be >= 0 and < context->num_comp_vectors.
+ *     Must be >= 0 and < context->num_comp_vectors
+ *     or IB_CQ_VECTOR_LEAST_ATTACHED.
  *
  * Users can examine the cq structure to determine the actual CQ size.
  */
-- 
1.5.3.7




More information about the general mailing list