Commit 418d5130 authored by Sean Hefty's avatar Sean Hefty Committed by Roland Dreier

RDMA/core: Add XRC SRQ type

XRC ("eXtended reliable connected") is an IB transport that provides
better scalability by allowing senders to specify which shared receive
queue (SRQ) should be used to receive a message, which essentially
allows one transport context (QP connection) to serve multiple
destinations (as long as they share an adapter, of course).

XRC defines SRQs that are specifically used by XRC connections.  Expand
the SRQ code to support XRC SRQs.  An XRC SRQ is currently restricted to
only XRC use according to the IB XRC Annex.

Portions of this patch were derived from work by
Jack Morgenstein <jackm@dev.mellanox.co.il>.
Signed-off-by: default avatarSean Hefty <sean.hefty@intel.com>
Signed-off-by: default avatarRoland Dreier <roland@purestorage.com>
parent 96104eda
...@@ -251,6 +251,12 @@ struct ib_srq *ib_create_srq(struct ib_pd *pd, ...@@ -251,6 +251,12 @@ struct ib_srq *ib_create_srq(struct ib_pd *pd,
srq->event_handler = srq_init_attr->event_handler; srq->event_handler = srq_init_attr->event_handler;
srq->srq_context = srq_init_attr->srq_context; srq->srq_context = srq_init_attr->srq_context;
srq->srq_type = srq_init_attr->srq_type; srq->srq_type = srq_init_attr->srq_type;
if (srq->srq_type == IB_SRQT_XRC) {
srq->ext.xrc.xrcd = srq_init_attr->ext.xrc.xrcd;
srq->ext.xrc.cq = srq_init_attr->ext.xrc.cq;
atomic_inc(&srq->ext.xrc.xrcd->usecnt);
atomic_inc(&srq->ext.xrc.cq->usecnt);
}
atomic_inc(&pd->usecnt); atomic_inc(&pd->usecnt);
atomic_set(&srq->usecnt, 0); atomic_set(&srq->usecnt, 0);
} }
...@@ -280,16 +286,29 @@ EXPORT_SYMBOL(ib_query_srq); ...@@ -280,16 +286,29 @@ EXPORT_SYMBOL(ib_query_srq);
int ib_destroy_srq(struct ib_srq *srq) int ib_destroy_srq(struct ib_srq *srq)
{ {
struct ib_pd *pd; struct ib_pd *pd;
enum ib_srq_type srq_type;
struct ib_xrcd *uninitialized_var(xrcd);
struct ib_cq *uninitialized_var(cq);
int ret; int ret;
if (atomic_read(&srq->usecnt)) if (atomic_read(&srq->usecnt))
return -EBUSY; return -EBUSY;
pd = srq->pd; pd = srq->pd;
srq_type = srq->srq_type;
if (srq_type == IB_SRQT_XRC) {
xrcd = srq->ext.xrc.xrcd;
cq = srq->ext.xrc.cq;
}
ret = srq->device->destroy_srq(srq); ret = srq->device->destroy_srq(srq);
if (!ret) if (!ret) {
atomic_dec(&pd->usecnt); atomic_dec(&pd->usecnt);
if (srq_type == IB_SRQT_XRC) {
atomic_dec(&xrcd->usecnt);
atomic_dec(&cq->usecnt);
}
}
return ret; return ret;
} }
......
...@@ -524,7 +524,8 @@ enum ib_cq_notify_flags { ...@@ -524,7 +524,8 @@ enum ib_cq_notify_flags {
}; };
enum ib_srq_type { enum ib_srq_type {
IB_SRQT_BASIC IB_SRQT_BASIC,
IB_SRQT_XRC
}; };
enum ib_srq_attr_mask { enum ib_srq_attr_mask {
...@@ -543,6 +544,13 @@ struct ib_srq_init_attr { ...@@ -543,6 +544,13 @@ struct ib_srq_init_attr {
void *srq_context; void *srq_context;
struct ib_srq_attr attr; struct ib_srq_attr attr;
enum ib_srq_type srq_type; enum ib_srq_type srq_type;
union {
struct {
struct ib_xrcd *xrcd;
struct ib_cq *cq;
} xrc;
} ext;
}; };
struct ib_qp_cap { struct ib_qp_cap {
...@@ -895,6 +903,14 @@ struct ib_srq { ...@@ -895,6 +903,14 @@ struct ib_srq {
void *srq_context; void *srq_context;
enum ib_srq_type srq_type; enum ib_srq_type srq_type;
atomic_t usecnt; atomic_t usecnt;
union {
struct {
struct ib_xrcd *xrcd;
struct ib_cq *cq;
u32 srq_num;
} xrc;
} ext;
}; };
struct ib_qp { struct ib_qp {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment