Re: [PATCH rdma-core 03/11] libbnxtre: Add support for CQ and QP management

Leon Romanovsky
2017-01-30T07:16:45Z

[-- Attachment #1: Type: text/plain, Size: 22813 bytes --]

On Sat, Jan 28, 2017 at 05:13:34PM -0500, Devesh Sharma wrote:
> This patch adds support for completion queue creation and
> destruction following are the changes:
>
> - Added User/Kernel ABI to communicate CQ specific parameters.
> - Added a function in a new file to allocate Page-Aligned address
> space.
> - Added a function to free page-aligned address space.
> - Added function to create and destroy completion queue.
> - Add ABI to for QP creation and WQE/RQE format.
> - Add functions to allocate SQ, RQ and Search PSN address
> space.
> - Add functions to store/clean qp-handles in the form of
> a linear table. There is table maintained in every instance
> of ucontext.
> - CQ and QP contexts now hold a pointer to the DPI mapped
> during PD allocation.
> - Removed hard-coding of page size during mapping DB page.
> - Renamed a variable in PD code.
> - Add support for create-qp.
> - Add support for destroy-qp.
> - Add support for modify-qp.
> - Add support for query-qp.
>
> Signed-off-by: Sriharsha Basavapatna <sriharsha.basavapatna-dY08KVG/lbpWk0Htik3J/w@public.gmane.org>
> Signed-off-by: Somnath Kotur <somnath.kotur-dY08KVG/lbpWk0Htik3J/w@public.gmane.org>
> Signed-off-by: Selvin Xavier <selvin.xavier-dY08KVG/lbpWk0Htik3J/w@public.gmane.org>
> Signed-off-by: Devesh Sharma <devesh.sharma-dY08KVG/lbpWk0Htik3J/w@public.gmane.org>
> ---
> providers/bnxtre/CMakeLists.txt | 1 +
> providers/bnxtre/abi.h | 127 +++++++++++++++++++++
> providers/bnxtre/main.c | 5 +
> providers/bnxtre/main.h | 61 +++++++++--
> providers/bnxtre/memory.c | 73 +++++++++++++
> providers/bnxtre/memory.h | 76 +++++++++++++
> providers/bnxtre/verbs.c | 236 +++++++++++++++++++++++++++++++++++++++-
> 7 files changed, 561 insertions(+), 18 deletions(-)
> create mode 100644 providers/bnxtre/memory.c
> create mode 100644 providers/bnxtre/memory.h
>
> diff --git a/providers/bnxtre/CMakeLists.txt b/providers/bnxtre/CMakeLists.txt
> index 4c61355..93bdf1a 100644
> --- a/providers/bnxtre/CMakeLists.txt
> +++ b/providers/bnxtre/CMakeLists.txt
> @@ -1,4 +1,5 @@
> rdma_provider(bnxtre
> + memory.c
> main.c
> verbs.c
> )
> diff --git a/providers/bnxtre/abi.h b/providers/bnxtre/abi.h
> index 0568d67..81d7585 100644
> --- a/providers/bnxtre/abi.h
> +++ b/providers/bnxtre/abi.h
> @@ -47,6 +47,10 @@ struct bnxt_re_cntx_resp {
> struct ibv_get_context_resp resp;
> __u32 dev_id;
> __u32 max_qp; /* To allocate qp-table */
> + __u32 pg_size;
> + __u32 cqe_size;
> + __u32 max_cqd;
> + __u32 rsvd;
> };
>
> struct bnxt_re_pd_resp {
> @@ -60,4 +64,127 @@ struct bnxt_re_mr_resp {
> struct ibv_reg_mr_resp resp;
> };
>
> +struct bnxt_re_cq_req {
> + struct ibv_create_cq cmd;
> + __u64 cq_va;
> + __u64 cq_handle;
> +};
> +
> +struct bnxt_re_cq_resp {
> + struct ibv_create_cq_resp resp;
> + __u32 cqid;
> + __u32 tail;
> + __u32 phase;
> + __u32 rsvd;
> +};
> +
> +struct bnxt_re_qp_req {
> + struct ibv_create_qp cmd;
> + __u64 qpsva;
> + __u64 qprva;
> + __u64 qp_handle;
> +};
> +
> +struct bnxt_re_qp_resp {
> + struct ibv_create_qp_resp resp;
> + __u32 qpid;
> + __u32 rsvd;
> +};
> +
> +struct bnxt_re_bsqe {
> + __u32 rsv_ws_fl_wt;
> + __u32 key_immd;
> +};
> +
> +struct bnxt_re_psns {
> + __u32 opc_spsn;
> + __u32 flg_npsn;
> +};
> +
> +struct bnxt_re_sge {
> + __u32 pa_lo;
> + __u32 pa_hi;
> + __u32 lkey;
> + __u32 length;
> +};
> +
> +/* Cu+ max inline data */
> +#define BNXT_RE_MAX_INLINE_SIZE 0x60
> +
> +struct bnxt_re_send {
> + __u32 length;
> + __u32 qkey;
> + __u32 dst_qp;
> + __u32 avid;
> + __u64 rsvd;
> +};
> +
> +struct bnxt_re_raw {
> + __u32 length;
> + __u32 rsvd1;
> + __u32 cfa_meta;
> + __u32 rsvd2;
> + __u64 rsvd3;
> +};
> +
> +struct bnxt_re_rdma {
> + __u32 length;
> + __u32 rsvd1;
> + __u32 rva_lo;
> + __u32 rva_hi;
> + __u32 rkey;
> + __u32 rsvd2;
> +};
> +
> +struct bnxt_re_atomic {
> + __u32 rva_lo;
> + __u32 rva_hi;
> + __u32 swp_dt_lo;
> + __u32 swp_dt_hi;
> + __u32 cmp_dt_lo;
> + __u32 cmp_dt_hi;
> +};
> +
> +struct bnxt_re_inval {
> + __u64 rsvd[3];
> +};
> +
> +struct bnxt_re_bind {
> + __u32 plkey;
> + __u32 lkey;
> + __u32 va_lo;
> + __u32 va_hi;
> + __u32 len_lo;
> + __u32 len_hi; /* only 40 bits are valid */
> +};
> +
> +struct bnxt_re_brqe {
> + __u32 rsv_ws_fl_wt;
> + __u32 rsvd;
> +};
> +
> +struct bnxt_re_rqe {
> + __u64 rsvd[3];
> +};
> +
> +struct bnxt_re_srqe {
> + __u32 srq_tag; /* 20 bits are valid */
> + __u32 rsvd1;
> + __u64 rsvd[2];
> +};
> +
> +static inline uint32_t bnxt_re_get_sqe_sz(void)
> +{
> + return sizeof(struct bnxt_re_bsqe) +
> + sizeof(struct bnxt_re_send) +
> + BNXT_RE_MAX_INLINE_SIZE;
> +}
> +
> +static inline uint32_t bnxt_re_get_rqe_sz(void)
> +{
> + return sizeof(struct bnxt_re_brqe) +
> + sizeof(struct bnxt_re_rqe) +
> + BNXT_RE_MAX_INLINE_SIZE;
> +}

I afraid that you misuse this abi.h file. Our intention is to keep it as
close as possible to kernel version, so no functions please.

> +
> #endif
> diff --git a/providers/bnxtre/main.c b/providers/bnxtre/main.c
> index 0c26c8b..3cb3827 100644
> --- a/providers/bnxtre/main.c
> +++ b/providers/bnxtre/main.c
> @@ -115,8 +115,10 @@ static int bnxt_re_init_context(struct verbs_device *vdev,
> {
> struct ibv_get_context cmd;
> struct bnxt_re_cntx_resp resp;
> + struct bnxt_re_dev *dev;
> struct bnxt_re_context *cntx;
>
> + dev = to_bnxt_re_dev(&vdev->device);
> cntx = to_bnxt_re_context(ibvctx);
>
> memset(&resp, 0, sizeof(resp));
> @@ -127,6 +129,9 @@ static int bnxt_re_init_context(struct verbs_device *vdev,
>
> cntx->dev_id = resp.dev_id;
> cntx->max_qp = resp.max_qp;
> + dev->pg_size = resp.pg_size;
> + dev->cqe_size = resp.cqe_size;
> + dev->max_cq_depth = resp.max_cqd;
> ibvctx->ops = bnxt_re_cntx_ops;
>
> return 0;
> diff --git a/providers/bnxtre/main.h b/providers/bnxtre/main.h
> index 700dcb8..954ac47 100644
> --- a/providers/bnxtre/main.h
> +++ b/providers/bnxtre/main.h
> @@ -47,6 +47,16 @@
> #include <infiniband/driver.h>
> #include <infiniband/arch.h>
>
> +#include "memory.h"
> +
> +#define DEV "bnxtre : "
> +
> +struct bnxt_re_dpi {
> + __u32 dpindx;
> + __u64 *dbpage;
> + pthread_spinlock_t db_lock;
> +};
> +
> struct bnxt_re_pd {
> struct ibv_pd ibvpd;
> uint32_t pdid;
> @@ -54,31 +64,48 @@ struct bnxt_re_pd {
>
> struct bnxt_re_cq {
> struct ibv_cq ibvcq;
> -};
> -
> -struct bnxt_re_qp {
> - struct ibv_qp ibvqp;
> + uint32_t cqid;
> + struct bnxt_re_queue cqq;
> + struct bnxt_re_dpi *udpi;
> + uint32_t cqe_size;
> + uint8_t phase;
> };
>
> struct bnxt_re_srq {
> struct ibv_srq ibvsrq;
> };
>
> -struct bnxt_re_mr {
> - struct ibv_mr ibvmr;
> +struct bnxt_re_qp {
> + struct ibv_qp ibvqp;
> + struct bnxt_re_queue *sqq;
> + struct bnxt_re_psns *psns; /* start ptr. */
> + struct bnxt_re_queue *rqq;
> + struct bnxt_re_srq *srq;
> + struct bnxt_re_cq *scq;
> + struct bnxt_re_cq *rcq;
> + struct bnxt_re_dpi *udpi;
> + uint64_t *swrid;
> + uint64_t *rwrid;
> + uint32_t qpid;
> + uint32_t tbl_indx;
> + uint16_t mtu;
> + uint16_t qpst;
> + uint8_t qptyp;
> + /* wrid? */
> + /* irdord? */
> };
>
> -#define DEV "bnxtre : "
> -
> -struct bnxt_re_dpi {
> - __u32 dpindx;
> - __u64 *dbpage;
> - pthread_spinlock_t db_lock;
> +struct bnxt_re_mr {
> + struct ibv_mr ibvmr;
> };
>
> struct bnxt_re_dev {
> struct verbs_device vdev;
> uint8_t abi_version;
> + uint32_t pg_size;
> +
> + uint32_t cqe_size;
> + uint32_t max_cq_depth;
> };
>
> struct bnxt_re_context {
> @@ -105,4 +132,14 @@ static inline struct bnxt_re_pd *to_bnxt_re_pd(struct ibv_pd *ibvpd)
> return container_of(ibvpd, struct bnxt_re_pd, ibvpd);
> }
>
> +static inline struct bnxt_re_cq *to_bnxt_re_cq(struct ibv_cq *ibvcq)
> +{
> + return container_of(ibvcq, struct bnxt_re_cq, ibvcq);
> +}
> +
> +static inline struct bnxt_re_qp *to_bnxt_re_qp(struct ibv_qp *ibvqp)
> +{
> + return container_of(ibvqp, struct bnxt_re_qp, ibvqp);
> +}
> +
> #endif
> diff --git a/providers/bnxtre/memory.c b/providers/bnxtre/memory.c
> new file mode 100644
> index 0000000..c96641e
> --- /dev/null
> +++ b/providers/bnxtre/memory.c
> @@ -0,0 +1,73 @@
> +/*
> + * Broadcom NetXtreme-E User Space RoCE driver
> + *
> + * Copyright (c) 2015-2016, Broadcom. All rights reserved. The term
> + * Broadcom refers to Broadcom Limited and/or its subsidiaries.
> + *
> + * 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:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> + * notice, this list of conditions and the following disclaimer.
> + * 2. 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.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS''
> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
> + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
> + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
> + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
> + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
> + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
> + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + *
> + * Description: Implements method to allocate page-aligned memory
> + * buffers.
> + */
> +
> +#include <sys/mman.h>
> +
> +#include "main.h"
> +
> +int bnxt_re_alloc_aligned(struct bnxt_re_queue *que, uint32_t pg_size)
> +{
> + int ret, bytes;
> +
> + bytes = (que->depth * que->stride);
> + que->bytes = get_aligned(bytes, pg_size);

There is the same function align(..) which many providers implemented it.
Please move it to common code to all providers and use it from there.

> + que->va = mmap(NULL, que->bytes, PROT_READ | PROT_WRITE,
> + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
> + if (que->va == MAP_FAILED) {
> + que->bytes = 0;
> + return errno;
> + }
> +
> + ret = ibv_dontfork_range(que->va, que->bytes);
> + if (ret) {
> + munmap(que->va, que->bytes);
> + que->bytes = 0;
> + }
> +
> + return ret;
> +}
> +
> +void bnxt_re_free_aligned(struct bnxt_re_queue *que)
> +{
> + if (que->bytes) {
> + ibv_dofork_range(que->va, que->bytes);
> + munmap(que->va, que->bytes);
> + que->bytes = 0;
> + }
> +}
> diff --git a/providers/bnxtre/memory.h b/providers/bnxtre/memory.h
> new file mode 100644
> index 0000000..6c4ebaa
> --- /dev/null
> +++ b/providers/bnxtre/memory.h
> @@ -0,0 +1,76 @@
> +/*
> + * Broadcom NetXtreme-E User Space RoCE driver
> + *
> + * Copyright (c) 2015-2016, Broadcom. All rights reserved. The term
> + * Broadcom refers to Broadcom Limited and/or its subsidiaries.
> + *
> + * 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:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> + * notice, this list of conditions and the following disclaimer.
> + * 2. 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.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS''
> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
> + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
> + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
> + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
> + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
> + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
> + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + *
> + * Description: Implements data-struture to allocate page-aligned
> + * memory buffer.
> + */
> +
> +#ifndef __BNXT_RE_MEMORY_H__
> +#define __BNXT_RE_MEMORY_H__
> +
> +#include <pthread.h>
> +
> +struct bnxt_re_queue {
> + void *va;
> + uint32_t bytes; /* for munmap */
> + uint32_t depth; /* no. of entries */
> + uint32_t head;
> + uint32_t tail;
> + uint32_t stride;
> + pthread_spinlock_t qlock;
> +};
> +
> +static inline unsigned long get_aligned(uint32_t size, uint32_t al_size)
> +{
> + return (unsigned long)(size + al_size - 1) & ~(al_size - 1);
> +}
> +
> +static inline unsigned long roundup_pow_of_two(unsigned long val)
> +{
> + unsigned long roundup = 1;
> +
> + if (val == 1)
> + return (roundup << 1);
> +
> + while (roundup < val)
> + roundup <<= 1;
> +
> + return roundup;
> +}

Please move to common code.

> +
> +int bnxt_re_alloc_aligned(struct bnxt_re_queue *que, uint32_t pg_size);
> +void bnxt_re_free_aligned(struct bnxt_re_queue *que);
> +
> +#endif
> diff --git a/providers/bnxtre/verbs.c b/providers/bnxtre/verbs.c
> index 9813db8..3cad358 100644
> --- a/providers/bnxtre/verbs.c
> +++ b/providers/bnxtre/verbs.c
> @@ -84,6 +84,7 @@ struct ibv_pd *bnxt_re_alloc_pd(struct ibv_context *ibvctx)
> struct ibv_alloc_pd cmd;
> struct bnxt_re_pd_resp resp;
> struct bnxt_re_context *cntx = to_bnxt_re_context(ibvctx);
> + struct bnxt_re_dev *dev = to_bnxt_re_dev(ibvctx->device);
> struct bnxt_re_pd *pd;
>
> pd = calloc(1, sizeof(*pd));
> @@ -99,7 +100,7 @@ struct ibv_pd *bnxt_re_alloc_pd(struct ibv_context *ibvctx)
>
> /* Map DB page now. */
> cntx->udpi.dpindx = resp.dpi;
> - cntx->udpi.dbpage = mmap(NULL, 4096, PROT_WRITE, MAP_SHARED,
> + cntx->udpi.dbpage = mmap(NULL, dev->pg_size, PROT_WRITE, MAP_SHARED,
> ibvctx->cmd_fd, resp.dbr);
> if (cntx->udpi.dbpage == MAP_FAILED) {
> (void)ibv_cmd_dealloc_pd(&pd->ibvpd);
> @@ -117,6 +118,7 @@ int bnxt_re_free_pd(struct ibv_pd *ibvpd)
> {
> struct bnxt_re_pd *pd = to_bnxt_re_pd(ibvpd);
> struct bnxt_re_context *cntx = to_bnxt_re_context(ibvpd->context);
> + struct bnxt_re_dev *dev = to_bnxt_re_dev(cntx->ibvctx.device);
> int status;
>
> status = ibv_cmd_dealloc_pd(ibvpd);
> @@ -125,7 +127,8 @@ int bnxt_re_free_pd(struct ibv_pd *ibvpd)
>
> pthread_spin_destroy(&cntx->udpi.db_lock);
> if (cntx->udpi.dbpage && (cntx->udpi.dbpage != MAP_FAILED))
> - munmap(cntx->udpi.dbpage, 4096);
> + munmap(cntx->udpi.dbpage, dev->pg_size);
> +
> free(pd);
>
> return 0;
> @@ -167,6 +170,48 @@ int bnxt_re_dereg_mr(struct ibv_mr *ibvmr)
> struct ibv_cq *bnxt_re_create_cq(struct ibv_context *ibvctx, int ncqe,
> struct ibv_comp_channel *channel, int vec)
> {
> + struct bnxt_re_cq *cq;
> + struct bnxt_re_cq_req cmd;
> + struct bnxt_re_cq_resp resp;
> +
> + struct bnxt_re_context *cntx = to_bnxt_re_context(ibvctx);
> + struct bnxt_re_dev *dev = to_bnxt_re_dev(ibvctx->device);
> +
> + if (ncqe > dev->max_cq_depth)
> + return NULL;
> +
> + cq = calloc(1, sizeof(*cq));
> + if (!cq)
> + return NULL;
> +
> + cq->cqq.depth = roundup_pow_of_two(ncqe + 1);
> + if (cq->cqq.depth > dev->max_cq_depth + 1)
> + cq->cqq.depth = dev->max_cq_depth + 1;
> + cq->cqq.stride = dev->cqe_size;
> + if (bnxt_re_alloc_aligned(&cq->cqq, dev->pg_size))
> + goto fail;
> +
> + pthread_spin_init(&cq->cqq.qlock, PTHREAD_PROCESS_PRIVATE);
> +
> + cmd.cq_va = (uint64_t)cq->cqq.va;
> + cmd.cq_handle = (uint64_t)cq;
> +
> + memset(&resp, 0, sizeof(resp));
> + if (ibv_cmd_create_cq(ibvctx, ncqe, channel, vec,
> + &cq->ibvcq, &cmd.cmd, sizeof(cmd),
> + &resp.resp, sizeof(resp)))
> + goto cmdfail;
> +
> + cq->cqid = resp.cqid;
> + cq->phase = resp.phase;
> + cq->cqq.tail = resp.tail;
> + cq->udpi = &cntx->udpi;
> +
> + return &cq->ibvcq;
> +cmdfail:
> + bnxt_re_free_aligned(&cq->cqq);
> +fail:
> + free(cq);
> return NULL;
> }
>
> @@ -177,7 +222,17 @@ int bnxt_re_resize_cq(struct ibv_cq *ibvcq, int ncqe)
>
> int bnxt_re_destroy_cq(struct ibv_cq *ibvcq)
> {
> - return -ENOSYS;
> + int status;
> + struct bnxt_re_cq *cq = to_bnxt_re_cq(ibvcq);
> +
> + status = ibv_cmd_destroy_cq(ibvcq);
> + if (status)
> + return status;
> +
> + bnxt_re_free_aligned(&cq->cqq);
> + free(cq);
> +
> + return 0;
> }
>
> int bnxt_re_poll_cq(struct ibv_cq *ibvcq, int nwc, struct ibv_wc *wc)
> @@ -195,27 +250,196 @@ int bnxt_re_arm_cq(struct ibv_cq *ibvcq, int flags)
> return -ENOSYS;
> }
>
> +static int bnxt_re_check_qp_limits(struct ibv_qp_init_attr *attr)
> +{
> + return 0;
> +}
> +
> +static void bnxt_re_free_queue_ptr(struct bnxt_re_qp *qp)
> +{
> + if (qp->rqq)
> + free(qp->rqq);
> + if (qp->sqq)
> + free(qp->sqq);
> +}
> +
> +static int bnxt_re_alloc_queue_ptr(struct bnxt_re_qp *qp,
> + struct ibv_qp_init_attr *attr)
> +{
> + qp->sqq = calloc(1, sizeof(struct bnxt_re_queue));
> + if (!qp->sqq)
> + return -ENOMEM;
> + if (attr->srq)
> + qp->srq = NULL;/*TODO: to_bnxt_re_srq(attr->srq);*/
> + else {
> + qp->rqq = calloc(1, sizeof(struct bnxt_re_queue));
> + if (!qp->rqq) {
> + free(qp->sqq);
> + return -ENOMEM;
> + }
> + }
> +
> + return 0;
> +}
> +
> +static void bnxt_re_free_queues(struct bnxt_re_qp *qp)
> +{
> + if (qp->rwrid)
> + free(qp->rwrid);
> + pthread_spin_destroy(&qp->rqq->qlock);
> + bnxt_re_free_aligned(qp->rqq);
> +
> + if (qp->swrid)
> + free(qp->swrid);
> + pthread_spin_destroy(&qp->sqq->qlock);
> + bnxt_re_free_aligned(qp->sqq);
> +}
> +
> +static int bnxt_re_alloc_queues(struct bnxt_re_qp *qp,
> + struct ibv_qp_init_attr *attr,
> + uint32_t pg_size) {
> + struct bnxt_re_queue *que;
> + uint32_t psn_depth;
> + int ret;
> +
> + if (attr->cap.max_send_wr) {
> + que = qp->sqq;
> + que->stride = bnxt_re_get_sqe_sz();
> + que->depth = roundup_pow_of_two(attr->cap.max_send_wr);
> + /* psn_depth extra entries of size que->stride */
> + psn_depth = (que->depth * sizeof(struct bnxt_re_psns)) /
> + que->stride;
> + que->depth += psn_depth;
> + ret = bnxt_re_alloc_aligned(qp->sqq, pg_size);
> + if (ret)
> + return ret;
> + /* exclude psns depth*/
> + que->depth -= psn_depth;
> + /* start of spsn space sizeof(struct bnxt_re_psns) each. */
> + qp->psns = (que->va + que->stride * que->depth);
> + pthread_spin_init(&que->qlock, PTHREAD_PROCESS_PRIVATE);
> + qp->swrid = calloc(que->depth, sizeof(uint64_t));
> + if (!qp->swrid) {
> + ret = -ENOMEM;
> + goto fail;
> + }
> + }
> +
> + if (attr->cap.max_recv_wr && qp->rqq) {
> + que = qp->rqq;
> + que->stride = bnxt_re_get_rqe_sz();
> + que->depth = roundup_pow_of_two(attr->cap.max_recv_wr);
> + ret = bnxt_re_alloc_aligned(qp->rqq, pg_size);
> + if (ret)
> + goto fail;
> + pthread_spin_init(&que->qlock, PTHREAD_PROCESS_PRIVATE);
> + qp->rwrid = calloc(que->depth, sizeof(uint64_t));
> + if (!qp->rwrid) {
> + ret = -ENOMEM;
> + goto fail;
> + }
> + }
> +
> + return 0;
> +
> +fail:
> + bnxt_re_free_queues(qp);
> + return ret;
> +}
> +
> struct ibv_qp *bnxt_re_create_qp(struct ibv_pd *ibvpd,
> struct ibv_qp_init_attr *attr)
> {
> + struct bnxt_re_qp *qp;
> + struct bnxt_re_qp_req req;
> + struct bnxt_re_qp_resp resp;
> +
> + struct bnxt_re_context *cntx = to_bnxt_re_context(ibvpd->context);
> + struct bnxt_re_dev *dev = to_bnxt_re_dev(cntx->ibvctx.device);
> +
> + if (bnxt_re_check_qp_limits(attr))
> + return NULL;
> +
> + qp = calloc(1, sizeof(*qp));
> + if (!qp)
> + return NULL;
> + /* alloc queue pointers */
> + if (bnxt_re_alloc_queue_ptr(qp, attr))
> + goto fail;
> + /* alloc queues */
> + if (bnxt_re_alloc_queues(qp, attr, dev->pg_size))
> + goto failq;
> + /* Fill ibv_cmd */
> + req.qpsva = (uint64_t)qp->sqq->va;
> + req.qprva = qp->rqq ? (uint64_t)qp->rqq->va : 0;
> + req.qp_handle = (uint64_t)qp;
> +
> + if (ibv_cmd_create_qp(ibvpd, &qp->ibvqp, attr, &req.cmd, sizeof(req),
> + &resp.resp, sizeof(resp))) {
> + goto failcmd;
> + }
> +
> + qp->qpid = resp.qpid;
> + qp->qptyp = attr->qp_type;
> + qp->qpst = IBV_QPS_RESET;
> + qp->scq = to_bnxt_re_cq(attr->send_cq);
> + qp->rcq = to_bnxt_re_cq(attr->recv_cq);
> + qp->udpi = &cntx->udpi;
> +
> + return &qp->ibvqp;
> +failcmd:
> + bnxt_re_free_queues(qp);
> +failq:
> + bnxt_re_free_queue_ptr(qp);
> +fail:
> + free(qp);
> +
> return NULL;
> }
>
> int bnxt_re_modify_qp(struct ibv_qp *ibvqp, struct ibv_qp_attr *attr,
> int attr_mask)
> {
> - return -ENOSYS;
> + struct ibv_modify_qp cmd = {};
> + struct bnxt_re_qp *qp = to_bnxt_re_qp(ibvqp);
> + int rc;
> +
> + rc = ibv_cmd_modify_qp(ibvqp, attr, attr_mask, &cmd, sizeof(cmd));
> + if (!rc)
> + qp->qpst = ibvqp->state;
> +
> + return rc;
> }
>
> int bnxt_re_query_qp(struct ibv_qp *ibvqp, struct ibv_qp_attr *attr,
> int attr_mask, struct ibv_qp_init_attr *init_attr)
> {
> - return -ENOSYS;
> + struct ibv_query_qp cmd;
> + struct bnxt_re_qp *qp = to_bnxt_re_qp(ibvqp);
> + int rc;
> +
> + rc = ibv_cmd_query_qp(ibvqp, attr, attr_mask, init_attr,
> + &cmd, sizeof(cmd));
> + if (!rc)
> + qp->qpst = ibvqp->state;
> +
> + return rc;
> }
>
> int bnxt_re_destroy_qp(struct ibv_qp *ibvqp)
> {
> - return -ENOSYS;
> + struct bnxt_re_qp *qp = to_bnxt_re_qp(ibvqp);
> + int status;
> +
> + status = ibv_cmd_destroy_qp(ibvqp);
> + if (status)
> + return status;
> +
> + bnxt_re_free_queues(qp);
> + bnxt_re_free_queue_ptr(qp);
> + free(qp);
> +
> + return 0;
> }
>
> int bnxt_re_post_send(struct ibv_qp *ibvqp, struct ibv_send_wr *wr,
> --
> 1.8.3.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]