RE: [PATCH v3 11/15] IB/pvrdma: Add Queue Pair support

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

 



On  Mon, Aug 29, 2016 at 07:44:24 -0700, Yuval Shaia wrote:
> On Wed, Aug 03, 2016 at 04:27:40PM -0700, Adit Ranadive wrote:
> > This patch adds the ability to create, modify, query and destroy QPs.
> > The PVRDMA device supports RC, UD and GSI QPs.
> >
> > Changes v2->v3:
> >  - Removed boolean in pvrdma_cmd_post.
> >
> > Reviewed-by: Jorgen Hansen <jhansen@xxxxxxxxxx>
> > Reviewed-by: George Zhang <georgezhang@xxxxxxxxxx>
> > Reviewed-by: Aditya Sarwade <asarwade@xxxxxxxxxx>
> > Reviewed-by: Bryan Tan <bryantan@xxxxxxxxxx>
> > Signed-off-by: Adit Ranadive <aditr@xxxxxxxxxx>
> > ---
> >  drivers/infiniband/hw/pvrdma/pvrdma_qp.c | 975
> > +++++++++++++++++++++++++++++++
> >  1 file changed, 975 insertions(+)
> >  create mode 100644 drivers/infiniband/hw/pvrdma/pvrdma_qp.c
> >

...

