]> git.openfabrics.org - ~shefty/librdmacm.git/commitdiff
librdmacm: allow user to specify max RDMA resouces
authorSean Hefty <sean.hefty@intel.com>
Thu, 6 May 2010 22:45:05 +0000 (15:45 -0700)
committerSean Hefty <sean.hefty@intel.com>
Thu, 6 May 2010 22:45:05 +0000 (15:45 -0700)
Allow the user to indicate that the library should select the
maximum RDMA read values available should be used when
establishing a connection.  The library selects the maximum
based on local hardware limitations and connection request
data.

Signed-off-by: Sean Hefty <sean.hefty@intel.com>
include/rdma/rdma_cma.h
src/cma.c
src/cma.h

index d8cbb912e009f3ef1d1ca99477fdf4e78d65507f..f50b4ddc0a74ddd3db84bc0044283a9b3847bf6a 100644 (file)
@@ -121,6 +121,11 @@ struct rdma_cm_id {
        struct ibv_cq           *recv_cq;
 };
 
+enum {
+       RDMA_MAX_RESP_RES = 0xFF,
+       RDMA_MAX_INIT_DEPTH = 0xFF
+};
+
 struct rdma_conn_param {
        const void *private_data;
        uint8_t private_data_len;
index 2296da2190ccf0ce68570e01de1a37c725391d76..37d2e210978dd9513fe4ce3e2c45e87399a4ea18 100644 (file)
--- a/src/cma.c
+++ b/src/cma.c
@@ -112,6 +112,8 @@ struct cma_id_private {
        pthread_mutex_t   mut;
        uint32_t          handle;
        struct cma_multicast *mc_list;
+       uint8_t           initiator_depth;
+       uint8_t           responder_resources;
 };
 
 struct cma_multicast {
@@ -850,8 +852,7 @@ static int rdma_init_qp_attr(struct rdma_cm_id *id, struct ibv_qp_attr *qp_attr,
        return 0;
 }
 
-static int ucma_modify_qp_rtr(struct rdma_cm_id *id,
-                             struct rdma_conn_param *conn_param)
+static int ucma_modify_qp_rtr(struct rdma_cm_id *id, uint8_t resp_res)
 {
        struct ibv_qp_attr qp_attr;
        int qp_attr_mask, ret;
@@ -874,13 +875,12 @@ static int ucma_modify_qp_rtr(struct rdma_cm_id *id,
        if (ret)
                return ret;
 
-       if (conn_param)
-               qp_attr.max_dest_rd_atomic = conn_param->responder_resources;
+       if (resp_res != RDMA_MAX_RESP_RES)
+               qp_attr.max_dest_rd_atomic = resp_res;
        return ibv_modify_qp(id->qp, &qp_attr, qp_attr_mask);
 }
 
-static int ucma_modify_qp_rts(struct rdma_cm_id *id,
-                             struct rdma_conn_param *conn_param)
+static int ucma_modify_qp_rts(struct rdma_cm_id *id, uint8_t init_depth)
 {
        struct ibv_qp_attr qp_attr;
        int qp_attr_mask, ret;
@@ -890,8 +890,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;
+       if (init_depth != RDMA_MAX_INIT_DEPTH)
+               qp_attr.max_rd_atomic = init_depth;
        return ibv_modify_qp(id->qp, &qp_attr, qp_attr_mask);
 }
 
@@ -1128,28 +1128,31 @@ void rdma_destroy_qp(struct rdma_cm_id *id)
 }
 
 static int ucma_valid_param(struct cma_id_private *id_priv,
-                           struct rdma_conn_param *conn_param)
+                           struct rdma_conn_param *param)
 {
        if (id_priv->id.ps != RDMA_PS_TCP)
                return 0;
 
-       if ((conn_param->responder_resources >
-            id_priv->cma_dev->max_responder_resources) ||
-           (conn_param->initiator_depth >
-            id_priv->cma_dev->max_initiator_depth))
+       if ((param->responder_resources != RDMA_MAX_RESP_RES) &&
+           (param->responder_resources > id_priv->cma_dev->max_responder_resources))
+               return ERR(EINVAL);
+
+       if ((param->initiator_depth != RDMA_MAX_INIT_DEPTH) &&
+           (param->initiator_depth > id_priv->cma_dev->max_initiator_depth))
                return ERR(EINVAL);
 
        return 0;
 }
 
-static void ucma_copy_conn_param_to_kern(struct ucma_abi_conn_param *dst,
+static void ucma_copy_conn_param_to_kern(struct cma_id_private *id_priv,
+                                        struct ucma_abi_conn_param *dst,
                                         struct rdma_conn_param *src,
                                         uint32_t qp_num, uint8_t srq)
 {
        dst->qp_num = qp_num;
        dst->srq = srq;
-       dst->responder_resources = src->responder_resources;
-       dst->initiator_depth = src->initiator_depth;
+       dst->responder_resources = id_priv->responder_resources;
+       dst->initiator_depth = id_priv->initiator_depth;
        dst->flow_control = src->flow_control;
        dst->retry_count = src->retry_count;
        dst->rnr_retry_count = src->rnr_retry_count;
@@ -1174,15 +1177,24 @@ int rdma_connect(struct rdma_cm_id *id, struct rdma_conn_param *conn_param)
        if (ret)
                return ret;
 
+       if (conn_param->initiator_depth != RDMA_MAX_INIT_DEPTH)
+               id_priv->initiator_depth = conn_param->initiator_depth;
+       else
+               id_priv->initiator_depth = id_priv->cma_dev->max_initiator_depth;
+       if (conn_param->responder_resources != RDMA_MAX_RESP_RES)
+               id_priv->responder_resources = conn_param->responder_resources;
+       else
+               id_priv->responder_resources = id_priv->cma_dev->max_responder_resources;
+
        CMA_CREATE_MSG_CMD(msg, cmd, UCMA_CMD_CONNECT, size);
        cmd->id = id_priv->handle;
        if (id->qp)
-               ucma_copy_conn_param_to_kern(&cmd->conn_param, conn_param,
-                                            id->qp->qp_num,
+               ucma_copy_conn_param_to_kern(id_priv, &cmd->conn_param,
+                                            conn_param, id->qp->qp_num,
                                             (id->qp->srq != NULL));
        else
-               ucma_copy_conn_param_to_kern(&cmd->conn_param, conn_param,
-                                            conn_param->qp_num,
+               ucma_copy_conn_param_to_kern(id_priv, &cmd->conn_param,
+                                            conn_param, conn_param->qp_num,
                                             conn_param->srq);
 
        ret = write(id->channel->fd, msg, size);
@@ -1226,12 +1238,25 @@ int rdma_accept(struct rdma_cm_id *id, struct rdma_conn_param *conn_param)
        if (ret)
                return ret;
 
+       if (conn_param->initiator_depth == RDMA_MAX_INIT_DEPTH) {
+               id_priv->initiator_depth = min(id_priv->initiator_depth,
+                                              id_priv->cma_dev->max_initiator_depth);
+       } else {
+               id_priv->initiator_depth = conn_param->initiator_depth;
+       }
+       if (conn_param->responder_resources == RDMA_MAX_RESP_RES) {
+               id_priv->responder_resources = min(id_priv->responder_resources,
+                                                  id_priv->cma_dev->max_responder_resources);
+       } else {
+               id_priv->responder_resources = conn_param->responder_resources;
+       }
+
        if (!ucma_is_ud_ps(id->ps)) {
-               ret = ucma_modify_qp_rtr(id, conn_param);
+               ret = ucma_modify_qp_rtr(id, id_priv->responder_resources);
                if (ret)
                        return ret;
 
-               ret = ucma_modify_qp_rts(id, conn_param);
+               ret = ucma_modify_qp_rts(id, id_priv->initiator_depth);
                if (ret)
                        return ret;
        }
@@ -1240,12 +1265,12 @@ int rdma_accept(struct rdma_cm_id *id, struct rdma_conn_param *conn_param)
        cmd->id = id_priv->handle;
        cmd->uid = (uintptr_t) id_priv;
        if (id->qp)
-               ucma_copy_conn_param_to_kern(&cmd->conn_param, conn_param,
-                                            id->qp->qp_num,
+               ucma_copy_conn_param_to_kern(id_priv, &cmd->conn_param,
+                                            conn_param, id->qp->qp_num,
                                             (id->qp->srq != NULL));
        else
-               ucma_copy_conn_param_to_kern(&cmd->conn_param, conn_param,
-                                            conn_param->qp_num,
+               ucma_copy_conn_param_to_kern(id_priv, &cmd->conn_param,
+                                            conn_param, conn_param->qp_num,
                                             conn_param->srq);
 
        ret = write(id->channel->fd, msg, size);
@@ -1565,6 +1590,8 @@ static int ucma_process_conn_req(struct cma_event *evt,
        evt->event.listen_id = &evt->id_priv->id;
        evt->event.id = &id_priv->id;
        id_priv->handle = handle;
+       id_priv->initiator_depth = evt->event.param.conn.initiator_depth;
+       id_priv->responder_resources = evt->event.param.conn.responder_resources;
 
        if (evt->id_priv->sync) {
                ret = rdma_migrate_id(&id_priv->id, NULL);
@@ -1591,11 +1618,11 @@ static int ucma_process_conn_resp(struct cma_id_private *id_priv)
        void *msg;
        int ret, size;
 
-       ret = ucma_modify_qp_rtr(&id_priv->id, NULL);
+       ret = ucma_modify_qp_rtr(&id_priv->id, RDMA_MAX_RESP_RES);
        if (ret)
                goto err;
 
-       ret = ucma_modify_qp_rts(&id_priv->id, NULL);
+       ret = ucma_modify_qp_rts(&id_priv->id, RDMA_MAX_INIT_DEPTH);
        if (ret)
                goto err;
 
index 1c0ab8b9737be49ce42c185734dd81d3db732c44..39c53ec175c96c63aa722ac2094136e1132279f4 100644 (file)
--- a/src/cma.h
+++ b/src/cma.h
@@ -64,6 +64,8 @@ static inline uint64_t htonll(uint64_t x) { return x; }
 static inline uint64_t ntohll(uint64_t x) { return x; }
 #endif
 
+#define min(a, b) (a < b ? a : b)
+
 static inline int ERR(int err)
 {
        errno = err;