Unverified Commit 138c2000 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!4935 RDMA/hns: Support userspace configuring congestion control algorithm with QP granularity

Merge Pull Request from: @stinft 
 
Junxian Huang (1):
   RDMA/hns: Support userspace configuring congestion control algorithm
   with QP granularity
Luoyouming (1):
   RDMA/hns: Fix mis-modifying default congestion control algorithm
https://gitee.com/openeuler/kernel/issues/I95UWO
 
 
Link:https://gitee.com/openeuler/kernel/pulls/4935

 

Reviewed-by: default avatarChengchang Tang <tangchengchang@huawei.com>
Signed-off-by: default avatarZheng Zengkai <zhengzengkai@huawei.com>
parents 696d5f9c 2dc6891c
Loading
Loading
Loading
Loading
+10 −8
Original line number Diff line number Diff line
@@ -594,6 +594,13 @@ struct hns_roce_work {
	u32 queue_num;
};

enum hns_roce_cong_type {
	CONG_TYPE_DCQCN,
	CONG_TYPE_LDCP,
	CONG_TYPE_HC3,
	CONG_TYPE_DIP,
};

struct hns_roce_qp {
	struct ib_qp		ibqp;
	struct hns_roce_wq	rq;
@@ -639,6 +646,7 @@ struct hns_roce_qp {
	u32			config;
	u8			tc_mode;
	u8			priority;
	enum hns_roce_cong_type cong_type;
};

struct hns_roce_ib_iboe {
@@ -719,13 +727,6 @@ enum hns_roce_scc_algo {
	HNS_ROCE_SCC_ALGO_TOTAL,
};

enum cong_type {
	CONG_TYPE_DCQCN,
	CONG_TYPE_LDCP,
	CONG_TYPE_HC3,
	CONG_TYPE_DIP,
};

struct hns_roce_caps {
	u64		fw_ver;
	u8		num_ports;
@@ -855,7 +856,8 @@ struct hns_roce_caps {
	u16		default_aeq_period;
	u16		default_aeq_arm_st;
	u16		default_ceq_arm_st;
	enum cong_type	cong_type;
	u8		cong_cap;
	enum hns_roce_cong_type default_cong_type;
};

enum hns_roce_device_state {
+7 −11
Original line number Diff line number Diff line
@@ -2209,11 +2209,12 @@ static int hns_roce_query_caps(struct hns_roce_dev *hr_dev)
	caps->max_wqes = 1 << le16_to_cpu(resp_c->sq_depth);

