Commit d18bb3e1 authored by Leon Romanovsky's avatar Leon Romanovsky Committed by Jason Gunthorpe
Browse files

RDMA: Clean MW allocation and free flows

Move allocation and destruction of memory windows under ib_core
responsibility and clean drivers to ensure that no updates to MW
ib_core structures are done in driver layer.

Link: https://lore.kernel.org/r/20200902081623.746359-2-leon@kernel.org


Signed-off-by: default avatarLeon Romanovsky <leonro@mellanox.com>
Signed-off-by: default avatarJason Gunthorpe <jgg@nvidia.com>
parent b5de0c60
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -2695,6 +2695,7 @@ void ib_set_device_ops(struct ib_device *dev, const struct ib_device_ops *ops)
	SET_OBJ_SIZE(dev_ops, ib_ah);
	SET_OBJ_SIZE(dev_ops, ib_counters);
	SET_OBJ_SIZE(dev_ops, ib_cq);
	SET_OBJ_SIZE(dev_ops, ib_mw);
	SET_OBJ_SIZE(dev_ops, ib_pd);
	SET_OBJ_SIZE(dev_ops, ib_srq);
	SET_OBJ_SIZE(dev_ops, ib_ucontext);
+14 −6
Original line number Diff line number Diff line
@@ -858,7 +858,7 @@ static int ib_uverbs_dereg_mr(struct uverbs_attr_bundle *attrs)
static int ib_uverbs_alloc_mw(struct uverbs_attr_bundle *attrs)
{
	struct ib_uverbs_alloc_mw      cmd;
	struct ib_uverbs_alloc_mw_resp resp;
	struct ib_uverbs_alloc_mw_resp resp = {};
	struct ib_uobject             *uobj;
	struct ib_pd                  *pd;
	struct ib_mw                  *mw;
@@ -884,15 +884,21 @@ static int ib_uverbs_alloc_mw(struct uverbs_attr_bundle *attrs)
		goto err_put;
	}

	mw = pd->device->ops.alloc_mw(pd, cmd.mw_type, &attrs->driver_udata);
	if (IS_ERR(mw)) {
		ret = PTR_ERR(mw);
	mw = rdma_zalloc_drv_obj(ib_dev, ib_mw);
	if (!mw) {
		ret = -ENOMEM;
		goto err_put;
	}

	mw->device  = pd->device;
	mw->device = ib_dev;
	mw->pd = pd;
	mw->uobject = uobj;
	mw->type = cmd.mw_type;

	ret = pd->device->ops.alloc_mw(mw, &attrs->driver_udata);
	if (ret)
		goto err_alloc;

	atomic_inc(&pd->usecnt);

	uobj->object = mw;
@@ -903,6 +909,8 @@ static int ib_uverbs_alloc_mw(struct uverbs_attr_bundle *attrs)
	resp.mw_handle = uobj->id;
	return uverbs_response(attrs, &resp, sizeof(resp));

err_alloc:
	kfree(mw);
err_put:
	uobj_put_obj_read(pd);
err_free:
+5 −2
Original line number Diff line number Diff line
@@ -108,8 +108,11 @@ int uverbs_dealloc_mw(struct ib_mw *mw)
	int ret;

	ret = mw->device->ops.dealloc_mw(mw);
	if (!ret)
	if (ret)
		return ret;

	atomic_dec(&pd->usecnt);
	kfree(mw);
	return ret;
}

+1 −2
Original line number Diff line number Diff line
@@ -985,8 +985,7 @@ int c4iw_map_mr_sg(struct ib_mr *ibmr, struct scatterlist *sg, int sg_nents,
		   unsigned int *sg_offset);
int c4iw_dealloc_mw(struct ib_mw *mw);
void c4iw_dealloc(struct uld_ctx *ctx);
struct ib_mw *c4iw_alloc_mw(struct ib_pd *pd, enum ib_mw_type type,
			    struct ib_udata *udata);
int c4iw_alloc_mw(struct ib_mw *mw, struct ib_udata *udata);
struct ib_mr *c4iw_reg_user_mr(struct ib_pd *pd, u64 start,
					   u64 length, u64 virt, int acc,
					   struct ib_udata *udata);
+11 −21
Original line number Diff line number Diff line
@@ -611,30 +611,23 @@ err_free_mhp:
	return ERR_PTR(err);
}

struct ib_mw *c4iw_alloc_mw(struct ib_pd *pd, enum ib_mw_type type,
			    struct ib_udata *udata)
int c4iw_alloc_mw(struct ib_mw *ibmw, struct ib_udata *udata)
{
	struct c4iw_mw *mhp = to_c4iw_mw(ibmw);
	struct c4iw_dev *rhp;
	struct c4iw_pd *php;
	struct c4iw_mw *mhp;
	u32 mmid;
	u32 stag = 0;
	int ret;

	if (type != IB_MW_TYPE_1)
		return ERR_PTR(-EINVAL);
	if (ibmw->type != IB_MW_TYPE_1)
		return -EINVAL;

	php = to_c4iw_pd(pd);
	php = to_c4iw_pd(ibmw->pd);
	rhp = php->rhp;
	mhp = kzalloc(sizeof(*mhp), GFP_KERNEL);
	if (!mhp)
		return ERR_PTR(-ENOMEM);

	mhp->wr_waitp = c4iw_alloc_wr_wait(GFP_KERNEL);
	if (!mhp->wr_waitp) {
		ret = -ENOMEM;
		goto free_mhp;
	}
	if (!mhp->wr_waitp)
		return -ENOMEM;

	mhp->dereg_skb = alloc_skb(SGE_MAX_WR_LEN, GFP_KERNEL);
	if (!mhp->dereg_skb) {
@@ -645,18 +638,19 @@ struct ib_mw *c4iw_alloc_mw(struct ib_pd *pd, enum ib_mw_type type,
	ret = allocate_window(&rhp->rdev, &stag, php->pdid, mhp->wr_waitp);
	if (ret)
		goto free_skb;

	mhp->rhp = rhp;
	mhp->attr.pdid = php->pdid;
	mhp->attr.type = FW_RI_STAG_MW;
	mhp->attr.stag = stag;
	mmid = (stag) >> 8;
	mhp->ibmw.rkey = stag;
	ibmw->rkey = stag;
	if (xa_insert_irq(&rhp->mrs, mmid, mhp, GFP_KERNEL)) {
		ret = -ENOMEM;
		goto dealloc_win;
	}
	pr_debug("mmid 0x%x mhp %p stag 0x%x\n", mmid, mhp, stag);
	return &(mhp->ibmw);
	return 0;

dealloc_win:
	deallocate_window(&rhp->rdev, mhp->attr.stag, mhp->dereg_skb,
@@ -665,9 +659,7 @@ free_skb:
	kfree_skb(mhp->dereg_skb);
free_wr_wait:
	c4iw_put_wr_wait(mhp->wr_waitp);
free_mhp:
	kfree(mhp);
	return ERR_PTR(ret);
	return ret;
}

int c4iw_dealloc_mw(struct ib_mw *mw)
@@ -684,8 +676,6 @@ int c4iw_dealloc_mw(struct ib_mw *mw)
			  mhp->wr_waitp);
	kfree_skb(mhp->dereg_skb);
	c4iw_put_wr_wait(mhp->wr_waitp);
	pr_debug("ib_mw %p mmid 0x%x ptr %p\n", mw, mmid, mhp);
	kfree(mhp);
	return 0;
}

Loading