Commit 09f1b7cb authored by Yixing Liu's avatar Yixing Liu Committed by ZhouJuan
Browse files

RDMA/hns: Support congestion control algorithm configuration at QP granularity

driver inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I6N1G4



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

This patch supports to configure congestion control algorithm
based on QP granulariy. The configuration will be sent to
driver from user space. And then driver configures the selected
algorithm into QPC.

The current XRC type QP cannot deliver the configured
algorithm to kernel space, so the driver will set the default
algorithm for XRC type QP. And the default algorithm type is
controlled by the firmware.

Signed-off-by: default avatarYixing Liu <liuyixing1@huawei.com>
Reviewed-by: default avatarYangyang Li <liyangyang20@huawei.com>
parent 87d0ab38
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -654,6 +654,7 @@ struct hns_roce_qp {
	struct hns_roce_db	rdb;
	struct hns_roce_db	sdb;
	unsigned long		en_flags;
	unsigned long		congest_type;
	u32			doorbell_qpn;
	enum ib_sig_type	sq_signal_bits;
	struct hns_roce_wq	sq;
@@ -914,6 +915,7 @@ struct hns_roce_caps {
	u16		default_aeq_arm_st;
	u16		default_ceq_arm_st;
	u8		congest_type;
	u8		default_congest_type;
};

enum hns_roce_device_state {
+3 −2
Original line number Diff line number Diff line
@@ -2452,6 +2452,7 @@ static int hns_roce_query_caps(struct hns_roce_dev *hr_dev)
	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_congest_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);
@@ -5094,10 +5095,10 @@ enum {
static int check_congest_type(struct ib_qp *ibqp,
			      struct hns_roce_congestion_algorithm *congest_alg)
{
	struct hns_roce_dev *hr_dev = to_hr_dev(ibqp->device);
	struct hns_roce_qp *hr_qp = to_hr_qp(ibqp);

	/* different congestion types match different configurations */
	switch (hr_dev->caps.congest_type) {
	switch (hr_qp->congest_type) {
	case HNS_ROCE_CONGEST_TYPE_DCQCN:
		congest_alg->alg_sel = CONGEST_DCQCN;
		congest_alg->alg_sub_sel = UNSUPPORT_CONGEST_LEVEL;
+1 −0
Original line number Diff line number Diff line
@@ -1241,6 +1241,7 @@ struct hns_roce_query_pf_caps_d {
#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)
+4 −0
Original line number Diff line number Diff line
@@ -440,6 +440,10 @@ static void ucontext_set_resp(struct ib_ucontext *uctx,
	resp->srq_tab_size = hr_dev->caps.num_srqs;
	resp->cqe_size = hr_dev->caps.cqe_sz;
	resp->mac_type = hr_dev->mac_type;

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

	if (context->dca_ctx.dca_mmap_entry) {
		resp->dca_qps = context->dca_ctx.max_qps;
		resp->dca_mmap_size = PAGE_SIZE * context->dca_ctx.status_npage;
+46 −0
Original line number Diff line number Diff line
@@ -1072,6 +1072,48 @@ static void free_kernel_wrid(struct hns_roce_qp *hr_qp)
	kfree(hr_qp->sq.wrid);
}

static inline void default_congest_type(struct hns_roce_dev *hr_dev,
					struct hns_roce_qp *hr_qp)
{
	struct hns_roce_caps *caps = &hr_dev->caps;

	hr_qp->congest_type = 1 << caps->default_congest_type;
}

static int set_congest_type(struct hns_roce_qp *hr_qp,
			    struct hns_roce_ib_create_qp *ucmd)
{
	int ret = 0;

	if (ucmd->congest_type_flags & HNS_ROCE_CREATE_QP_FLAGS_DCQCN)
		hr_qp->congest_type = HNS_ROCE_CREATE_QP_FLAGS_DCQCN;
	else if (ucmd->congest_type_flags & HNS_ROCE_CREATE_QP_FLAGS_LDCP)
		hr_qp->congest_type = HNS_ROCE_CREATE_QP_FLAGS_LDCP;
	else if (ucmd->congest_type_flags & HNS_ROCE_CREATE_QP_FLAGS_HC3)
		hr_qp->congest_type = HNS_ROCE_CREATE_QP_FLAGS_HC3;
	else if (ucmd->congest_type_flags & HNS_ROCE_CREATE_QP_FLAGS_DIP)
		hr_qp->congest_type = HNS_ROCE_CREATE_QP_FLAGS_DIP;
	else
		ret = -EINVAL;

	return ret;
}

static void set_congest_param(struct hns_roce_dev *hr_dev,
			      struct hns_roce_qp *hr_qp,
			      struct hns_roce_ib_create_qp *ucmd)
{
	int ret;

	if (ucmd->comp_mask & HNS_ROCE_CREATE_QP_MASK_CONGEST_TYPE) {
		ret = set_congest_type(hr_qp, ucmd);
		if (ret == 0)
			return;
	}

	default_congest_type(hr_dev, hr_qp);
}

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,
@@ -1096,6 +1138,9 @@ static int set_qp_param(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp,
		return ret;
	}

	if (init_attr->qp_type == IB_QPT_XRC_TGT)
		default_congest_type(hr_dev, hr_qp);

	if (udata) {
		ret = ib_copy_from_udata(ucmd, udata,
					 min(udata->inlen, sizeof(*ucmd)));
@@ -1113,6 +1158,7 @@ static int set_qp_param(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp,
		if (ret)
			ibdev_err(ibdev, "Failed to set user SQ size, ret = %d\n",
				  ret);
		set_congest_param(hr_dev, hr_qp, ucmd);
	} else {
		if (init_attr->create_flags &
		    IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK) {
Loading