[openib-general] [PATCH 4/7 v2] for 2.6.20 rdma/cma: add rdma_establish to force connection if RTU is lost
Sean Hefty
sean.hefty at intel.com
Tue Oct 24 15:45:51 PDT 2006
Allow ULPs to transition to RTS before sending a REP. This allows the
ULP to respond to a received message if it arrives before the RTU or
communication established event.
Modify the RDMA CM to transition to RTS when sending a REP over IB, and
expose a new rdma_establish interface that a user can invoke to force a
connection into the established state if it polls a receive completion
before an RTU arrives.
Signed-off-by: Sean Hefty <sean.hefty at intel.com>
---
diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c
index 1cf0d42..492d4ce 100644
--- a/drivers/infiniband/core/cm.c
+++ b/drivers/infiniband/core/cm.c
@@ -3242,6 +3242,10 @@ static int cm_init_qp_rts_attr(struct cm
spin_lock_irqsave(&cm_id_priv->lock, flags);
switch (cm_id_priv->id.state) {
+ /* Allow transition to RTS before sending REP */
+ case IB_CM_REQ_RCVD:
+ case IB_CM_MRA_REQ_SENT:
+
case IB_CM_REP_RCVD:
case IB_CM_MRA_REP_SENT:
case IB_CM_REP_SENT:
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index 622c8f9..416fee8 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -759,22 +759,6 @@ static int cma_verify_rep(struct rdma_id
return 0;
}
-static int cma_rtu_recv(struct rdma_id_private *id_priv)
-{
- int ret;
-
- ret = cma_modify_qp_rts(&id_priv->id);
- if (ret)
- goto reject;
-
- return 0;
-reject:
- cma_modify_qp_err(&id_priv->id);
- ib_send_cm_rej(id_priv->cm_id.ib, IB_CM_REJ_CONSUMER_DEFINED,
- NULL, 0, NULL, 0);
- return ret;
-}
-
static void cma_set_rep_event_data(struct rdma_cm_event *event,
struct ib_cm_rep_event_param *rep_data,
void *private_data)
@@ -820,9 +804,8 @@ static int cma_ib_handler(struct ib_cm_i
ib_event->private_data);
break;
case IB_CM_RTU_RECEIVED:
- event.status = cma_rtu_recv(id_priv);
- event.event = event.status ? RDMA_CM_EVENT_CONNECT_ERROR :
- RDMA_CM_EVENT_ESTABLISHED;
+ case IB_CM_USER_ESTABLISHED:
+ event.event = RDMA_CM_EVENT_ESTABLISHED;
break;
case IB_CM_DREQ_ERROR:
event.status = -ETIMEDOUT; /* fall through */
@@ -1990,11 +1973,25 @@ static int cma_accept_ib(struct rdma_id_
struct rdma_conn_param *conn_param)
{
struct ib_cm_rep_param rep;
- int ret;
+ struct ib_qp_attr qp_attr;
+ int qp_attr_mask, ret;
- ret = cma_modify_qp_rtr(&id_priv->id);
- if (ret)
- return ret;
+ if (id_priv->id.qp) {
+ ret = cma_modify_qp_rtr(&id_priv->id);
+ if (ret)
+ goto out;
+
+ qp_attr.qp_state = IB_QPS_RTS;
+ ret = ib_cm_init_qp_attr(id_priv->cm_id.ib, &qp_attr,
+ &qp_attr_mask);
+ if (ret)
+ goto out;
+
+ qp_attr.max_rd_atomic = conn_param->initiator_depth;
+ ret = ib_modify_qp(id_priv->id.qp, &qp_attr, qp_attr_mask);
+ if (ret)
+ goto out;
+ }
memset(&rep, 0, sizeof rep);
rep.qp_num = id_priv->qp_num;
@@ -2009,7 +2006,9 @@ static int cma_accept_ib(struct rdma_id_
rep.rnr_retry_count = conn_param->rnr_retry_count;
rep.srq = id_priv->srq ? 1 : 0;
- return ib_send_cm_rep(id_priv->cm_id.ib, &rep);
+ ret = ib_send_cm_rep(id_priv->cm_id.ib, &rep);
+out:
+ return ret;
}
static int cma_accept_iw(struct rdma_id_private *id_priv,
@@ -2074,6 +2073,27 @@ reject:
}
EXPORT_SYMBOL(rdma_accept);
+int rdma_establish(struct rdma_cm_id *id)
+{
+ struct rdma_id_private *id_priv;
+ int ret;
+
+ id_priv = container_of(id, struct rdma_id_private, id);
+ if (!cma_comp(id_priv, CMA_CONNECT))
+ return -EINVAL;
+
+ switch (id->device->node_type) {
+ case RDMA_NODE_IB_CA:
+ ret = ib_cm_establish(id_priv->cm_id.ib);
+ break;
+ default:
+ ret = 0;
+ break;
+ }
+ return ret;
+}
+EXPORT_SYMBOL(rdma_establish);
+
int rdma_reject(struct rdma_cm_id *id, const void *private_data,
u8 private_data_len)
{
diff --git a/include/rdma/rdma_cm.h b/include/rdma/rdma_cm.h
index aa6ce47..dbc7c56 100644
--- a/include/rdma/rdma_cm.h
+++ b/include/rdma/rdma_cm.h
@@ -253,6 +253,16 @@ int rdma_listen(struct rdma_cm_id *id, i
int rdma_accept(struct rdma_cm_id *id, struct rdma_conn_param *conn_param);
/**
+ * rdma_establish - Forces a connection state to established.
+ * @id: Connection identifier to transition to established.
+ *
+ * This routine should be invoked by users who receive messages on a
+ * QP before being notified that the connection has been established by the
+ * RDMA CM.
+ */
+int rdma_establish(struct rdma_cm_id *id);
+
+/**
* rdma_reject - Called to reject a connection request or response.
*/
int rdma_reject(struct rdma_cm_id *id, const void *private_data,
More information about the general
mailing list