All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Saleem, Shiraz" <shiraz.saleem@intel.com>
To: Gal Pressman <galpress@amazon.com>,
	"dledford@redhat.com" <dledford@redhat.com>,
	"jgg@ziepe.ca" <jgg@ziepe.ca>,
	"davem@davemloft.net" <davem@davemloft.net>
Cc: "linux-rdma@vger.kernel.org" <linux-rdma@vger.kernel.org>,
	"netdev@vger.kernel.org" <netdev@vger.kernel.org>,
	"Ismail, Mustafa" <mustafa.ismail@intel.com>,
	"Kirsher, Jeffrey T" <jeffrey.t.kirsher@intel.com>,
	Yossi Leybovich <sleybo@amazon.com>
Subject: RE: [RFC v1 12/19] RDMA/irdma: Implement device supported verb APIs
Date: Tue, 26 Feb 2019 21:09:21 +0000	[thread overview]
Message-ID: <9DD61F30A802C4429A01CA4200E302A7A5A4FB85@fmsmsx124.amr.corp.intel.com> (raw)
In-Reply-To: <01b0d571-81d8-ed6c-77b7-e83ee0ab9caa@amazon.com>

>Subject: Re: [RFC v1 12/19] RDMA/irdma: Implement device supported verb APIs
>
>On 15-Feb-19 19:10, Shiraz Saleem wrote:
>> /**
>>  * irdma_dealloc_ucontext - deallocate the user context data structure
>>  * @context: user context created during alloc  */ static int
>> irdma_dealloc_ucontext(struct ib_ucontext *context) {
>> 	struct irdma_ucontext *ucontext = to_ucontext(context);
>> 	unsigned long flags;
>>
>> 	spin_lock_irqsave(&ucontext->cq_reg_mem_list_lock, flags);
>> 	if (!list_empty(&ucontext->cq_reg_mem_list)) {
>> 		spin_unlock_irqrestore(&ucontext->cq_reg_mem_list_lock, flags);
>> 		return -EBUSY;
>> 	}
>> 	spin_unlock_irqrestore(&ucontext->cq_reg_mem_list_lock, flags);
>>
>> 	spin_lock_irqsave(&ucontext->qp_reg_mem_list_lock, flags);
>> 	if (!list_empty(&ucontext->qp_reg_mem_list)) {
>> 		spin_unlock_irqrestore(&ucontext->qp_reg_mem_list_lock, flags);
>> 		return -EBUSY;
>
>Drivers are not permitted to fail dealloc_ucontext.

This is fixed in RFC v1 submission. Maybe this was pasted from the v0 ver?

[..]

>> +/**
>> + * irdma_alloc_pd - allocate protection domain
>> + * @pd: PD pointer
>> + * @context: user context created during alloc
>> + * @udata: user data
>> + */
>> +static int irdma_alloc_pd(struct ib_pd *pd,
>> +			  struct ib_ucontext *context,
>> +			  struct ib_udata *udata)
>> +{
>> +	struct irdma_pd *iwpd = to_iwpd(pd);
>> +	struct irdma_device *iwdev = to_iwdev(pd->device);
>> +	struct irdma_sc_dev *dev = &iwdev->rf->sc_dev;
>> +	struct irdma_pci_f *rf = iwdev->rf;
>> +	struct irdma_alloc_pd_resp uresp = {};
>> +	struct irdma_sc_pd *sc_pd;
>> +	struct irdma_ucontext *ucontext;
>> +	u32 pd_id = 0;
>> +	int err;
>> +
>> +	if (iwdev->closing)
>> +		return -ENODEV;
>> +
>> +	err = irdma_alloc_rsrc(rf, rf->allocated_pds, rf->max_pd, &pd_id,
>> +			       &rf->next_pd);
>> +	if (err)
>> +		return err;
>> +
>> +	sc_pd = &iwpd->sc_pd;
>> +	if (context) {
>
>I think this should be 'if (udata)', this applies to many other places in this driver.

That’s right. Will fix it.

>
>> +		ucontext = to_ucontext(context);
>> +		dev->iw_pd_ops->pd_init(dev, sc_pd, pd_id, ucontext->abi_ver);
>> +		uresp.pd_id = pd_id;
>> +		if (ib_copy_to_udata(udata, &uresp, sizeof(uresp))) {
>> +			err = -EFAULT;
>> +			goto error;
>> +		}
>> +	} else {
>> +		dev->iw_pd_ops->pd_init(dev, sc_pd, pd_id, -1);
>> +	}
>> +
>> +	irdma_add_pdusecount(iwpd);
>> +
>> +	return 0;
>> +error:
>> +	irdma_free_rsrc(rf, rf->allocated_pds, pd_id);
>> +
>> +	return err;
>> +}
>> +/**
>> + * irdma_create_qp - create qp
>> + * @ibpd: ptr of pd
>> + * @init_attr: attributes for qp
>> + * @udata: user data for create qp
>> + */
>> +static struct ib_qp *irdma_create_qp(struct ib_pd *ibpd,
>> +				     struct ib_qp_init_attr *init_attr,
>> +				     struct ib_udata *udata)
>> +{
>> +	struct irdma_pd *iwpd = to_iwpd(ibpd);
>> +	struct irdma_device *iwdev = to_iwdev(ibpd->device);
>> +	struct irdma_pci_f *rf = iwdev->rf;
>> +	struct irdma_cqp *iwcqp = &rf->cqp;
>> +	struct irdma_qp *iwqp;
>> +	struct irdma_ucontext *ucontext;
>> +	struct irdma_create_qp_req req;
>> +	struct irdma_create_qp_resp uresp = {};
>> +	struct i40iw_create_qp_resp uresp_gen1 = {};
>> +	u32 qp_num = 0;
>> +	void *mem;
>> +	enum irdma_status_code ret;
>> +	int err_code = 0;
>> +	int sq_size;
>> +	int rq_size;
>> +	struct irdma_sc_qp *qp;
>> +	struct irdma_sc_dev *dev = &rf->sc_dev;
>> +	struct irdma_qp_init_info init_info = {};
>> +	struct irdma_create_qp_info *qp_info;
>> +	struct irdma_cqp_request *cqp_request;
>> +	struct cqp_cmds_info *cqp_info;
>> +	struct irdma_qp_host_ctx_info *ctx_info;
>> +	struct irdma_iwarp_offload_info *iwarp_info;
>> +	struct irdma_roce_offload_info *roce_info;
>> +	struct irdma_udp_offload_info *udp_info;
>> +	unsigned long flags;
>> +
>> +	if (iwdev->closing)
>> +		return ERR_PTR(-ENODEV);
>> +
>> +	if (init_attr->create_flags)
>> +		return ERR_PTR(-EINVAL);
>> +
>> +	if (init_attr->cap.max_inline_data > dev->hw_attrs.max_hw_inline)
>> +		init_attr->cap.max_inline_data = dev->hw_attrs.max_hw_inline;
>> +
>> +	if (init_attr->cap.max_send_sge > dev->hw_attrs.max_hw_wq_frags)
>> +		init_attr->cap.max_send_sge = dev-
>>hw_attrs.max_hw_wq_frags;
>> +
>> +	if (init_attr->cap.max_recv_sge > dev->hw_attrs.max_hw_wq_frags)
>> +		init_attr->cap.max_recv_sge = dev->hw_attrs.max_hw_wq_frags;
>
>AFAIK, you can change the requested values to be greater than or equal to the
>values requested. I don't think you can change them to something smaller.

Hmm...This is a sanity check to make sure we don’t exceed the device supported values.
But we should fail the call.

[..]

>> +	mem = kzalloc(sizeof(*iwqp), GFP_KERNEL);
>> +	if (!mem)
>> +		return ERR_PTR(-ENOMEM);
>> +
>> +	iwqp = (struct irdma_qp *)mem;
>> +	iwqp->allocated_buf = mem;
>
>'allocated_buf' feels redundant. Why is iwqp not sufficient?

I agree.
[..]

>> +	if (udata) {
>> +		err_code = ib_copy_from_udata(&req, udata, sizeof(req));
>
>Perhaps ib_copy_from_udata(&req, udata, min(sizeof(req), udata->inlen)?
>Applies to other call sites of ib_copy_from/to_udata as well.
>

It’s a good idea.

>> + * irdma_query - query qp attributes
>> + * @ibqp: qp pointer
>> + * @attr: attributes pointer
>> + * @attr_mask: Not used
>> + * @init_attr: qp attributes to return  */ static int
>> +irdma_query_qp(struct ib_qp *ibqp,
>> +			  struct ib_qp_attr *attr,
>> +			  int attr_mask,
>> +			  struct ib_qp_init_attr *init_attr) {
>> +	struct irdma_qp *iwqp = to_iwqp(ibqp);
>> +	struct irdma_sc_qp *qp = &iwqp->sc_qp;
>> +
>> +	attr->qp_state = iwqp->ibqp_state;
>> +	attr->cur_qp_state = iwqp->ibqp_state;
>> +	attr->qp_access_flags = 0;
>> +	attr->cap.max_send_wr = qp->qp_uk.sq_size - 1;
>> +	attr->cap.max_recv_wr = qp->qp_uk.rq_size - 1;
>
>Why -1?

It's reserved for HW. But the equation should be 
(sqdepth - I40IW_SQ_RSVD) >> sqshift.

[....]
>
>> +	attr->cap.max_inline_data = qp->qp_uk.max_inline_data;
>> +	attr->cap.max_send_sge = qp->qp_uk.max_sq_frag_cnt;
>> +	attr->cap.max_recv_sge = qp->qp_uk.max_rq_frag_cnt;
>> +	attr->qkey = iwqp->roce_info.qkey;
>> +
>> +	init_attr->event_handler = iwqp->ibqp.event_handler;
>> +	init_attr->qp_context = iwqp->ibqp.qp_context;
>> +	init_attr->send_cq = iwqp->ibqp.send_cq;
>> +	init_attr->recv_cq = iwqp->ibqp.recv_cq;
>> +	init_attr->srq = iwqp->ibqp.srq;
>> +	init_attr->cap = attr->cap;
>> +
>> +	return 0;
>> +}
>> +
>> +/**
>> + * irdma_destroy_cq - destroy cq
>> + * @ib_cq: cq pointer
>> + */
>> +static int irdma_destroy_cq(struct ib_cq *ib_cq) {
>> +	struct irdma_cq *iwcq;
>> +	struct irdma_device *iwdev;
>> +	struct irdma_sc_cq *cq;
>> +
>> +	if (!ib_cq) {
>> +		irdma_pr_err("ib_cq == NULL\n");
>> +		return 0;
>> +	}
>
>Is this really needed? Which caller can pass NULL pointer?

Not needed.

>> +
>> +/**
>> + * board_id_show
>> + */
>> +static ssize_t board_id_show(struct device *dev,
>> +			     struct device_attribute *attr,
>> +			     char *buf)
>> +{
>> +	return sprintf(buf, "%.*s\n", 32, "IRDMA Board ID");
>
>That doesn't add much information.

Will fix.

>
>> +}
>> +
>> +static DEVICE_ATTR_RO(hw_rev);
>> +static DEVICE_ATTR_RO(hca_type);
>> +static DEVICE_ATTR_RO(board_id);
>> +
>> +static struct attribute *irdma_dev_attributes[] = {
>> +	&dev_attr_hw_rev.attr,
>> +	&dev_attr_hca_type.attr,
>> +	&dev_attr_board_id.attr,
>> +	NULL
>> +};
>> +
>> +static const struct attribute_group irdma_attr_group = {
>> +	.attrs = irdma_dev_attributes,
>> +};
>> +
>> +/**
>> + * irdma_modify_port  Modify port properties
>> + * @ibdev: device pointer from stack
>> + * @port: port number
>> + * @port_modify_mask: mask for port modifications
>> + * @props: port properties
>> + */
>> +static int irdma_modify_port(struct ib_device *ibdev,
>> +			     u8 port,
>> +			     int port_modify_mask,
>> +			     struct ib_port_modify *props) {
>> +	return 0;
>> +}
>
>Same question as disacossiate_ucontext.

This was likely added during early dev. and can be removed.

>
>> +
>> +/**
>> + * irdma_query_gid_roce - Query port GID for Roce
>> + * @ibdev: device pointer from stack
>> + * @port: port number
>> + * @index: Entry index
>> + * @gid: Global ID
>> + */
>> +static int irdma_query_gid_roce(struct ib_device *ibdev,
>> +				u8 port,
>> +				int index,
>> +				union ib_gid *gid)
>> +{
>> +	int ret;
>> +
>> +	ret = rdma_query_gid(ibdev, port, index, gid);
>> +	if (ret == -EAGAIN) {
>
>I can't see a path where rdma_query_gid returns -EAGAIN.

This function can be removed now. It's only applicable to non-Roce providers.

>
>> +		memcpy(gid, &zgid, sizeof(*gid));
>> +		return 0;
>> +	}
>> +
>> +	return ret;
>> +}
>> +
>
>> +/**
>> + * irdma_create_ah - create address handle
>> + * @ibpd: ptr to protection domain
>> + * @ah_attr: address handle attributes
>
>'ah_attr' -> 'attr', missing flags and udata.

Will fix all these hits in the driver.

[..]
>> + */
>> +static int irdma_destroy_ah(struct ib_ah *ibah, u32 flags) {
>> +	struct irdma_device *iwdev = to_iwdev(ibah->device);
>> +	struct irdma_ah *ah = to_iwah(ibah);
>> +	int err;
>> +
>> +	if (!ah->sc_ah.ah_info.ah_valid)
>> +		return -EINVAL;
>> +
>> +	err = irdma_ah_cqp_op(iwdev->rf, &ah->sc_ah,
>IRDMA_OP_AH_DESTROY,
>> +			      flags & RDMA_DESTROY_AH_SLEEPABLE,
>> +			      irdma_destroy_ah_cb, ah);
>> +	if (!err)
>> +		return 0;
>
>Why are the rest of the cleanups only in case of error?

On success, the cleanup is done in the callback, irdma_destroy_ah_cb.

[...]


>> +static __be64 irdma_mac_to_guid(struct net_device *ndev) {
>> +	unsigned char *mac = ndev->dev_addr;
>> +	__be64 guid;
>> +	unsigned char *dst = (unsigned char *)&guid;
>> +
>> +	dst[0] = mac[0] ^ 2;
>> +	dst[1] = mac[1];
>> +	dst[2] = mac[2];
>> +	dst[3] = 0xff;
>> +	dst[4] = 0xfe;
>> +	dst[5] = mac[3];
>> +	dst[6] = mac[4];
>> +	dst[7] = mac[5];
>> +
>> +	return guid;
>> +}
>
>There's a variant of this function in irdma, bnxt_re, ocrdma and qedr.
>Maybe it's time to provide it in common code?

Agreed.

  parent reply	other threads:[~2019-02-26 21:09 UTC|newest]

Thread overview: 59+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-02-15 17:10 [RFC v1 00/19] Add unified Intel Ethernet RDMA driver (irdma) Shiraz Saleem
2019-02-15 17:10 ` [RFC v1 01/19] net/i40e: Add peer register/unregister to struct i40e_netdev_priv Shiraz Saleem
2019-02-15 17:22   ` Jason Gunthorpe
2019-02-21  2:19     ` Saleem, Shiraz
2019-02-21 19:35       ` Jason Gunthorpe
2019-02-22 20:13         ` Ertman, David M
2019-02-22 20:23           ` Jason Gunthorpe
2019-03-13  2:11             ` Jeff Kirsher
2019-03-13 13:28               ` Jason Gunthorpe
2019-05-10 13:31                 ` Shiraz Saleem
2019-05-10 18:17                   ` Jason Gunthorpe
2019-02-15 17:10 ` [RFC v1 02/19] net/ice: Create framework for VSI queue context Shiraz Saleem
2019-02-15 17:10 ` [RFC v1 03/19] net/ice: Add support for ice peer devices and drivers Shiraz Saleem
2019-02-15 17:10 ` [RFC v1 04/19] RDMA/irdma: Add driver framework definitions Shiraz Saleem
2019-02-24 15:02   ` Gal Pressman
2019-02-24 15:02     ` Gal Pressman
2019-02-26 21:08     ` Saleem, Shiraz
2019-02-15 17:10 ` [RFC v1 05/19] RDMA/irdma: Implement device initialization definitions Shiraz Saleem
2019-02-15 17:10 ` [RFC v1 06/19] RDMA/irdma: Implement HW Admin Queue OPs Shiraz Saleem
2019-02-15 17:10 ` [RFC v1 07/19] RDMA/irdma: Add HMC backing store setup functions Shiraz Saleem
2019-02-15 17:10 ` [RFC v1 08/19] RDMA/irdma: Add privileged UDA queue implementation Shiraz Saleem
2019-02-24 11:42   ` Gal Pressman
2019-02-24 11:42     ` Gal Pressman
2019-02-15 17:10 ` [RFC v1 09/19] RDMA/irdma: Add QoS definitions Shiraz Saleem
2019-02-15 17:10 ` [RFC v1 10/19] RDMA/irdma: Add connection manager Shiraz Saleem
2019-02-24 11:21   ` Gal Pressman
2019-02-24 11:21     ` Gal Pressman
2019-02-25 18:46     ` Jason Gunthorpe
2019-02-26 21:07       ` Saleem, Shiraz
2019-02-15 17:10 ` [RFC v1 11/19] RDMA/irdma: Add PBLE resource manager Shiraz Saleem
2019-02-27  6:58   ` Leon Romanovsky
2019-02-15 17:10 ` [RFC v1 12/19] RDMA/irdma: Implement device supported verb APIs Shiraz Saleem
2019-02-15 17:35   ` Jason Gunthorpe
2019-02-15 22:19     ` Shiraz Saleem
2019-02-15 22:32       ` Jason Gunthorpe
2019-02-20 14:52     ` Saleem, Shiraz
2019-02-20 16:51       ` Jason Gunthorpe
2019-02-24 14:35   ` Gal Pressman
2019-02-24 14:35     ` Gal Pressman
2019-02-25 18:50     ` Jason Gunthorpe
2019-02-26 21:09       ` Saleem, Shiraz
2019-02-26 21:09     ` Saleem, Shiraz [this message]
2019-02-27  7:31       ` Gal Pressman
2019-02-15 17:11 ` [RFC v1 13/19] RDMA/irdma: Add RoCEv2 UD OP support Shiraz Saleem
2019-02-27  6:50   ` Leon Romanovsky
2019-02-15 17:11 ` [RFC v1 14/19] RDMA/irdma: Add user/kernel shared libraries Shiraz Saleem
2019-02-15 17:11 ` [RFC v1 15/19] RDMA/irdma: Add miscellaneous utility definitions Shiraz Saleem
2019-02-15 17:47   ` Jason Gunthorpe
2019-02-20  7:51     ` Leon Romanovsky
2019-02-20 14:53     ` Saleem, Shiraz
2019-02-20 16:53       ` Jason Gunthorpe
2019-02-15 17:11 ` [RFC v1 16/19] RDMA/irdma: Add dynamic tracing for CM Shiraz Saleem
2019-02-15 17:11 ` [RFC v1 17/19] RDMA/irdma: Add ABI definitions Shiraz Saleem
2019-02-15 17:16   ` Jason Gunthorpe
2019-02-20 14:52     ` Saleem, Shiraz
2019-02-20 16:50       ` Jason Gunthorpe
2019-02-15 17:11 ` [RFC v1 18/19] RDMA/irdma: Add Kconfig and Makefile Shiraz Saleem
2019-02-15 17:11 ` [RFC v1 19/19] RDMA/irdma: Update MAINTAINERS file Shiraz Saleem
2019-02-15 17:20 ` [RFC v1 00/19] Add unified Intel Ethernet RDMA driver (irdma) Jason Gunthorpe

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=9DD61F30A802C4429A01CA4200E302A7A5A4FB85@fmsmsx124.amr.corp.intel.com \
    --to=shiraz.saleem@intel.com \
    --cc=davem@davemloft.net \
    --cc=dledford@redhat.com \
    --cc=galpress@amazon.com \
    --cc=jeffrey.t.kirsher@intel.com \
    --cc=jgg@ziepe.ca \
    --cc=linux-rdma@vger.kernel.org \
    --cc=mustafa.ismail@intel.com \
    --cc=netdev@vger.kernel.org \
    --cc=sleybo@amazon.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.