From 742f75282720fc80c028108daba43b3680d72d52 Mon Sep 17 00:00:00 2001 From: Sean Hefty Date: Fri, 18 May 2012 17:07:11 -0700 Subject: [PATCH] rsockets: Reduce QP size if larger than hardware maximums When porting rsockets to iwarp, it was discovered that the default QP size (512) was larger than that supported by the hardware. Decrease the size of the QP if the default size is larger than the maximum supported by the hardware. Signed-off-by: Sean Hefty --- src/cma.c | 10 ++++++++ src/cma.h | 3 ++- src/rsocket.c | 68 +++++++++++++++++++++++++++++++++++++-------------- 3 files changed, 62 insertions(+), 19 deletions(-) diff --git a/src/cma.c b/src/cma.c index 9cd34cf5..753612c5 100755 --- a/src/cma.c +++ b/src/cma.c @@ -76,6 +76,7 @@ struct cma_device { struct ibv_pd *pd; uint64_t guid; int port_cnt; + int max_qpsize; uint8_t max_initiator_depth; uint8_t max_responder_resources; }; @@ -267,6 +268,7 @@ int ucma_init(void) } cma_dev->port_cnt = attr.phys_port_cnt; + cma_dev->max_qpsize = attr.max_qp_wr; cma_dev->max_initiator_depth = (uint8_t) attr.max_qp_init_rd_atom; cma_dev->max_responder_resources = (uint8_t) attr.max_qp_rd_atom; ib += (cma_dev->verbs->device->transport_type == IBV_TRANSPORT_IB); @@ -2217,3 +2219,11 @@ void rdma_destroy_ep(struct rdma_cm_id *id) rdma_destroy_id(id); } + +int ucma_max_qpsize(struct rdma_cm_id *id) +{ + struct cma_id_private *id_priv; + + id_priv = container_of(id, struct cma_id_private, id); + return id_priv->cma_dev->max_qpsize; +} diff --git a/src/cma.h b/src/cma.h index 7703fe88..f28eaf3a 100644 --- a/src/cma.h +++ b/src/cma.h @@ -67,7 +67,7 @@ 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) +#define min(a, b) ((a) < (b) ? a : b) /* * Fast synchronization for low contention locking. @@ -104,6 +104,7 @@ static inline void fastlock_release(fastlock_t *lock) } #endif /* DEFINE_ATOMICS */ +int ucma_max_qpsize(struct rdma_cm_id *id); int ucma_complete(struct rdma_cm_id *id); static inline int ERR(int err) { diff --git a/src/rsocket.c b/src/rsocket.c index 01b7248d..4e0671fe 100644 --- a/src/rsocket.c +++ b/src/rsocket.c @@ -55,6 +55,8 @@ #define RS_OLAP_START_SIZE 2048 #define RS_MAX_TRANSFER 65536 #define RS_QP_SIZE 512 +#define RS_QP_MAX_SIZE 0xFFFE +#define RS_QP_MIN_SIZE 8 #define RS_QP_CTRL_SIZE 4 #define RS_CONN_RETRIES 6 #define RS_SGL_SIZE 2 @@ -160,7 +162,9 @@ struct rsocket { int sbuf_bytes_avail; uint16_t sseq_no; uint16_t sseq_comp; + uint16_t sq_size; + uint16_t rq_size; uint16_t rseq_no; uint16_t rseq_comp; int rbuf_bytes_avail; @@ -168,7 +172,7 @@ struct rsocket { int rbuf_offset; int rmsg_head; int rmsg_tail; - struct rs_msg rmsg[RS_QP_SIZE + 1]; + struct rs_msg *rmsg; int remote_sge; struct rs_sge remote_sgl; @@ -222,8 +226,17 @@ static struct rsocket *rs_alloc(struct rsocket *inherited_rs) return NULL; rs->index = -1; - rs->sbuf_size = inherited_rs ? inherited_rs->sbuf_size : RS_BUF_SIZE; - rs->rbuf_size = inherited_rs ? inherited_rs->rbuf_size : RS_BUF_SIZE; + if (inherited_rs) { + rs->sbuf_size = inherited_rs->sbuf_size; + rs->rbuf_size = inherited_rs->rbuf_size; + rs->sq_size = inherited_rs->sq_size; + rs->rq_size = inherited_rs->rq_size; + rs->ctrl_avail = inherited_rs->ctrl_avail; + } else { + rs->sbuf_size = rs->rbuf_size = RS_BUF_SIZE; + rs->sq_size = rs->rq_size = RS_QP_SIZE; + rs->ctrl_avail = RS_QP_CTRL_SIZE; + } fastlock_init(&rs->slock); fastlock_init(&rs->rlock); fastlock_init(&rs->cq_lock); @@ -244,8 +257,24 @@ static int rs_set_nonblocking(struct rsocket *rs, long arg) return ret; } +static void rs_set_qp_size(struct rsocket *rs) +{ + uint16_t max_size; + + max_size = min(ucma_max_qpsize(rs->cm_id), RS_QP_MAX_SIZE); + + if (rs->sq_size > max_size) + rs->sq_size = max_size; + if (rs->rq_size > max_size) + rs->rq_size = max_size; +} + static int rs_init_bufs(struct rsocket *rs) { + rs->rmsg = calloc(rs->rq_size + 1, sizeof(*rs->rmsg)); + if (!rs->rmsg) + return -1; + rs->sbuf = calloc(rs->sbuf_size, sizeof(*rs->sbuf)); if (!rs->sbuf) return -1; @@ -273,9 +302,8 @@ static int rs_init_bufs(struct rsocket *rs) rs->rbuf_free_offset = rs->rbuf_size >> 1; rs->rbuf_bytes_avail = rs->rbuf_size >> 1; - rs->ctrl_avail = RS_QP_CTRL_SIZE; - rs->sqe_avail = RS_QP_SIZE - rs->ctrl_avail; - rs->rseq_comp = RS_QP_SIZE >> 1; + rs->sqe_avail = rs->sq_size - rs->ctrl_avail; + rs->rseq_comp = rs->rq_size >> 1; return 0; } @@ -285,7 +313,7 @@ static int rs_create_cq(struct rsocket *rs) if (!rs->cm_id->recv_cq_channel) return -1; - rs->cm_id->recv_cq = ibv_create_cq(rs->cm_id->verbs, RS_QP_SIZE * 2, + rs->cm_id->recv_cq = ibv_create_cq(rs->cm_id->verbs, rs->sq_size + rs->rq_size, rs->cm_id, rs->cm_id->recv_cq_channel, 0); if (!rs->cm_id->recv_cq) goto err1; @@ -313,6 +341,7 @@ static int rs_create_ep(struct rsocket *rs) struct ibv_qp_init_attr qp_attr; int i, ret; + rs_set_qp_size(rs); ret = rs_init_bufs(rs); if (ret) return ret; @@ -327,8 +356,8 @@ static int rs_create_ep(struct rsocket *rs) qp_attr.recv_cq = rs->cm_id->recv_cq; qp_attr.qp_type = IBV_QPT_RC; qp_attr.sq_sig_all = 1; - qp_attr.cap.max_send_wr = RS_QP_SIZE; - qp_attr.cap.max_recv_wr = RS_QP_SIZE; + qp_attr.cap.max_send_wr = rs->sq_size; + qp_attr.cap.max_recv_wr = rs->rq_size; qp_attr.cap.max_send_sge = 2; qp_attr.cap.max_recv_sge = 1; qp_attr.cap.max_inline_data = RS_INLINE; @@ -337,7 +366,7 @@ static int rs_create_ep(struct rsocket *rs) if (ret) return ret; - for (i = 0; i < RS_QP_SIZE; i++) { + for (i = 0; i < rs->rq_size; i++) { ret = rdma_post_recvv(rs->cm_id, NULL, NULL, 0); if (ret) return ret; @@ -350,6 +379,9 @@ static void rs_free(struct rsocket *rs) if (rs->index >= 0) rs_remove(rs); + if (rs->rmsg) + free(rs->rmsg); + if (rs->sbuf) { if (rs->smr) rdma_dereg_mr(rs->smr); @@ -383,7 +415,7 @@ static void rs_set_conn_data(struct rsocket *rs, struct rdma_conn_param *param, { conn->version = 1; conn->flags = rs_host_is_net() ? RS_CONN_FLAG_NET : 0; - conn->credits = htons(RS_QP_SIZE); + conn->credits = htons(rs->rq_size); conn->reserved2 = 0; conn->target_sgl.addr = htonll((uintptr_t) rs->target_sgl); @@ -703,7 +735,7 @@ static void rs_send_credits(struct rsocket *rs) struct rs_sge sge; rs->ctrl_avail--; - rs->rseq_comp = rs->rseq_no + (RS_QP_SIZE >> 1); + rs->rseq_comp = rs->rseq_no + (rs->rq_size >> 1); if (rs->rbuf_bytes_avail >= (rs->rbuf_size >> 1)) { if (!(rs->opts & RS_OPT_SWAP_SGL)) { sge.addr = (uintptr_t) &rs->rbuf[rs->rbuf_free_offset]; @@ -720,7 +752,7 @@ static void rs_send_credits(struct rsocket *rs) ibsge.length = sizeof(sge); rs_post_write(rs, 0, &ibsge, 1, - rs_msg_set(RS_OP_SGL, rs->rseq_no + RS_QP_SIZE), + rs_msg_set(RS_OP_SGL, rs->rseq_no + rs->rq_size), IBV_SEND_INLINE, rs->remote_sgl.addr + rs->remote_sge * sizeof(struct rs_sge), @@ -734,7 +766,7 @@ static void rs_send_credits(struct rsocket *rs) rs->remote_sge = 0; } else { rs_post_write(rs, 0, NULL, 0, - rs_msg_set(RS_OP_SGL, rs->rseq_no + RS_QP_SIZE), 0, 0, 0); + rs_msg_set(RS_OP_SGL, rs->rseq_no + rs->rq_size), 0, 0, 0); } } @@ -778,7 +810,7 @@ static int rs_poll_cq(struct rsocket *rs) default: rs->rmsg[rs->rmsg_tail].op = rs_msg_op(imm_data); rs->rmsg[rs->rmsg_tail].data = rs_msg_data(imm_data); - if (++rs->rmsg_tail == RS_QP_SIZE + 1) + if (++rs->rmsg_tail == rs->rq_size + 1) rs->rmsg_tail = 0; break; } @@ -920,7 +952,7 @@ static int rs_have_rdata(struct rsocket *rs) static int rs_all_sends_done(struct rsocket *rs) { - return (rs->sqe_avail + rs->ctrl_avail) == RS_QP_SIZE; + return (rs->sqe_avail + rs->ctrl_avail) == rs->sq_size; } static ssize_t rs_peek(struct rsocket *rs, void *buf, size_t len) @@ -937,7 +969,7 @@ static ssize_t rs_peek(struct rsocket *rs, void *buf, size_t len) rsize = left; } else { rsize = rs->rmsg[rmsg_head].data; - if (++rmsg_head == RS_QP_SIZE + 1) + if (++rmsg_head == rs->rq_size + 1) rmsg_head = 0; } @@ -998,7 +1030,7 @@ ssize_t rrecv(int socket, void *buf, size_t len, int flags) } else { rs->rseq_no++; rsize = rs->rmsg[rs->rmsg_head].data; - if (++rs->rmsg_head == RS_QP_SIZE + 1) + if (++rs->rmsg_head == rs->rq_size + 1) rs->rmsg_head = 0; } -- 2.45.2