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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxxxxx>
> Signed-off-by: Somnath Kotur <somnath.kotur@xxxxxxxxxxxx>
> Signed-off-by: Selvin Xavier <selvin.xavier@xxxxxxxxxxxx>
> Signed-off-by: Devesh Sharma <devesh.sharma@xxxxxxxxxxxx>
> ---
>  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@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

Attachment: signature.asc
Description: PGP signature


[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Photo]     [Yosemite News]     [Yosemite Photos]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux