Skip to content

Commit 2e07a3d

Browse files
Wenpeng Liangjgunthorpe
authored andcommitted
RDMA/hns: Refactor hns_roce_v2_post_srq_recv()
The SRQ in the hns driver consists of the following four parts: * wqe buf: the buffer to store WQE. * wqe_idx buf: the cqe of SRQ may be not generated in the order of wqe, so the wqe_idx corresponding to the idle WQE needs to be pushed into the index queue which is a FIFO, then it instructs the hardware to obtain the corresponding WQE. * bitmap: bitmap is used to generate and release wqe_idx. When the user has a new WR, the driver finds the idx of the idle wqe in bitmap. When the CQE of wqe is generated, the driver will release the idx. * wr_id buf: wr_id buf is used to store the user's wr_id, then return it to the user when poll_cq verb is invoked. The process of post SRQ recv is refactored to make preceding code clearer. Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Wenpeng Liang <[email protected]> Signed-off-by: Weihang Li <[email protected]> Signed-off-by: Jason Gunthorpe <[email protected]>
1 parent 6b981e2 commit 2e07a3d

File tree

1 file changed

+43
-26
lines changed

1 file changed

+43
-26
lines changed

drivers/infiniband/hw/hns/hns_roce_hw_v2.c

Lines changed: 43 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -869,13 +869,32 @@ static void hns_roce_free_srq_wqe(struct hns_roce_srq *srq, u32 wqe_index)
869869
spin_unlock(&srq->lock);
870870
}
871871

872-
int hns_roce_srqwq_overflow(struct hns_roce_srq *srq, u32 nreq)
872+
static int hns_roce_srqwq_overflow(struct hns_roce_srq *srq)
873873
{
874874
struct hns_roce_idx_que *idx_que = &srq->idx_que;
875-
unsigned int cur;
876875

877-
cur = idx_que->head - idx_que->tail;
878-
return cur + nreq >= srq->wqe_cnt;
876+
return idx_que->head - idx_que->tail >= srq->wqe_cnt;
877+
}
878+
879+
static int check_post_srq_valid(struct hns_roce_srq *srq, u32 max_sge,
880+
const struct ib_recv_wr *wr)
881+
{
882+
struct ib_device *ib_dev = srq->ibsrq.device;
883+
884+
if (unlikely(wr->num_sge > max_sge)) {
885+
ibdev_err(ib_dev,
886+
"failed to check sge, wr->num_sge = %d, max_sge = %u.\n",
887+
wr->num_sge, max_sge);
888+
return -EINVAL;
889+
}
890+
891+
if (unlikely(hns_roce_srqwq_overflow(srq))) {
892+
ibdev_err(ib_dev,
893+
"failed to check srqwq status, srqwq is full.\n");
894+
return -ENOMEM;
895+
}
896+
897+
return 0;
879898
}
880899

881900
static int get_srq_wqe_idx(struct hns_roce_srq *srq, u32 *wqe_idx)
@@ -892,36 +911,40 @@ static int get_srq_wqe_idx(struct hns_roce_srq *srq, u32 *wqe_idx)
892911
return 0;
893912
}
894913

914+
static void fill_wqe_idx(struct hns_roce_srq *srq, unsigned int wqe_idx)
915+
{
916+
struct hns_roce_idx_que *idx_que = &srq->idx_que;
917+
unsigned int head;
918+
__le32 *buf;
919+
920+
head = idx_que->head & (srq->wqe_cnt - 1);
921+
922+
buf = get_idx_buf(idx_que, head);
923+
*buf = cpu_to_le32(wqe_idx);
924+
925+
idx_que->head++;
926+
}
927+
895928
static int hns_roce_v2_post_srq_recv(struct ib_srq *ibsrq,
896929
const struct ib_recv_wr *wr,
897930
const struct ib_recv_wr **bad_wr)
898931
{
899932
struct hns_roce_dev *hr_dev = to_hr_dev(ibsrq->device);
900933
struct hns_roce_srq *srq = to_hr_srq(ibsrq);
901-
u32 wqe_idx, ind, nreq, max_sge;
902934
struct hns_roce_v2_db srq_db;
903935
unsigned long flags;
904-
__le32 *srq_idx;
905936
int ret = 0;
937+
u32 max_sge;
938+
u32 wqe_idx;
906939
void *wqe;
940+
u32 nreq;
907941

908942
spin_lock_irqsave(&srq->lock, flags);
909943

910-
ind = srq->idx_que.head & (srq->wqe_cnt - 1);
911944
max_sge = srq->max_gs - srq->rsv_sge;
912-
913945
for (nreq = 0; wr; ++nreq, wr = wr->next) {
914-
if (unlikely(wr->num_sge > max_sge)) {
915-
ibdev_err(&hr_dev->ib_dev,
916-
"srq: num_sge = %d, max_sge = %u.\n",
917-
wr->num_sge, max_sge);
918-
ret = -EINVAL;
919-
*bad_wr = wr;
920-
break;
921-
}
922-
923-
if (unlikely(hns_roce_srqwq_overflow(srq, nreq))) {
924-
ret = -ENOMEM;
946+
ret = check_post_srq_valid(srq, max_sge, wr);
947+
if (ret) {
925948
*bad_wr = wr;
926949
break;
927950
}
@@ -934,17 +957,11 @@ static int hns_roce_v2_post_srq_recv(struct ib_srq *ibsrq,
934957

935958
wqe = get_srq_wqe_buf(srq, wqe_idx);
936959
fill_recv_sge_to_wqe(wr, wqe, max_sge, srq->rsv_sge);
937-
938-
srq_idx = get_idx_buf(&srq->idx_que, ind);
939-
*srq_idx = cpu_to_le32(wqe_idx);
940-
960+
fill_wqe_idx(srq, wqe_idx);
941961
srq->wrid[wqe_idx] = wr->wr_id;
942-
ind = (ind + 1) & (srq->wqe_cnt - 1);
943962
}
944963

945964
if (likely(nreq)) {
946-
srq->idx_que.head += nreq;
947-
948965
/*
949966
* Make sure that descriptors are written before
950967
* doorbell record.

0 commit comments

Comments
 (0)