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 |
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 --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);