Commit 3ee0e170 authored by Lijun Ou's avatar Lijun Ou Committed by Jason Gunthorpe
Browse files

RDMA/hns: Package for hns_roce_rereg_user_mr function

Move some code of the hns_roce_rereg_user_mr() function into an
independent function in oder to improve readability.

Link: https://lore.kernel.org/r/1562593285-8037-8-git-send-email-oulijun@huawei.com


Signed-off-by: default avatarLang Cheng <chenglang@huawei.com>
Signed-off-by: default avatarLijun Ou <oulijun@huawei.com>
Signed-off-by: default avatarJason Gunthorpe <jgg@mellanox.com>
parent 89b4b70b
Loading
Loading
Loading
Loading
+89 −64
Original line number Diff line number Diff line
@@ -1206,60 +1206,34 @@ err_free:
	return ERR_PTR(ret);
}

int hns_roce_rereg_user_mr(struct ib_mr *ibmr, int flags, u64 start, u64 length,
			   u64 virt_addr, int mr_access_flags, struct ib_pd *pd,
			   struct ib_udata *udata)
static int rereg_mr_trans(struct ib_mr *ibmr, int flags,
			  u64 start, u64 length,
			  u64 virt_addr, int mr_access_flags,
			  struct hns_roce_cmd_mailbox *mailbox,
			  u32 pdn, struct ib_udata *udata)
{
	struct hns_roce_dev *hr_dev = to_hr_dev(ibmr->device);
	struct hns_roce_mr *mr = to_hr_mr(ibmr);
	struct hns_roce_cmd_mailbox *mailbox;
	struct device *dev = hr_dev->dev;
	unsigned long mtpt_idx;
	u32 pdn = 0;
	int npages;
	int ret;

	if (!mr->enabled)
		return -EINVAL;

	mailbox = hns_roce_alloc_cmd_mailbox(hr_dev);
	if (IS_ERR(mailbox))
		return PTR_ERR(mailbox);

	mtpt_idx = key_to_hw_index(mr->key) & (hr_dev->caps.num_mtpts - 1);
	ret = hns_roce_cmd_mbox(hr_dev, 0, mailbox->dma, mtpt_idx, 0,
				HNS_ROCE_CMD_QUERY_MPT,
				HNS_ROCE_CMD_TIMEOUT_MSECS);
	if (ret)
		goto free_cmd_mbox;

	ret = hns_roce_hw2sw_mpt(hr_dev, NULL, mtpt_idx);
	if (ret)
		dev_warn(dev, "HW2SW_MPT failed (%d)\n", ret);

	mr->enabled = 0;

	if (flags & IB_MR_REREG_PD)
		pdn = to_hr_pd(pd)->pdn;

	if (flags & IB_MR_REREG_TRANS) {
	if (mr->size != ~0ULL) {
		npages = ib_umem_page_count(mr->umem);

		if (hr_dev->caps.pbl_hop_num)
			hns_roce_mhop_free(hr_dev, mr);
		else
				dma_free_coherent(dev, npages * 8, mr->pbl_buf,
						  mr->pbl_dma_addr);
			dma_free_coherent(dev, npages * 8,
					  mr->pbl_buf, mr->pbl_dma_addr);
	}
	ib_umem_release(mr->umem);

		mr->umem =
			ib_umem_get(udata, start, length, mr_access_flags, 0);
	mr->umem = ib_umem_get(udata, start, length, mr_access_flags, 0);
	if (IS_ERR(mr->umem)) {
		ret = PTR_ERR(mr->umem);
		mr->umem = NULL;
			goto free_cmd_mbox;
		return -ENOMEM;
	}
	npages = ib_umem_page_count(mr->umem);

@@ -1276,19 +1250,14 @@ int hns_roce_rereg_user_mr(struct ib_mr *ibmr, int flags, u64 start, u64 length,
			goto release_umem;
		}
	}
	}

	ret = hr_dev->hw->rereg_write_mtpt(hr_dev, mr, flags, pdn,
					   mr_access_flags, virt_addr,
					   length, mailbox->buf);
	if (ret) {
		if (flags & IB_MR_REREG_TRANS)
	if (ret)
		goto release_umem;
		else
			goto free_cmd_mbox;
	}

	if (flags & IB_MR_REREG_TRANS) {

	ret = hns_roce_ib_umem_write_mr(hr_dev, mr, mr->umem);
	if (ret) {
		if (mr->size != ~0ULL) {
@@ -1304,12 +1273,71 @@ int hns_roce_rereg_user_mr(struct ib_mr *ibmr, int flags, u64 start, u64 length,

		goto release_umem;
	}

	return 0;

release_umem:
	ib_umem_release(mr->umem);
	return ret;

}


int hns_roce_rereg_user_mr(struct ib_mr *ibmr, int flags, u64 start, u64 length,
			   u64 virt_addr, int mr_access_flags, struct ib_pd *pd,
			   struct ib_udata *udata)
{
	struct hns_roce_dev *hr_dev = to_hr_dev(ibmr->device);
	struct hns_roce_mr *mr = to_hr_mr(ibmr);
	struct hns_roce_cmd_mailbox *mailbox;
	struct device *dev = hr_dev->dev;
	unsigned long mtpt_idx;
	u32 pdn = 0;
	int ret;

	if (!mr->enabled)
		return -EINVAL;

	mailbox = hns_roce_alloc_cmd_mailbox(hr_dev);
	if (IS_ERR(mailbox))
		return PTR_ERR(mailbox);

	mtpt_idx = key_to_hw_index(mr->key) & (hr_dev->caps.num_mtpts - 1);
	ret = hns_roce_cmd_mbox(hr_dev, 0, mailbox->dma, mtpt_idx, 0,
				HNS_ROCE_CMD_QUERY_MPT,
				HNS_ROCE_CMD_TIMEOUT_MSECS);
	if (ret)
		goto free_cmd_mbox;

	ret = hns_roce_hw2sw_mpt(hr_dev, NULL, mtpt_idx);
	if (ret)
		dev_warn(dev, "HW2SW_MPT failed (%d)\n", ret);

	mr->enabled = 0;

	if (flags & IB_MR_REREG_PD)
		pdn = to_hr_pd(pd)->pdn;

	if (flags & IB_MR_REREG_TRANS) {
		ret = rereg_mr_trans(ibmr, flags,
				     start, length,
				     virt_addr, mr_access_flags,
				     mailbox, pdn, udata);
		if (ret)
			goto free_cmd_mbox;
	} else {
		ret = hr_dev->hw->rereg_write_mtpt(hr_dev, mr, flags, pdn,
						   mr_access_flags, virt_addr,
						   length, mailbox->buf);
		if (ret)
			goto free_cmd_mbox;
	}

	ret = hns_roce_sw2hw_mpt(hr_dev, mailbox, mtpt_idx);
	if (ret) {
		dev_err(dev, "SW2HW_MPT failed (%d)\n", ret);
		goto release_umem;
		ib_umem_release(mr->umem);
		goto free_cmd_mbox;
	}

	mr->enabled = 1;
@@ -1320,9 +1348,6 @@ int hns_roce_rereg_user_mr(struct ib_mr *ibmr, int flags, u64 start, u64 length,

	return 0;

release_umem:
	ib_umem_release(mr->umem);

free_cmd_mbox:
	hns_roce_free_cmd_mailbox(hr_dev, mailbox);