Skip to content

Commit 9b2cf76

Browse files
wangxi11jgunthorpe
authored andcommitted
RDMA/hns: Optimize PBL buffer allocation process
PBL table has its own implementation for multi-hop addressing currently, but for the hardware, all table's addressing use the same logic, there is no need to implement repeatedly. So optimize the PBL buffer allocation process by using the mtr's interfaces. Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Xi Wang <[email protected]> Signed-off-by: Lang Cheng <[email protected]> Signed-off-by: Weihang Li <[email protected]> Reported-by: kbuild test robot <[email protected]> Signed-off-by: Jason Gunthorpe <[email protected]>
1 parent 5ac55df commit 9b2cf76

File tree

4 files changed

+197
-669
lines changed

4 files changed

+197
-669
lines changed

drivers/infiniband/hw/hns/hns_roce_device.h

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -403,30 +403,17 @@ struct hns_roce_mw {
403403

404404
struct hns_roce_mr {
405405
struct ib_mr ibmr;
406-
struct ib_umem *umem;
407406
u64 iova; /* MR's virtual orignal addr */
408407
u64 size; /* Address range of MR */
409408
u32 key; /* Key of MR */
410409
u32 pd; /* PD num of MR */
411410
u32 access; /* Access permission of MR */
412-
u32 npages;
413411
int enabled; /* MR's active status */
414412
int type; /* MR's register type */
415-
u64 *pbl_buf; /* MR's PBL space */
416-
dma_addr_t pbl_dma_addr; /* MR's PBL space PA */
417-
u32 pbl_size; /* PA number in the PBL */
418-
u64 pbl_ba; /* page table address */
419-
u32 l0_chunk_last_num; /* L0 last number */
420-
u32 l1_chunk_last_num; /* L1 last number */
421-
u64 **pbl_bt_l2; /* PBL BT L2 */
422-
u64 **pbl_bt_l1; /* PBL BT L1 */
423-
u64 *pbl_bt_l0; /* PBL BT L0 */
424-
dma_addr_t *pbl_l2_dma_addr; /* PBL BT L2 dma addr */
425-
dma_addr_t *pbl_l1_dma_addr; /* PBL BT L1 dma addr */
426-
dma_addr_t pbl_l0_dma_addr; /* PBL BT L0 dma addr */
427-
u32 pbl_ba_pg_sz; /* BT chunk page size */
428-
u32 pbl_buf_pg_sz; /* buf chunk page size */
429413
u32 pbl_hop_num; /* multi-hop number */
414+
struct hns_roce_mtr pbl_mtr;
415+
u32 npages;
416+
dma_addr_t *page_list;
430417
};
431418

432419
struct hns_roce_mr_table {

drivers/infiniband/hw/hns/hns_roce_hw_v1.c

Lines changed: 14 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1099,7 +1099,6 @@ static int hns_roce_v1_dereg_mr(struct hns_roce_dev *hr_dev,
10991099
struct completion comp;
11001100
long end = HNS_ROCE_V1_FREE_MR_TIMEOUT_MSECS;
11011101
unsigned long start = jiffies;
1102-
int npages;
11031102
int ret = 0;
11041103

11051104
priv = (struct hns_roce_v1_priv *)hr_dev->priv;
@@ -1146,17 +1145,9 @@ static int hns_roce_v1_dereg_mr(struct hns_roce_dev *hr_dev,
11461145
dev_dbg(dev, "Free mr 0x%x use 0x%x us.\n",
11471146
mr->key, jiffies_to_usecs(jiffies) - jiffies_to_usecs(start));
11481147

1149-
if (mr->size != ~0ULL) {
1150-
npages = ib_umem_page_count(mr->umem);
1151-
dma_free_coherent(dev, npages * 8, mr->pbl_buf,
1152-
mr->pbl_dma_addr);
1153-
}
1154-
11551148
hns_roce_bitmap_free(&hr_dev->mr_table.mtpt_bitmap,
11561149
key_to_hw_index(mr->key), 0);
1157-
1158-
ib_umem_release(mr->umem);
1159-
1150+
hns_roce_mtr_destroy(hr_dev, &mr->pbl_mtr);
11601151
kfree(mr);
11611152

11621153
return ret;
@@ -1826,9 +1817,12 @@ static void hns_roce_v1_set_mtu(struct hns_roce_dev *hr_dev, u8 phy_port,
18261817
static int hns_roce_v1_write_mtpt(void *mb_buf, struct hns_roce_mr *mr,
18271818
unsigned long mtpt_idx)
18281819
{
1820+
struct hns_roce_dev *hr_dev = to_hr_dev(mr->ibmr.device);
1821+
u64 pages[HNS_ROCE_MAX_INNER_MTPT_NUM] = { 0 };
1822+
struct ib_device *ibdev = &hr_dev->ib_dev;
18291823
struct hns_roce_v1_mpt_entry *mpt_entry;
1830-
struct sg_dma_page_iter sg_iter;
1831-
u64 *pages;
1824+
dma_addr_t pbl_ba;
1825+
int count;
18321826
int i;
18331827

18341828
/* MPT filled into mailbox buf */
@@ -1878,22 +1872,15 @@ static int hns_roce_v1_write_mtpt(void *mb_buf, struct hns_roce_mr *mr,
18781872
if (mr->type == MR_TYPE_DMA)
18791873
return 0;
18801874

1881-
pages = (u64 *) __get_free_page(GFP_KERNEL);
1882-
if (!pages)
1883-
return -ENOMEM;
1884-
1885-
i = 0;
1886-
for_each_sg_dma_page(mr->umem->sg_head.sgl, &sg_iter, mr->umem->nmap, 0) {
1887-
pages[i] = ((u64)sg_page_iter_dma_address(&sg_iter)) >> 12;
1888-
1889-
/* Directly record to MTPT table firstly 7 entry */
1890-
if (i >= HNS_ROCE_MAX_INNER_MTPT_NUM)
1891-
break;
1892-
i++;
1875+
count = hns_roce_mtr_find(hr_dev, &mr->pbl_mtr, 0, pages,
1876+
ARRAY_SIZE(pages), &pbl_ba);
1877+
if (count < 1) {
1878+
ibdev_err(ibdev, "failed to find PBL mtr, count = %d.", count);
1879+
return -ENOBUFS;
18931880
}
18941881

18951882
/* Register user mr */
1896-
for (i = 0; i < HNS_ROCE_MAX_INNER_MTPT_NUM; i++) {
1883+
for (i = 0; i < count; i++) {
18971884
switch (i) {
18981885
case 0:
18991886
mpt_entry->pa0_l = cpu_to_le32((u32)(pages[i]));
@@ -1959,13 +1946,9 @@ static int hns_roce_v1_write_mtpt(void *mb_buf, struct hns_roce_mr *mr,
19591946
}
19601947
}
19611948

1962-
free_page((unsigned long) pages);
1963-
1964-
mpt_entry->pbl_addr_l = cpu_to_le32((u32)(mr->pbl_dma_addr));
1965-
1949+
mpt_entry->pbl_addr_l = cpu_to_le32(pbl_ba);
19661950
roce_set_field(mpt_entry->mpt_byte_12, MPT_BYTE_12_PBL_ADDR_H_M,
1967-
MPT_BYTE_12_PBL_ADDR_H_S,
1968-
((u32)(mr->pbl_dma_addr >> 32)));
1951+
MPT_BYTE_12_PBL_ADDR_H_S, upper_32_bits(pbl_ba));
19691952

19701953
return 0;
19711954
}

drivers/infiniband/hw/hns/hns_roce_hw_v2.c

Lines changed: 41 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ static void set_frmr_seg(struct hns_roce_v2_rc_send_wqe *rc_sq_wqe,
9595
{
9696
struct hns_roce_mr *mr = to_hr_mr(wr->mr);
9797
struct hns_roce_wqe_frmr_seg *fseg = wqe;
98+
u64 pbl_ba;
9899

99100
/* use ib_access_flags */
100101
roce_set_bit(rc_sq_wqe->byte_4, V2_RC_FRMR_WQE_BYTE_4_BIND_EN_S,
@@ -109,19 +110,20 @@ static void set_frmr_seg(struct hns_roce_v2_rc_send_wqe *rc_sq_wqe,
109110
wr->access & IB_ACCESS_LOCAL_WRITE ? 1 : 0);
110111

111112
/* Data structure reuse may lead to confusion */
112-
rc_sq_wqe->msg_len = cpu_to_le32(mr->pbl_ba & 0xffffffff);
113-
rc_sq_wqe->inv_key = cpu_to_le32(mr->pbl_ba >> 32);
113+
pbl_ba = mr->pbl_mtr.hem_cfg.root_ba;
114+
rc_sq_wqe->msg_len = cpu_to_le32(lower_32_bits(pbl_ba));
115+
rc_sq_wqe->inv_key = cpu_to_le32(upper_32_bits(pbl_ba));
114116

115117
rc_sq_wqe->byte_16 = cpu_to_le32(wr->mr->length & 0xffffffff);
116118
rc_sq_wqe->byte_20 = cpu_to_le32(wr->mr->length >> 32);
117119
rc_sq_wqe->rkey = cpu_to_le32(wr->key);
118120
rc_sq_wqe->va = cpu_to_le64(wr->mr->iova);
119121

120-
fseg->pbl_size = cpu_to_le32(mr->pbl_size);
122+
fseg->pbl_size = cpu_to_le32(mr->npages);
121123
roce_set_field(fseg->mode_buf_pg_sz,
122124
V2_RC_FRMR_WQE_BYTE_40_PBL_BUF_PG_SZ_M,
123125
V2_RC_FRMR_WQE_BYTE_40_PBL_BUF_PG_SZ_S,
124-
mr->pbl_buf_pg_sz + PG_SHIFT_OFFSET);
126+
to_hr_hw_page_shift(mr->pbl_mtr.hem_cfg.buf_pg_shift));
125127
roce_set_bit(fseg->mode_buf_pg_sz,
126128
V2_RC_FRMR_WQE_BYTE_40_BLK_MODE_S, 0);
127129
}
@@ -2439,32 +2441,30 @@ static int hns_roce_v2_set_mac(struct hns_roce_dev *hr_dev, u8 phy_port,
24392441
static int set_mtpt_pbl(struct hns_roce_v2_mpt_entry *mpt_entry,
24402442
struct hns_roce_mr *mr)
24412443
{
2442-
struct sg_dma_page_iter sg_iter;
2443-
u64 page_addr;
2444-
u64 *pages;
2445-
int i;
2444+
struct hns_roce_dev *hr_dev = to_hr_dev(mr->ibmr.device);
2445+
u64 pages[HNS_ROCE_V2_MAX_INNER_MTPT_NUM] = { 0 };
2446+
struct ib_device *ibdev = &hr_dev->ib_dev;
2447+
dma_addr_t pbl_ba;
2448+
int i, count;
24462449

2447-
mpt_entry->pbl_size = cpu_to_le32(mr->pbl_size);
2448-
mpt_entry->pbl_ba_l = cpu_to_le32(lower_32_bits(mr->pbl_ba >> 3));
2449-
roce_set_field(mpt_entry->byte_48_mode_ba,
2450-
V2_MPT_BYTE_48_PBL_BA_H_M, V2_MPT_BYTE_48_PBL_BA_H_S,
2451-
upper_32_bits(mr->pbl_ba >> 3));
2450+
count = hns_roce_mtr_find(hr_dev, &mr->pbl_mtr, 0, pages,
2451+
ARRAY_SIZE(pages), &pbl_ba);
2452+
if (count < 1) {
2453+
ibdev_err(ibdev, "failed to find PBL mtr, count = %d.\n",
2454+
count);
2455+
return -ENOBUFS;
2456+
}
24522457

2453-
pages = (u64 *)__get_free_page(GFP_KERNEL);
2454-
if (!pages)
2455-
return -ENOMEM;
2458+
/* Aligned to the hardware address access unit */
2459+
for (i = 0; i < count; i++)
2460+
pages[i] >>= 6;
24562461

2457-
i = 0;
2458-
for_each_sg_dma_page(mr->umem->sg_head.sgl, &sg_iter, mr->umem->nmap, 0) {
2459-
page_addr = sg_page_iter_dma_address(&sg_iter);
2460-
pages[i] = page_addr >> 6;
2462+
mpt_entry->pbl_size = cpu_to_le32(mr->npages);
2463+
mpt_entry->pbl_ba_l = cpu_to_le32(pbl_ba >> 3);
2464+
roce_set_field(mpt_entry->byte_48_mode_ba,
2465+
V2_MPT_BYTE_48_PBL_BA_H_M, V2_MPT_BYTE_48_PBL_BA_H_S,
2466+
upper_32_bits(pbl_ba >> 3));
24612467

2462-
/* Record the first 2 entry directly to MTPT table */
2463-
if (i >= HNS_ROCE_V2_MAX_INNER_MTPT_NUM - 1)
2464-
goto found;
2465-
i++;
2466-
}
2467-
found:
24682468
mpt_entry->pa0_l = cpu_to_le32(lower_32_bits(pages[0]));
24692469
roce_set_field(mpt_entry->byte_56_pa0_h, V2_MPT_BYTE_56_PA0_H_M,
24702470
V2_MPT_BYTE_56_PA0_H_S, upper_32_bits(pages[0]));
@@ -2475,9 +2475,7 @@ static int set_mtpt_pbl(struct hns_roce_v2_mpt_entry *mpt_entry,
24752475
roce_set_field(mpt_entry->byte_64_buf_pa1,
24762476
V2_MPT_BYTE_64_PBL_BUF_PG_SZ_M,
24772477
V2_MPT_BYTE_64_PBL_BUF_PG_SZ_S,
2478-
mr->pbl_buf_pg_sz + PG_SHIFT_OFFSET);
2479-
2480-
free_page((unsigned long)pages);
2478+
to_hr_hw_page_shift(mr->pbl_mtr.hem_cfg.buf_pg_shift));
24812479

24822480
return 0;
24832481
}
@@ -2499,7 +2497,7 @@ static int hns_roce_v2_write_mtpt(void *mb_buf, struct hns_roce_mr *mr,
24992497
roce_set_field(mpt_entry->byte_4_pd_hop_st,
25002498
V2_MPT_BYTE_4_PBL_BA_PG_SZ_M,
25012499
V2_MPT_BYTE_4_PBL_BA_PG_SZ_S,
2502-
mr->pbl_ba_pg_sz + PG_SHIFT_OFFSET);
2500+
to_hr_hw_page_shift(mr->pbl_mtr.hem_cfg.ba_pg_shift));
25032501
roce_set_field(mpt_entry->byte_4_pd_hop_st, V2_MPT_BYTE_4_PD_M,
25042502
V2_MPT_BYTE_4_PD_S, mr->pd);
25052503

@@ -2585,19 +2583,27 @@ static int hns_roce_v2_rereg_write_mtpt(struct hns_roce_dev *hr_dev,
25852583

25862584
static int hns_roce_v2_frmr_write_mtpt(void *mb_buf, struct hns_roce_mr *mr)
25872585
{
2586+
struct hns_roce_dev *hr_dev = to_hr_dev(mr->ibmr.device);
2587+
struct ib_device *ibdev = &hr_dev->ib_dev;
25882588
struct hns_roce_v2_mpt_entry *mpt_entry;
2589+
dma_addr_t pbl_ba = 0;
25892590

25902591
mpt_entry = mb_buf;
25912592
memset(mpt_entry, 0, sizeof(*mpt_entry));
25922593

2594+
if (hns_roce_mtr_find(hr_dev, &mr->pbl_mtr, 0, NULL, 0, &pbl_ba) < 0) {
2595+
ibdev_err(ibdev, "failed to find frmr mtr.\n");
2596+
return -ENOBUFS;
2597+
}
2598+
25932599
roce_set_field(mpt_entry->byte_4_pd_hop_st, V2_MPT_BYTE_4_MPT_ST_M,
25942600
V2_MPT_BYTE_4_MPT_ST_S, V2_MPT_ST_FREE);
25952601
roce_set_field(mpt_entry->byte_4_pd_hop_st, V2_MPT_BYTE_4_PBL_HOP_NUM_M,
25962602
V2_MPT_BYTE_4_PBL_HOP_NUM_S, 1);
25972603
roce_set_field(mpt_entry->byte_4_pd_hop_st,
25982604
V2_MPT_BYTE_4_PBL_BA_PG_SZ_M,
25992605
V2_MPT_BYTE_4_PBL_BA_PG_SZ_S,
2600-
mr->pbl_ba_pg_sz + PG_SHIFT_OFFSET);
2606+
to_hr_hw_page_shift(mr->pbl_mtr.hem_cfg.ba_pg_shift));
26012607
roce_set_field(mpt_entry->byte_4_pd_hop_st, V2_MPT_BYTE_4_PD_M,
26022608
V2_MPT_BYTE_4_PD_S, mr->pd);
26032609

@@ -2610,17 +2616,17 @@ static int hns_roce_v2_frmr_write_mtpt(void *mb_buf, struct hns_roce_mr *mr)
26102616
roce_set_bit(mpt_entry->byte_12_mw_pa, V2_MPT_BYTE_12_MR_MW_S, 0);
26112617
roce_set_bit(mpt_entry->byte_12_mw_pa, V2_MPT_BYTE_12_BPD_S, 1);
26122618

2613-
mpt_entry->pbl_size = cpu_to_le32(mr->pbl_size);
2619+
mpt_entry->pbl_size = cpu_to_le32(mr->npages);
26142620

2615-
mpt_entry->pbl_ba_l = cpu_to_le32(lower_32_bits(mr->pbl_ba >> 3));
2621+
mpt_entry->pbl_ba_l = cpu_to_le32(lower_32_bits(pbl_ba >> 3));
26162622
roce_set_field(mpt_entry->byte_48_mode_ba, V2_MPT_BYTE_48_PBL_BA_H_M,
26172623
V2_MPT_BYTE_48_PBL_BA_H_S,
2618-
upper_32_bits(mr->pbl_ba >> 3));
2624+
upper_32_bits(pbl_ba >> 3));
26192625

26202626
roce_set_field(mpt_entry->byte_64_buf_pa1,
26212627
V2_MPT_BYTE_64_PBL_BUF_PG_SZ_M,
26222628
V2_MPT_BYTE_64_PBL_BUF_PG_SZ_S,
2623-
mr->pbl_buf_pg_sz + PG_SHIFT_OFFSET);
2629+
to_hr_hw_page_shift(mr->pbl_mtr.hem_cfg.buf_pg_shift));
26242630

26252631
return 0;
26262632
}

0 commit comments

Comments
 (0)