[ewg] [PATCH] IB/core: Add support for Receive Core Affinity

Eli Cohen eli at mellanox.co.il
Tue Jul 15 09:13:31 PDT 2008


Add the capability flag IB_DEVICE_IPOIB_RCA to denote devices which
support distribution of received packects to multiple receive queues.
This results in better utilization of the system CPU cores by
distributing interrupt handling between the cores. The patch adds a
new verb, ib_create_qp_range(), to create a list range of QPs with
specific alignment requirements that should be used by a consumer to
for the different receive queues.

Signed-off-by: Eli Cohen <eli at mellanox.co.il>
---
 drivers/infiniband/core/verbs.c |   39 ++++++++++++++++++++++++++++++++++++++-
 include/rdma/ib_verbs.h         |   30 +++++++++++++++++++++++++++++-
 2 files changed, 67 insertions(+), 2 deletions(-)

diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c
index a7da9be..871fb1e 100644
--- a/drivers/infiniband/core/verbs.c
+++ b/drivers/infiniband/core/verbs.c
@@ -280,6 +280,39 @@ EXPORT_SYMBOL(ib_destroy_srq);
 
 /* Queue pairs */
 
+int ib_create_qp_range(struct ib_pd *pd, struct ib_qp_init_attr *qp_init_attr,
+		       int nqps, int align, struct ib_qp *list[])
+{
+	int ret;
+	int i;
+
+	ret = pd->device->create_qp_range ?
+		pd->device->create_qp_range(pd, qp_init_attr, NULL, nqps,
+					    align, list) :
+		-ENOSYS;
+
+	if (!ret) {
+		for (i = 0; i < nqps; ++i) {
+			list[i]->device		= pd->device;
+			list[i]->pd		= pd;
+			list[i]->send_cq	= qp_init_attr[i].send_cq;
+			list[i]->recv_cq	= qp_init_attr[i].recv_cq;
+			list[i]->srq		= qp_init_attr[i].srq;
+			list[i]->uobject	= NULL;
+			list[i]->event_handler	= qp_init_attr[i].event_handler;
+			list[i]->qp_context	= qp_init_attr[i].qp_context;
+			list[i]->qp_type	= qp_init_attr[i].qp_type;
+			atomic_inc(&pd->usecnt);
+			atomic_inc(&qp_init_attr[i].send_cq->usecnt);
+			atomic_inc(&qp_init_attr[i].recv_cq->usecnt);
+			if (qp_init_attr[i].srq)
+				atomic_inc(&qp_init_attr[i].srq->usecnt);
+		}
+	}
+	return ret;
+}
+EXPORT_SYMBOL(ib_create_qp_range);
+
 struct ib_qp *ib_create_qp(struct ib_pd *pd,
 			   struct ib_qp_init_attr *qp_init_attr)
 {
@@ -331,6 +364,9 @@ static const struct {
 						IB_QP_QKEY),
 				[IB_QPT_GSI] = (IB_QP_PKEY_INDEX		|
 						IB_QP_QKEY),
+			},
+			.opt_param = {
+				[IB_QPT_UD]  = IB_QP_RCA,
 			}
 		},
 	},
@@ -427,7 +463,8 @@ static const struct {
 			.valid = 1,
 			.opt_param = {
 				[IB_QPT_UD]  = (IB_QP_CUR_STATE			|
-						IB_QP_QKEY),
+						IB_QP_QKEY			|
+						IB_QP_RCA),
 				[IB_QPT_UC]  = (IB_QP_CUR_STATE			|
 						IB_QP_ACCESS_FLAGS		|
 						IB_QP_ALT_PATH			|
diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
index 58a0c3f..3bb391b 100644
--- a/include/rdma/ib_verbs.h
+++ b/include/rdma/ib_verbs.h
@@ -105,6 +105,7 @@ enum ib_device_cap_flags {
 	IB_DEVICE_UD_TSO		= (1<<19),
 	IB_DEVICE_MEM_MGT_EXTENSIONS	= (1<<21),
 	IB_DEVICE_BLOCK_MULTICAST_LOOPBACK = (1<<22),
+	IB_DEVICE_IPOIB_RCA		= (1<<23),
 };
 
 enum ib_atomic_cap {
@@ -558,6 +559,7 @@ enum ib_qp_type {
 enum ib_qp_create_flags {
 	IB_QP_CREATE_IPOIB_UD_LSO		= 1 << 0,
 	IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK	= 1 << 1,
+	IB_QP_CREATE_IPOIB_RCA			= 1 << 2,
 };
 
 struct ib_qp_init_attr {
@@ -629,7 +631,8 @@ enum ib_qp_attr_mask {
 	IB_QP_MAX_DEST_RD_ATOMIC	= (1<<17),
 	IB_QP_PATH_MIG_STATE		= (1<<18),
 	IB_QP_CAP			= (1<<19),
-	IB_QP_DEST_QPN			= (1<<20)
+	IB_QP_DEST_QPN			= (1<<20),
+	IB_QP_RCA			= (1<<21)
 };
 
 enum ib_qp_state {
@@ -648,6 +651,12 @@ enum ib_mig_state {
 	IB_MIG_ARMED
 };
 
+struct rca_attr {
+	int	base_qpn;
+	int	num_qpn;
+	int	default_qpn;
+};
+
 struct ib_qp_attr {
 	enum ib_qp_state	qp_state;
 	enum ib_qp_state	cur_qp_state;
@@ -674,6 +683,7 @@ struct ib_qp_attr {
 	u8			rnr_retry;
 	u8			alt_port_num;
 	u8			alt_timeout;
+	struct rca_attr 	rca;
 };
 
 enum ib_wr_opcode {
@@ -1043,6 +1053,10 @@ struct ib_device {
 	int                        (*post_srq_recv)(struct ib_srq *srq,
 						    struct ib_recv_wr *recv_wr,
 						    struct ib_recv_wr **bad_recv_wr);
+	int 			   (*create_qp_range)(struct ib_pd *pd,
+						      struct ib_qp_init_attr *qp_init_attr,
+						      struct ib_udata *udata, int nqps,
+						      int align, struct ib_qp *list[]);
 	struct ib_qp *             (*create_qp)(struct ib_pd *pd,
 						struct ib_qp_init_attr *qp_init_attr,
 						struct ib_udata *udata);
@@ -1373,6 +1387,20 @@ static inline int ib_post_srq_recv(struct ib_srq *srq,
 }
 
 /**
+ * ib_create_qp_range - Creates a range of QPs associated with the
+ * specified protection domain.
+ * @pd: The protection domain associated with the QP.
+ * @qp_init_attr: A list of initial attributes required to create the
+ *   QPs.  If QP creation succeeds, then the attributes are updated to
+ *   the actual capabilities of the created QP.
+ * @nqps: The number of required QPs
+ * @align: Required alignment for the allocated QP numbers.
+ * @list: pointer to an array to hold allocated QPs
+ */
+int ib_create_qp_range(struct ib_pd *pd, struct ib_qp_init_attr *qp_init_attr,
+		       int nqps, int align, struct ib_qp *list[]);
+
+/**
  * ib_create_qp - Creates a QP associated with the specified protection
  *   domain.
  * @pd: The protection domain associated with the QP.
-- 
1.5.6




More information about the ewg mailing list