Skip to content

Commit 8d18ad8

Browse files
oulijundledford
authored andcommitted
RDMA/hns: Fix bug when wqe num is larger than 16K
hip08 can support up to 32768 wqes in one qp. currently if the wqe num is larger than 16384, the driver will lead a calltrace as follows. [21361.393725] Call trace: [21361.398605] hns_roce_v2_modify_qp+0xbcc/0x1360 [hns_roce_hw_v2] [21361.410627] hns_roce_modify_qp+0x1d8/0x2f8 [hns_roce] [21361.420906] _ib_modify_qp+0x70/0x118 [21361.428222] ib_modify_qp+0x14/0x1c [21361.435193] rt_ktest_modify_qp+0xb8/0x650 [rdma_test] [21361.445472] exec_modify_qp_cmd+0x110/0x4d8 [rdma_test] [21361.455924] rt_ktest_dispatch_cmd_3+0xa94/0x2edc [rdma_test] [21361.467422] rt_ktest_dispatch_cmd_2+0x9c/0x108 [rdma_test] [21361.478570] rt_ktest_dispatch_cmd+0x138/0x904 [rdma_test] [21361.489545] rt_ktest_dev_write+0x328/0x4b0 [rdma_test] [21361.499998] __vfs_write+0x38/0x15c [21361.506966] vfs_write+0xa8/0x1a0 [21361.513586] ksys_write+0x50/0xb0 [21361.520206] sys_write+0xc/0x14 [21361.526479] el0_svc_naked+0x30/0x34 [21361.533622] Code: 1ac10841 d37d7c22 0b000021 d37df021 (f86268c0) [21361.545815] ---[ end trace e2a1feb2c3d7f13c ]--- When the wqe num is larger than 16384, hns_roce_table_find will return an invalid mtt, this will lead an kernel paging requet error if the driver try to access it. It's the mtt design defect which can't support up to the max wqe num of hip08. This patch fixs it by replacing mtt with mtr for wqe. Fixes: 926a01d ("RDMA/hns: Add QP operations support for hip08 SoC") Signed-off-by: Xi Wang <[email protected]> Signed-off-by: Lijun Ou <[email protected]> Signed-off-by: Doug Ledford <[email protected]>
1 parent 2ac0bc5 commit 8d18ad8

File tree

3 files changed

+235
-83
lines changed

3 files changed

+235
-83
lines changed

