From: Leon Romanovsky <leon@kernel.org>
To: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Cc: gregkh@linuxfoundation.org, jgg@ziepe.ca,
Mustafa Ismail <mustafa.ismail@intel.com>,
netdev@vger.kernel.org, linux-rdma@vger.kernel.org,
nhorman@redhat.com, sassmann@redhat.com,
Shiraz Saleem <shiraz.saleem@intel.com>
Subject: Re: [RFC PATCH v5 09/16] RDMA/irdma: Implement device supported verb APIs
Date: Fri, 17 Apr 2020 22:59:28 +0300 [thread overview]
Message-ID: <20200417195928.GE3083@unreal> (raw)
In-Reply-To: <20200417171251.1533371-10-jeffrey.t.kirsher@intel.com>
On Fri, Apr 17, 2020 at 10:12:44AM -0700, Jeff Kirsher wrote:
> From: Mustafa Ismail <mustafa.ismail@intel.com>
>
> Implement device supported verb APIs. The supported APIs
> vary based on the underlying transport the ibdev is
> registered as (i.e. iWARP or RoCEv2).
>
> Signed-off-by: Mustafa Ismail <mustafa.ismail@intel.com>
> Signed-off-by: Shiraz Saleem <shiraz.saleem@intel.com>
> ---
> drivers/infiniband/hw/irdma/verbs.c | 4555 +++++++++++++++++++++++
> drivers/infiniband/hw/irdma/verbs.h | 213 ++
> include/uapi/rdma/ib_user_ioctl_verbs.h | 1 +
> 3 files changed, 4769 insertions(+)
> create mode 100644 drivers/infiniband/hw/irdma/verbs.c
> create mode 100644 drivers/infiniband/hw/irdma/verbs.h
<...>
> +static int irdma_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata)
> +{
> + struct irdma_qp *iwqp = to_iwqp(ibqp);
> +
> + iwqp->destroyed = 1;
> + if (iwqp->ibqp_state >= IB_QPS_INIT && iwqp->ibqp_state < IB_QPS_RTS)
> + irdma_next_iw_state(iwqp, IRDMA_QP_STATE_ERROR, 0, 0, 0);
> +
> + if (!iwqp->user_mode) {
> + if (iwqp->iwscq) {
> + irdma_clean_cqes(iwqp, iwqp->iwscq);
> + if (iwqp->iwrcq != iwqp->iwscq)
> + irdma_clean_cqes(iwqp, iwqp->iwrcq);
> + }
> + }
> +
> + irdma_remove_push_mmap_entries(iwqp);
> + irdma_free_lsmm_rsrc(iwqp);
> + irdma_rem_ref(&iwqp->ibqp);
No, please ensure that call to destroy_qp is kfree QP without any need
in reference counting. We need this to move QP allocation to be IB/core
responsibility. I hope that all other verbs objects (with MR as
exception) follow the same pattern: create->kzalloc->destroy>kfree.
> +
> + return 0;
> +}
<...>
> +
> +/**
> + * 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_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_uk_attrs *uk_attrs = &dev->hw_attrs.uk_attrs;
> + 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 (init_attr->create_flags ||
> + init_attr->cap.max_inline_data > uk_attrs->max_hw_inline ||
> + init_attr->cap.max_send_sge > uk_attrs->max_hw_wq_frags ||
> + init_attr->cap.max_recv_sge > uk_attrs->max_hw_wq_frags)
> + return ERR_PTR(-EINVAL);
> +
> + sq_size = init_attr->cap.max_send_wr;
> + rq_size = init_attr->cap.max_recv_wr;
> +
> + init_info.vsi = &iwdev->vsi;
> + init_info.qp_uk_init_info.uk_attrs = uk_attrs;
> + init_info.qp_uk_init_info.sq_size = sq_size;
> + init_info.qp_uk_init_info.rq_size = rq_size;
> + init_info.qp_uk_init_info.max_sq_frag_cnt = init_attr->cap.max_send_sge;
> + init_info.qp_uk_init_info.max_rq_frag_cnt = init_attr->cap.max_recv_sge;
> + init_info.qp_uk_init_info.max_inline_data = init_attr->cap.max_inline_data;
> +
> + mem = kzalloc(sizeof(*iwqp), GFP_KERNEL);
> + if (!mem)
> + return ERR_PTR(-ENOMEM);
> +
> + iwqp = mem;
I'm confused, why do you need "mem" in the first place?
> + qp = &iwqp->sc_qp;
> + qp->qp_uk.back_qp = (void *)iwqp;
> + qp->qp_uk.lock = &iwqp->lock;
> + qp->push_idx = IRDMA_INVALID_PUSH_PAGE_INDEX;
> +
> + iwqp->q2_ctx_mem.size = ALIGN(IRDMA_Q2_BUF_SIZE + IRDMA_QP_CTX_SIZE,
> + 256);
> + iwqp->q2_ctx_mem.va = dma_alloc_coherent(hw_to_dev(dev->hw),
> + iwqp->q2_ctx_mem.size,
> + &iwqp->q2_ctx_mem.pa,
> + GFP_KERNEL);
> + if (!iwqp->q2_ctx_mem.va) {
> + err_code = -ENOMEM;
> + goto error;
> + }
> +
> + init_info.q2 = iwqp->q2_ctx_mem.va;
> + init_info.q2_pa = iwqp->q2_ctx_mem.pa;
> + init_info.host_ctx = (void *)init_info.q2 + IRDMA_Q2_BUF_SIZE;
> + init_info.host_ctx_pa = init_info.q2_pa + IRDMA_Q2_BUF_SIZE;
> +
> + if (init_attr->qp_type == IB_QPT_GSI && !rf->ldev.ftype)
> + qp_num = 1;
> + else
> + err_code = irdma_alloc_rsrc(rf, rf->allocated_qps, rf->max_qp,
> + &qp_num, &rf->next_qp);
> + if (err_code)
> + goto error;
> +
> + iwqp->iwdev = iwdev;
> + iwqp->iwpd = iwpd;
> + if (init_attr->qp_type == IB_QPT_GSI && !rf->ldev.ftype)
> + iwqp->ibqp.qp_num = 1;
> + else
> + iwqp->ibqp.qp_num = qp_num;
> +
> + qp = &iwqp->sc_qp;
> + iwqp->iwscq = to_iwcq(init_attr->send_cq);
> + iwqp->iwrcq = to_iwcq(init_attr->recv_cq);
> + iwqp->host_ctx.va = init_info.host_ctx;
> + iwqp->host_ctx.pa = init_info.host_ctx_pa;
> + iwqp->host_ctx.size = IRDMA_QP_CTX_SIZE;
> +
> + init_info.pd = &iwpd->sc_pd;
> + init_info.qp_uk_init_info.qp_id = iwqp->ibqp.qp_num;
> + if (!rdma_protocol_roce(&iwdev->ibdev, 1))
> + init_info.qp_uk_init_info.first_sq_wq = 1;
> + iwqp->ctx_info.qp_compl_ctx = (uintptr_t)qp;
> + init_waitqueue_head(&iwqp->waitq);
> + init_waitqueue_head(&iwqp->mod_qp_waitq);
> +
> + if (rdma_protocol_roce(&iwdev->ibdev, 1)) {
> + if (init_attr->qp_type != IB_QPT_RC &&
> + init_attr->qp_type != IB_QPT_UD &&
> + init_attr->qp_type != IB_QPT_GSI) {
> + err_code = -EINVAL;
> + goto error;
> + }
> + } else {
> + if (init_attr->qp_type != IB_QPT_RC) {
> + err_code = -EINVAL;
> + goto error;
> + }
> + }
> + if (udata) {
> + err_code = ib_copy_from_udata(&req, udata,
> + min(sizeof(req), udata->inlen));
> + if (err_code) {
> + ibdev_dbg(to_ibdev(iwdev),
> + "VERBS: ib_copy_from_data fail\n");
> + goto error;
> + }
> +
> + iwqp->ctx_info.qp_compl_ctx = req.user_compl_ctx;
> + iwqp->user_mode = 1;
> + if (req.user_wqe_bufs) {
> + struct irdma_ucontext *ucontext =
> + rdma_udata_to_drv_context(udata,
> + struct irdma_ucontext,
> + ibucontext);
> + spin_lock_irqsave(&ucontext->qp_reg_mem_list_lock, flags);
> + iwqp->iwpbl = irdma_get_pbl((unsigned long)req.user_wqe_bufs,
> + &ucontext->qp_reg_mem_list);
> + spin_unlock_irqrestore(&ucontext->qp_reg_mem_list_lock, flags);
> +
> + if (!iwqp->iwpbl) {
> + err_code = -ENODATA;
> + ibdev_dbg(to_ibdev(iwdev),
> + "VERBS: no pbl info\n");
> + goto error;
> + }
> + }
> + init_info.qp_uk_init_info.abi_ver = iwpd->sc_pd.abi_ver;
> + err_code = irdma_setup_virt_qp(iwdev, iwqp, &init_info);
> + } else {
> + init_info.qp_uk_init_info.abi_ver = IRDMA_ABI_VER;
> + err_code = irdma_setup_kmode_qp(iwdev, iwqp, &init_info, init_attr);
> + }
> +
> + if (err_code) {
> + ibdev_dbg(to_ibdev(iwdev), "VERBS: setup qp failed\n");
> + goto error;
> + }
> +
> + if (rdma_protocol_roce(&iwdev->ibdev, 1)) {
> + if (init_attr->qp_type == IB_QPT_RC) {
> + init_info.type = IRDMA_QP_TYPE_ROCE_RC;
> + init_info.qp_uk_init_info.qp_caps = IRDMA_SEND_WITH_IMM |
> + IRDMA_WRITE_WITH_IMM |
> + IRDMA_ROCE;
> + } else {
> + init_info.type = IRDMA_QP_TYPE_ROCE_UD;
> + init_info.qp_uk_init_info.qp_caps = IRDMA_SEND_WITH_IMM |
> + IRDMA_ROCE;
> + }
> + } else {
> + init_info.type = IRDMA_QP_TYPE_IWARP;
> + init_info.qp_uk_init_info.qp_caps = IRDMA_WRITE_WITH_IMM;
> + }
> +
> + ret = dev->iw_priv_qp_ops->qp_init(qp, &init_info);
> + if (ret) {
> + err_code = -EPROTO;
> + ibdev_dbg(to_ibdev(iwdev), "VERBS: qp_init fail\n");
> + goto error;
> + }
> +
> + ctx_info = &iwqp->ctx_info;
> + if (rdma_protocol_roce(&iwdev->ibdev, 1)) {
> + iwqp->ctx_info.roce_info = &iwqp->roce_info;
> + iwqp->ctx_info.udp_info = &iwqp->udp_info;
> + udp_info = &iwqp->udp_info;
> + udp_info->snd_mss = irdma_roce_mtu(iwdev->vsi.mtu);
> + udp_info->cwnd = 0x400;
> + udp_info->src_port = 0xc000;
> + udp_info->dst_port = ROCE_V2_UDP_DPORT;
> + roce_info = &iwqp->roce_info;
> + ether_addr_copy(roce_info->mac_addr, iwdev->netdev->dev_addr);
> +
> + if (init_attr->qp_type == IB_QPT_GSI && !rf->sc_dev.privileged)
> + roce_info->is_qp1 = true;
> + roce_info->rd_en = true;
> + roce_info->wr_rdresp_en = true;
> + roce_info->dcqcn_en = true;
> +
> + roce_info->ack_credits = 0x1E;
> + roce_info->ird_size = IRDMA_MAX_ENCODED_IRD_SIZE;
> + roce_info->ord_size = dev->hw_attrs.max_hw_ord;
> +
> + if (!iwqp->user_mode) {
> + roce_info->priv_mode_en = true;
> + roce_info->fast_reg_en = true;
> + roce_info->udprivcq_en = true;
> + }
> + roce_info->roce_tver = 0;
> + } else {
> + iwqp->ctx_info.iwarp_info = &iwqp->iwarp_info;
> + iwarp_info = &iwqp->iwarp_info;
> + ether_addr_copy(iwarp_info->mac_addr, iwdev->netdev->dev_addr);
> + iwarp_info->rd_en = true;
> + iwarp_info->wr_rdresp_en = true;
> + iwarp_info->ecn_en = true;
> +
> + if (dev->hw_attrs.uk_attrs.hw_rev > IRDMA_GEN_1)
> + iwarp_info->ib_rd_en = true;
> + if (!iwqp->user_mode) {
> + iwarp_info->priv_mode_en = true;
> + iwarp_info->fast_reg_en = true;
> + }
> + iwarp_info->ddp_ver = 1;
> + iwarp_info->rdmap_ver = 1;
> + ctx_info->iwarp_info_valid = true;
> + }
> + ctx_info->send_cq_num = iwqp->iwscq->sc_cq.cq_uk.cq_id;
> + ctx_info->rcv_cq_num = iwqp->iwrcq->sc_cq.cq_uk.cq_id;
> + if (rdma_protocol_roce(&iwdev->ibdev, 1)) {
> + ret = dev->iw_priv_qp_ops->qp_setctx_roce(&iwqp->sc_qp,
> + iwqp->host_ctx.va,
> + ctx_info);
> + } else {
> + ret = dev->iw_priv_qp_ops->qp_setctx(&iwqp->sc_qp,
> + iwqp->host_ctx.va,
> + ctx_info);
> + ctx_info->iwarp_info_valid = false;
> + }
> +
> + cqp_request = irdma_get_cqp_request(iwcqp, true);
> + if (!cqp_request) {
> + err_code = -ENOMEM;
> + goto error;
> + }
> +
> + cqp_info = &cqp_request->info;
> + qp_info = &cqp_request->info.in.u.qp_create.info;
> + memset(qp_info, 0, sizeof(*qp_info));
> + qp_info->mac_valid = true;
> + qp_info->cq_num_valid = true;
> + qp_info->next_iwarp_state = IRDMA_QP_STATE_IDLE;
> +
> + cqp_info->cqp_cmd = IRDMA_OP_QP_CREATE;
> + cqp_info->post_sq = 1;
> + cqp_info->in.u.qp_create.qp = qp;
> + cqp_info->in.u.qp_create.scratch = (uintptr_t)cqp_request;
> + ret = irdma_handle_cqp_op(rf, cqp_request);
> + if (ret) {
> + ibdev_dbg(to_ibdev(iwdev), "VERBS: CQP-OP QP create fail");
> + err_code = -ENOMEM;
> + goto error;
> + }
> +
> + refcount_set(&iwqp->refcnt, 1);
> + spin_lock_init(&iwqp->lock);
> + spin_lock_init(&iwqp->sc_qp.pfpdu.lock);
> + iwqp->sig_all = (init_attr->sq_sig_type == IB_SIGNAL_ALL_WR) ? 1 : 0;
> + rf->qp_table[qp_num] = iwqp;
> + iwqp->max_send_wr = sq_size;
> + iwqp->max_recv_wr = rq_size;
> + if (udata) {
> + /* GEN_1 legacy support with libi40iw */
> + if (iwpd->sc_pd.abi_ver <= 5) {
> + uresp_gen1.lsmm = 1;
> + uresp_gen1.actual_sq_size = sq_size;
> + uresp_gen1.actual_rq_size = rq_size;
> + uresp_gen1.qp_id = qp_num;
> + uresp_gen1.push_idx = IRDMA_INVALID_PUSH_PAGE_INDEX;
> + uresp_gen1.lsmm = 1;
> + err_code = ib_copy_to_udata(udata, &uresp_gen1,
> + min(sizeof(uresp_gen1), udata->outlen));
> + } else {
> + if (rdma_protocol_iwarp(&iwdev->ibdev, 1))
> + uresp.lsmm = 1;
> + uresp.actual_sq_size = sq_size;
> + uresp.actual_rq_size = rq_size;
> + uresp.qp_id = qp_num;
> + uresp.qp_caps = qp->qp_uk.qp_caps;
> +
> + err_code = ib_copy_to_udata(udata, &uresp,
> + min(sizeof(uresp), udata->outlen));
> + }
> + if (err_code) {
> + ibdev_dbg(to_ibdev(iwdev),
> + "VERBS: copy_to_udata failed\n");
> + irdma_destroy_qp(&iwqp->ibqp, udata);
> + return ERR_PTR(err_code);
> + }
> + }
> + init_completion(&iwqp->sq_drained);
> + init_completion(&iwqp->rq_drained);
> + return &iwqp->ibqp;
> +
> +error:
> + irdma_free_qp_rsrc(iwdev, iwqp, qp_num);
> +
> + return ERR_PTR(err_code);
> +}
> +
This function was too long.
Thanks
next prev parent reply other threads:[~2020-04-17 19:59 UTC|newest]
Thread overview: 51+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-04-17 17:12 [RFC PATCH v5 00/16] Add Intel Ethernet Protocol Driver for RDMA (irdma) Jeff Kirsher
2020-04-17 17:12 ` [RFC PATCH v5 01/16] RDMA/irdma: Add driver framework definitions Jeff Kirsher
2020-04-17 19:34 ` Leon Romanovsky
2020-04-21 0:23 ` Saleem, Shiraz
2020-04-21 0:46 ` Jason Gunthorpe
2020-04-21 18:19 ` Saleem, Shiraz
2020-04-21 18:22 ` Jason Gunthorpe
2020-04-23 0:32 ` Saleem, Shiraz
2020-04-23 15:02 ` Jason Gunthorpe
2020-04-23 17:15 ` Saleem, Shiraz
2020-04-23 19:03 ` Jason Gunthorpe
2020-04-23 23:54 ` Saleem, Shiraz
2020-04-24 0:48 ` Jason Gunthorpe
2020-04-27 23:57 ` Saleem, Shiraz
2020-04-28 0:03 ` Jason Gunthorpe
2020-04-21 7:14 ` Leon Romanovsky
2020-04-17 19:37 ` Jason Gunthorpe
2020-04-17 17:12 ` [RFC PATCH v5 02/16] RDMA/irdma: Implement device initialization definitions Jeff Kirsher
2020-04-17 17:12 ` [RFC PATCH v5 03/16] RDMA/irdma: Implement HW Admin Queue OPs Jeff Kirsher
2020-04-17 17:12 ` [RFC PATCH v5 04/16] RDMA/irdma: Add HMC backing store setup functions Jeff Kirsher
2020-04-17 20:17 ` Leon Romanovsky
2020-04-21 0:25 ` Saleem, Shiraz
2020-04-17 17:12 ` [RFC PATCH v5 05/16] RDMA/irdma: Add privileged UDA queue implementation Jeff Kirsher
2020-04-17 17:12 ` [RFC PATCH v5 06/16] RDMA/irdma: Add QoS definitions Jeff Kirsher
2020-04-17 17:12 ` [RFC PATCH v5 07/16] RDMA/irdma: Add connection manager Jeff Kirsher
2020-04-17 20:23 ` Leon Romanovsky
2020-04-21 0:26 ` Saleem, Shiraz
2020-04-21 7:33 ` Leon Romanovsky
2020-04-17 17:12 ` [RFC PATCH v5 08/16] RDMA/irdma: Add PBLE resource manager Jeff Kirsher
2020-04-17 17:12 ` [RFC PATCH v5 09/16] RDMA/irdma: Implement device supported verb APIs Jeff Kirsher
2020-04-17 19:59 ` Leon Romanovsky [this message]
2020-04-21 0:29 ` Saleem, Shiraz
2020-04-21 7:16 ` Leon Romanovsky
2020-04-17 17:12 ` [RFC PATCH v5 10/16] RDMA/irdma: Add RoCEv2 UD OP support Jeff Kirsher
2020-04-17 19:46 ` Leon Romanovsky
2020-04-21 0:27 ` Saleem, Shiraz
2020-04-17 17:12 ` [RFC PATCH v5 11/16] RDMA/irdma: Add user/kernel shared libraries Jeff Kirsher
2020-04-17 17:12 ` [RFC PATCH v5 12/16] RDMA/irdma: Add miscellaneous utility definitions Jeff Kirsher
2020-04-17 20:32 ` Leon Romanovsky
2020-04-21 0:27 ` Saleem, Shiraz
2020-04-21 7:30 ` Leon Romanovsky
2020-04-22 0:02 ` Saleem, Shiraz
2020-04-22 0:06 ` Jason Gunthorpe
2020-04-23 0:32 ` Saleem, Shiraz
2020-04-17 17:12 ` [RFC PATCH v5 13/16] RDMA/irdma: Add dynamic tracing for CM Jeff Kirsher
2020-04-17 17:12 ` [RFC PATCH v5 14/16] RDMA/irdma: Add ABI definitions Jeff Kirsher
2020-04-17 19:43 ` Leon Romanovsky
2020-04-21 0:29 ` Saleem, Shiraz
2020-04-21 7:22 ` Leon Romanovsky
2020-04-17 17:12 ` [RFC PATCH v5 15/16] RDMA/irdma: Add irdma Kconfig/Makefile and remove i40iw Jeff Kirsher
2020-04-17 17:12 ` [RFC PATCH v5 16/16] RDMA/irdma: Update MAINTAINERS file Jeff Kirsher
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=20200417195928.GE3083@unreal \
--to=leon@kernel.org \
--cc=gregkh@linuxfoundation.org \
--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=nhorman@redhat.com \
--cc=sassmann@redhat.com \
--cc=shiraz.saleem@intel.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.