Re: [PATCH for-next 3/3] RDMA/bnxt_re: Share a page to expose per SRQ info with userspace

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

 



On Wed, Aug 28, 2024 at 01:47:12AM -0700, Selvin Xavier wrote:
> From: Chandramohan Akula <chandramohan.akula@xxxxxxxxxxxx>
> 
> Gen P7 adapters needs to share a toggle bits information received
> in kernel driver with the user space. User space needs this
> info to arm the SRQ.
> 
> User space application can get this page using the
> UAPI routines. Library will mmap this page and get the
> toggle bits to be used in the next ARM Doorbell.
> 
> Uses a hash list to map the SRQ structure from the SRQ ID.
> SRQ structure is retrieved from the hash list while the
> library calls the UAPI routine to get the toggle page
> mapping. Currently the full page is mapped per SRQ. This
> can be optimized to enable multiple SRQs from the same
> application share the same page and different offsets
> in the page
> 
> Signed-off-by: Chandramohan Akula <chandramohan.akula@xxxxxxxxxxxx>
> Signed-off-by: Selvin Xavier <selvin.xavier@xxxxxxxxxxxx>
> ---
>  drivers/infiniband/hw/bnxt_re/bnxt_re.h  |  2 ++
>  drivers/infiniband/hw/bnxt_re/ib_verbs.c | 34 +++++++++++++++++++++++++++++++-
>  drivers/infiniband/hw/bnxt_re/ib_verbs.h |  1 +
>  drivers/infiniband/hw/bnxt_re/main.c     |  6 +++++-
>  include/uapi/rdma/bnxt_re-abi.h          |  5 +++++
>  5 files changed, 46 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/infiniband/hw/bnxt_re/bnxt_re.h b/drivers/infiniband/hw/bnxt_re/bnxt_re.h
> index 0912d2f..2be9a62 100644
> --- a/drivers/infiniband/hw/bnxt_re/bnxt_re.h
> +++ b/drivers/infiniband/hw/bnxt_re/bnxt_re.h
> @@ -141,6 +141,7 @@ struct bnxt_re_pacing {
>  #define BNXT_RE_GRC_FIFO_REG_BASE 0x2000
>  
>  #define MAX_CQ_HASH_BITS		(16)
> +#define MAX_SRQ_HASH_BITS		(16)
>  struct bnxt_re_dev {
>  	struct ib_device		ibdev;
>  	struct list_head		list;
> @@ -196,6 +197,7 @@ struct bnxt_re_dev {
>  	struct work_struct dbq_fifo_check_work;
>  	struct delayed_work dbq_pacing_work;
>  	DECLARE_HASHTABLE(cq_hash, MAX_CQ_HASH_BITS);
> +	DECLARE_HASHTABLE(srq_hash, MAX_SRQ_HASH_BITS);
>  };
>  
>  #define to_bnxt_re_dev(ptr, member)	\
> diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
> index 1e76093..0219c8a 100644
> --- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c
> +++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
> @@ -1685,6 +1685,10 @@ int bnxt_re_destroy_srq(struct ib_srq *ib_srq, struct ib_udata *udata)
>  
>  	if (qplib_srq->cq)
>  		nq = qplib_srq->cq->nq;
> +	if (rdev->chip_ctx->modes.toggle_bits & BNXT_QPLIB_SRQ_TOGGLE_BIT) {
> +		free_page((unsigned long)srq->uctx_srq_page);
> +		hash_del(&srq->hash_entry);
> +	}
>  	bnxt_qplib_destroy_srq(&rdev->qplib_res, qplib_srq);
>  	ib_umem_release(srq->umem);
>  	atomic_dec(&rdev->stats.res.srq_count);
> @@ -1789,9 +1793,18 @@ int bnxt_re_create_srq(struct ib_srq *ib_srq,
>  	}
>  
>  	if (udata) {
> -		struct bnxt_re_srq_resp resp;
> +		struct bnxt_re_srq_resp resp = {};
>  
>  		resp.srqid = srq->qplib_srq.id;
> +		if (rdev->chip_ctx->modes.toggle_bits & BNXT_QPLIB_SRQ_TOGGLE_BIT) {
> +			hash_add(rdev->srq_hash, &srq->hash_entry, srq->qplib_srq.id);
> +			srq->uctx_srq_page = (void *)get_zeroed_page(GFP_KERNEL);
> +			if (!srq->uctx_srq_page) {
> +				rc = -ENOMEM;
> +				goto fail;
> +			}
> +			resp.comp_mask |= BNXT_RE_SRQ_TOGGLE_PAGE_SUPPORT;
> +		}
>  		rc = ib_copy_to_udata(udata, &resp, sizeof(resp));
>  		if (rc) {
>  			ibdev_err(&rdev->ibdev, "SRQ copy to udata failed!");
> @@ -4266,6 +4279,19 @@ static struct bnxt_re_cq *bnxt_re_search_for_cq(struct bnxt_re_dev *rdev, u32 cq
>  	return cq;
>  }
>  
> +static struct bnxt_re_srq *bnxt_re_search_for_srq(struct bnxt_re_dev *rdev, u32 srq_id)
> +{
> +	struct bnxt_re_srq *srq = NULL, *tmp_srq;
> +
> +	hash_for_each_possible(rdev->srq_hash, tmp_srq, hash_entry, srq_id) {
> +		if (tmp_srq->qplib_srq.id == srq_id) {
> +			srq = tmp_srq;
> +			break;
> +		}
> +	}
> +	return srq;
> +}
> +
>  /* Helper function to mmap the virtual memory from user app */
>  int bnxt_re_mmap(struct ib_ucontext *ib_uctx, struct vm_area_struct *vma)
>  {
> @@ -4494,6 +4520,7 @@ static int UVERBS_HANDLER(BNXT_RE_METHOD_GET_TOGGLE_MEM)(struct uverbs_attr_bund
>  	struct bnxt_re_ucontext *uctx;
>  	struct ib_ucontext *ib_uctx;
>  	struct bnxt_re_dev *rdev;
> +	struct bnxt_re_srq *srq;
>  	u32 length = PAGE_SIZE;
>  	struct bnxt_re_cq *cq;
>  	u64 mem_offset;
> @@ -4525,6 +4552,11 @@ static int UVERBS_HANDLER(BNXT_RE_METHOD_GET_TOGGLE_MEM)(struct uverbs_attr_bund
>  		addr = (u64)cq->uctx_cq_page;
>  		break;
>  	case BNXT_RE_SRQ_TOGGLE_MEM:
> +		srq = bnxt_re_search_for_srq(rdev, res_id);
> +		if (!srq)
> +			return -EINVAL;
> +
> +		addr = (u64)srq->uctx_srq_page;
>  		break;
>  
>  	default:
> diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.h b/drivers/infiniband/hw/bnxt_re/ib_verbs.h
> index 4e113b9..9c74dfe 100644
> --- a/drivers/infiniband/hw/bnxt_re/ib_verbs.h
> +++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.h
> @@ -78,6 +78,7 @@ struct bnxt_re_srq {
>  	struct ib_umem		*umem;
>  	spinlock_t		lock;		/* protect srq */
>  	void			*uctx_srq_page;
> +	struct hlist_node       hash_entry;
>  };
>  
>  struct bnxt_re_qp {
> diff --git a/drivers/infiniband/hw/bnxt_re/main.c b/drivers/infiniband/hw/bnxt_re/main.c
> index 9714b9a..1211fe5 100644
> --- a/drivers/infiniband/hw/bnxt_re/main.c
> +++ b/drivers/infiniband/hw/bnxt_re/main.c
> @@ -139,8 +139,10 @@ static void bnxt_re_set_drv_mode(struct bnxt_re_dev *rdev, u8 mode)
>  	if (bnxt_re_hwrm_qcaps(rdev))
>  		dev_err(rdev_to_dev(rdev),
>  			"Failed to query hwrm qcaps\n");
> -	if (bnxt_qplib_is_chip_gen_p7(rdev->chip_ctx))
> +	if (bnxt_qplib_is_chip_gen_p7(rdev->chip_ctx)) {
>  		cctx->modes.toggle_bits |= BNXT_QPLIB_CQ_TOGGLE_BIT;
> +		cctx->modes.toggle_bits |= BNXT_QPLIB_SRQ_TOGGLE_BIT;
> +	}
>  }
>  
>  static void bnxt_re_destroy_chip_ctx(struct bnxt_re_dev *rdev)
> @@ -1771,6 +1773,8 @@ static int bnxt_re_dev_init(struct bnxt_re_dev *rdev, u8 wqe_mode)
>  		bnxt_re_vf_res_config(rdev);
>  	}
>  	hash_init(rdev->cq_hash);
> +	if (rdev->chip_ctx->modes.toggle_bits & BNXT_QPLIB_SRQ_TOGGLE_BIT)
> +		hash_init(rdev->srq_hash);
>  
>  	return 0;
>  free_sctx:
> diff --git a/include/uapi/rdma/bnxt_re-abi.h b/include/uapi/rdma/bnxt_re-abi.h
> index e61104f..84917a9 100644
> --- a/include/uapi/rdma/bnxt_re-abi.h
> +++ b/include/uapi/rdma/bnxt_re-abi.h
> @@ -134,8 +134,13 @@ struct bnxt_re_srq_req {
>  	__aligned_u64 srq_handle;
>  };
>  
> +enum bnxt_re_srq_mask {
> +	BNXT_RE_SRQ_TOGGLE_PAGE_SUPPORT = 0x1,
> +};
> +
>  struct bnxt_re_srq_resp {
>  	__u32 srqid;

I think that you should add __u32 reserved field here to align the
struct.

> +	__aligned_u64 comp_mask;
>  };
>  
>  enum bnxt_re_shpg_offt {
> -- 
> 2.5.5
> 




[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