drivers/infiniband/hw/hns/hns_roce_device.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -660,6 +660,14 @@ struct hns_roce_qp {
660660

661661
struct ib_umem *umem;
662662
struct hns_roce_mtt mtt;
663+
struct hns_roce_mtr mtr;
664+
665+
/* this define must less than HNS_ROCE_MAX_BT_REGION */
666+
#define HNS_ROCE_WQE_REGION_MAX 3
667+
struct hns_roce_buf_region regions[HNS_ROCE_WQE_REGION_MAX];
668+
int region_cnt;
669+
int wqe_bt_pg_shift;
670+
663671
u32 buff_size;
664672
struct mutex mutex;
665673
u8 port;
@@ -870,6 +878,9 @@ struct hns_roce_caps {
870878
u32 mtt_ba_pg_sz;
871879
u32 mtt_buf_pg_sz;
872880
u32 mtt_hop_num;
881+
u32 wqe_sq_hop_num;
882+
u32 wqe_sge_hop_num;
883+
u32 wqe_rq_hop_num;
873884
u32 sccc_ba_pg_sz;
874885
u32 sccc_buf_pg_sz;
875886
u32 sccc_hop_num;

drivers/infiniband/hw/hns/hns_roce_hw_v2.c

Lines changed: 77 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1574,6 +1574,9 @@ static int hns_roce_v2_profile(struct hns_roce_dev *hr_dev)
15741574
caps->mtt_ba_pg_sz = 0;
15751575
caps->mtt_buf_pg_sz = 0;
15761576
caps->mtt_hop_num = HNS_ROCE_MTT_HOP_NUM;
1577+
caps->wqe_sq_hop_num = 2;
1578+
caps->wqe_sge_hop_num = 1;
1579+
caps->wqe_rq_hop_num = 2;
15771580
caps->cqe_ba_pg_sz = 0;
15781581
caps->cqe_buf_pg_sz = 0;
15791582
caps->cqe_hop_num = HNS_ROCE_CQE_HOP_NUM;
@@ -3021,7 +3024,6 @@ static int hns_roce_v2_clear_hem(struct hns_roce_dev *hr_dev,
30213024
}
30223025

30233026
static int hns_roce_v2_qp_modify(struct hns_roce_dev *hr_dev,
3024-
struct hns_roce_mtt *mtt,
30253027
enum ib_qp_state cur_state,
30263028
enum ib_qp_state new_state,
30273029
struct hns_roce_v2_qp_context *context,
@@ -3517,6 +3519,31 @@ static void modify_qp_init_to_init(struct ib_qp *ibqp,
35173519
}
35183520
}
35193521

3522+
static bool check_wqe_rq_mtt_count(struct hns_roce_dev *hr_dev,
3523+
struct hns_roce_qp *hr_qp, int mtt_cnt,
3524+
u32 page_size)
3525+
{
3526+
struct device *dev = hr_dev->dev;
3527+
3528+
if (hr_qp->rq.wqe_cnt < 1)
3529+
return true;
3530+
3531+
if (mtt_cnt < 1) {
3532+
dev_err(dev, "qp(0x%lx) rqwqe buf ba find failed\n",
3533+
hr_qp->qpn);
3534+
return false;
3535+
}
3536+
3537+
if (mtt_cnt < MTT_MIN_COUNT &&
3538+
(hr_qp->rq.offset + page_size) < hr_qp->buff_size) {
3539+
dev_err(dev, "qp(0x%lx) next rqwqe buf ba find failed\n",
3540+
hr_qp->qpn);
3541+
return false;
3542+
}
3543+
3544+
return true;
3545+
}
3546+
35203547
static int modify_qp_init_to_rtr(struct ib_qp *ibqp,
35213548
const struct ib_qp_attr *attr, int attr_mask,
35223549
struct hns_roce_v2_qp_context *context,
@@ -3526,25 +3553,27 @@ static int modify_qp_init_to_rtr(struct ib_qp *ibqp,
35263553
struct hns_roce_dev *hr_dev = to_hr_dev(ibqp->device);
35273554
struct hns_roce_qp *hr_qp = to_hr_qp(ibqp);
35283555
struct device *dev = hr_dev->dev;
3556+
u64 mtts[MTT_MIN_COUNT] = { 0 };
35293557
dma_addr_t dma_handle_3;
35303558
dma_addr_t dma_handle_2;
3531-
dma_addr_t dma_handle;
3559+
u64 wqe_sge_ba;
35323560
u32 page_size;
35333561
u8 port_num;
35343562
u64 *mtts_3;
35353563
u64 *mtts_2;
3536-
u64 *mtts;
3564+
int count;
35373565
u8 *dmac;
35383566
u8 *smac;
35393567
int port;
35403568

35413569
/* Search qp buf's mtts */
3542-
mtts = hns_roce_table_find(hr_dev, &hr_dev->mr_table.mtt_table,
3543-
hr_qp->mtt.first_seg, &dma_handle);
3544-
if (!mtts) {
3545-
dev_err(dev, "qp buf pa find failed\n");
3546-
return -EINVAL;
3547-
}
3570+
page_size = 1 << (hr_dev->caps.mtt_buf_pg_sz + PAGE_SHIFT);
3571+
count = hns_roce_mtr_find(hr_dev, &hr_qp->mtr,
3572+
hr_qp->rq.offset / page_size, mtts,
3573+
MTT_MIN_COUNT, &wqe_sge_ba);
3574+
if (!ibqp->srq)
3575+
if (!check_wqe_rq_mtt_count(hr_dev, hr_qp, count, page_size))
3576+
return -EINVAL;
35483577

35493578
/* Search IRRL's mtts */
35503579
mtts_2 = hns_roce_table_find(hr_dev, &hr_dev->qp_table.irrl_table,
@@ -3568,7 +3597,7 @@ static int modify_qp_init_to_rtr(struct ib_qp *ibqp,
35683597
}
35693598

35703599
dmac = (u8 *)attr->ah_attr.roce.dmac;
3571-
context->wqe_sge_ba = (u32)(dma_handle >> 3);
3600+
context->wqe_sge_ba = (u32)(wqe_sge_ba >> 3);
35723601
qpc_mask->wqe_sge_ba = 0;
35733602

35743603
/*
@@ -3578,39 +3607,40 @@ static int modify_qp_init_to_rtr(struct ib_qp *ibqp,
35783607
* 0 at the same time, else set them to 0x1.
35793608
*/
35803609
roce_set_field(context->byte_12_sq_hop, V2_QPC_BYTE_12_WQE_SGE_BA_M,
3581-
V2_QPC_BYTE_12_WQE_SGE_BA_S, dma_handle >> (32 + 3));
3610+
V2_QPC_BYTE_12_WQE_SGE_BA_S, wqe_sge_ba >> (32 + 3));
35823611
roce_set_field(qpc_mask->byte_12_sq_hop, V2_QPC_BYTE_12_WQE_SGE_BA_M,
35833612
V2_QPC_BYTE_12_WQE_SGE_BA_S, 0);
35843613

35853614
roce_set_field(context->byte_12_sq_hop, V2_QPC_BYTE_12_SQ_HOP_NUM_M,
35863615
V2_QPC_BYTE_12_SQ_HOP_NUM_S,
3587-
hr_dev->caps.mtt_hop_num == HNS_ROCE_HOP_NUM_0 ?
3588-
0 : hr_dev->caps.mtt_hop_num);
3616+
hr_dev->caps.wqe_sq_hop_num == HNS_ROCE_HOP_NUM_0 ?
3617+
0 : hr_dev->caps.wqe_sq_hop_num);
35893618
roce_set_field(qpc_mask->byte_12_sq_hop, V2_QPC_BYTE_12_SQ_HOP_NUM_M,
35903619
V2_QPC_BYTE_12_SQ_HOP_NUM_S, 0);
35913620

35923621
roce_set_field(context->byte_20_smac_sgid_idx,
35933622
V2_QPC_BYTE_20_SGE_HOP_NUM_M,
35943623
V2_QPC_BYTE_20_SGE_HOP_NUM_S,
3595-
((ibqp->qp_type == IB_QPT_GSI) || hr_qp->sq.max_gs > 2) ?
3596-
hr_dev->caps.mtt_hop_num : 0);
3624+
((ibqp->qp_type == IB_QPT_GSI) ||
3625+
hr_qp->sq.max_gs > HNS_ROCE_V2_UC_RC_SGE_NUM_IN_WQE) ?
3626+
hr_dev->caps.wqe_sge_hop_num : 0);
35973627
roce_set_field(qpc_mask->byte_20_smac_sgid_idx,
35983628
V2_QPC_BYTE_20_SGE_HOP_NUM_M,
35993629
V2_QPC_BYTE_20_SGE_HOP_NUM_S, 0);
36003630

36013631
roce_set_field(context->byte_20_smac_sgid_idx,
36023632
V2_QPC_BYTE_20_RQ_HOP_NUM_M,
36033633
V2_QPC_BYTE_20_RQ_HOP_NUM_S,
3604-
hr_dev->caps.mtt_hop_num == HNS_ROCE_HOP_NUM_0 ?
3605-
0 : hr_dev->caps.mtt_hop_num);
3634+
hr_dev->caps.wqe_rq_hop_num == HNS_ROCE_HOP_NUM_0 ?
3635+
0 : hr_dev->caps.wqe_rq_hop_num);
36063636
roce_set_field(qpc_mask->byte_20_smac_sgid_idx,
36073637
V2_QPC_BYTE_20_RQ_HOP_NUM_M,
36083638
V2_QPC_BYTE_20_RQ_HOP_NUM_S, 0);
36093639

36103640
roce_set_field(context->byte_16_buf_ba_pg_sz,
36113641
V2_QPC_BYTE_16_WQE_SGE_BA_PG_SZ_M,
36123642
V2_QPC_BYTE_16_WQE_SGE_BA_PG_SZ_S,
3613-
hr_dev->caps.mtt_ba_pg_sz + PG_SHIFT_OFFSET);
3643+
hr_qp->wqe_bt_pg_shift + PG_SHIFT_OFFSET);
36143644
roce_set_field(qpc_mask->byte_16_buf_ba_pg_sz,
36153645
V2_QPC_BYTE_16_WQE_SGE_BA_PG_SZ_M,
36163646
V2_QPC_BYTE_16_WQE_SGE_BA_PG_SZ_S, 0);
@@ -3623,29 +3653,24 @@ static int modify_qp_init_to_rtr(struct ib_qp *ibqp,
36233653
V2_QPC_BYTE_16_WQE_SGE_BUF_PG_SZ_M,
36243654
V2_QPC_BYTE_16_WQE_SGE_BUF_PG_SZ_S, 0);
36253655

