diff mbox series

[RESEND,for-next] RDMA/hns: Restore mr status when rereg mr fails

Message ID 1629339948-32231-1-git-send-email-liangwenpeng@huawei.com (mailing list archive)
State Changes Requested
Delegated to: Jason Gunthorpe
Headers show
Series [RESEND,for-next] RDMA/hns: Restore mr status when rereg mr fails | expand

Commit Message

Wenpeng Liang Aug. 19, 2021, 2:25 a.m. UTC
From: Yangyang Li <liyangyang20@huawei.com>

If rereg_user_mr fails, mr needs to stay in a safe state. The mr state is
backed up when entering the rereg_user_mr function, and the mr state is
restored when the rereg fails.

Fixes: 4e9fc1dae2a9 ("RDMA/hns: Optimize the MR registration process")
Reported-by: Leon Romanovsky <leonro@nvidia.com>
Signed-off-by: Yangyang Li <liyangyang20@huawei.com>
Signed-off-by: YueHaibing <yuehaibing@huawei.com>
Signed-off-by: Wenpeng Liang <liangwenpeng@huawei.com>
---
 drivers/infiniband/hw/hns/hns_roce_mr.c | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

Comments

Jason Gunthorpe Aug. 19, 2021, 3:23 p.m. UTC | #1
On Thu, Aug 19, 2021 at 10:25:48AM +0800, Wenpeng Liang wrote:
> From: Yangyang Li <liyangyang20@huawei.com>
> 
> If rereg_user_mr fails, mr needs to stay in a safe state. The mr state is
> backed up when entering the rereg_user_mr function, and the mr state is
> restored when the rereg fails.
> 
> Fixes: 4e9fc1dae2a9 ("RDMA/hns: Optimize the MR registration process")
> Reported-by: Leon Romanovsky <leonro@nvidia.com>
> Signed-off-by: Yangyang Li <liyangyang20@huawei.com>
> Signed-off-by: YueHaibing <yuehaibing@huawei.com>
> Signed-off-by: Wenpeng Liang <liangwenpeng@huawei.com>
>  drivers/infiniband/hw/hns/hns_roce_mr.c | 28 ++++++++++++++++++++++++++++
>  1 file changed, 28 insertions(+)
> 
> diff --git a/drivers/infiniband/hw/hns/hns_roce_mr.c b/drivers/infiniband/hw/hns/hns_roce_mr.c
> index 006c84b..d0870b4 100644
> +++ b/drivers/infiniband/hw/hns/hns_roce_mr.c
> @@ -285,6 +285,27 @@ struct ib_mr *hns_roce_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
>  	return ERR_PTR(ret);
>  }
>  
> +static void copy_mr(struct hns_roce_mr *dst, struct hns_roce_mr *src)
> +{
> +	dst->enabled = src->enabled;
> +	dst->iova = src->iova;
> +	dst->size = src->size;
> +	dst->pd = src->pd;
> +	dst->access = src->access;
> +}
> +
> +static void store_rereg_mr(struct hns_roce_mr *mr_bak,
> +				  struct hns_roce_mr *mr)
> +{
> +	copy_mr(mr_bak, mr);
> +}
> +
> +static void restore_rereg_mr(struct hns_roce_mr *mr_bak,
> +				    struct hns_roce_mr *mr)
> +{
> +	copy_mr(mr, mr_bak);
> +}
> +
>  struct ib_mr *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,
> @@ -294,9 +315,12 @@ struct ib_mr *hns_roce_rereg_user_mr(struct ib_mr *ibmr, int flags, u64 start,
>  	struct ib_device *ib_dev = &hr_dev->ib_dev;
>  	struct hns_roce_mr *mr = to_hr_mr(ibmr);
>  	struct hns_roce_cmd_mailbox *mailbox;
> +	struct hns_roce_mr mr_bak;
>  	unsigned long mtpt_idx;
>  	int ret;
>  
> +	store_rereg_mr(&mr_bak, mr);
> +

Is this enough?

What state is the MR in once hns_roce_hw_destroy_mpt() was executed?

Jason
diff mbox series

Patch

diff --git a/drivers/infiniband/hw/hns/hns_roce_mr.c b/drivers/infiniband/hw/hns/hns_roce_mr.c
index 006c84b..d0870b4 100644
--- a/drivers/infiniband/hw/hns/hns_roce_mr.c
+++ b/drivers/infiniband/hw/hns/hns_roce_mr.c
@@ -285,6 +285,27 @@  struct ib_mr *hns_roce_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
 	return ERR_PTR(ret);
 }
 
+static void copy_mr(struct hns_roce_mr *dst, struct hns_roce_mr *src)
+{
+	dst->enabled = src->enabled;
+	dst->iova = src->iova;
+	dst->size = src->size;
+	dst->pd = src->pd;
+	dst->access = src->access;
+}
+
+static void store_rereg_mr(struct hns_roce_mr *mr_bak,
+				  struct hns_roce_mr *mr)
+{
+	copy_mr(mr_bak, mr);
+}
+
+static void restore_rereg_mr(struct hns_roce_mr *mr_bak,
+				    struct hns_roce_mr *mr)
+{
+	copy_mr(mr, mr_bak);
+}
+
 struct ib_mr *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,
@@ -294,9 +315,12 @@  struct ib_mr *hns_roce_rereg_user_mr(struct ib_mr *ibmr, int flags, u64 start,
 	struct ib_device *ib_dev = &hr_dev->ib_dev;
 	struct hns_roce_mr *mr = to_hr_mr(ibmr);
 	struct hns_roce_cmd_mailbox *mailbox;
+	struct hns_roce_mr mr_bak;
 	unsigned long mtpt_idx;
 	int ret;
 
+	store_rereg_mr(&mr_bak, mr);
+
 	if (!mr->enabled)
 		return ERR_PTR(-EINVAL);
 
@@ -349,7 +373,11 @@  struct ib_mr *hns_roce_rereg_user_mr(struct ib_mr *ibmr, int flags, u64 start,
 
 	mr->enabled = 1;
 
+	hns_roce_free_cmd_mailbox(hr_dev, mailbox);
+	return NULL;
+
 free_cmd_mbox:
+	restore_rereg_mr(&mr_bak, mr);
 	hns_roce_free_cmd_mailbox(hr_dev, mailbox);
 
 	return ERR_PTR(ret);