Skip to content

Commit

Permalink
RDMA/cma: Pass QP type into rdma_create_id()
Browse files Browse the repository at this point in the history
The RDMA CM currently infers the QP type from the port space selected
by the user.  In the future (eg with RDMA_PS_IB or XRC), there may not
be a 1-1 correspondence between port space and QP type.  For netlink
export of RDMA CM state, we want to export the QP type to userspace,
so it is cleaner to explicitly associate a QP type to an ID.

Modify rdma_create_id() to allow the user to specify the QP type, and
use it to make our selections of datagram versus connected mode.

Signed-off-by: Sean Hefty <[email protected]>
Signed-off-by: Roland Dreier <[email protected]>
  • Loading branch information
shefty authored and rolandd committed May 25, 2011
1 parent 9a7147b commit b26f9b9
Show file tree
Hide file tree
Showing 12 changed files with 55 additions and 33 deletions.
35 changes: 16 additions & 19 deletions drivers/infiniband/core/cma.c
Original file line number Diff line number Diff line change
Expand Up @@ -265,11 +265,6 @@ static inline void sdp_set_ip_ver(struct sdp_hh *hh, u8 ip_ver)
hh->ip_version = (ip_ver << 4) | (hh->ip_version & 0xF);
}

static inline int cma_is_ud_ps(enum rdma_port_space ps)
{
return (ps == RDMA_PS_UDP || ps == RDMA_PS_IPOIB);
}

static void cma_attach_to_dev(struct rdma_id_private *id_priv,
struct cma_device *cma_dev)
{
Expand Down Expand Up @@ -415,7 +410,8 @@ static int cma_has_cm_dev(struct rdma_id_private *id_priv)
}

