The librdmacm documentation (rdma_cm.7 man page) specifies that librdmacm functions return 0 on success and -1 on error, with errno set correctly. The libibverbs abstractions simply pass the libibverbs return codes through to the user. Since libibverbs may return errno directly through a given call, convert the return status to use errno where appropriate.
This fixes an issue with rdma_get_send_comp and rdma_get_recv_comp, where a return value of 1 could indicate both success (1 completed request returned) and failure (EPERM error). Signed-off-by: Sean Hefty <sean.he...@intel.com> --- include/rdma/rdma_verbs.h | 44 +++++++++++++++++++++++++++----------------- src/cma.c | 1 + 2 files changed, 28 insertions(+), 17 deletions(-) mode change 100644 => 100755 include/rdma/rdma_verbs.h diff --git a/include/rdma/rdma_verbs.h b/include/rdma/rdma_verbs.h old mode 100644 new mode 100755 index 12429a7..d75d906 --- a/include/rdma/rdma_verbs.h +++ b/include/rdma/rdma_verbs.h @@ -36,11 +36,21 @@ #include <assert.h> #include <infiniband/verbs.h> #include <rdma/rdma_cma.h> +#include <errno.h> #ifdef __cplusplus extern "C" { #endif +static inline int rdma_seterrno(int ret) +{ + if (ret) { + errno = ret; + ret = -1; + } + return ret; +} + /* * Memory registration helpers. */ @@ -53,7 +63,7 @@ rdma_reg_msgs(struct rdma_cm_id *id, void *addr, size_t length) static inline struct ibv_mr * rdma_reg_read(struct rdma_cm_id *id, void *addr, size_t length) { - return ibv_reg_mr(id->qp->pd, addr, length, IBV_ACCESS_LOCAL_WRITE| + return ibv_reg_mr(id->qp->pd, addr, length, IBV_ACCESS_LOCAL_WRITE | IBV_ACCESS_REMOTE_READ); } @@ -67,7 +77,7 @@ rdma_reg_write(struct rdma_cm_id *id, void *addr, size_t length) static inline int rdma_dereg_mr(struct ibv_mr *mr) { - return ibv_dereg_mr(mr); + return rdma_seterrno(ibv_dereg_mr(mr)); } @@ -86,7 +96,7 @@ rdma_post_recvv(struct rdma_cm_id *id, void *context, struct ibv_sge *sgl, wr.sg_list = sgl; wr.num_sge = nsge; - return ibv_post_recv(id->qp, &wr, &bad); + return rdma_seterrno(ibv_post_recv(id->qp, &wr, &bad)); } static inline int @@ -102,7 +112,7 @@ rdma_post_sendv(struct rdma_cm_id *id, void *context, struct ibv_sge *sgl, wr.opcode = IBV_WR_SEND; wr.send_flags = flags; - return ibv_post_send(id->qp, &wr, &bad); + return rdma_seterrno(ibv_post_send(id->qp, &wr, &bad)); } static inline int @@ -120,7 +130,7 @@ rdma_post_readv(struct rdma_cm_id *id, void *context, struct ibv_sge *sgl, wr.wr.rdma.remote_addr = remote_addr; wr.wr.rdma.rkey = rkey; - return ibv_post_send(id->qp, &wr, &bad); + return rdma_seterrno(ibv_post_send(id->qp, &wr, &bad)); } static inline int @@ -138,7 +148,7 @@ rdma_post_writev(struct rdma_cm_id *id, void *context, struct ibv_sge *sgl, wr.wr.rdma.remote_addr = remote_addr; wr.wr.rdma.rkey = rkey; - return ibv_post_send(id->qp, &wr, &bad); + return rdma_seterrno(ibv_post_send(id->qp, &wr, &bad)); } /* @@ -221,7 +231,7 @@ rdma_post_ud_send(struct rdma_cm_id *id, void *context, void *addr, wr.wr.ud.remote_qpn = remote_qpn; wr.wr.ud.remote_qkey = RDMA_UDP_QKEY; - return ibv_post_send(id->qp, &wr, &bad); + return rdma_seterrno(ibv_post_send(id->qp, &wr, &bad)); } static inline int @@ -233,22 +243,22 @@ rdma_get_send_comp(struct rdma_cm_id *id, struct ibv_wc *wc) ret = ibv_poll_cq(id->send_cq, 1, wc); if (ret) - return ret; + goto out; ret = ibv_req_notify_cq(id->send_cq, 0); if (ret) - return ret; + return rdma_seterrno(ret); while (!(ret = ibv_poll_cq(id->send_cq, 1, wc))) { ret = ibv_get_cq_event(id->send_cq_channel, &cq, &context); if (ret) - break; + return rdma_seterrno(ret); assert(cq == id->send_cq && context == id); ibv_ack_cq_events(id->send_cq, 1); } - - return ret; +out: + return (ret < 0) ? rdma_seterrno(ret) : ret; } static inline int @@ -260,22 +270,22 @@ rdma_get_recv_comp(struct rdma_cm_id *id, struct ibv_wc *wc) ret = ibv_poll_cq(id->recv_cq, 1, wc); if (ret) - return ret; + goto out; ret = ibv_req_notify_cq(id->recv_cq, 0); if (ret) - return ret; + return rdma_seterrno(ret); while (!(ret = ibv_poll_cq(id->recv_cq, 1, wc))) { ret = ibv_get_cq_event(id->recv_cq_channel, &cq, &context); if (ret) - break; + return rdma_seterrno(ret); assert(cq == id->recv_cq && context == id); ibv_ack_cq_events(id->recv_cq, 1); } - - return ret; +out: + return (ret < 0) ? rdma_seterrno(ret) : ret; } #ifdef __cplusplus diff --git a/src/cma.c b/src/cma.c index 7ddccbb..a20e2f5 100644 --- a/src/cma.c +++ b/src/cma.c @@ -56,6 +56,7 @@ #include <infiniband/marshall.h> #include <rdma/rdma_cma.h> #include <rdma/rdma_cma_abi.h> +#include <rdma/rdma_verbs.h> #include <infiniband/ib.h> #define CMA_CREATE_MSG_CMD_RESP(msg, cmd, resp, type, size) \ -- 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