Commit 98a61519 authored by Yangyang Li's avatar Yangyang Li Committed by Jason Gunthorpe

RDMA/hns: Fix a calltrace when registering MR from userspace

ibmr.device is assigned after MR is successfully registered, but both
write_mtpt() and frmr_write_mtpt() accesses it during the mr registration
process, which may cause the following error when trying to register MR in
userspace and pbl_hop_num is set to 0.

  pc : hns_roce_mtr_find+0xa0/0x200 [hns_roce]
  lr : set_mtpt_pbl+0x54/0x118 [hns_roce_hw_v2]
  sp : ffff00023e73ba20
  x29: ffff00023e73ba20 x28: ffff00023e73bad8
  x27: 0000000000000000 x26: 0000000000000000
  x25: 0000000000000002 x24: 0000000000000000
  x23: ffff00023e73bad0 x22: 0000000000000000
  x21: ffff0000094d9000 x20: 0000000000000000
  x19: ffff8020a6bdb2c0 x18: 0000000000000000
  x17: 0000000000000000 x16: 0000000000000000
  x15: 0000000000000000 x14: 0000000000000000
  x13: 0140000000000000 x12: 0040000000000041
  x11: ffff000240000000 x10: 0000000000001000
  x9 : 0000000000000000 x8 : ffff802fb7558480
  x7 : ffff802fb7558480 x6 : 000000000003483d
  x5 : ffff00023e73bad0 x4 : 0000000000000002
  x3 : ffff00023e73bad8 x2 : 0000000000000000
  x1 : 0000000000000000 x0 : ffff0000094d9708
  Call trace:
   hns_roce_mtr_find+0xa0/0x200 [hns_roce]
   set_mtpt_pbl+0x54/0x118 [hns_roce_hw_v2]
   hns_roce_v2_write_mtpt+0x14c/0x168 [hns_roce_hw_v2]
   hns_roce_mr_enable+0x6c/0x148 [hns_roce]
   hns_roce_reg_user_mr+0xd8/0x130 [hns_roce]
   ib_uverbs_reg_mr+0x14c/0x2e0 [ib_uverbs]
   ib_uverbs_write+0x27c/0x3e8 [ib_uverbs]
   __vfs_write+0x60/0x190
   vfs_write+0xac/0x1c0
   ksys_write+0x6c/0xd8
   __arm64_sys_write+0x24/0x30
   el0_svc_common+0x78/0x130
   el0_svc_handler+0x38/0x78
   el0_svc+0x8/0xc

Solve above issue by adding a pointer of structure hns_roce_dev as a
parameter of write_mtpt() and frmr_write_mtpt(), so that both of these
functions can access it before finishing MR's registration.