struct rdma_cm_id *rdma_create_id(rdma_cm_event_handler event_handler,
void *context, enum rdma_port_space ps)
void *context, enum rdma_port_space ps,
enum ib_qp_type qp_type)
{
struct rdma_id_private *id_priv;

Expand All @@ -427,6 +423,7 @@ struct rdma_cm_id *rdma_create_id(rdma_cm_event_handler event_handler,
id_priv->id.context = context;
id_priv->id.event_handler = event_handler;
id_priv->id.ps = ps;
id_priv->id.qp_type = qp_type;
spin_lock_init(&id_priv->lock);
mutex_init(&id_priv->qp_mutex);
init_completion(&id_priv->comp);
Expand Down Expand Up @@ -494,7 +491,7 @@ int rdma_create_qp(struct rdma_cm_id *id, struct ib_pd *pd,
if (IS_ERR(qp))
return PTR_ERR(qp);

if (cma_is_ud_ps(id_priv->id.ps))
if (id->qp_type == IB_QPT_UD)
ret = cma_init_ud_qp(id_priv, qp);
else
ret = cma_init_conn_qp(id_priv, qp);
Expand Down Expand Up @@ -622,7 +619,7 @@ static int cma_ib_init_qp_attr(struct rdma_id_private *id_priv,
qp_attr->port_num = id_priv->id.port_num;
*qp_attr_mask = IB_QP_STATE | IB_QP_PKEY_INDEX | IB_QP_PORT;

if (cma_is_ud_ps(id_priv->id.ps)) {
if (id_priv->id.qp_type == IB_QPT_UD) {
ret = cma_set_qkey(id_priv);
if (ret)
return ret;
Expand All @@ -645,7 +642,7 @@ int rdma_init_qp_attr(struct rdma_cm_id *id, struct ib_qp_attr *qp_attr,
id_priv = container_of(id, struct rdma_id_private, id);
switch (rdma_node_get_transport(id_priv->id.device->node_type)) {
case RDMA_TRANSPORT_IB:
if (!id_priv->cm_id.ib || cma_is_ud_ps(id_priv->id.ps))
if (!id_priv->cm_id.ib || (id_priv->id.qp_type == IB_QPT_UD))
ret = cma_ib_init_qp_attr(id_priv, qp_attr, qp_attr_mask);
else
ret = ib_cm_init_qp_attr(id_priv->cm_id.ib, qp_attr,
Expand Down Expand Up @@ -1088,7 +1085,7 @@ static struct rdma_id_private *cma_new_conn_id(struct rdma_cm_id *listen_id,
goto err;

id = rdma_create_id(listen_id->event_handler, listen_id->context,
listen_id->ps);
listen_id->ps, ib_event->param.req_rcvd.qp_type);
if (IS_ERR(id))
goto err;

Expand Down Expand Up @@ -1139,7 +1136,7 @@ static struct rdma_id_private *cma_new_udp_id(struct rdma_cm_id *listen_id,
int ret;

id = rdma_create_id(listen_id->event_handler, listen_id->context,
listen_id->ps);
listen_id->ps, IB_QPT_UD);
if (IS_ERR(id))
return NULL;

Expand Down Expand Up @@ -1194,7 +1191,7 @@ static int cma_req_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event)
memset(&event, 0, sizeof event);
offset = cma_user_data_offset(listen_id->id.ps);
event.event = RDMA_CM_EVENT_CONNECT_REQUEST;
if (cma_is_ud_ps(listen_id->id.ps)) {
if (listen_id->id.qp_type == IB_QPT_UD) {
conn_id = cma_new_udp_id(&listen_id->id, ib_event);
event.param.ud.private_data = ib_event->private_data + offset;
event.param.ud.private_data_len =
Expand Down Expand Up @@ -1230,8 +1227,7 @@ static int cma_req_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event)
* while we're accessing the cm_id.
*/
mutex_lock(&lock);
if (cma_comp(conn_id, RDMA_CM_CONNECT) &&
!cma_is_ud_ps(conn_id->id.ps))
if (cma_comp(conn_id, RDMA_CM_CONNECT) && (conn_id->id.qp_type != IB_QPT_UD))
ib_send_cm_mra(cm_id, CMA_CM_MRA_SETTING, NULL, 0);
mutex_unlock(&lock);
mutex_unlock(&conn_id->handler_mutex);
Expand Down Expand Up @@ -1386,7 +1382,7 @@ static int iw_conn_req_handler(struct iw_cm_id *cm_id,
/* Create a new RDMA id for the new IW CM ID */
new_cm_id = rdma_create_id(listen_id->id.event_handler,
listen_id->id.context,
RDMA_PS_TCP);
RDMA_PS_TCP, IB_QPT_RC);
if (IS_ERR(new_cm_id)) {
ret = -ENOMEM;
goto out;
Expand Down Expand Up @@ -1535,7 +1531,8 @@ static void cma_listen_on_dev(struct rdma_id_private *id_priv,
struct rdma_cm_id *id;
int ret;

id = rdma_create_id(cma_listen_handler, id_priv, id_priv->id.ps);
id = rdma_create_id(cma_listen_handler, id_priv, id_priv->id.ps,
id_priv->id.qp_type);
if (IS_ERR(id))
return;

Expand Down Expand Up @@ -2645,7 +2642,7 @@ int rdma_connect(struct rdma_cm_id *id, struct rdma_conn_param *conn_param)

switch (rdma_node_get_transport(id->device->node_type)) {
case RDMA_TRANSPORT_IB:
if (cma_is_ud_ps(id->ps))
if (id->qp_type == IB_QPT_UD)
ret = cma_resolve_ib_udp(id_priv, conn_param);
else
ret = cma_connect_ib(id_priv, conn_param);
Expand Down Expand Up @@ -2758,7 +2755,7 @@ int rdma_accept(struct rdma_cm_id *id, struct rdma_conn_param *conn_param)

switch (rdma_node_get_transport(id->device->node_type)) {
case RDMA_TRANSPORT_IB:
if (cma_is_ud_ps(id->ps))
if (id->qp_type == IB_QPT_UD)
ret = cma_send_sidr_rep(id_priv, IB_SIDR_SUCCESS,
conn_param->private_data,
conn_param->private_data_len);
Expand Down Expand Up @@ -2819,7 +2816,7 @@ int rdma_reject(struct rdma_cm_id *id, const void *private_data,

switch (rdma_node_get_transport(id->device->node_type)) {
case RDMA_TRANSPORT_IB:
if (cma_is_ud_ps(id->ps))
if (id->qp_type == IB_QPT_UD)
ret = cma_send_sidr_rep(id_priv, IB_SIDR_REJECT,
private_data, private_data_len);
else
Expand Down
27 changes: 23 additions & 4 deletions drivers/infiniband/core/ucma.c
Original file line number Diff line number Diff line change
Expand Up @@ -367,13 +367,28 @@ static ssize_t ucma_get_event(struct ucma_file *file, const char __user *inbuf,
return ret;
}

static ssize_t ucma_create_id(struct ucma_file *file,
const char __user *inbuf,
int in_len, int out_len)
static int ucma_get_qp_type(struct rdma_ucm_create_id *cmd, enum ib_qp_type *qp_type)
{
switch (cmd->ps) {
case RDMA_PS_TCP:
*qp_type = IB_QPT_RC;
return 0;
case RDMA_PS_UDP:
case RDMA_PS_IPOIB:
*qp_type = IB_QPT_UD;
return 0;
default:
return -EINVAL;
}
}

static ssize_t ucma_create_id(struct ucma_file *file, const char __user *inbuf,
int in_len, int out_len)
{
struct rdma_ucm_create_id cmd;
struct rdma_ucm_create_id_resp resp;
struct ucma_context *ctx;
enum ib_qp_type qp_type;
int ret;

if (out_len < sizeof(resp))
Expand All @@ -382,14 +397,18 @@ static ssize_t ucma_create_id(struct ucma_file *file,
if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
return -EFAULT;

ret = ucma_get_qp_type(&cmd, &qp_type);
if (ret)
return ret;

mutex_lock(&file->mut);
ctx = ucma_alloc_ctx(file);
mutex_unlock(&file->mut);
if (!ctx)
return -ENOMEM;

ctx->uid = cmd.uid;
ctx->cm_id = rdma_create_id(ucma_event_handler, ctx, cmd.ps);
ctx->cm_id = rdma_create_id(ucma_event_handler, ctx, cmd.ps, qp_type);
if (IS_ERR(ctx->cm_id)) {
ret = PTR_ERR(ctx->cm_id);
goto err1;
Expand Down
2 changes: 1 addition & 1 deletion drivers/infiniband/ulp/iser/iser_verbs.c
Original file line number Diff line number Diff line change
Expand Up @@ -548,7 +548,7 @@ int iser_connect(struct iser_conn *ib_conn,
iser_conn_get(ib_conn); /* ref ib conn's cma id */
ib_conn->cma_id = rdma_create_id(iser_cma_handler,
(void *)ib_conn,
RDMA_PS_TCP);
RDMA_PS_TCP, IB_QPT_RC);
if (IS_ERR(ib_conn->cma_id)) {
err = PTR_ERR(ib_conn->cma_id);
iser_err("rdma_create_id failed: %d\n", err);
Expand Down
5 changes: 4 additions & 1 deletion include/rdma/rdma_cm.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ struct rdma_cm_id {
rdma_cm_event_handler event_handler;
struct rdma_route route;
enum rdma_port_space ps;
enum ib_qp_type qp_type;
u8 port_num;
};

Expand All @@ -154,9 +155,11 @@ struct rdma_cm_id {
* returned rdma_id.
* @context: User specified context associated with the id.
* @ps: RDMA port space.
* @qp_type: type of queue pair associated with the id.
*/
struct rdma_cm_id *rdma_create_id(rdma_cm_event_handler event_handler,
void *context, enum rdma_port_space ps);
void *context, enum rdma_port_space ps,
enum ib_qp_type qp_type);

/**
* rdma_destroy_id - Destroys an RDMA identifier.
Expand Down
3 changes: 2 additions & 1 deletion net/9p/trans_rdma.c
Original file line number Diff line number Diff line change
Expand Up @@ -591,7 +591,8 @@ rdma_create_trans(struct p9_client *client, const char *addr, char *args)
return -ENOMEM;

/* Create the RDMA CM ID */
rdma->cm_id = rdma_create_id(p9_cm_event_handler, client, RDMA_PS_TCP);
rdma->cm_id = rdma_create_id(p9_cm_event_handler, client, RDMA_PS_TCP,
IB_QPT_RC);
if (IS_ERR(rdma->cm_id))
goto error;

Expand Down
2 changes: 1 addition & 1 deletion net/rds/ib.c
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ static int rds_ib_laddr_check(__be32 addr)
/* Create a CMA ID and try to bind it. This catches both
* IB and iWARP capable NICs.
*/
cm_id = rdma_create_id(NULL, NULL, RDMA_PS_TCP);
cm_id = rdma_create_id(NULL, NULL, RDMA_PS_TCP, IB_QPT_RC);
if (IS_ERR(cm_id))
return PTR_ERR(cm_id);

Expand Down
2 changes: 1 addition & 1 deletion net/rds/ib_cm.c
Original file line number Diff line number Diff line change
Expand Up @@ -587,7 +587,7 @@ int rds_ib_conn_connect(struct rds_connection *conn)
/* XXX I wonder what affect the port space has */
/* delegate cm event handler to rdma_transport */
ic->i_cm_id = rdma_create_id(rds_rdma_cm_event_handler, conn,
RDMA_PS_TCP);
RDMA_PS_TCP, IB_QPT_RC);
if (IS_ERR(ic->i_cm_id)) {
ret = PTR_ERR(ic->i_cm_id);
ic->i_cm_id = NULL;
Expand Down
2 changes: 1 addition & 1 deletion net/rds/iw.c
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ static int rds_iw_laddr_check(__be32 addr)
/* Create a CMA ID and try to bind it. This catches both
* IB and iWARP capable NICs.
*/
cm_id = rdma_create_id(NULL, NULL, RDMA_PS_TCP);
cm_id = rdma_create_id(NULL, NULL, RDMA_PS_TCP, IB_QPT_RC);
if (IS_ERR(cm_id))
return PTR_ERR(cm_id);

Expand Down
2 changes: 1 addition & 1 deletion net/rds/iw_cm.c
Original file line number Diff line number Diff line change
Expand Up @@ -522,7 +522,7 @@ int rds_iw_conn_connect(struct rds_connection *conn)
/* XXX I wonder what affect the port space has */
/* delegate cm event handler to rdma_transport */
ic->i_cm_id = rdma_create_id(rds_rdma_cm_event_handler, conn,
RDMA_PS_TCP);
RDMA_PS_TCP, IB_QPT_RC);
if (IS_ERR(ic->i_cm_id)) {
ret = PTR_ERR(ic->i_cm_id);
ic->i_cm_id = NULL;
Expand Down
3 changes: 2 additions & 1 deletion net/rds/rdma_transport.c
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,8 @@ static int rds_rdma_listen_init(void)
struct rdma_cm_id *cm_id;
int ret;

cm_id = rdma_create_id(rds_rdma_cm_event_handler, NULL, RDMA_PS_TCP);
cm_id = rdma_create_id(rds_rdma_cm_event_handler, NULL, RDMA_PS_TCP,
IB_QPT_RC);
if (IS_ERR(cm_id)) {
ret = PTR_ERR(cm_id);
printk(KERN_ERR "RDS/RDMA: failed to setup listener, "
Expand Down
3 changes: 2 additions & 1 deletion net/sunrpc/xprtrdma/svc_rdma_transport.c
Original file line number Diff line number Diff line change
Expand Up @@ -695,7 +695,8 @@ static struct svc_xprt *svc_rdma_create(struct svc_serv *serv,
return ERR_PTR(-ENOMEM);
xprt = &cma_xprt->sc_xprt;

listen_id = rdma_create_id(rdma_listen_handler, cma_xprt, RDMA_PS_TCP);
listen_id = rdma_create_id(rdma_listen_handler, cma_xprt, RDMA_PS_TCP,
IB_QPT_RC);
if (IS_ERR(listen_id)) {
ret = PTR_ERR(listen_id);
dprintk("svcrdma: rdma_create_id failed = %d\n", ret);
Expand Down
2 changes: 1 addition & 1 deletion net/sunrpc/xprtrdma/verbs.c
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,7 @@ rpcrdma_create_id(struct rpcrdma_xprt *xprt,

init_completion(&ia->ri_done);

id = rdma_create_id(rpcrdma_conn_upcall, xprt, RDMA_PS_TCP);
id = rdma_create_id(rpcrdma_conn_upcall, xprt, RDMA_PS_TCP, IB_QPT_RC);
if (IS_ERR(id)) {
rc = PTR_ERR(id);
dprintk("RPC: %s: rdma_create_id() failed %i\n",
Expand Down

0 comments on commit b26f9b9

Please sign in to comment.