In order to handle a race condition where the passive side of
a connection can receive data on a QP before the connection established
event has been received, transition the QP to RTS before sending the reply.
This allows a user to send a response to any received message immediately,
rather than waiting until the connection established event has been
processed.

A similar fix was applied to the kernel rdma_cm a while ago.
Simply duplicate the fix in the user space library.

Signed-off-by: Sean Hefty <sean.he...@intel.com>
---

 src/cma.c |   27 +++++++++------------------
 1 files changed, 9 insertions(+), 18 deletions(-)

diff --git a/src/cma.c b/src/cma.c
index efad6ae..59e89dd 100644
--- a/src/cma.c
+++ b/src/cma.c
@@ -652,7 +652,8 @@ static int ucma_modify_qp_rtr(struct rdma_cm_id *id,
        return ibv_modify_qp(id->qp, &qp_attr, qp_attr_mask);
 }
 
-static int ucma_modify_qp_rts(struct rdma_cm_id *id)
+static int ucma_modify_qp_rts(struct rdma_cm_id *id,
+                             struct rdma_conn_param *conn_param)
 {
        struct ibv_qp_attr qp_attr;
        int qp_attr_mask, ret;
@@ -662,6 +663,8 @@ static int ucma_modify_qp_rts(struct rdma_cm_id *id)
        if (ret)
                return ret;
 
+       if (conn_param)
+               qp_attr.max_rd_atomic = conn_param->initiator_depth;
        return ibv_modify_qp(id->qp, &qp_attr, qp_attr_mask);
 }
 
@@ -929,6 +932,10 @@ int rdma_accept(struct rdma_cm_id *id, struct 
rdma_conn_param *conn_param)
                ret = ucma_modify_qp_rtr(id, conn_param);
                if (ret)
                        return ret;
+
+               ret = ucma_modify_qp_rts(id, conn_param);
+               if (ret)
+                       return ret;
        }
 
        CMA_CREATE_MSG_CMD(msg, cmd, UCMA_CMD_ACCEPT, size);
@@ -1212,7 +1219,7 @@ static int ucma_process_conn_resp(struct cma_id_private 
*id_priv)
        if (ret)
                goto err;
 
-       ret = ucma_modify_qp_rts(&id_priv->id);
+       ret = ucma_modify_qp_rts(&id_priv->id, NULL);
        if (ret)
                goto err;
 
@@ -1231,17 +1238,6 @@ err:
        return ret;
 }
 
-static int ucma_process_establish(struct rdma_cm_id *id)
-{
-       int ret;
-
-       ret = ucma_modify_qp_rts(id);
-       if (ret)
-               ucma_modify_qp_err(id);
-
-       return ret;
-}
-
 static int ucma_process_join(struct cma_event *evt)
 {
        evt->mc->mgid = evt->event.param.ud.ah_attr.grh.dgid;
@@ -1367,11 +1363,6 @@ retry:
                }
 
                ucma_copy_conn_event(evt, &resp->param.conn);
-               evt->event.status = ucma_process_establish(&evt->id_priv->id);
-               if (evt->event.status) {
-                       evt->event.event = RDMA_CM_EVENT_CONNECT_ERROR;
-                       evt->id_priv->connect_error = 1;
-               }
                break;
        case RDMA_CM_EVENT_REJECTED:
                if (evt->id_priv->connect_error) {



--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to