Skip to content

Commit fe96220

Browse files
Junxian Huangrleon
authored andcommitted
RDMA/hns: Fix wrong WQE data when QP wraps around
When QP wraps around, WQE data from the previous use at the same position still remains as driver does not clear it. The WQE field layout differs across different opcodes, causing that the fields that are not explicitly assigned for the current opcode retain stale values, and are issued to HW by mistake. Such fields are as follows: * MSG_START_SGE_IDX field in ATOMIC WQE * BLOCK_SIZE and ZBVA fields in FRMR WQE * DirectWQE fields when DirectWQE not used For ATOMIC WQE, always set the latest sge index in MSG_START_SGE_IDX as required by HW. For FRMR WQE and DirectWQE, clear only those unassigned fields instead of the entire WQE to avoid performance penalty. Fixes: 68a997c ("RDMA/hns: Add FRMR support for hip08") Signed-off-by: Junxian Huang <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Leon Romanovsky <[email protected]>
1 parent f5a7cbe commit fe96220

File tree

1 file changed

+8
-3
lines changed

1 file changed

+8
-3
lines changed

drivers/infiniband/hw/hns/hns_roce_hw_v2.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,8 @@ static void set_frmr_seg(struct hns_roce_v2_rc_send_wqe *rc_sq_wqe,
165165
hr_reg_write(fseg, FRMR_PBL_BUF_PG_SZ,
166166
to_hr_hw_page_shift(mr->pbl_mtr.hem_cfg.buf_pg_shift));
167167
hr_reg_clear(fseg, FRMR_BLK_MODE);
168+
hr_reg_clear(fseg, FRMR_BLOCK_SIZE);
169+
hr_reg_clear(fseg, FRMR_ZBVA);
168170
}
169171

170172
static void set_atomic_seg(const struct ib_send_wr *wr,
@@ -339,9 +341,6 @@ static int set_rwqe_data_seg(struct ib_qp *ibqp, const struct ib_send_wr *wr,
339341
int j = 0;
340342
int i;
341343

342-
hr_reg_write(rc_sq_wqe, RC_SEND_WQE_MSG_START_SGE_IDX,
343-
(*sge_ind) & (qp->sge.sge_cnt - 1));
344-
345344
hr_reg_write(rc_sq_wqe, RC_SEND_WQE_INLINE,
346345
!!(wr->send_flags & IB_SEND_INLINE));
347346
if (wr->send_flags & IB_SEND_INLINE)
@@ -586,6 +585,9 @@ static inline int set_rc_wqe(struct hns_roce_qp *qp,
586585
hr_reg_write(rc_sq_wqe, RC_SEND_WQE_CQE,
587586
(wr->send_flags & IB_SEND_SIGNALED) ? 1 : 0);
588587

588+
hr_reg_write(rc_sq_wqe, RC_SEND_WQE_MSG_START_SGE_IDX,
589+
curr_idx & (qp->sge.sge_cnt - 1));
590+
589591
if (wr->opcode == IB_WR_ATOMIC_CMP_AND_SWP ||
590592
wr->opcode == IB_WR_ATOMIC_FETCH_AND_ADD) {
591593
if (msg_len != ATOMIC_WR_LEN)
@@ -734,6 +736,9 @@ static int hns_roce_v2_post_send(struct ib_qp *ibqp,
734736
owner_bit =
735737
~(((qp->sq.head + nreq) >> ilog2(qp->sq.wqe_cnt)) & 0x1);
736738

739+
/* RC and UD share the same DirectWQE field layout */
740+
((struct hns_roce_v2_rc_send_wqe *)wqe)->byte_4 = 0;
741+
737742
/* Corresponding to the QP type, wqe process separately */
738743
if (ibqp->qp_type == IB_QPT_RC)
739744
ret = set_rc_wqe(qp, wr, wqe, &sge_idx, owner_bit);

0 commit comments

Comments
 (0)