Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit af56e53c authored by Tatyana Nikolova's avatar Tatyana Nikolova Committed by Doug Ledford
Browse files

i40iw: Free QP PBLEs when the QP is destroyed



If the physical buffer list entries (PBLEs) of a QP are freed
up at i40iw_dereg_mr, they can be assigned to a newly
created QP before the previous QP is destroyed. Fix this
by freeing PBLEs only when the QP is destroyed.

Signed-off-by: default avatarTatyana Nikolova <tatyana.e.nikolova@intel.com>
Signed-off-by: default avatarFaisal Latif <faisal.latif@intel.com>
Signed-off-by: default avatarDoug Ledford <dledford@redhat.com>
parent 44b99f88
Loading
Loading
Loading
Loading
+11 −4
Original line number Diff line number Diff line
@@ -426,9 +426,13 @@ void i40iw_free_qp_resources(struct i40iw_device *iwdev,
			     struct i40iw_qp *iwqp,
			     u32 qp_num)
{
	struct i40iw_pbl *iwpbl = &iwqp->iwpbl;

	i40iw_dealloc_push_page(iwdev, &iwqp->sc_qp);
	if (qp_num)
		i40iw_free_resource(iwdev, iwdev->allocated_qps, qp_num);
	if (iwpbl->pbl_allocated)
		i40iw_free_pble(iwdev->pble_rsrc, &iwpbl->pble_alloc);
	i40iw_free_dma_mem(iwdev->sc_dev.hw, &iwqp->q2_ctx_mem);
	i40iw_free_dma_mem(iwdev->sc_dev.hw, &iwqp->kqp.dma_mem);
	kfree(iwqp->kqp.wrid_mem);
@@ -483,7 +487,7 @@ static int i40iw_setup_virt_qp(struct i40iw_device *iwdev,
			       struct i40iw_qp *iwqp,
			       struct i40iw_qp_init_info *init_info)
{
	struct i40iw_pbl *iwpbl = iwqp->iwpbl;
	struct i40iw_pbl *iwpbl = &iwqp->iwpbl;
	struct i40iw_qp_mr *qpmr = &iwpbl->qp_mr;

	iwqp->page = qpmr->sq_page;
@@ -688,19 +692,22 @@ static struct ib_qp *i40iw_create_qp(struct ib_pd *ibpd,
			ucontext = to_ucontext(ibpd->uobject->context);

			if (req.user_wqe_buffers) {
				struct i40iw_pbl *iwpbl;

				spin_lock_irqsave(
				    &ucontext->qp_reg_mem_list_lock, flags);
				iwqp->iwpbl = i40iw_get_pbl(
				iwpbl = i40iw_get_pbl(
				    (unsigned long)req.user_wqe_buffers,
				    &ucontext->qp_reg_mem_list);
				spin_unlock_irqrestore(
				    &ucontext->qp_reg_mem_list_lock, flags);

				if (!iwqp->iwpbl) {
				if (!iwpbl) {
					err_code = -ENODATA;
					i40iw_pr_err("no pbl info\n");
					goto error;
				}
				memcpy(&iwqp->iwpbl, iwpbl, sizeof(iwqp->iwpbl));
			}
		}
		err_code = i40iw_setup_virt_qp(iwdev, iwqp, &init_info);
@@ -2063,7 +2070,7 @@ static int i40iw_dereg_mr(struct ib_mr *ib_mr)
			ucontext = to_ucontext(ibpd->uobject->context);
			i40iw_del_memlist(iwmr, ucontext);
		}
		if (iwpbl->pbl_allocated)
		if (iwpbl->pbl_allocated && iwmr->type != IW_MEMREG_TYPE_QP)
			i40iw_free_pble(iwdev->pble_rsrc, palloc);
		kfree(iwmr);
		return 0;
+1 −1
Original line number Diff line number Diff line
@@ -170,7 +170,7 @@ struct i40iw_qp {
	struct i40iw_qp_kmode kqp;
	struct i40iw_dma_mem host_ctx;
	struct timer_list terminate_timer;
	struct i40iw_pbl *iwpbl;
	struct i40iw_pbl iwpbl;
	struct i40iw_dma_mem q2_ctx_mem;
	struct i40iw_dma_mem ietf_mem;
	struct completion sq_drained;