	caps->num_srqs = 1 << hr_reg_read(resp_d, PF_CAPS_D_NUM_SRQS);
	caps->cong_type = hr_reg_read(resp_d, PF_CAPS_D_CONG_TYPE);
	caps->cong_cap = hr_reg_read(resp_d, PF_CAPS_D_CONG_CAP);
	caps->max_srq_wrs = 1 << le16_to_cpu(resp_d->srq_depth);
	caps->ceqe_depth = 1 << hr_reg_read(resp_d, PF_CAPS_D_CEQ_DEPTH);
	caps->num_comp_vectors = hr_reg_read(resp_d, PF_CAPS_D_NUM_CEQS);
	caps->aeqe_depth = 1 << hr_reg_read(resp_d, PF_CAPS_D_AEQ_DEPTH);
	caps->default_cong_type = hr_reg_read(resp_d, PF_CAPS_D_DEFAULT_ALG);
	caps->reserved_pds = hr_reg_read(resp_d, PF_CAPS_D_RSV_PDS);
	caps->num_uars = 1 << hr_reg_read(resp_d, PF_CAPS_D_NUM_UARS);
	caps->reserved_qps = hr_reg_read(resp_d, PF_CAPS_D_RSV_QPS);
@@ -4737,13 +4738,10 @@ enum {
static int check_cong_type(struct ib_qp *ibqp,
			   struct hns_roce_congestion_algorithm *cong_alg)
{
	struct hns_roce_dev *hr_dev = to_hr_dev(ibqp->device);

	if (ibqp->qp_type == IB_QPT_UD)
		hr_dev->caps.cong_type = CONG_TYPE_DCQCN;
	struct hns_roce_qp *hr_qp = to_hr_qp(ibqp);

	/* different congestion types match different configurations */
	switch (hr_dev->caps.cong_type) {
	switch (hr_qp->cong_type) {
	case CONG_TYPE_DCQCN:
		cong_alg->alg_sel = CONG_DCQCN;
		cong_alg->alg_sub_sel = UNSUPPORT_CONG_LEVEL;
@@ -4769,10 +4767,7 @@ static int check_cong_type(struct ib_qp *ibqp,
		cong_alg->wnd_mode_sel = WND_LIMIT;
		break;
	default:
		ibdev_warn(&hr_dev->ib_dev,
			   "invalid type(%u) for congestion selection.\n",
			   hr_dev->caps.cong_type);
		hr_dev->caps.cong_type = CONG_TYPE_DCQCN;
		hr_qp->cong_type = CONG_TYPE_DCQCN;
		cong_alg->alg_sel = CONG_DCQCN;
		cong_alg->alg_sub_sel = UNSUPPORT_CONG_LEVEL;
		cong_alg->dip_vld = DIP_INVALID;
@@ -4791,6 +4786,7 @@ static int fill_cong_field(struct ib_qp *ibqp, const struct ib_qp_attr *attr,
	struct hns_roce_congestion_algorithm cong_field;
	struct ib_device *ibdev = ibqp->device;
	struct hns_roce_dev *hr_dev = to_hr_dev(ibdev);
	struct hns_roce_qp *hr_qp = to_hr_qp(ibqp);
	u32 dip_idx = 0;
	int ret;

@@ -4803,7 +4799,7 @@ static int fill_cong_field(struct ib_qp *ibqp, const struct ib_qp_attr *attr,
		return ret;

	hr_reg_write(context, QPC_CONG_ALGO_TMPL_ID, hr_dev->cong_algo_tmpl_id +
		     hr_dev->caps.cong_type * HNS_ROCE_CONG_SIZE);
		     hr_qp->cong_type * HNS_ROCE_CONG_SIZE);
	hr_reg_clear(qpc_mask, QPC_CONG_ALGO_TMPL_ID);
	hr_reg_write(&context->ext, QPCEX_CONG_ALG_SEL, cong_field.alg_sel);
	hr_reg_clear(&qpc_mask->ext, QPCEX_CONG_ALG_SEL);
+2 −1
Original line number Diff line number Diff line
@@ -1224,12 +1224,13 @@ struct hns_roce_query_pf_caps_d {
#define PF_CAPS_D_RQWQE_HOP_NUM PF_CAPS_D_FIELD_LOC(21, 20)
#define PF_CAPS_D_EX_SGE_HOP_NUM PF_CAPS_D_FIELD_LOC(23, 22)
#define PF_CAPS_D_SQWQE_HOP_NUM PF_CAPS_D_FIELD_LOC(25, 24)
#define PF_CAPS_D_CONG_TYPE PF_CAPS_D_FIELD_LOC(29, 26)
#define PF_CAPS_D_CONG_CAP PF_CAPS_D_FIELD_LOC(29, 26)
#define PF_CAPS_D_CEQ_DEPTH PF_CAPS_D_FIELD_LOC(85, 64)
#define PF_CAPS_D_NUM_CEQS PF_CAPS_D_FIELD_LOC(95, 86)
#define PF_CAPS_D_AEQ_DEPTH PF_CAPS_D_FIELD_LOC(117, 96)
#define PF_CAPS_D_AEQ_ARM_ST PF_CAPS_D_FIELD_LOC(119, 118)
#define PF_CAPS_D_CEQ_ARM_ST PF_CAPS_D_FIELD_LOC(121, 120)
#define PF_CAPS_D_DEFAULT_ALG PF_CAPS_D_FIELD_LOC(127, 122)
#define PF_CAPS_D_RSV_PDS PF_CAPS_D_FIELD_LOC(147, 128)
#define PF_CAPS_D_NUM_UARS PF_CAPS_D_FIELD_LOC(155, 148)
#define PF_CAPS_D_RSV_QPS PF_CAPS_D_FIELD_LOC(179, 160)
+3 −0
Original line number Diff line number Diff line
@@ -415,6 +415,9 @@ static int hns_roce_alloc_ucontext(struct ib_ucontext *uctx,
			resp.config |= HNS_ROCE_RSP_CQE_INLINE_FLAGS;
	}

	if (hr_dev->pci_dev->revision >= PCI_REVISION_ID_HIP09)
		resp.congest_type = hr_dev->caps.cong_cap;

	ret = hns_roce_uar_alloc(hr_dev, &context->uar);
	if (ret)
		goto error_out;
+60 −0
Original line number Diff line number Diff line
@@ -1004,6 +1004,60 @@ static void free_kernel_wrid(struct hns_roce_qp *hr_qp)
	kfree(hr_qp->sq.wrid);
}

static void default_congest_type(struct hns_roce_dev *hr_dev,
				 struct hns_roce_qp *hr_qp)
{
	if (hr_qp->ibqp.qp_type == IB_QPT_UD ||
	    hr_qp->ibqp.qp_type == IB_QPT_GSI)
		hr_qp->cong_type = CONG_TYPE_DCQCN;
	else
		hr_qp->cong_type = hr_dev->caps.default_cong_type;
}

static int set_congest_type(struct hns_roce_qp *hr_qp,
			    struct hns_roce_ib_create_qp *ucmd)
{
	struct hns_roce_dev *hr_dev = to_hr_dev(hr_qp->ibqp.device);

	switch (ucmd->cong_type_flags) {
	case HNS_ROCE_CREATE_QP_FLAGS_DCQCN:
		hr_qp->cong_type = CONG_TYPE_DCQCN;
		break;
	case HNS_ROCE_CREATE_QP_FLAGS_LDCP:
		hr_qp->cong_type = CONG_TYPE_LDCP;
		break;
	case HNS_ROCE_CREATE_QP_FLAGS_HC3:
		hr_qp->cong_type = CONG_TYPE_HC3;
		break;
	case HNS_ROCE_CREATE_QP_FLAGS_DIP:
		hr_qp->cong_type = CONG_TYPE_DIP;
		break;
	default:
		return -EINVAL;
	}

	if (!test_bit(hr_qp->cong_type, (unsigned long *)&hr_dev->caps.cong_cap))
		return -EOPNOTSUPP;

	if (hr_qp->ibqp.qp_type == IB_QPT_UD &&
	    hr_qp->cong_type != CONG_TYPE_DCQCN)
		return -EOPNOTSUPP;

	return 0;
}

static int set_congest_param(struct hns_roce_dev *hr_dev,
			     struct hns_roce_qp *hr_qp,
			     struct hns_roce_ib_create_qp *ucmd)
{
	if (ucmd->comp_mask & HNS_ROCE_CREATE_QP_MASK_CONGEST_TYPE)
		return set_congest_type(hr_qp, ucmd);

	default_congest_type(hr_dev, hr_qp);

	return 0;
}

static int set_qp_param(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp,
			struct ib_qp_init_attr *init_attr,
			struct ib_udata *udata,
@@ -1043,6 +1097,10 @@ static int set_qp_param(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp,
			ibdev_err(ibdev,
				  "failed to set user SQ size, ret = %d.\n",
				  ret);

		ret = set_congest_param(hr_dev, hr_qp, ucmd);
		if (ret)
			return ret;
	} else {
		if (hr_dev->pci_dev->revision >= PCI_REVISION_ID_HIP09)
			hr_qp->config = HNS_ROCE_EXSGE_FLAGS;
@@ -1051,6 +1109,8 @@ static int set_qp_param(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp,
			ibdev_err(ibdev,
				  "failed to set kernel SQ size, ret = %d.\n",
				  ret);

		default_congest_type(hr_dev, hr_qp);
	}

	return ret;
Loading