提交 ef5c5d4e 编写于 作者: W Weihang Li 提交者: Xie XiuQi

RDMA/hns: reserve one sge in order to avoid local length error

driver inclusion
category: bugfix
bugzilla: NA
CVE: NA

When rq/srq sge length is smaller than sq sge length, local length error
would occur. Then, for rq wqe and srq wqe, one reserved sge pointing to
a reserved mr is used to avoid this error.

Feature or Bugfix: Bugfix
Signed-off-by: NWeihang Li <liweihang@hisilicon.com>
Reviewed-by: Nliuyixian <liuyixian@huawei.com>
Reviewed-by: NYang Yingliang <yangyingliang@huawei.com>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
上级 e77793f5
...@@ -73,6 +73,8 @@ ...@@ -73,6 +73,8 @@
#define HNS_ROCE_WORKQ_NAME_LEN 32 #define HNS_ROCE_WORKQ_NAME_LEN 32
#define HNS_ROCE_RESERVED_SGE 1
#define HNS_ROCE_MAX_IRQ_NUM 128 #define HNS_ROCE_MAX_IRQ_NUM 128
#define HNS_ROCE_SGE_IN_WQE 2 #define HNS_ROCE_SGE_IN_WQE 2
......
...@@ -769,8 +769,8 @@ static int hns_roce_v2_post_recv(struct ib_qp *ibqp, struct ib_recv_wr *wr, ...@@ -769,8 +769,8 @@ static int hns_roce_v2_post_recv(struct ib_qp *ibqp, struct ib_recv_wr *wr,
goto out; goto out;
} }
if (unlikely(wr->num_sge > hr_qp->rq.max_gs)) { if (unlikely(wr->num_sge >= hr_qp->rq.max_gs)) {
dev_err(dev, "rq:num_sge=%d > qp->rq.max_gs=%d\n", dev_err(dev, "rq:num_sge=%d >= qp->rq.max_gs=%d\n",
wr->num_sge, hr_qp->rq.max_gs); wr->num_sge, hr_qp->rq.max_gs);
ret = -EINVAL; ret = -EINVAL;
*bad_wr = wr; *bad_wr = wr;
...@@ -786,9 +786,10 @@ static int hns_roce_v2_post_recv(struct ib_qp *ibqp, struct ib_recv_wr *wr, ...@@ -786,9 +786,10 @@ static int hns_roce_v2_post_recv(struct ib_qp *ibqp, struct ib_recv_wr *wr,
dseg++; dseg++;
} }
if (i < hr_qp->rq.max_gs) { if (wr->num_sge < hr_qp->rq.max_gs) {
dseg->lkey = cpu_to_le32(HNS_ROCE_INVALID_LKEY); dseg->lkey = cpu_to_le32(HNS_ROCE_INVALID_LKEY);
dseg->addr = 0; dseg->addr = 0;
dseg->len = HNS_ROCE_INVALID_SGE_LENGTH;
} }
/* rq support inline data */ /* rq support inline data */
...@@ -6794,7 +6795,7 @@ static int hns_roce_v2_post_srq_recv(struct ib_srq *ibsrq, ...@@ -6794,7 +6795,7 @@ static int hns_roce_v2_post_srq_recv(struct ib_srq *ibsrq,
ind = srq->head & (srq->max - 1); ind = srq->head & (srq->max - 1);
for (nreq = 0; wr; ++nreq, wr = wr->next) { for (nreq = 0; wr; ++nreq, wr = wr->next) {
if (unlikely(wr->num_sge > srq->max_gs)) { if (unlikely(wr->num_sge >= srq->max_gs)) {
dev_err(hr_dev->dev, dev_err(hr_dev->dev,
"srq(0x%lx) wr sge num(%d) exceed the max num %d.\n", "srq(0x%lx) wr sge num(%d) exceed the max num %d.\n",
srq->srqn, wr->num_sge, srq->max_gs); srq->srqn, wr->num_sge, srq->max_gs);
...@@ -6822,10 +6823,10 @@ static int hns_roce_v2_post_srq_recv(struct ib_srq *ibsrq, ...@@ -6822,10 +6823,10 @@ static int hns_roce_v2_post_srq_recv(struct ib_srq *ibsrq,
dseg[i].addr = cpu_to_le64(wr->sg_list[i].addr); dseg[i].addr = cpu_to_le64(wr->sg_list[i].addr);
} }
if (i < srq->max_gs) { if (wr->num_sge < srq->max_gs) {
dseg[i].len = 0; dseg[i].len = cpu_to_le32(HNS_ROCE_INVALID_SGE_LENGTH);
dseg[i].lkey = cpu_to_le32(0x100); dseg[i].lkey = cpu_to_le32(HNS_ROCE_INVALID_LKEY);
dseg[i].addr = 0; dseg[i].addr = 0;
} }
srq->wrid[wqe_idx] = wr->wr_id; srq->wrid[wqe_idx] = wr->wr_id;
......
...@@ -53,15 +53,16 @@ ...@@ -53,15 +53,16 @@
#define HNS_ROCE_V2_MAX_WQE_NUM 0x8000 #define HNS_ROCE_V2_MAX_WQE_NUM 0x8000
#define HNS_ROCE_V2_MAX_SRQ 0x100000 #define HNS_ROCE_V2_MAX_SRQ 0x100000
#define HNS_ROCE_V2_MAX_SRQ_WR 0x8000 #define HNS_ROCE_V2_MAX_SRQ_WR 0x8000
#define HNS_ROCE_V2_MAX_SRQ_SGE 0x100 #define HNS_ROCE_V2_MAX_SRQ_SGE 0xff
#define HNS_ROCE_V2_MAX_CQ_NUM 0x100000 #define HNS_ROCE_V2_MAX_CQ_NUM 0x100000
#define HNS_ROCE_V2_MAX_CQC_TIMER_NUM 0x100 #define HNS_ROCE_V2_MAX_CQC_TIMER_NUM 0x100
#define HNS_ROCE_V2_MAX_SRQ_NUM 0x100000 #define HNS_ROCE_V2_MAX_SRQ_NUM 0x100000
#define HNS_ROCE_V2_MAX_CQE_NUM 0x400000 #define HNS_ROCE_V2_MAX_CQE_NUM 0x400000
#define HNS_ROCE_V2_MAX_SRQWQE_NUM 0x8000 #define HNS_ROCE_V2_MAX_SRQWQE_NUM 0x8000
#define HNS_ROCE_V2_MAX_RQ_SGE_NUM 0x100 /* reserve one sge to circumvent a hardware issue */
#define HNS_ROCE_V2_MAX_RQ_SGE_NUM 0xff
#define HNS_ROCE_V2_MAX_SQ_SGE_NUM 0xff #define HNS_ROCE_V2_MAX_SQ_SGE_NUM 0xff
#define HNS_ROCE_V2_MAX_SRQ_SGE_NUM 0x100 #define HNS_ROCE_V2_MAX_SRQ_SGE_NUM 0xff
#define HNS_ROCE_V2_MAX_EXTEND_SGE_NUM 0x200000 #define HNS_ROCE_V2_MAX_EXTEND_SGE_NUM 0x200000
#define HNS_ROCE_V2_MAX_SQ_INLINE 0x20 #define HNS_ROCE_V2_MAX_SQ_INLINE 0x20
#define HNS_ROCE_V2_UAR_NUM 256 #define HNS_ROCE_V2_UAR_NUM 256
...@@ -97,7 +98,8 @@ ...@@ -97,7 +98,8 @@
#define HNS_ROCE_V2_CQC_TIMER_ENTRY_SZ 4096 #define HNS_ROCE_V2_CQC_TIMER_ENTRY_SZ 4096
#define HNS_ROCE_V2_PAGE_SIZE_SUPPORTED 0xFFFFF000 #define HNS_ROCE_V2_PAGE_SIZE_SUPPORTED 0xFFFFF000
#define HNS_ROCE_V2_MAX_INNER_MTPT_NUM 2 #define HNS_ROCE_V2_MAX_INNER_MTPT_NUM 2
#define HNS_ROCE_INVALID_LKEY 0x100 #define HNS_ROCE_INVALID_LKEY 0x0
#define HNS_ROCE_INVALID_SGE_LENGTH 0x80000000
#define HNS_ROCE_CMQ_TX_TIMEOUT 30000 #define HNS_ROCE_CMQ_TX_TIMEOUT 30000
#define HNS_ROCE_V2_UC_RC_SGE_NUM_IN_WQE 2 #define HNS_ROCE_V2_UC_RC_SGE_NUM_IN_WQE 2
#define HNS_ROCE_V2_RSV_QPS 8 #define HNS_ROCE_V2_RSV_QPS 8
......
...@@ -382,7 +382,8 @@ static int hns_roce_set_rq_size(struct hns_roce_dev *hr_dev, ...@@ -382,7 +382,8 @@ static int hns_roce_set_rq_size(struct hns_roce_dev *hr_dev,
} }
max_cnt = max(1U, cap->max_recv_sge); max_cnt = max(1U, cap->max_recv_sge);
hr_qp->rq.max_gs = roundup_pow_of_two(max_cnt); hr_qp->rq.max_gs = roundup_pow_of_two(max_cnt +
HNS_ROCE_RESERVED_SGE);
if (hr_dev->caps.max_rq_sg <= HNS_ROCE_MAX_SGE_NUM) if (hr_dev->caps.max_rq_sg <= HNS_ROCE_MAX_SGE_NUM)
hr_qp->rq.wqe_shift = hr_qp->rq.wqe_shift =
ilog2(hr_dev->caps.max_rq_desc_sz); ilog2(hr_dev->caps.max_rq_desc_sz);
...@@ -393,7 +394,7 @@ static int hns_roce_set_rq_size(struct hns_roce_dev *hr_dev, ...@@ -393,7 +394,7 @@ static int hns_roce_set_rq_size(struct hns_roce_dev *hr_dev,
} }
cap->max_recv_wr = hr_qp->rq.max_post = hr_qp->rq.wqe_cnt; cap->max_recv_wr = hr_qp->rq.max_post = hr_qp->rq.wqe_cnt;
cap->max_recv_sge = hr_qp->rq.max_gs; cap->max_recv_sge = hr_qp->rq.max_gs - HNS_ROCE_RESERVED_SGE;
return 0; return 0;
} }
......
...@@ -450,7 +450,7 @@ struct ib_srq *hns_roce_create_srq(struct ib_pd *pd, ...@@ -450,7 +450,7 @@ struct ib_srq *hns_roce_create_srq(struct ib_pd *pd,
spin_lock_init(&srq->lock); spin_lock_init(&srq->lock);
srq->max = roundup_pow_of_two(srq_init_attr->attr.max_wr + 1); srq->max = roundup_pow_of_two(srq_init_attr->attr.max_wr + 1);
srq->max_gs = srq_init_attr->attr.max_sge; srq->max_gs = srq_init_attr->attr.max_sge + HNS_ROCE_RESERVED_SGE;
srq_desc_size = max(HNS_ROCE_SGE_SIZE, HNS_ROCE_SGE_SIZE * srq->max_gs); srq_desc_size = max(HNS_ROCE_SGE_SIZE, HNS_ROCE_SGE_SIZE * srq->max_gs);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册