RDMA: Clean MW allocation and free flows
Subsystems (5)
PATCH v2 1/1 RDMA: Clean MW allocation and free flows
From: Leon Romanovsky <[email protected]>
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.
Signed-off-by Leon Romanovsky <[email protected]>
---
Changelog:
v2: Changed the way of how rkey is assigned.
v1: https://lore.kernel.org/linux-rdma/[email protected]
--- drivers/infiniband/core/device.c | 1 + drivers/infiniband/core/uverbs.h | 2 +- drivers/infiniband/core/uverbs_cmd.c | 26 ++++++++----- drivers/infiniband/core/uverbs_main.c | 10 ++--- drivers/infiniband/core/uverbs_std_types.c | 3 +- drivers/infiniband/hw/cxgb4/iw_cxgb4.h | 5 +-- drivers/infiniband/hw/cxgb4/mem.c | 35 ++++++----------- drivers/infiniband/hw/cxgb4/provider.c | 4 +- drivers/infiniband/hw/hns/hns_roce_device.h | 5 +-- drivers/infiniband/hw/hns/hns_roce_main.c | 2 + drivers/infiniband/hw/hns/hns_roce_mr.c | 31 +++++---------- drivers/infiniband/hw/mlx4/main.c | 2 + drivers/infiniband/hw/mlx4/mlx4_ib.h | 5 +-- drivers/infiniband/hw/mlx4/mr.c | 33 +++++----------- drivers/infiniband/hw/mlx5/main.c | 2 + drivers/infiniband/hw/mlx5/mlx5_ib.h | 5 +-- drivers/infiniband/hw/mlx5/mr.c | 42 ++++++++------------- include/rdma/ib_verbs.h | 6 +-- 18 files changed, 91 insertions(+), 128 deletions(-)
drivers/infiniband/core/device.c +1 -0
@@ -2689,6 +2689,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);
drivers/infiniband/core/uverbs.h +1 -1
@@ -242,7 +242,7 @@ int ib_uverbs_dealloc_xrcd(struct ib_uobject *uobject, struct ib_xrcd *xrcd,enum rdma_remove_reason why, struct uverbs_attr_bundle *attrs); -int uverbs_dealloc_mw (struct ib_mw *mw); +void uverbs_dealloc_mw (struct ib_mw *mw);void ib_uverbs_detach_umcast (struct ib_qp *qp,struct ib_uqp_object *uobj);
drivers/infiniband/core/uverbs_cmd.c +16 -10
@@ -890,7 +890,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;
@@ -916,21 +916,24 @@ 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->pd = pd; + mw->device = ib_dev; + mw->pd = pd; mw->uobject = uobj; -atomic_inc (&pd->usecnt); - uobj->object = mw; + mw->type = cmd.mw_type; -memset (&resp,0 ,sizeof (resp)); - resp.rkey = mw->rkey; + ret = pd->device->ops.alloc_mw (mw, &attrs->driver_udata); +if (ret) + goto err_alloc; + +atomic_inc (&pd->usecnt); + resp.rkey = mw->rkey; resp.mw_handle = uobj->id; ret =uverbs_response (attrs, &resp,sizeof (resp));
@@ -943,6 +946,9 @@ static int ib_uverbs_alloc_mw(struct uverbs_attr_bundle *attrs) err_copy:uverbs_dealloc_mw (mw); + mw =NULL ; +err_alloc: +kfree (mw); err_put:uobj_put_obj_read (pd); err_free:
drivers/infiniband/core/uverbs_main.c +4 -6
@@ -102,15 +102,13 @@ struct ib_ucontext *ib_uverbs_get_ucontext_file(struct ib_uverbs_file *ufile) }EXPORT_SYMBOL (ib_uverbs_get_ucontext_file); -int uverbs_dealloc_mw (struct ib_mw *mw) +void uverbs_dealloc_mw (struct ib_mw *mw) {struct ib_pd *pd = mw->pd; -int ret; - ret = mw->device->ops.dealloc_mw (mw); -if (!ret) -atomic_dec (&pd->usecnt); -return ret; + mw->device->ops.dealloc_mw (mw); +atomic_dec (&pd->usecnt); +kfree (mw); }static void ib_uverbs_release_dev (struct device *device)
drivers/infiniband/core/uverbs_std_types.c +2 -1
@@ -72,7 +72,8 @@ static int uverbs_free_mw(struct ib_uobject *uobject, enum rdma_remove_reason why, struct uverbs_attr_bundle *attrs) { - return uverbs_dealloc_mw((struct ib_mw *)uobject->object); + uverbs_dealloc_mw((struct ib_mw *)uobject->object); +return 0 ; } static int uverbs_free_rwq_ind_tbl(struct ib_uobject *uobject,
drivers/infiniband/hw/cxgb4/iw_cxgb4.h +2 -3
@@ -983,10 +983,9 @@ struct ib_mr *c4iw_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type, u32 max_num_sg);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_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);
drivers/infiniband/hw/cxgb4/mem.c +12 -23
@@ -611,30 +611,23 @@ struct ib_mr *c4iw_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,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,12 +659,10 @@ struct ib_mw *c4iw_alloc_mw(struct ib_pd *pd, enum ib_mw_type type,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) +void c4iw_dealloc_mw (struct ib_mw *mw) {struct c4iw_dev *rhp;struct c4iw_mw *mhp;
@@ -684,9 +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 ; } struct ib_mr *c4iw_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type,
drivers/infiniband/hw/cxgb4/provider.c +3 -1
@@ -508,8 +508,10 @@ static const struct ib_device_ops c4iw_dev_ops = { .query_qp = c4iw_ib_query_qp, .reg_user_mr = c4iw_reg_user_mr, .req_notify_cq = c4iw_arm_cq, -INIT_RDMA_OBJ_SIZE (ib_pd, c4iw_pd, ibpd), +INIT_RDMA_OBJ_SIZE (ib_cq, c4iw_cq, ibcq), +INIT_RDMA_OBJ_SIZE (ib_mw, c4iw_mw, ibmw), +INIT_RDMA_OBJ_SIZE (ib_pd, c4iw_pd, ibpd),INIT_RDMA_OBJ_SIZE (ib_srq, c4iw_srq, ibsrq), INIT_RDMA_OBJ_SIZE(ib_ucontext, c4iw_ucontext, ibucontext), };
drivers/infiniband/hw/hns/hns_roce_device.h +2 -3
@@ -1201,9 +1201,8 @@ int hns_roce_hw_destroy_mpt(struct hns_roce_dev *hr_dev, unsigned long mpt_index);unsigned long key_to_hw_index (u32 key); -struct ib_mw *hns_roce_alloc_mw (struct ib_pd *pd,enum ib_mw_type , -struct ib_udata *udata); -int hns_roce_dealloc_mw (struct ib_mw *ibmw); +int hns_roce_alloc_mw (struct ib_mw *mw,struct ib_udata *udata); +void hns_roce_dealloc_mw (struct ib_mw *ibmw);void hns_roce_buf_free (struct hns_roce_dev *hr_dev,struct hns_roce_buf *buf); int hns_roce_buf_alloc(struct hns_roce_dev *hr_dev, u32 size, u32 max_direct,
drivers/infiniband/hw/hns/hns_roce_main.c +2 -0
@@ -454,6 +454,8 @@ static const struct ib_device_ops hns_roce_dev_mr_ops = {static const struct ib_device_ops hns_roce_dev_mw_ops = { .alloc_mw = hns_roce_alloc_mw, .dealloc_mw = hns_roce_dealloc_mw, + +INIT_RDMA_OBJ_SIZE (ib_mw, hns_roce_mw, ibmw), };static const struct ib_device_ops hns_roce_dev_frmr_ops = {
drivers/infiniband/hw/hns/hns_roce_mr.c +9 -22
@@ -589,28 +589,22 @@ static int hns_roce_mw_enable(struct hns_roce_dev *hr_dev,return ret; } -struct ib_mw *hns_roce_alloc_mw (struct ib_pd *ib_pd,enum ib_mw_type type, -struct ib_udata *udata) +int hns_roce_alloc_mw (struct ib_mw *ibmw,struct ib_udata *udata) { -struct hns_roce_dev *hr_dev =to_hr_dev (ib_pd->device); -struct hns_roce_mw *mw; +struct hns_roce_dev *hr_dev =to_hr_dev (ibmw->device); +struct hns_roce_mw *mw =to_hr_mw (ibmw);unsigned long index =0 ;int ret; - mw =kmalloc (sizeof (*mw),GFP_KERNEL ); -if (!mw) -return ERR_PTR (-ENOMEM ); -/* Allocate a key for mw from bitmap */ ret =hns_roce_bitmap_alloc (&hr_dev->mr_table.mtpt_bitmap, &index);if (ret) - goto err_bitmap; +return ret; mw->rkey =hw_index_to_key (index); - mw->ibmw.rkey = mw->rkey; - mw->ibmw.type = type; - mw->pdn =to_hr_pd (ib_pd)->pdn; + ibmw->rkey = mw->rkey; + mw->pdn =to_hr_pd (ibmw->pd)->pdn; mw->pbl_hop_num = hr_dev->caps.pbl_hop_num; mw->pbl_ba_pg_sz = hr_dev->caps.pbl_ba_pg_sz; mw->pbl_buf_pg_sz = hr_dev->caps.pbl_buf_pg_sz;
@@ -619,26 +613,19 @@ struct ib_mw *hns_roce_alloc_mw(struct ib_pd *ib_pd, enum ib_mw_type type,if (ret) goto err_mw; -return &mw->ibmw; +return 0 ; err_mw:hns_roce_mw_free (hr_dev, mw); - -err_bitmap: -kfree (mw); - -return ERR_PTR (ret); +return ret; } -int hns_roce_dealloc_mw (struct ib_mw *ibmw) +void hns_roce_dealloc_mw (struct ib_mw *ibmw) {struct hns_roce_dev *hr_dev =to_hr_dev (ibmw->device);struct hns_roce_mw *mw =to_hr_mw (ibmw);hns_roce_mw_free (hr_dev, mw); -kfree (mw); - -return 0 ; } static int mtr_map_region(struct hns_roce_dev *hr_dev, struct hns_roce_mtr *mtr,
drivers/infiniband/hw/mlx4/main.c +2 -0
@@ -2593,6 +2593,8 @@ static const struct ib_device_ops mlx4_ib_dev_wq_ops = {static const struct ib_device_ops mlx4_ib_dev_mw_ops = { .alloc_mw = mlx4_ib_alloc_mw, .dealloc_mw = mlx4_ib_dealloc_mw, + +INIT_RDMA_OBJ_SIZE (ib_mw, mlx4_ib_mw, ibmw), };static const struct ib_device_ops mlx4_ib_dev_xrc_ops = {
drivers/infiniband/hw/mlx4/mlx4_ib.h +2 -3
@@ -725,9 +725,8 @@ struct ib_mr *mlx4_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, u64 virt_addr, int access_flags, struct ib_udata *udata);int mlx4_ib_dereg_mr (struct ib_mr *mr,struct ib_udata *udata); -struct ib_mw *mlx4_ib_alloc_mw (struct ib_pd *pd,enum ib_mw_type type, -struct ib_udata *udata); -int mlx4_ib_dealloc_mw (struct ib_mw *mw); +int mlx4_ib_alloc_mw (struct ib_mw *mw,struct ib_udata *udata); +void mlx4_ib_dealloc_mw (struct ib_mw *mw);struct ib_mr *mlx4_ib_alloc_mr (struct ib_pd *pd,enum ib_mr_type mr_type,u32 max_num_sg); int mlx4_ib_map_mr_sg(struct ib_mr *ibmr, struct scatterlist *sg, int sg_nents,
drivers/infiniband/hw/mlx4/mr.c +10 -23
@@ -610,47 +610,34 @@ int mlx4_ib_dereg_mr(struct ib_mr *ibmr, struct ib_udata *udata)return 0 ; } -struct ib_mw *mlx4_ib_alloc_mw (struct ib_pd *pd,enum ib_mw_type type, -struct ib_udata *udata) +int mlx4_ib_alloc_mw (struct ib_mw *ibmw,struct ib_udata *udata) { -struct mlx4_ib_dev *dev =to_mdev (pd->device); -struct mlx4_ib_mw *mw; +struct mlx4_ib_dev *dev =to_mdev (ibmw->device); +struct mlx4_ib_mw *mw =to_mmw (ibmw);int err; - mw =kmalloc (sizeof (*mw),GFP_KERNEL ); -if (!mw) -return ERR_PTR (-ENOMEM ); - - err =mlx4_mw_alloc (dev->dev,to_mpd (pd)->pdn, -to_mlx4_type (type), &mw->mmw); + err =mlx4_mw_alloc (dev->dev,to_mpd (ibmw->pd)->pdn, +to_mlx4_type (ibmw->type), &mw->mmw);if (err) - goto err_free; +return err; err =mlx4_mw_enable (dev->dev, &mw->mmw);if (err) goto err_mw; - mw->ibmw.rkey = mw->mmw.key; - -return &mw->ibmw; + ibmw->rkey = mw->mmw.key; +return 0 ; err_mw:mlx4_mw_free (dev->dev, &mw->mmw); - -err_free: -kfree (mw); - -return ERR_PTR (err); +return err; } -int mlx4_ib_dealloc_mw (struct ib_mw *ibmw) +void mlx4_ib_dealloc_mw (struct ib_mw *ibmw) {struct mlx4_ib_mw *mw =to_mmw (ibmw);mlx4_mw_free (to_mdev (ibmw->device)->dev, &mw->mmw); -kfree (mw); - -return 0 ; } struct ib_mr *mlx4_ib_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type,
drivers/infiniband/hw/mlx5/main.c +2 -0
@@ -6666,6 +6666,8 @@ static const struct ib_device_ops mlx5_ib_dev_sriov_ops = {static const struct ib_device_ops mlx5_ib_dev_mw_ops = { .alloc_mw = mlx5_ib_alloc_mw, .dealloc_mw = mlx5_ib_dealloc_mw, + +INIT_RDMA_OBJ_SIZE (ib_mw, mlx5_ib_mw, ibmw), };static const struct ib_device_ops mlx5_ib_dev_xrc_ops = {
drivers/infiniband/hw/mlx5/mlx5_ib.h +2 -3
@@ -1195,9 +1195,8 @@ int mlx5_ib_advise_mr(struct ib_pd *pd,struct ib_sge *sg_list, u32 num_sge, struct uverbs_attr_bundle *attrs); -struct ib_mw *mlx5_ib_alloc_mw (struct ib_pd *pd,enum ib_mw_type type, -struct ib_udata *udata); -int mlx5_ib_dealloc_mw (struct ib_mw *mw); +int mlx5_ib_alloc_mw (struct ib_mw *mw,struct ib_udata *udata); +void mlx5_ib_dealloc_mw (struct ib_mw *mw);int mlx5_ib_update_xlt (struct mlx5_ib_mr *mr,u64 idx,int npages,int page_shift,int flags); struct mlx5_ib_mr *mlx5_ib_alloc_implicit_mr(struct mlx5_ib_pd *pd,
drivers/infiniband/hw/mlx5/mr.c +16 -26
109 lines not on this page · raw message
include/rdma/ib_verbs.h +3 -3
@@ -2490,9 +2490,8 @@ struct ib_device_ops { unsigned int *sg_offset);int (*check_mr_status)(struct ib_mr *mr,u32 check_mask,struct ib_mr_status *mr_status); -struct ib_mw *(*alloc_mw)(struct ib_pd *pd,enum ib_mw_type type, -struct ib_udata *udata); -int (*dealloc_mw)(struct ib_mw *mw); +int (*alloc_mw)(struct ib_mw *mw,struct ib_udata *udata); +void (*dealloc_mw)(struct ib_mw *mw);int (*attach_mcast)(struct ib_qp *qp,union ib_gid *gid,u16 lid);int (*detach_mcast)(struct ib_qp *qp,union ib_gid *gid,u16 lid);int (*alloc_xrcd)(struct ib_xrcd *xrcd,struct ib_udata *udata);
@@ -2652,6 +2651,7 @@ struct ib_device_ops {DECLARE_RDMA_OBJ_SIZE (ib_ah);DECLARE_RDMA_OBJ_SIZE (ib_counters);DECLARE_RDMA_OBJ_SIZE (ib_cq); +DECLARE_RDMA_OBJ_SIZE (ib_mw);DECLARE_RDMA_OBJ_SIZE (ib_pd);DECLARE_RDMA_OBJ_SIZE (ib_srq);DECLARE_RDMA_OBJ_SIZE (ib_ucontext);
--
2.26.2