From 79bc6280a20fbe0dd8de03f2b979f7f3adfd81f8 Mon Sep 17 00:00:00 2001 From: 张智皓 Date: Fri, 4 Aug 2023 03:19:28 +0000 Subject: 上传新文件 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- userlib/src/siw_verbs.c | 491 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 491 insertions(+) create mode 100644 userlib/src/siw_verbs.c diff --git a/userlib/src/siw_verbs.c b/userlib/src/siw_verbs.c new file mode 100644 index 0000000..231711f --- /dev/null +++ b/userlib/src/siw_verbs.c @@ -0,0 +1,491 @@ +/* + * Software iWARP library for Linux + * + * Authors: Bernard Metzler + * + * Copyright (c) 2008-2016, IBM Corporation + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of IBM nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#if HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include +#include "siw.h" +#include "siw_abi.h" + +const int siw_debug = 0; + +int siw_query_device(struct ibv_context *ctx, struct ibv_device_attr *attr) +{ + struct ibv_query_device cmd; + uint64_t raw_fw_ver; + unsigned major, minor, sub_minor; + int rv; + + rv = ibv_cmd_query_device(ctx, attr, &raw_fw_ver, &cmd, + sizeof cmd); + if (rv) + return rv; + + major = (raw_fw_ver >> 32) & 0xffff; + minor = (raw_fw_ver >> 16) & 0xffff; + sub_minor = raw_fw_ver & 0xffff; + + snprintf(attr->fw_ver, sizeof attr->fw_ver, + "%d.%d.%d", major, minor, sub_minor); + + return 0; +} + +int siw_query_port(struct ibv_context *ctx, uint8_t port, + struct ibv_port_attr *attr) +{ + struct ibv_query_port cmd; + + return ibv_cmd_query_port(ctx, port, attr, &cmd, sizeof cmd); +} + + +int siw_query_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr, + int attr_mask, struct ibv_qp_init_attr *init_attr) +{ + struct ibv_query_qp cmd; + + return ibv_cmd_query_qp(qp, attr, attr_mask, init_attr, &cmd, sizeof(cmd)); +} + + +struct ibv_pd *siw_alloc_pd(struct ibv_context *ctx) +{ + struct ibv_alloc_pd cmd; + struct siw_alloc_pd_resp resp; + struct siw_pd *pd; + + pd = malloc(sizeof *pd); + if (!pd) + return NULL; + + if (ibv_cmd_alloc_pd(ctx, &pd->ofa_pd, &cmd, sizeof cmd, + &resp.ofa, sizeof resp)) { + free(pd); + return NULL; + } + return &pd->ofa_pd; +} + +int siw_free_pd(struct ibv_pd *pd) +{ + int rv; + + rv = ibv_cmd_dealloc_pd(pd); + if (rv) + return rv; + + free(pd); + return 0; +} + + +struct ibv_mr *siw_reg_mr(struct ibv_pd *pd, void *addr, + size_t len, int access) +{ + struct siw_mr *mr; + struct siw_cmd_reg_umr_req req; + struct siw_cmd_reg_umr_resp resp; + + int rv; + + mr = malloc(sizeof *mr); + + if (!mr) + return NULL; + + rv = ibv_cmd_reg_mr(pd, addr, len, (uintptr_t)addr, access, &mr->ofa_mr, + &req.ofa, sizeof req, &resp.ofa, sizeof resp); + + if (rv) { + free(mr); + return NULL; + } + return &mr->ofa_mr; +} + +int siw_dereg_mr(struct ibv_mr *ofa_mr) +{ + struct siw_mr *mr = mr_ofa2siw(ofa_mr); + int rv; + + rv = ibv_cmd_dereg_mr(ofa_mr); + + if (rv) + return rv; + + free(mr); + + return 0; +} + +struct ibv_cq *siw_create_cq(struct ibv_context *ctx, int num_cqe, + struct ibv_comp_channel *channel, int comp_vector) +{ + struct siw_cq *cq; + struct siw_cmd_create_cq cmd; + struct siw_cmd_create_cq_resp resp; + int rv; + + cq = calloc(1, sizeof *cq); + if (!cq) + return NULL; + + rv = ibv_cmd_create_cq(ctx, num_cqe, channel, comp_vector, + &cq->ofa_cq, &cmd.ofa, sizeof cmd, + &resp.ofa, sizeof resp); + if (rv) + goto fail; + + pthread_spin_init(&cq->lock, PTHREAD_PROCESS_PRIVATE); + + cq->id = resp.siw.cq_id; + cq->num_cqe = resp.siw.num_cqe; + + if (resp.siw.cq_key <= SIW_MAX_UOBJ_KEY) { + int cq_size = resp.siw.num_cqe * sizeof(struct siw_cqe) + + sizeof(struct siw_cq_ctrl); + + if (siw_debug) + printf("CQ mapping: %d elements, size %d\n", + resp.siw.num_cqe, cq_size); + + cq->queue = mmap(NULL, cq_size, + PROT_READ|PROT_WRITE, MAP_SHARED, + ctx->cmd_fd, resp.siw.cq_key); + + if (cq->queue == MAP_FAILED) + goto fail; + + cq->ctrl = (struct siw_cq_ctrl *)&cq->queue[cq->num_cqe]; + cq->ctrl->notify = SIW_NOTIFY_NOT; + } else + goto fail; + + return &cq->ofa_cq; + +fail: + if (siw_debug) + printf("CQ mapping failed: %d", resp.siw.num_cqe); + + free (cq); + + return (struct ibv_cq *) NULL; +} + +int siw_resize_cq(struct ibv_cq *ofa_cq, int num_cqe) +{ + return -ENOSYS; +} + +int siw_destroy_cq(struct ibv_cq *ofacq) +{ + struct siw_cq *cq = cq_ofa2siw(ofacq); + int rv; + + if (siw_debug) + printf("destroy CQ[%d]\n", cq->id); + + pthread_spin_lock(&cq->lock); + + if (cq->queue) + munmap(cq->queue, cq->num_cqe * sizeof(struct siw_cqe) + + sizeof (struct siw_cq_ctrl)); + + rv = ibv_cmd_destroy_cq(ofacq); + if (rv) { + pthread_spin_unlock(&cq->lock); + return rv; + } + pthread_spin_unlock(&cq->lock); + + free(cq); + + return 0; +} + +struct ibv_srq *siw_create_srq(struct ibv_pd *pd, + struct ibv_srq_init_attr *attr) +{ + struct siw_cmd_create_srq cmd; + struct siw_cmd_create_srq_resp resp; + struct siw_srq *srq = calloc(1, sizeof *srq); + + if (!srq) + return NULL; + + if (ibv_cmd_create_srq(pd, &srq->ofa_srq, attr, &cmd.ofa, + sizeof cmd, &resp.ofa, sizeof resp)) { + free(srq); + return NULL; + } + pthread_spin_init(&srq->lock, PTHREAD_PROCESS_PRIVATE); + + if (resp.siw.srq_key <= SIW_MAX_UOBJ_KEY) { + struct ibv_context *ctx = pd->context; + int rq_size = resp.siw.num_rqe * sizeof(struct siw_rqe); + + srq->num_rqe = resp.siw.num_rqe; + + if (siw_debug) + printf("SRQ mapping: %d\n", srq->num_rqe); + + srq->recvq = mmap(NULL, rq_size, PROT_READ|PROT_WRITE, + MAP_SHARED, ctx->cmd_fd, resp.siw.srq_key); + + if (srq->recvq == MAP_FAILED) { + if (siw_debug) + printf("SRQ mapping failed: %d", + resp.siw.num_rqe); + srq->recvq = NULL; + } + } + return &srq->ofa_srq; +} + +int siw_modify_srq(struct ibv_srq *ofa_srq, struct ibv_srq_attr *attr, + int attr_mask) +{ + struct siw_srq *srq = srq_ofa2siw(ofa_srq); + struct ibv_modify_srq cmd; + int rv; + + pthread_spin_lock(&srq->lock); + rv = ibv_cmd_modify_srq(ofa_srq, attr, attr_mask, &cmd, sizeof cmd); + pthread_spin_unlock(&srq->lock); + + return rv; +} + +int siw_destroy_srq(struct ibv_srq *ofa_srq) +{ + struct siw_srq *srq = srq_ofa2siw(ofa_srq); + + pthread_spin_lock(&srq->lock); + ibv_cmd_destroy_srq(ofa_srq); + pthread_spin_unlock(&srq->lock); + + if (srq->recvq) + munmap(srq->recvq, srq->num_rqe * sizeof(struct siw_rqe)); + + free(srq); + + return 0; +} + +struct ibv_qp *siw_create_qp(struct ibv_pd *pd, struct ibv_qp_init_attr *attr) +{ + struct siw_cmd_create_qp cmd; + struct siw_cmd_create_qp_resp resp; + struct siw_qp *qp; + struct ibv_context *ofa_ctx = pd->context; + struct siw_context *ctx = ctx_ofa2siw(ofa_ctx); + + int rv; + + qp = calloc(1, sizeof *qp); + if (!qp) + return NULL; + + qp->dev_id = ctx->dev_id; + + rv = ibv_cmd_create_qp(pd, &qp->ofa_qp, attr, &cmd.ofa, + sizeof cmd, &resp.ofa, sizeof resp); + if (rv) + goto fail; + + qp->id = resp.siw.qp_id; + qp->num_sqe = resp.siw.num_sqe; + qp->num_rqe = resp.siw.num_rqe; + qp->sq_sig_all = attr->sq_sig_all; + + pthread_spin_init(&qp->sq_lock, PTHREAD_PROCESS_PRIVATE); + pthread_spin_init(&qp->rq_lock, PTHREAD_PROCESS_PRIVATE); + + if (resp.siw.sq_key <= SIW_MAX_UOBJ_KEY) { + int sq_size = resp.siw.num_sqe * sizeof(struct siw_sqe); + + if (siw_debug) + printf("SQ mapping: %d\n", resp.siw.num_sqe); + + qp->sendq = mmap(NULL, sq_size, + PROT_READ|PROT_WRITE, MAP_SHARED, + ofa_ctx->cmd_fd, resp.siw.sq_key); + + if (qp->sendq == MAP_FAILED) { + printf("SQ mapping failed: %d", resp.siw.num_sqe); + qp->sendq = NULL; + goto fail; + } + } else { + if (siw_debug) + printf("SQ mapping failed\n"); + goto fail; + } + if (attr->srq) { + struct siw_srq *srq = srq_ofa2siw(attr->srq); + qp->srq = srq; + } else if (resp.siw.rq_key <= SIW_MAX_UOBJ_KEY) { + int rq_size = resp.siw.num_rqe * sizeof(struct siw_rqe); + + if (siw_debug) + printf("RQ mapping: %d\n", resp.siw.num_rqe); + + qp->recvq = mmap(NULL, rq_size, + PROT_READ|PROT_WRITE, MAP_SHARED, + ofa_ctx->cmd_fd, resp.siw.rq_key); + + if (qp->recvq == MAP_FAILED) { + if (siw_debug) + printf("RQ mapping failed: %d\n", + resp.siw.num_rqe); + qp->recvq = NULL; + goto fail; + } + } else { + if (siw_debug) + printf("RQ mapping failed\n"); + goto fail; + } + return &qp->ofa_qp; + +fail: + if (qp->sendq) + munmap(qp->sendq, qp->num_sqe * sizeof(struct siw_sqe)); + if (qp->recvq) + munmap(qp->recvq, qp->num_rqe * sizeof(struct siw_rqe)); + + free(qp); + + return (struct ibv_qp *) NULL; +} + +int siw_modify_qp(struct ibv_qp *ofaqp, struct ibv_qp_attr *attr, + int attr_mask) +{ + struct siw_qp *qp = qp_ofa2siw(ofaqp); + struct ibv_modify_qp cmd; + int rv; + + if (siw_debug) + printf("modify QP[%d]\n", qp->id); + + pthread_spin_lock(&qp->sq_lock); + pthread_spin_lock(&qp->rq_lock); + + rv = ibv_cmd_modify_qp(ofaqp, attr, attr_mask, &cmd, sizeof cmd); + + pthread_spin_unlock(&qp->rq_lock); + pthread_spin_unlock(&qp->sq_lock); + + return rv; +} + +int siw_destroy_qp(struct ibv_qp *ofaqp) +{ + struct siw_qp *qp = qp_ofa2siw(ofaqp); + int rv; + + if (siw_debug) + printf("destroy QP[%d]\n", qp->id); + + pthread_spin_lock(&qp->sq_lock); + pthread_spin_lock(&qp->rq_lock); + + if (qp->sendq) + munmap(qp->sendq, qp->num_sqe * sizeof(struct siw_sqe)); + if (qp->recvq) + munmap(qp->recvq, qp->num_rqe * sizeof(struct siw_rqe)); + + rv = ibv_cmd_destroy_qp(ofaqp); + if (rv) { + pthread_spin_unlock(&qp->rq_lock); + pthread_spin_unlock(&qp->sq_lock); + return rv; + } + pthread_spin_unlock(&qp->rq_lock); + pthread_spin_unlock(&qp->sq_lock); + + free(qp); + + return 0; +} + +struct ibv_ah *siw_create_ah(struct ibv_pd *pd, struct ibv_ah_attr *attr) +{ + return NULL; +} + +int siw_destroy_ah(struct ibv_ah *ah) +{ + return -ENOSYS; +} + +void siw_async_event(struct ibv_async_event *event) +{ + + switch (event->event_type) { + + case IBV_EVENT_CQ_ERR: + break; + + case IBV_EVENT_QP_FATAL: + case IBV_EVENT_QP_REQ_ERR: + case IBV_EVENT_QP_ACCESS_ERR: + /* TODO: flush qp */ + break; + + case IBV_EVENT_SQ_DRAINED: + case IBV_EVENT_COMM_EST: + case IBV_EVENT_QP_LAST_WQE_REACHED: + break; + + default: + break; + } +} -- cgit v1.2.3