提交 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 @@
#define HNS_ROCE_WORKQ_NAME_LEN 32
#define HNS_ROCE_RESERVED_SGE 1
#define HNS_ROCE_MAX_IRQ_NUM 128
#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,
goto out;
}
if (unlikely(wr->num_sge > hr_qp->rq.max_gs)) {
dev_err(dev, "rq:num_sge=%d > qp->rq.max_gs=%d\n",
if (unlikely(wr->num_sge >= hr_qp->rq.max_gs)) {
dev_err(dev, "rq:num_sge=%d >= qp->rq.max_gs=%d\n",
wr->num_sge, hr_qp->rq.max_gs);
ret = -EINVAL;
*bad_wr = wr;
......@@ -786,9 +786,10 @@ static int hns_roce_v2_post_recv(struct ib_qp *ibqp, struct ib_recv_wr *wr,
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->addr = 0;
dseg->len = HNS_ROCE_INVALID_SGE_LENGTH;
}
/* rq support inline data */
......@@ -6794,7 +6795,7 @@ static int hns_roce_v2_post_srq_recv(struct ib_srq *ibsrq,
ind = srq->head & (srq->max - 1);
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,
"srq(0x%lx) wr sge num(%d) exceed the max num %d.\n",
srq->srqn, wr->num_sge, srq->max_gs);
......@@ -6822,9 +6823,9 @@ static int hns_roce_v2_post_srq_recv(struct ib_srq *ibsrq,
dseg[i].addr = cpu_to_le64(wr->sg_list[i].addr);
}
if (i < srq->max_gs) {
dseg[i].len = 0;
dseg[i].lkey = cpu_to_le32(0x100);
if (wr->num_sge < srq->max_gs) {
dseg[i].len = cpu_to_le32(HNS_ROCE_INVALID_SGE_LENGTH);
dseg[i].lkey = cpu_to_le32(HNS_ROCE_INVALID_LKEY);
dseg[i].addr = 0;
}
......
......@@ -53,15 +53,16 @@
#define HNS_ROCE_V2_MAX_WQE_NUM 0x8000
#define HNS_ROCE_V2_MAX_SRQ 0x100000
#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_CQC_TIMER_NUM 0x100
#define HNS_ROCE_V2_MAX_SRQ_NUM 0x100000
#define HNS_ROCE_V2_MAX_CQE_NUM 0x400000
#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_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_SQ_INLINE 0x20
#define HNS_ROCE_V2_UAR_NUM 256
......@@ -97,7 +98,8 @@
#define HNS_ROCE_V2_CQC_TIMER_ENTRY_SZ 4096
#define HNS_ROCE_V2_PAGE_SIZE_SUPPORTED 0xFFFFF000
#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_V2_UC_RC_SGE_NUM_IN_WQE 2
#define HNS_ROCE_V2_RSV_QPS 8
......
......@@ -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);
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)
hr_qp->rq.wqe_shift =
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,
}
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;
}
......
......@@ -450,7 +450,7 @@ struct ib_srq *hns_roce_create_srq(struct ib_pd *pd,
spin_lock_init(&srq->lock);
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);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册