> > +static int pvrdma_set_rq_size(struct pvrdma_dev *dev,
> > +			      struct ib_qp_cap *cap,
> > +			      struct pvrdma_qp *qp)
> > +{
> > +	if (cap->max_recv_wr > dev->dsr->caps.max_qp_wr ||
> > +	    cap->max_recv_sge > dev->dsr->caps.max_sge) {
> > +		dev_warn(&dev->pdev->dev, "recv queue size invalid\n");
> > +		return -EINVAL;
> > +	}
> 
> (extremely) minor suggestion to rename cap to req_cap as w/o knowing the
> context (cap is caller's requested attr) one might be confused how come QP
> max can be more than device max.
> Again, minor.
> (applied also to pvrdma_set_sq_size).

Ok. Makes sense. Adding in v4.

> > +
> > +	qp->rq.wqe_cnt = roundup_pow_of_two(max(1U, cap-
> >max_recv_wr));
> > +	qp->rq.max_gs = roundup_pow_of_two(max(1U, cap-
> >max_recv_sge));
> > +
> > +	/* Write back */
> > +	cap->max_recv_wr = qp->rq.wqe_cnt;
> > +	cap->max_recv_sge = qp->rq.max_gs;
> > +
> > +	qp->rq.wqe_size = roundup_pow_of_two(sizeof(struct
> pvrdma_rq_wqe_hdr) +
> > +					     sizeof(struct ib_sge) *
> > +					     qp->rq.max_gs);
> > +	qp->npages_recv = (qp->rq.wqe_cnt * qp->rq.wqe_size +
> PAGE_SIZE - 1) /
> > +			  PAGE_SIZE;
> > +
> > +	return 0;
> > +}
> > +
> > +static int pvrdma_set_sq_size(struct pvrdma_dev *dev, struct ib_qp_cap
> *cap,
> > +			      enum ib_qp_type type, struct pvrdma_qp *qp) {
> > +	if (cap->max_send_wr > dev->dsr->caps.max_qp_wr ||
> > +	    cap->max_send_sge > dev->dsr->caps.max_sge) {
> > +		dev_warn(&dev->pdev->dev, "send queue size invalid\n");
> > +		return -EINVAL;
> > +	}
> > +
> > +	qp->sq.wqe_cnt = roundup_pow_of_two(max(1U, cap-
> >max_send_wr));
> > +	qp->sq.max_gs = roundup_pow_of_two(max(1U, cap-
> >max_send_sge));
> > +
> > +	/* Write back */
> > +	cap->max_send_wr = qp->sq.wqe_cnt;
> > +	cap->max_send_sge = qp->sq.max_gs;
> > +
> > +	qp->sq.wqe_size = roundup_pow_of_two(sizeof(struct
> pvrdma_sq_wqe_hdr) +
> > +					     sizeof(struct ib_sge) *
> > +					     qp->sq.max_gs);
> > +	/* Note: one extra page for the header. */
> > +	qp->npages_send = 1 + (qp->sq.wqe_cnt * qp->sq.wqe_size +
> > +			       PAGE_SIZE - 1) / PAGE_SIZE;
> > +
> > +	return 0;
> > +}
> > +
> > +/**
> > + * pvrdma_create_qp - create queue pair
> > + * @pd: protection domain
> > + * @init_attr: queue pair attributes
> > + * @udata: user data
> > + *
> > + * @return: the ib_qp pointer on success, otherwise returns an errno.
> > + */
> > +struct ib_qp *pvrdma_create_qp(struct ib_pd *pd,
> > +			       struct ib_qp_init_attr *init_attr,
> > +			       struct ib_udata *udata)
> > +{
> > +	struct pvrdma_qp *qp;
> > +	struct pvrdma_dev *dev = to_vdev(pd->device);
> > +	struct pvrdma_cq *send_cq, *recv_cq;
> > +	union pvrdma_cmd_req req;
> > +	union pvrdma_cmd_resp rsp;
> > +	struct pvrdma_cmd_create_qp *cmd = &req.create_qp;
> > +	struct pvrdma_cmd_create_qp_resp *resp = &rsp.create_qp_resp;
> > +	struct pvrdma_create_qp ucmd;
> > +	unsigned long flags;
> > +	int ret;
> > +
> > +	if (!atomic_add_unless(&dev->num_qps, 1, dev->dsr-
> >caps.max_qp))
> > +		return ERR_PTR(-EINVAL);
> 
> Suggesting EAGAIN, ENOMEM, ENOSPC but not "Invalid argument" as
> nothing is wrong with input args.

Changed this to -ENOMEM.

> > +
> > +	if (init_attr->create_flags) {
> > +		dev_warn(&dev->pdev->dev,
> > +			 "invalid create queuepair flags %#x\n",
> > +			 init_attr->create_flags);
> > +		atomic_dec(&dev->num_qps);
> > +		return ERR_PTR(-EINVAL);
> > +	}
> > +
> > +	if (init_attr->qp_type != IB_QPT_RC &&
> > +	    init_attr->qp_type != IB_QPT_UD &&
> > +	    init_attr->qp_type != IB_QPT_GSI) {
> > +		dev_warn(&dev->pdev->dev, "queuepair type %d not
> supported\n",
> > +			 init_attr->qp_type);
> > +		atomic_dec(&dev->num_qps);
> > +		return ERR_PTR(-EINVAL);
> > +	}
> 
> Can we move the two blocks above so we would not need to dec(num_qps)
> on validation failure.
> It also make sense to first validate input and just then to allocate resource.

Ok.

...

> > +static void pvrdma_free_qp(struct pvrdma_qp *qp) {
> > +	struct pvrdma_dev *dev = to_vdev(qp->ibqp.device);
> > +	struct pvrdma_cq *scq;
> > +	struct pvrdma_cq *rcq;
> > +	unsigned long flags, flags1, flags2;
> > +
> > +	/* In case cq is polling */
> > +	get_cqs(qp, &scq, &rcq);
> > +	if ((uintptr_t)scq <= (uintptr_t)rcq) {
> 
> ???
> Comment might help here :)

I updated this whole cleanup CQs path so this check will go away.

...

> > +
> > +	index = pvrdma_idx(&qp->sq.ring->prod_tail, qp->sq.wqe_cnt);
> > +	for (nreq = 0; wr; nreq++, wr = wr->next) {
> > +		unsigned int tail;
> > +
> > +		if (unlikely(!pvrdma_idx_ring_has_space(
> > +				qp->sq.ring, qp->sq.wqe_cnt, &tail))) {
> > +			dev_warn(&dev->pdev->dev, "send queue is
> full\n");
> 
> Please consider replace it with dev_warn_ratelimited.
> (applied to all dev_warn in this function and in pvrdma_post_recv).

Ok. Will look at this.

Thanks,
Adit
--
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




[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