Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9b44703d authored by Yixian Liu's avatar Yixian Liu Committed by Doug Ledford
Browse files

RDMA/hns: Support cq record doorbell for the user space



This patch updates to support cq record doorbell for
the user space.

Signed-off-by: default avatarYixian Liu <liuyixian@huawei.com>
Signed-off-by: default avatarLijun Ou <oulijun@huawei.com>
Signed-off-by: default avatarWei Hu (Xavier) <xavier.huwei@huawei.com>
Signed-off-by: default avatarShaobo Xu <xushaobo2@huawei.com>
Signed-off-by: default avatarDoug Ledford <dledford@redhat.com>
parent e088a685
Loading
Loading
Loading
Loading
+36 −6
Original line number Diff line number Diff line
@@ -315,6 +315,7 @@ struct ib_cq *hns_roce_ib_create_cq(struct ib_device *ib_dev,
	struct hns_roce_dev *hr_dev = to_hr_dev(ib_dev);
	struct device *dev = hr_dev->dev;
	struct hns_roce_ib_create_cq ucmd;
	struct hns_roce_ib_create_cq_resp resp;
	struct hns_roce_cq *hr_cq = NULL;
	struct hns_roce_uar *uar = NULL;
	int vector = attr->comp_vector;
@@ -378,6 +379,16 @@ struct ib_cq *hns_roce_ib_create_cq(struct ib_device *ib_dev,
		goto err_mtt;
	}

	if (context && (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_RECORD_DB) &&
	    (udata->outlen == sizeof(resp))) {
		ret = hns_roce_db_map_user(to_hr_ucontext(context),
					   ucmd.db_addr, &hr_cq->db);
		if (ret) {
			dev_err(dev, "cq record doorbell map failed!\n");
			goto err_cqc;
		}
	}

	/*
	 * For the QP created by kernel space, tptr value should be initialized
	 * to zero; For the QP created by user space, it will cause synchronous
@@ -393,14 +404,27 @@ struct ib_cq *hns_roce_ib_create_cq(struct ib_device *ib_dev,
	hr_cq->cq_depth = cq_entries;

	if (context) {
		if (ib_copy_to_udata(udata, &hr_cq->cqn, sizeof(u64))) {
			ret = -EFAULT;
			goto err_cqc;
		}
		if ((hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_RECORD_DB) &&
					(udata->outlen == sizeof(resp))) {
			hr_cq->db_en = 1;
			resp.cqn = hr_cq->cqn;
			resp.cap_flags |= HNS_ROCE_SUPPORT_CQ_RECORD_DB;
			ret = ib_copy_to_udata(udata, &resp, sizeof(resp));
		} else
			ret = ib_copy_to_udata(udata, &hr_cq->cqn, sizeof(u64));

		if (ret)
			goto err_dbmap;
	}

	return &hr_cq->ib_cq;

err_dbmap:
	if (context && (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_RECORD_DB) &&
	    (udata->outlen == sizeof(resp)))
		hns_roce_db_unmap_user(to_hr_ucontext(context),
				       &hr_cq->db);

err_cqc:
	hns_roce_free_cq(hr_dev, hr_cq);

@@ -430,12 +454,18 @@ int hns_roce_ib_destroy_cq(struct ib_cq *ib_cq)
		hns_roce_free_cq(hr_dev, hr_cq);
		hns_roce_mtt_cleanup(hr_dev, &hr_cq->hr_buf.hr_mtt);

		if (ib_cq->uobject)
		if (ib_cq->uobject) {
			ib_umem_release(hr_cq->umem);
		else

			if (hr_cq->db_en == 1)
				hns_roce_db_unmap_user(
					to_hr_ucontext(ib_cq->uobject->context),
					&hr_cq->db);
		} else {
			/* Free the buff of stored cq */
			hns_roce_ib_free_cq_buf(hr_dev, &hr_cq->hr_buf,
						ib_cq->cqe);
		}

		kfree(hr_cq);
	}
+6 −0
Original line number Diff line number Diff line
@@ -109,6 +109,10 @@ enum {
	HNS_ROCE_SUPPORT_RQ_RECORD_DB = 1 << 0,
};

enum {
	HNS_ROCE_SUPPORT_CQ_RECORD_DB = 1 << 0,
};

enum hns_roce_qp_state {
	HNS_ROCE_QP_STATE_RST,
	HNS_ROCE_QP_STATE_INIT,
@@ -381,6 +385,8 @@ struct hns_roce_cq_buf {
struct hns_roce_cq {
	struct ib_cq			ib_cq;
	struct hns_roce_cq_buf		hr_buf;
	struct hns_roce_db		db;
	u8				db_en;
	spinlock_t			lock;
	struct ib_umem			*umem;
	void (*comp)(struct hns_roce_cq *cq);
+10 −0
Original line number Diff line number Diff line
@@ -1638,6 +1638,16 @@ static void hns_roce_v2_write_cqc(struct hns_roce_dev *hr_dev,
	roce_set_field(cq_context->byte_40_cqe_ba, V2_CQC_BYTE_40_CQE_BA_M,
		       V2_CQC_BYTE_40_CQE_BA_S, (dma_handle >> (32 + 3)));

	if (hr_cq->db_en)
		roce_set_bit(cq_context->byte_44_db_record,
			     V2_CQC_BYTE_44_DB_RECORD_EN_S, 1);

	roce_set_field(cq_context->byte_44_db_record,
		       V2_CQC_BYTE_44_DB_RECORD_ADDR_M,
		       V2_CQC_BYTE_44_DB_RECORD_ADDR_S,
		       ((u32)hr_cq->db.dma) >> 1);
	cq_context->db_record_addr = hr_cq->db.dma >> 32;

	roce_set_field(cq_context->byte_56_cqe_period_maxcnt,
		       V2_CQC_BYTE_56_CQ_MAX_CNT_M,
		       V2_CQC_BYTE_56_CQ_MAX_CNT_S,
+3 −0
Original line number Diff line number Diff line
@@ -299,6 +299,9 @@ struct hns_roce_v2_cq_context {

#define	V2_CQC_BYTE_44_DB_RECORD_EN_S 0

#define	V2_CQC_BYTE_44_DB_RECORD_ADDR_S 1
#define	V2_CQC_BYTE_44_DB_RECORD_ADDR_M GENMASK(31, 1)

#define	V2_CQC_BYTE_52_CQE_CNT_S 0
#define	V2_CQC_BYTE_52_CQE_CNT_M GENMASK(23, 0)

+7 −0
Original line number Diff line number Diff line
@@ -38,6 +38,13 @@

struct hns_roce_ib_create_cq {
	__u64   buf_addr;
	__u64	db_addr;
};

struct hns_roce_ib_create_cq_resp {
	__u32	cqn;
	__u32	reserved;
	__u64	cap_flags;
};

struct hns_roce_ib_create_qp {