3626-
page_size = 1 << (hr_dev->caps.mtt_buf_pg_sz + PAGE_SHIFT);
3627-
context->rq_cur_blk_addr = (u32)(mtts[hr_qp->rq.offset / page_size]
3628-
>> PAGE_ADDR_SHIFT);
3656+
context->rq_cur_blk_addr = (u32)(mtts[0] >> PAGE_ADDR_SHIFT);
36293657
qpc_mask->rq_cur_blk_addr = 0;
36303658

36313659
roce_set_field(context->byte_92_srq_info,
36323660
V2_QPC_BYTE_92_RQ_CUR_BLK_ADDR_M,
36333661
V2_QPC_BYTE_92_RQ_CUR_BLK_ADDR_S,
3634-
mtts[hr_qp->rq.offset / page_size]
3635-
>> (32 + PAGE_ADDR_SHIFT));
3662+
mtts[0] >> (32 + PAGE_ADDR_SHIFT));
36363663
roce_set_field(qpc_mask->byte_92_srq_info,
36373664
V2_QPC_BYTE_92_RQ_CUR_BLK_ADDR_M,
36383665
V2_QPC_BYTE_92_RQ_CUR_BLK_ADDR_S, 0);
36393666

3640-
context->rq_nxt_blk_addr = (u32)(mtts[hr_qp->rq.offset / page_size + 1]
3641-
>> PAGE_ADDR_SHIFT);
3667+
context->rq_nxt_blk_addr = (u32)(mtts[1] >> PAGE_ADDR_SHIFT);
36423668
qpc_mask->rq_nxt_blk_addr = 0;
36433669

