Commit feb23a69 authored by Junxian Huang's avatar Junxian Huang Committed by openeuler-sync-bot
Browse files

RDMA/hns: Fix a missing check of atomic wr length

driver inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I7A2SA



---------------------------------------------------------------

The only supported length of atomic wr in kernel space is 8. The
driver needs to check the length before post send.

Fixes: 00a59d30 ("RDMA/hns: Optimize wqe buffer filling process for post send")
Signed-off-by: default avatarJunxian Huang <huangjunxian6@hisilicon.com>
(cherry picked from commit 555adba6)
parent 42baa54d
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -92,6 +92,8 @@
/* Configure to HW for PAGE_SIZE larger than 4KB */
#define PG_SHIFT_OFFSET				(PAGE_SHIFT - 12)

#define ATOMIC_WR_LEN				8

#define HNS_ROCE_IDX_QUE_ENTRY_SZ		4
#define SRQ_DB_REG				0x230

+14 −4
Original line number Diff line number Diff line
@@ -167,15 +167,22 @@ static void set_frmr_seg(struct hns_roce_v2_rc_send_wqe *rc_sq_wqe,
	hr_reg_clear(fseg, FRMR_BLK_MODE);
}

static void set_atomic_seg(const struct ib_send_wr *wr,
static int set_atomic_seg(struct hns_roce_dev *hr_dev,
			  const struct ib_send_wr *wr,
			  struct hns_roce_v2_rc_send_wqe *rc_sq_wqe,
			   unsigned int valid_num_sge)
			  unsigned int valid_num_sge, u32 msg_len)
{
	struct hns_roce_v2_wqe_data_seg *dseg =
		(void *)rc_sq_wqe + sizeof(struct hns_roce_v2_rc_send_wqe);
	struct hns_roce_wqe_atomic_seg *aseg =
		(void *)dseg + sizeof(struct hns_roce_v2_wqe_data_seg);

	if (msg_len != ATOMIC_WR_LEN) {
		ibdev_err(&hr_dev->ib_dev, "invalid atomic wr len, len = %u.\n",
			  msg_len);
		return -EINVAL;
	}

	set_data_seg_v2(dseg, wr->sg_list);

	if (wr->opcode == IB_WR_ATOMIC_CMP_AND_SWP) {
@@ -188,6 +195,8 @@ static void set_atomic_seg(const struct ib_send_wr *wr,
	}

	hr_reg_write(rc_sq_wqe, RC_SEND_WQE_SGE_NUM, valid_num_sge);

	return 0;
}

static int fill_ext_sge_inl_data(struct hns_roce_qp *qp,
@@ -691,7 +700,8 @@ static inline int set_rc_wqe(struct hns_roce_qp *qp,

	if (wr->opcode == IB_WR_ATOMIC_CMP_AND_SWP ||
	    wr->opcode == IB_WR_ATOMIC_FETCH_AND_ADD)
		set_atomic_seg(wr, rc_sq_wqe, valid_num_sge);
		ret = set_atomic_seg(hr_dev, wr, rc_sq_wqe, valid_num_sge,
				     msg_len);
	else if (wr->opcode != IB_WR_REG_MR)
		ret = set_rwqe_data_seg(&qp->ibqp, wr, rc_sq_wqe,
					&curr_idx, valid_num_sge);