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 <[EMAIL PROTECTED]>
---
 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

_______________________________________________
general mailing list
general@lists.openfabrics.org
http://lists.openfabrics.org/cgi-bin/mailman/listinfo/general

To unsubscribe, please visit http://openib.org/mailman/listinfo/openib-general

Reply via email to