From: Shunfeng Yang yangshunfeng2@huawei.com
mainline inclusion from mainline-v5.12 commit 1620f09b96ec category: bugfix bugzilla: NA CVE: NA
If a user posts WR by wr_list, the head pointer of idx_queue won't be updated until all wqes are filled, so the judgment of whether head equals to tail will get a wrong result. Fix above issue and move the head and tail pointer from the srq structure into the idx_queue structure. After idx_queue is filled with wqe idx, the head pointer of it will increase.
Signed-off-by: Shunfeng Yang yangshunfeng2@huawei.com Signed-off-by: Yangyang Li liyangyang20@huawei.com Reviewed-by: chunzhi hu huchunzhi@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- drivers/infiniband/hw/hns/hns_roce_device.h | 5 +++-- drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 19 ++++++++++++++----- drivers/infiniband/hw/hns/hns_roce_srq.c | 5 +++-- 3 files changed, 20 insertions(+), 9 deletions(-)
diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h b/drivers/infiniband/hw/hns/hns_roce_device.h index 6e1ec2d77ce2a..d11b6066a5308 100644 --- a/drivers/infiniband/hw/hns/hns_roce_device.h +++ b/drivers/infiniband/hw/hns/hns_roce_device.h @@ -635,6 +635,8 @@ struct hns_roce_idx_que { struct ib_umem *umem; struct hns_roce_mtt mtt; unsigned long *bitmap; + u32 head; + u32 tail; };
struct hns_roce_srq { @@ -656,8 +658,6 @@ struct hns_roce_srq { struct hns_roce_mtt mtt; struct hns_roce_idx_que idx_que; spinlock_t lock; - int head; - int tail; u16 wqe_ctr; struct mutex mutex; }; @@ -713,6 +713,7 @@ struct hns_roce_av { u8 stat_rate; u8 hop_limit; u32 flowlabel; + u16 udp_sport; u8 sl; u8 tclass; u8 dgid[HNS_ROCE_GID_SIZE]; diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c index 4c3787cb61255..298fba6e349c9 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c @@ -3035,7 +3035,7 @@ static void hns_roce_free_srq_wqe(struct hns_roce_srq *srq, int wqe_index) bitmap_num = wqe_index / BITS_PER_LONG_LONG; bit_num = wqe_index % BITS_PER_LONG_LONG; srq->idx_que.bitmap[bitmap_num] |= (1ULL << bit_num); - srq->tail++; + srq->idx_que.tail++;
spin_unlock(&srq->lock); } @@ -7003,6 +7003,15 @@ int hns_roce_v2_query_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr) return ret; }
+int hns_roce_srqwq_overflow(struct hns_roce_srq *srq, int nreq) +{ + struct hns_roce_idx_que *idx_que = &srq->idx_que; + unsigned int cur; + + cur = idx_que->head - idx_que->tail; + return cur + nreq >= srq->max - 1; +} + static int find_empty_entry(struct hns_roce_idx_que *idx_que) { int bit_num; @@ -7052,7 +7061,7 @@ static int hns_roce_v2_post_srq_recv(struct ib_srq *ibsrq,
spin_lock_irqsave(&srq->lock, flags);
- ind = srq->head & (srq->max - 1); + ind = srq->idx_que.head & (srq->max - 1); max_sge = srq->max_gs - srq->rsv_sge; for (nreq = 0; wr; ++nreq, wr = wr->next) { if (unlikely(wr->num_sge > max_sge)) { @@ -7064,7 +7073,7 @@ static int hns_roce_v2_post_srq_recv(struct ib_srq *ibsrq, break; }
- if (unlikely(srq->head == srq->tail)) { + if (unlikely(hns_roce_srqwq_overflow(srq, nreq))) { dev_err(hr_dev->dev, "srq(0x%lx) head equals tail\n", srq->srqn); ret = -ENOMEM; @@ -7094,7 +7103,7 @@ static int hns_roce_v2_post_srq_recv(struct ib_srq *ibsrq, }
if (likely(nreq)) { - srq->head += nreq; + srq->idx_que.head += nreq;
/* * Make sure that descriptors are written before @@ -7105,7 +7114,7 @@ static int hns_roce_v2_post_srq_recv(struct ib_srq *ibsrq, srq_db.byte_4 = cpu_to_le32(HNS_ROCE_V2_SRQ_DB << V2_DB_BYTE_4_CMD_S | (srq->srqn & V2_DB_BYTE_4_TAG_M)); - srq_db.parameter = cpu_to_le32(srq->head); + srq_db.parameter = cpu_to_le32(srq->idx_que.head);
hns_roce_write64(hr_dev, (__le32 *)&srq_db, srq->db_reg_l);
diff --git a/drivers/infiniband/hw/hns/hns_roce_srq.c b/drivers/infiniband/hw/hns/hns_roce_srq.c index 292e0e503884e..40ce6abdcd374 100644 --- a/drivers/infiniband/hw/hns/hns_roce_srq.c +++ b/drivers/infiniband/hw/hns/hns_roce_srq.c @@ -336,6 +336,9 @@ static int hns_roce_create_idx_que(struct ib_pd *pd, struct hns_roce_srq *srq, for (i = 0; i < bitmap_num; i++) idx_que->bitmap[i] = ~(0UL);
+ idx_que->head = 0; + idx_que->tail = 0; + return 0; }
@@ -352,8 +355,6 @@ static int create_kernel_srq(struct ib_pd *pd, struct hns_roce_srq *srq, return -ENOMEM;
srq->buf = kbuf; - srq->head = 0; - srq->tail = srq->max - 1; srq->wqe_ctr = 0;
ret = hns_roce_mtt_init(hr_dev, kbuf->npages, kbuf->page_shift,