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