36443670
roce_set_field(context->byte_104_rq_sge,
36453671
V2_QPC_BYTE_104_RQ_NXT_BLK_ADDR_M,
36463672
V2_QPC_BYTE_104_RQ_NXT_BLK_ADDR_S,
3647-
mtts[hr_qp->rq.offset / page_size + 1]
3648-
>> (32 + PAGE_ADDR_SHIFT));
3673+
mtts[1] >> (32 + PAGE_ADDR_SHIFT));
36493674
roce_set_field(qpc_mask->byte_104_rq_sge,
36503675
V2_QPC_BYTE_104_RQ_NXT_BLK_ADDR_M,
36513676
V2_QPC_BYTE_104_RQ_NXT_BLK_ADDR_S, 0);
@@ -3773,18 +3798,30 @@ static int modify_qp_rtr_to_rts(struct ib_qp *ibqp,
37733798
struct hns_roce_dev *hr_dev = to_hr_dev(ibqp->device);
37743799
struct hns_roce_qp *hr_qp = to_hr_qp(ibqp);
37753800
struct device *dev = hr_dev->dev;
3776-
dma_addr_t dma_handle;
3801+
u64 sge_cur_blk = 0;
3802+
u64 sq_cur_blk = 0;
37773803
u32 page_size;
3778-
u64 *mtts;
3804+
int count;
37793805

37803806
/* Search qp buf's mtts */
3781-
mtts = hns_roce_table_find(hr_dev, &hr_dev->mr_table.mtt_table,
3782-
hr_qp->mtt.first_seg, &dma_handle);
3783-
if (!mtts) {
3784-
dev_err(dev, "qp buf pa find failed\n");
3807+
count = hns_roce_mtr_find(hr_dev, &hr_qp->mtr, 0, &sq_cur_blk, 1, NULL);
3808+
if (count < 1) {
3809+
dev_err(dev, "qp(0x%lx) buf pa find failed\n", hr_qp->qpn);
37853810
return -EINVAL;
37863811
}
37873812

3813+
if (hr_qp->sge.offset) {
3814+
page_size = 1 << (hr_dev->caps.mtt_buf_pg_sz + PAGE_SHIFT);
3815+
count = hns_roce_mtr_find(hr_dev, &hr_qp->mtr,
3816+
hr_qp->sge.offset / page_size,
3817+
&sge_cur_blk, 1, NULL);
3818+
if (count < 1) {
3819+
dev_err(dev, "qp(0x%lx) sge pa find failed\n",
3820+
hr_qp->qpn);
3821+
return -EINVAL;
3822+
}
3823+
}
3824+
37883825
/* Not support alternate path and path migration */
37893826
if ((attr_mask & IB_QP_ALT_PATH) ||
37903827
(attr_mask & IB_QP_PATH_MIG_STATE)) {
@@ -3798,38 +3835,37 @@ static int modify_qp_rtr_to_rts(struct ib_qp *ibqp,
37983835
* we should set all bits of the relevant fields in context mask to
37993836
* 0 at the same time, else set them to 0x1.
38003837
*/
3801-
context->sq_cur_blk_addr = (u32)(mtts[0] >> PAGE_ADDR_SHIFT);
3838+
context->sq_cur_blk_addr = (u32)(sq_cur_blk >> PAGE_ADDR_SHIFT);
38023839
roce_set_field(context->byte_168_irrl_idx,
38033840
V2_QPC_BYTE_168_SQ_CUR_BLK_ADDR_M,
38043841
V2_QPC_BYTE_168_SQ_CUR_BLK_ADDR_S,
3805-
mtts[0] >> (32 + PAGE_ADDR_SHIFT));
3842+
sq_cur_blk >> (32 + PAGE_ADDR_SHIFT));
38063843
qpc_mask->sq_cur_blk_addr = 0;
38073844
roce_set_field(qpc_mask->byte_168_irrl_idx,
38083845
V2_QPC_BYTE_168_SQ_CUR_BLK_ADDR_M,
38093846
V2_QPC_BYTE_168_SQ_CUR_BLK_ADDR_S, 0);
38103847

3811-
page_size = 1 << (hr_dev->caps.mtt_buf_pg_sz + PAGE_SHIFT);
38123848
context->sq_cur_sge_blk_addr = ((ibqp->qp_type == IB_QPT_GSI) ||
38133849
hr_qp->sq.max_gs > HNS_ROCE_V2_UC_RC_SGE_NUM_IN_WQE) ?
3814-
((u32)(mtts[hr_qp->sge.offset / page_size] >>
3850+
((u32)(sge_cur_blk >>
38153851
PAGE_ADDR_SHIFT)) : 0;
38163852
roce_set_field(context->byte_184_irrl_idx,
38173853
V2_QPC_BYTE_184_SQ_CUR_SGE_BLK_ADDR_M,
38183854
V2_QPC_BYTE_184_SQ_CUR_SGE_BLK_ADDR_S,
38193855
((ibqp->qp_type == IB_QPT_GSI) || hr_qp->sq.max_gs >
38203856
HNS_ROCE_V2_UC_RC_SGE_NUM_IN_WQE) ?
3821-
(mtts[hr_qp->sge.offset / page_size] >>
3857+
(sge_cur_blk >>
38223858
(32 + PAGE_ADDR_SHIFT)) : 0);
38233859
qpc_mask->sq_cur_sge_blk_addr = 0;
38243860
roce_set_field(qpc_mask->byte_184_irrl_idx,
38253861
V2_QPC_BYTE_184_SQ_CUR_SGE_BLK_ADDR_M,
38263862
V2_QPC_BYTE_184_SQ_CUR_SGE_BLK_ADDR_S, 0);
38273863

3828-
context->rx_sq_cur_blk_addr = (u32)(mtts[0] >> PAGE_ADDR_SHIFT);
3864+
context->rx_sq_cur_blk_addr = (u32)(sq_cur_blk >> PAGE_ADDR_SHIFT);
38293865
roce_set_field(context->byte_232_irrl_sge,
38303866
V2_QPC_BYTE_232_RX_SQ_CUR_BLK_ADDR_M,
38313867
V2_QPC_BYTE_232_RX_SQ_CUR_BLK_ADDR_S,
3832-
mtts[0] >> (32 + PAGE_ADDR_SHIFT));
3868+
sq_cur_blk >> (32 + PAGE_ADDR_SHIFT));
38333869
qpc_mask->rx_sq_cur_blk_addr = 0;
38343870
roce_set_field(qpc_mask->byte_232_irrl_sge,
38353871
V2_QPC_BYTE_232_RX_SQ_CUR_BLK_ADDR_M,
@@ -4230,7 +4266,7 @@ static int hns_roce_v2_modify_qp(struct ib_qp *ibqp,
42304266
V2_QPC_BYTE_60_QP_ST_S, 0);
42314267

42324268
/* SW pass context to HW */
4233-
ret = hns_roce_v2_qp_modify(hr_dev, &hr_qp->mtt, cur_state, new_state,
4269+
ret = hns_roce_v2_qp_modify(hr_dev, cur_state, new_state,
42344270
context, hr_qp);
42354271
if (ret) {
42364272
dev_err(dev, "hns_roce_qp_modify failed(%d)\n", ret);

0 commit comments

Comments
 (0)