Fixes: 9b2cf76c ("RDMA/hns: Optimize PBL buffer allocation process")
Link: https://lore.kernel.org/r/1592314629-51715-1-git-send-email-liweihang@huawei.comSigned-off-by: default avatarYangyang Li <liyangyang20@huawei.com>
Signed-off-by: default avatarWeihang Li <liweihang@huawei.com>
Signed-off-by: default avatarJason Gunthorpe <jgg@mellanox.com>
parent ab183d46
...@@ -898,13 +898,14 @@ struct hns_roce_hw { ...@@ -898,13 +898,14 @@ struct hns_roce_hw {
int (*set_mac)(struct hns_roce_dev *hr_dev, u8 phy_port, u8 *addr); int (*set_mac)(struct hns_roce_dev *hr_dev, u8 phy_port, u8 *addr);
void (*set_mtu)(struct hns_roce_dev *hr_dev, u8 phy_port, void (*set_mtu)(struct hns_roce_dev *hr_dev, u8 phy_port,
enum ib_mtu mtu); enum ib_mtu mtu);
int (*write_mtpt)(void *mb_buf, struct hns_roce_mr *mr, int (*write_mtpt)(struct hns_roce_dev *hr_dev, void *mb_buf,
unsigned long mtpt_idx); struct hns_roce_mr *mr, unsigned long mtpt_idx);
int (*rereg_write_mtpt)(struct hns_roce_dev *hr_dev, int (*rereg_write_mtpt)(struct hns_roce_dev *hr_dev,
struct hns_roce_mr *mr, int flags, u32 pdn, struct hns_roce_mr *mr, int flags, u32 pdn,
int mr_access_flags, u64 iova, u64 size, int mr_access_flags, u64 iova, u64 size,
void *mb_buf); void *mb_buf);
int (*frmr_write_mtpt)(void *mb_buf, struct hns_roce_mr *mr); int (*frmr_write_mtpt)(struct hns_roce_dev *hr_dev, void *mb_buf,
struct hns_roce_mr *mr);
int (*mw_write_mtpt)(void *mb_buf, struct hns_roce_mw *mw); int (*mw_write_mtpt)(void *mb_buf, struct hns_roce_mw *mw);
void (*write_cqc)(struct hns_roce_dev *hr_dev, void (*write_cqc)(struct hns_roce_dev *hr_dev,
struct hns_roce_cq *hr_cq, void *mb_buf, u64 *mtts, struct hns_roce_cq *hr_cq, void *mb_buf, u64 *mtts,
......
...@@ -1756,10 +1756,10 @@ static void hns_roce_v1_set_mtu(struct hns_roce_dev *hr_dev, u8 phy_port, ...@@ -1756,10 +1756,10 @@ static void hns_roce_v1_set_mtu(struct hns_roce_dev *hr_dev, u8 phy_port,
val); val);
} }
static int hns_roce_v1_write_mtpt(void *mb_buf, struct hns_roce_mr *mr, static int hns_roce_v1_write_mtpt(struct hns_roce_dev *hr_dev, void *mb_buf,
struct hns_roce_mr *mr,
unsigned long mtpt_idx) unsigned long mtpt_idx)
{ {
struct hns_roce_dev *hr_dev = to_hr_dev(mr->ibmr.device);
u64 pages[HNS_ROCE_MAX_INNER_MTPT_NUM] = { 0 }; u64 pages[HNS_ROCE_MAX_INNER_MTPT_NUM] = { 0 };
struct ib_device *ibdev = &hr_dev->ib_dev; struct ib_device *ibdev = &hr_dev->ib_dev;
struct hns_roce_v1_mpt_entry *mpt_entry; struct hns_roce_v1_mpt_entry *mpt_entry;
......
...@@ -2529,10 +2529,10 @@ static int hns_roce_v2_set_mac(struct hns_roce_dev *hr_dev, u8 phy_port, ...@@ -2529,10 +2529,10 @@ static int hns_roce_v2_set_mac(struct hns_roce_dev *hr_dev, u8 phy_port,
return hns_roce_cmq_send(hr_dev, &desc, 1); return hns_roce_cmq_send(hr_dev, &desc, 1);
} }
static int set_mtpt_pbl(struct hns_roce_v2_mpt_entry *mpt_entry, static int set_mtpt_pbl(struct hns_roce_dev *hr_dev,
struct hns_roce_v2_mpt_entry *mpt_entry,
struct hns_roce_mr *mr) struct hns_roce_mr *mr)
{ {
struct hns_roce_dev *hr_dev = to_hr_dev(mr->ibmr.device);
u64 pages[HNS_ROCE_V2_MAX_INNER_MTPT_NUM] = { 0 }; u64 pages[HNS_ROCE_V2_MAX_INNER_MTPT_NUM] = { 0 };
struct ib_device *ibdev = &hr_dev->ib_dev; struct ib_device *ibdev = &hr_dev->ib_dev;
dma_addr_t pbl_ba; dma_addr_t pbl_ba;
...@@ -2571,7 +2571,8 @@ static int set_mtpt_pbl(struct hns_roce_v2_mpt_entry *mpt_entry, ...@@ -2571,7 +2571,8 @@ static int set_mtpt_pbl(struct hns_roce_v2_mpt_entry *mpt_entry,
return 0; return 0;
} }
static int hns_roce_v2_write_mtpt(void *mb_buf, struct hns_roce_mr *mr, static int hns_roce_v2_write_mtpt(struct hns_roce_dev *hr_dev,
void *mb_buf, struct hns_roce_mr *mr,
unsigned long mtpt_idx) unsigned long mtpt_idx)
{ {
struct hns_roce_v2_mpt_entry *mpt_entry; struct hns_roce_v2_mpt_entry *mpt_entry;
...@@ -2620,7 +2621,7 @@ static int hns_roce_v2_write_mtpt(void *mb_buf, struct hns_roce_mr *mr, ...@@ -2620,7 +2621,7 @@ static int hns_roce_v2_write_mtpt(void *mb_buf, struct hns_roce_mr *mr,
if (mr->type == MR_TYPE_DMA) if (mr->type == MR_TYPE_DMA)
return 0; return 0;
ret = set_mtpt_pbl(mpt_entry, mr); ret = set_mtpt_pbl(hr_dev, mpt_entry, mr);
return ret; return ret;
} }
...@@ -2666,15 +2667,15 @@ static int hns_roce_v2_rereg_write_mtpt(struct hns_roce_dev *hr_dev, ...@@ -2666,15 +2667,15 @@ static int hns_roce_v2_rereg_write_mtpt(struct hns_roce_dev *hr_dev,
mr->iova = iova; mr->iova = iova;
mr->size = size; mr->size = size;
ret = set_mtpt_pbl(mpt_entry, mr); ret = set_mtpt_pbl(hr_dev, mpt_entry, mr);
} }
return ret; return ret;
} }
static int hns_roce_v2_frmr_write_mtpt(void *mb_buf, struct hns_roce_mr *mr) static int hns_roce_v2_frmr_write_mtpt(struct hns_roce_dev *hr_dev,
void *mb_buf, struct hns_roce_mr *mr)
{ {
struct hns_roce_dev *hr_dev = to_hr_dev(mr->ibmr.device);
struct ib_device *ibdev = &hr_dev->ib_dev; struct ib_device *ibdev = &hr_dev->ib_dev;
struct hns_roce_v2_mpt_entry *mpt_entry; struct hns_roce_v2_mpt_entry *mpt_entry;
dma_addr_t pbl_ba = 0; dma_addr_t pbl_ba = 0;
......
...@@ -180,9 +180,10 @@ static int hns_roce_mr_enable(struct hns_roce_dev *hr_dev, ...@@ -180,9 +180,10 @@ static int hns_roce_mr_enable(struct hns_roce_dev *hr_dev,
} }
if (mr->type != MR_TYPE_FRMR) if (mr->type != MR_TYPE_FRMR)
ret = hr_dev->hw->write_mtpt(mailbox->buf, mr, mtpt_idx); ret = hr_dev->hw->write_mtpt(hr_dev, mailbox->buf, mr,
mtpt_idx);
else else
ret = hr_dev->hw->frmr_write_mtpt(mailbox->buf, mr); ret = hr_dev->hw->frmr_write_mtpt(hr_dev, mailbox->buf, mr);
if (ret) { if (ret) {
dev_err(dev, "Write mtpt fail!\n"); dev_err(dev, "Write mtpt fail!\n");
goto err_page; goto err_page;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment