RE: [PATCH rdma-next v2 09/11] RDMA/efa: Add EFA verbs implementation

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

 



>Subject: [PATCH rdma-next v2 09/11] RDMA/efa: Add EFA verbs implementation
>
>Add a file that implements the EFA verbs.
>
>Signed-off-by: Gal Pressman <galpress@xxxxxxxxxx>
>---
> drivers/infiniband/hw/efa/efa_verbs.c | 1891
>+++++++++++++++++++++++++++++++++
> 1 file changed, 1891 insertions(+)
> create mode 100644 drivers/infiniband/hw/efa/efa_verbs.c
>
[...]
>+int efa_query_port(struct ib_device *ibdev, u8 port,
>+		   struct ib_port_attr *props)
>+{
>+	struct efa_dev *dev = to_edev(ibdev);
>+
>+	memset(props, 0, sizeof(*props));
I don't think you need to explicitly zero initialize this struct. It's already done by core in ib_query_port(). 

[....]

>+struct ib_qp *efa_create_qp(struct ib_pd *ibpd,
>+			    struct ib_qp_init_attr *init_attr,
>+			    struct ib_udata *udata)
>+{
>+	struct efa_com_create_qp_params create_qp_params = {};
>+	struct efa_com_create_qp_result create_qp_resp;
>+	struct efa_dev *dev = to_edev(ibpd->device);
>+	struct efa_ibv_create_qp_resp resp = {};
>+	struct efa_ibv_create_qp cmd = {};
>+	struct efa_ucontext *ucontext;
>+	struct efa_qp *qp;
>+	int err;
>+
>+	ucontext = ibpd->uobject ? to_eucontext(ibpd->uobject->context) :
>+				   NULL;
>+
>+	if (!udata) {
>+		efa_err_rl(&dev->ibdev.dev, "udata is NULL\n");
>+		err = -EOPNOTSUPP;
>+		goto err_out;
>+	}
>+
>+	err = efa_qp_validate_cap(dev, init_attr);
>+	if (err)
>+		goto err_out;
>+
>+	err = efa_qp_validate_attr(dev, init_attr);
>+	if (err)
>+		goto err_out;
>+
>+	if (!field_avail(cmd, driver_qp_type, udata->inlen)) {
>+		efa_err_rl(&dev->ibdev.dev,
>+			   "Incompatible ABI params, no input udata\n");
>+		err = -EINVAL;
>+		goto err_out;
>+	}
>+
>+	if (udata->inlen > sizeof(cmd) &&
>+	    !ib_is_udata_cleared(udata, sizeof(cmd),
>+				 udata->inlen - sizeof(cmd))) {
>+		efa_err_rl(&dev->ibdev.dev,
>+			   "Incompatible ABI params, unknown fields in udata\n");
>+		err = -EINVAL;
>+		goto err_out;
>+	}
>+
>+	err = ib_copy_from_udata(&cmd, udata,
>+				 min(sizeof(cmd), udata->inlen));
>+	if (err) {
>+		efa_err_rl(&dev->ibdev.dev,
>+			   "Cannot copy udata for create_qp\n");
>+		goto err_out;
>+	}
>+
>+	if (cmd.comp_mask) {
>+		efa_err_rl(&dev->ibdev.dev,
>+			   "Incompatible ABI params, unknown fields in udata\n");
>+		err = -EINVAL;
>+		goto err_out;
>+	}
>+
>+	qp = kzalloc(sizeof(*qp), GFP_KERNEL);
>+	if (!qp) {
>+		err = -ENOMEM;
>+		goto err_out;
>+	}
>+
>+	create_qp_params.uarn = ucontext->uarn;
>+	create_qp_params.pd = to_epd(ibpd)->pdn;
>+
>+	if (init_attr->qp_type == IB_QPT_UD) {
>+		create_qp_params.qp_type = EFA_ADMIN_QP_TYPE_UD;
>+	} else if (cmd.driver_qp_type == EFA_QP_DRIVER_TYPE_SRD) {
>+		create_qp_params.qp_type = EFA_ADMIN_QP_TYPE_SRD;
>+	} else {
>+		efa_err(&dev->ibdev.dev,
>+			"Unsupported qp type %d driver qp type %d\n",
>+			init_attr->qp_type, cmd.driver_qp_type);
>+		err = -EOPNOTSUPP;
>+		goto err_free_qp;
>+	}
>+
>+	efa_dbg(&dev->ibdev.dev, "Create QP: qp type %d driver qp type
>%#x\n",
>+		init_attr->qp_type, cmd.driver_qp_type);
>+	create_qp_params.send_cq_idx = to_ecq(init_attr->send_cq)->cq_idx;
>+	create_qp_params.recv_cq_idx = to_ecq(init_attr->recv_cq)->cq_idx;
>+	create_qp_params.sq_depth = init_attr->cap.max_send_wr;
>+	create_qp_params.sq_ring_size_in_bytes = cmd.sq_ring_size;
>+
>+	create_qp_params.rq_depth = init_attr->cap.max_recv_wr;
>+	create_qp_params.rq_ring_size_in_bytes = cmd.rq_ring_size;
>+	qp->rq_size = PAGE_ALIGN(create_qp_params.rq_ring_size_in_bytes);
>+	if (qp->rq_size) {
>+		qp->rq_cpu_addr = efa_zalloc_mapped(dev, &qp->rq_dma_addr,
>+						    qp->rq_size,
>DMA_TO_DEVICE);
>+		if (!qp->rq_cpu_addr) {
>+			err = -ENOMEM;
>+			goto err_free_qp;
>+		}
>+
>+		efa_dbg(&dev->ibdev.dev,
>+			"qp->cpu_addr[%p] allocated: size[%lu], dma[%pad]\n",
>+			qp->rq_cpu_addr, qp->rq_size, &qp->rq_dma_addr);
>+		create_qp_params.rq_base_addr = qp->rq_dma_addr;
>+	}
>+
>+	memset(&resp, 0, sizeof(resp));
>+	err = efa_com_create_qp(dev->edev, &create_qp_params,
>+				&create_qp_resp);
>+	if (err)
>+		goto err_free_mapped;
>+
>+	WARN_ON_ONCE(create_qp_resp.sq_db_offset > dev->db_bar_len);
>+	WARN_ON_ONCE(create_qp_resp.rq_db_offset > dev->db_bar_len);
>+	WARN_ON_ONCE(create_qp_resp.llq_descriptors_offset >
>+		     dev->mem_bar_len);

I saw many instances of WARN or WARN_ON_ONCE in the driver. Is this what you
really want? Perhaps a pr_ or dev_ warn variant?

[...]
>+static struct ib_cq *do_create_cq(struct ib_device *ibdev, int entries,
>+				  int vector, struct ib_ucontext *ibucontext,
>+				  struct ib_udata *udata)
>+{
>+	struct efa_ibv_create_cq_resp resp = {};
>+	struct efa_com_create_cq_params params;
>+	struct efa_com_create_cq_result result;
>+	struct efa_dev *dev = to_edev(ibdev);
>+	struct efa_ibv_create_cq cmd = {};
>+	struct efa_cq *cq;
>+	int err;
>+
>+	efa_dbg(&ibdev->dev, "create_cq entries %d udata %p\n", entries,
>udata);
>+
>+	if (entries < 1 || entries > dev->dev_attr.max_cq_depth) {
>+		efa_err(&ibdev->dev,
>+			"cq: requested entries[%u] non-positive or greater than
>max[%u]\n",
>+			entries, dev->dev_attr.max_cq_depth);
>+		err = -EINVAL;
>+		goto err_out;
>+	}
>+
>+	if (!udata) {
>+		efa_err_rl(&ibdev->dev, "udata is NULL\n");
>+		err = -EOPNOTSUPP;
>+		goto err_out;
>+	}
>+
>+	if (!field_avail(cmd, num_sub_cqs, udata->inlen)) {
>+		efa_err_rl(&ibdev->dev,
>+			   "Incompatible ABI params, no input udata\n");
>+		err = -EINVAL;
>+		goto err_out;
>+	}
>+
>+	if (udata->inlen > sizeof(cmd) &&
>+	    !ib_is_udata_cleared(udata, sizeof(cmd),
>+				 udata->inlen - sizeof(cmd))) {
>+		efa_err_rl(&ibdev->dev,
>+			   "Incompatible ABI params, unknown fields in udata\n");
>+		err = -EINVAL;
>+		goto err_out;
>+	}
>+
>+	err = ib_copy_from_udata(&cmd, udata,
>+				 min(sizeof(cmd), udata->inlen));
>+	if (err) {
>+		efa_err_rl(&ibdev->dev,
>+			   "Cannot copy udata for create_cq\n");
>+		goto err_out;
>+	}
>+
>+	if (cmd.comp_mask || !is_reserved_cleared(cmd.reserved_50)) {
>+		efa_err_rl(&ibdev->dev,
>+			   "Incompatible ABI params, unknown fields in udata\n");
>+		err = -EINVAL;
>+		goto err_out;
>+	}
>+
>+	if (!cmd.cq_entry_size) {
>+		efa_err(&ibdev->dev,
>+			"Invalid entry size [%u]\n", cmd.cq_entry_size);
>+		err = -EINVAL;
>+		goto err_out;
>+	}
>+
>+	if (cmd.num_sub_cqs != dev->dev_attr.sub_cqs_per_cq) {
>+		efa_err(&ibdev->dev,
>+			"Invalid number of sub cqs[%u] expected[%u]\n",
>+			cmd.num_sub_cqs, dev->dev_attr.sub_cqs_per_cq);
>+		err = -EINVAL;
>+		goto err_out;
>+	}
>+
>+	cq = kzalloc(sizeof(*cq), GFP_KERNEL);
>+	if (!cq) {
>+		err = -ENOMEM;
>+		goto err_out;
>+	}
>+
>+	memset(&resp, 0, sizeof(resp));

This was already initialized. Few instances of these..

>+
>+/*
>+ * initialize pbl indirect mode:
>+ * create a chunk list out of the dma addresses of the physical pages of
>+ * pbl buffer.
>+ */
>+static int pbl_indirect_initialize(struct efa_dev *dev, struct pbl_context *pbl)
>+{
>+	u32 size_in_pages = DIV_ROUND_UP(pbl->pbl_buf_size_in_bytes,
>+					 EFA_PAGE_SIZE);
>+	struct scatterlist *sgl;
>+	int sg_dma_cnt, err;
>+
>+	sgl = efa_vmalloc_buf_to_sg(pbl->pbl_buf, size_in_pages);
>+	if (!sgl)
>+		return -ENOMEM;
>+
>+	sg_dma_cnt = dma_map_sg(&dev->pdev->dev, sgl, size_in_pages,
>DMA_TO_DEVICE);
>+	if (!sg_dma_cnt) {
>+		err = -EINVAL;
>+		goto err_map;
>+	}
>+
>+	pbl->phys.indirect.pbl_buf_size_in_pages = size_in_pages;
>+	pbl->phys.indirect.sgl = sgl;
>+	pbl->phys.indirect.sg_dma_cnt = sg_dma_cnt;
>+	err = pbl_chunk_list_create(dev, pbl);
>+	if (err) {
>+		efa_err(&dev->ibdev.dev,
>+			"chunk_list creation failed[%d]\n", err);
>+		goto err_chunk;
>+	}

Seems like you have many error prints in this driver. Do you really want this to show up
in dmesg or just the critical ones? Consider dev or pr_dbg?

Reviewed-by: Shiraz Saleem <shiraz.saleem@xxxxxxxxx>



[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