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

!2675 RDMA/hns: Support STARS over RDMA

Merge Pull Request from: @stinft 
 
STARS is a HW scheduler. These patches support STARS taking over HNS RoCE.

Chengchang Tang (6):
   RDMA/hns: Support query HW ID from user space.
   RDMA/hns: Fix print after query hw id failed.
   RDMA/hns: Support configuring POE channels and creating POE CQs
   RDMA/hns: Support STARS mode QP
   RDMA/hns: Support kernel ULP querying HW ID
   RDMA/hns: Support write with notify

bugzilla: https://gitee.com/openeuler/kernel/issues/I8C2IP 
 
Link:https://gitee.com/openeuler/kernel/pulls/2675

 

Reviewed-by: default avatarChengchang Tang <tangchengchang@huawei.com>
Signed-off-by: default avatarJialin Zhang <zhangjialin11@huawei.com>
parents 3fcd03c9 21cacb51
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -10,7 +10,8 @@ ccflags-y += -I $(srctree)/drivers/net/ethernet/hisilicon/hns3/hns3_common
hns-roce-objs := hns_roce_main.o hns_roce_cmd.o hns_roce_pd.o \
	hns_roce_ah.o hns_roce_hem.o hns_roce_mr.o hns_roce_qp.o \
	hns_roce_cq.o hns_roce_alloc.o hns_roce_db.o hns_roce_srq.o hns_roce_restrack.o \
	hns_roce_bond.o hns_roce_dca.o hns_roce_debugfs.o hns_roce_sysfs.o
	hns_roce_bond.o hns_roce_dca.o hns_roce_debugfs.o hns_roce_sysfs.o \
	hns_roce_poe.o hns_roce_ext.o

ifdef CONFIG_INFINIBAND_HNS_HIP08
hns-roce-hw-v2-objs := hns_roce_hw_v2.o $(hns-roce-objs)
+3 −0
Original line number Diff line number Diff line
@@ -42,6 +42,9 @@
#define roce_get_field(origin, mask, shift)                                    \
	((le32_to_cpu(origin) & (mask)) >> (u32)(shift))

#define roce_get_field64(origin, mask, shift)                                    \
	((le64_to_cpu(origin) & (mask)) >> (u32)(shift))

#define roce_get_bit(origin, shift) \
	roce_get_field((origin), (1ul << (shift)), (shift))

+112 −2
Original line number Diff line number Diff line
@@ -311,10 +311,84 @@ static int get_cq_ucmd(struct hns_roce_cq *hr_cq, struct ib_udata *udata,
	return 0;
}

static void set_cq_param(struct hns_roce_cq *hr_cq, u32 cq_entries, int vector,
static int set_poe_param(struct hns_roce_dev *hr_dev,
			 struct hns_roce_cq *hr_cq,
			 struct hns_roce_ib_create_cq *ucmd)
{
	if (!(ucmd->create_flags & HNS_ROCE_CREATE_CQ_FLAGS_POE_MODE))
		return 0;

	if (!poe_is_supported(hr_dev))
		return -EOPNOTSUPP;

	if (ucmd->poe_channel >= hr_dev->poe_ctx.poe_num)
		return -EINVAL;

	if (!hr_dev->poe_ctx.poe_ch[ucmd->poe_channel].en)
		return -EFAULT;

	hr_cq->flags |= HNS_ROCE_CQ_FLAG_POE_EN;
	hr_cq->poe_channel = ucmd->poe_channel;
	return 0;
}

static bool is_notify_support(struct hns_roce_dev *hr_dev,
			      enum hns_roce_notify_mode notify_mode,
			      enum hns_roce_notify_device_en device_en)
{
	if (!is_write_notify_supported(hr_dev))
		return false;

	/* some configuration is not supported in HIP10 */
	if (hr_dev->pci_dev->revision != PCI_REVISION_ID_HIP10)
		return true;

	if (notify_mode == HNS_ROCE_NOTIFY_MODE_64B_ALIGN ||
	    device_en == HNS_ROCE_NOTIFY_DDR) {
		ibdev_err(&hr_dev->ib_dev, "Unsupported notify_mode.\n");
		return false;
	}

	return true;
}

static int set_write_notify_param(struct hns_roce_dev *hr_dev,
				  struct hns_roce_cq *hr_cq,
				  struct hns_roce_ib_create_cq *ucmd)
{
#define NOTIFY_MODE_MASK 0x3
	const struct {
		u8 mode;
		u8 mem_type;
	} notify_attr[] = {
		{HNS_ROCE_NOTIFY_MODE_64B_ALIGN, HNS_ROCE_NOTIFY_DEV},
		{HNS_ROCE_NOTIFY_MODE_4B_ALIGN, HNS_ROCE_NOTIFY_DEV},
		{HNS_ROCE_NOTIFY_MODE_64B_ALIGN, HNS_ROCE_NOTIFY_DDR},
		{HNS_ROCE_NOTIFY_MODE_4B_ALIGN, HNS_ROCE_NOTIFY_DDR},
	};
	u8 attr = ucmd->notify_mode & NOTIFY_MODE_MASK;

	if (!(ucmd->create_flags & HNS_ROCE_CREATE_CQ_FLAGS_WRITE_WITH_NOTIFY))
		return 0;

	if (!is_notify_support(hr_dev, notify_attr[attr].mode,
			       notify_attr[attr].mem_type))
		return -EOPNOTSUPP;

	hr_cq->flags |= HNS_ROCE_CQ_FLAG_NOTIFY_EN;
	hr_cq->write_notify.notify_addr =
		hr_dev->notify_tbl[ucmd->notify_idx].base_addr;
	hr_cq->write_notify.notify_mode = notify_attr[attr].mode;
	hr_cq->write_notify.notify_device_en = notify_attr[attr].mem_type;

	return 0;
}

static int set_cq_param(struct hns_roce_cq *hr_cq, u32 cq_entries, int vector,
			 struct hns_roce_ib_create_cq *ucmd)
{
	struct hns_roce_dev *hr_dev = to_hr_dev(hr_cq->ib_cq.device);
	int ret;

	cq_entries = max(cq_entries, hr_dev->caps.min_cqes);
	cq_entries = roundup_pow_of_two(cq_entries);
@@ -325,6 +399,19 @@ static void set_cq_param(struct hns_roce_cq *hr_cq, u32 cq_entries, int vector,
	spin_lock_init(&hr_cq->lock);
	INIT_LIST_HEAD(&hr_cq->sq_list);
	INIT_LIST_HEAD(&hr_cq->rq_list);

	if (!ucmd->create_flags)
		return 0;

	if ((ucmd->create_flags & HNS_ROCE_CREATE_CQ_FLAGS_POE_MODE) &&
	    (ucmd->create_flags & HNS_ROCE_CREATE_CQ_FLAGS_WRITE_WITH_NOTIFY))
		return -EINVAL;

	ret = set_poe_param(hr_dev, hr_cq, ucmd);
	if (ret)
		return ret;

	return set_write_notify_param(hr_dev, hr_cq, ucmd);
}

static int set_cqe_size(struct hns_roce_cq *hr_cq, struct ib_udata *udata,
@@ -353,6 +440,22 @@ static int set_cqe_size(struct hns_roce_cq *hr_cq, struct ib_udata *udata,
	return 0;
}

static void poe_ch_ref_cnt_inc(struct hns_roce_dev *hr_dev,
			       struct hns_roce_cq *hr_cq)
{
	struct hns_roce_poe_ch *poe_ch =
		&hr_dev->poe_ctx.poe_ch[hr_cq->poe_channel];
	refcount_inc(&poe_ch->ref_cnt);
}

static void poe_ch_ref_cnt_dec(struct hns_roce_dev *hr_dev,
			       struct hns_roce_cq *hr_cq)
{
	struct hns_roce_poe_ch *poe_ch =
		&hr_dev->poe_ctx.poe_ch[hr_cq->poe_channel];
	refcount_dec(&poe_ch->ref_cnt);
}

int hns_roce_create_cq(struct ib_cq *ib_cq, const struct ib_cq_init_attr *attr,
		       struct ib_udata *udata)
{
@@ -379,7 +482,9 @@ int hns_roce_create_cq(struct ib_cq *ib_cq, const struct ib_cq_init_attr *attr,

	}

	set_cq_param(hr_cq, attr->cqe, attr->comp_vector, &ucmd);
	ret = set_cq_param(hr_cq, attr->cqe, attr->comp_vector, &ucmd);
	if (ret)
		goto err_out;

	ret = set_cqe_size(hr_cq, udata, &ucmd);
	if (ret)
@@ -412,6 +517,9 @@ int hns_roce_create_cq(struct ib_cq *ib_cq, const struct ib_cq_init_attr *attr,

	if (udata) {
		resp.cqn = hr_cq->cqn;
		resp.cap_flags = hr_cq->flags;
		if (hr_cq->flags & HNS_ROCE_CQ_FLAG_POE_EN)
			poe_ch_ref_cnt_inc(hr_dev, hr_cq);
		ret = ib_copy_to_udata(udata, &resp,
				       min(udata->outlen, sizeof(resp)));
		if (ret)
@@ -444,6 +552,8 @@ int hns_roce_destroy_cq(struct ib_cq *ib_cq, struct ib_udata *udata)
	struct hns_roce_dev *hr_dev = to_hr_dev(ib_cq->device);
	struct hns_roce_cq *hr_cq = to_hr_cq(ib_cq);

	if (hr_cq->flags & HNS_ROCE_CQ_FLAG_POE_EN)
		poe_ch_ref_cnt_dec(hr_dev, hr_cq);
	free_cqc(hr_dev, hr_cq);
	free_cqn(hr_dev, hr_cq->cqn);
	free_cq_db(hr_dev, hr_cq, udata);
+111 −0
Original line number Diff line number Diff line
@@ -74,10 +74,22 @@ struct hns_dca_debugfs {
	struct hns_dca_ctx_debugfs kctx; /* kDCA context */
};

struct hns_poe_ch_debugfs {
	struct dentry *root; /* dev debugfs entry */
	struct hns_debugfs_seqfile en; /* enable stats fir this ch */
	struct hns_debugfs_seqfile addr; /* addr of this ch */
	struct hns_debugfs_seqfile ref_cnt; /* ref_cnt for this ch */
};

struct hns_poe_debugfs {
	struct dentry *root; /* dev debugfs entry */
};

/* Debugfs for device */
struct hns_roce_dev_debugfs {
	struct dentry *root;
	struct hns_dca_debugfs *dca_root;
	struct hns_poe_debugfs *poe_root;
};

struct dca_mem_stats {
@@ -497,6 +509,97 @@ static void destroy_dca_debugfs(struct hns_dca_debugfs *dca_dbgfs)
	kfree(dca_dbgfs);
}

static int poe_debugfs_en_show(struct seq_file *file, void *offset)
{
	struct hns_roce_poe_ch *poe_ch = file->private;

	seq_printf(file, "%-10s\n", poe_ch->en ? "enable" : "disable");
	return 0;
}

static int poe_debugfs_addr_show(struct seq_file *file, void *offset)
{
#define POE_ADDR_OFFSET_MASK GENMASK(31, 0)
	struct hns_roce_poe_ch *poe_ch = file->private;

	seq_printf(file, "0x%llx\n", poe_ch->addr & POE_ADDR_OFFSET_MASK);
	return 0;
}

static int poe_debugfs_ref_cnt_show(struct seq_file *file, void *offset)
{
	struct hns_roce_poe_ch *poe_ch = file->private;

	seq_printf(file, "0x%-10u\n", refcount_read(&poe_ch->ref_cnt));
	return 0;
}

static void init_poe_ch_debugfs(struct hns_roce_dev *hr_dev, uint8_t index,
				struct dentry *parent)
{
#define POE_CH_NAME_LEN 10
	struct hns_roce_poe_ch *poe_ch = &hr_dev->poe_ctx.poe_ch[index];
	struct hns_poe_ch_debugfs *dbgfs;
	char name[POE_CH_NAME_LEN];

	dbgfs = kvzalloc(sizeof(*dbgfs), GFP_KERNEL);
	if (!dbgfs)
		return;

	snprintf(name, sizeof(name), "poe_%u", index);
	dbgfs->root = debugfs_create_dir(name, parent);

	init_debugfs_seqfile(&dbgfs->en, "en", dbgfs->root,
			     poe_debugfs_en_show, poe_ch);
	init_debugfs_seqfile(&dbgfs->addr, "addr", dbgfs->root,
			     poe_debugfs_addr_show, poe_ch);
	init_debugfs_seqfile(&dbgfs->ref_cnt, "ref_cnt", dbgfs->root,
			     poe_debugfs_ref_cnt_show, poe_ch);
	poe_ch->poe_ch_debugfs = dbgfs;
}

static void cleanup_poe_ch_debugfs(struct hns_roce_dev *hr_dev, uint8_t index)
{
	struct hns_roce_poe_ch *poe_ch = &hr_dev->poe_ctx.poe_ch[index];
	struct hns_poe_ch_debugfs *dbgfs = poe_ch->poe_ch_debugfs;

	cleanup_debugfs_seqfile(&dbgfs->en);
	cleanup_debugfs_seqfile(&dbgfs->addr);
	cleanup_debugfs_seqfile(&dbgfs->ref_cnt);
	debugfs_remove_recursive(dbgfs->root);
	kvfree(dbgfs);
}

static struct hns_poe_debugfs *
create_poe_debugfs(struct hns_roce_dev *hr_dev, struct dentry *parent)
{
	struct hns_poe_debugfs *dbgfs;
	int i;

	dbgfs = kvzalloc(sizeof(*dbgfs), GFP_KERNEL);
	if (!dbgfs)
		return NULL;

	dbgfs->root = debugfs_create_dir("poe", parent);

	for (i = 0; i < hr_dev->poe_ctx.poe_num; i++)
		init_poe_ch_debugfs(hr_dev, i, dbgfs->root);

	return dbgfs;
}

static void destroy_poe_debugfs(struct hns_roce_dev *hr_dev,
				struct hns_poe_debugfs *poe_dbgfs)
{
	int i;

	for (i = 0; i < hr_dev->poe_ctx.poe_num; i++)
		cleanup_poe_ch_debugfs(hr_dev, i);

	debugfs_remove_recursive(poe_dbgfs->root);
	kvfree(poe_dbgfs);
}

/* debugfs for ucontext */
void hns_roce_register_uctx_debugfs(struct hns_roce_dev *hr_dev,
				    struct hns_roce_ucontext *uctx)
@@ -553,6 +656,9 @@ void hns_roce_register_debugfs(struct hns_roce_dev *hr_dev)
	if (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_DCA_MODE)
		dbgfs->dca_root = create_dca_debugfs(hr_dev, dbgfs->root);

	if (poe_is_supported(hr_dev))
		dbgfs->poe_root = create_poe_debugfs(hr_dev, dbgfs->root);

	hr_dev->dbgfs = dbgfs;
}

@@ -572,6 +678,11 @@ void hns_roce_unregister_debugfs(struct hns_roce_dev *hr_dev)
		dbgfs->dca_root = NULL;
	}

	if (dbgfs->poe_root) {
		destroy_poe_debugfs(hr_dev, dbgfs->poe_root);
		dbgfs->poe_root = NULL;
	}

	debugfs_remove_recursive(dbgfs->root);
	hr_dev->dbgfs = NULL;
	kfree(dbgfs);
+63 −0
Original line number Diff line number Diff line
@@ -37,9 +37,11 @@
#include <rdma/ib_verbs.h>
#include <rdma/hns-abi.h>
#include "hns_roce_bond.h"
#include "hns_roce_ext.h"

#define PCI_REVISION_ID_HIP08			0x21
#define PCI_REVISION_ID_HIP09			0x30
#define PCI_REVISION_ID_HIP10			0x32

#define HNS_ROCE_MAX_MSG_LEN			0x80000000

@@ -104,6 +106,10 @@
#define CQ_BANKID_SHIFT 2
#define CQ_BANKID_MASK GENMASK(1, 0)

#define MAX_NOTIFY_MEM_SIZE BIT(24)

#define HNS_ROCE_MEM_BAR 2

enum {
	SERV_TYPE_RC,
	SERV_TYPE_UC,
@@ -160,10 +166,12 @@ enum {
	HNS_ROCE_CAP_FLAG_SVE_DIRECT_WQE	= BIT(13),
	HNS_ROCE_CAP_FLAG_SDI_MODE		= BIT(14),
	HNS_ROCE_CAP_FLAG_DCA_MODE		= BIT(15),
	HNS_ROCE_CAP_FLAG_WRITE_NOTIFY          = BIT(16),
	HNS_ROCE_CAP_FLAG_STASH			= BIT(17),
	HNS_ROCE_CAP_FLAG_CQE_INLINE		= BIT(19),
	HNS_ROCE_CAP_FLAG_BOND			= BIT(21),
	HNS_ROCE_CAP_FLAG_SRQ_RECORD_DB		= BIT(22),
	HNS_ROCE_CAP_FLAG_POE                   = BIT(27),
};

#define HNS_ROCE_DB_TYPE_COUNT			2
@@ -221,6 +229,18 @@ struct hns_user_mmap_entry {
	u64 address;
};

struct hns_roce_poe_ch {
	uint8_t en;
	refcount_t ref_cnt;
	uint64_t addr;
	void *poe_ch_debugfs;
};

struct hns_roce_poe_ctx {
	uint8_t poe_num;
	struct hns_roce_poe_ch *poe_ch;
};

struct hns_roce_dca_ctx {
	struct list_head pool; /* all DCA mems link to @pool */
	spinlock_t pool_lock; /* protect @pool */
@@ -473,6 +493,22 @@ struct hns_roce_db {
	unsigned long	order;
};

enum hns_roce_notify_mode {
	HNS_ROCE_NOTIFY_MODE_64B_ALIGN = 0,
	HNS_ROCE_NOTIFY_MODE_4B_ALIGN = 1,
};

enum hns_roce_notify_device_en {
	HNS_ROCE_NOTIFY_DEV = 0,
	HNS_ROCE_NOTIFY_DDR = 1,
};

struct hns_roce_notify_conf {
	u64 notify_addr; /* should be aligned to 4k */
	u8 notify_mode; /* use enum hns_roce_notify_mode */
	u8 notify_device_en; /* use enum hns_roce_notify_device_en */
};

struct hns_roce_cq {
	struct ib_cq			ib_cq;
	struct hns_roce_mtr		mtr;
@@ -493,6 +529,8 @@ struct hns_roce_cq {
	struct list_head		rq_list; /* all qps on this recv cq */
	int				is_armed; /* cq is armed */
	struct list_head		node; /* all armed cqs are on a list */
	u8				poe_channel;
	struct hns_roce_notify_conf	write_notify;
};

struct hns_roce_idx_que {
@@ -788,6 +826,8 @@ enum congest_type {
	HNS_ROCE_CONGEST_TYPE_DIP = 1 << HNS_ROCE_SCC_ALGO_DIP,
};

#define HNS_ROCE_POE_CH_NUM 4

struct hns_roce_caps {
	u64		fw_ver;
	u8		num_ports;
@@ -919,6 +959,7 @@ struct hns_roce_caps {
	u16		default_ceq_arm_st;
	u8		congest_type;
	u8		default_congest_type;
	u8              poe_ch_num;
};

enum hns_roce_device_state {
@@ -1034,6 +1075,7 @@ struct hns_roce_hw {
				enum hns_roce_scc_algo algo);
	int (*query_scc_param)(struct hns_roce_dev *hr_dev, u8 port_num,
			       enum hns_roce_scc_algo alog);
	int (*cfg_poe_ch)(struct hns_roce_dev *hr_dev, u32 index, u64 poe_addr);
};

#define HNS_ROCE_SCC_PARAM_SIZE 4
@@ -1092,6 +1134,10 @@ struct hns_roce_dev {
	u32                     vendor_id;
	u32                     vendor_part_id;
	u32                     hw_rev;
	u16 chip_id;
	u16 die_id;
	u16 mac_id;
	u16 func_id;
	void __iomem            *priv_addr;

	struct hns_roce_cmdq	cmd;
@@ -1129,6 +1175,10 @@ struct hns_roce_dev {
	struct notifier_block bond_nb;
	struct hns_roce_port port_data[HNS_ROCE_MAX_PORTS];
	atomic64_t *dfx_cnt;
	struct hns_roce_poe_ctx poe_ctx; /* poe ch array */

	struct rdma_notify_mem *notify_tbl;
	size_t notify_num;
};

static inline struct hns_roce_dev *to_hr_dev(struct ib_device *ib_dev)
@@ -1286,6 +1336,16 @@ static inline u8 get_hr_bus_num(struct hns_roce_dev *hr_dev)
	return hr_dev->pci_dev->bus->number;
}

static inline bool poe_is_supported(struct hns_roce_dev *hr_dev)
{
	return !!(hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_POE);
}

static inline bool is_write_notify_supported(struct hns_roce_dev *dev)
{
	return !!(dev->caps.flags & HNS_ROCE_CAP_FLAG_WRITE_NOTIFY);
}

void hns_roce_init_uar_table(struct hns_roce_dev *dev);
int hns_roce_uar_alloc(struct hns_roce_dev *dev, struct hns_roce_uar *uar);

@@ -1427,4 +1487,7 @@ hns_roce_user_mmap_entry_insert(struct ib_ucontext *ucontext, u64 address,
int hns_roce_create_port_files(struct ib_device *ibdev, u8 port_num,
			       struct kobject *kobj);
void hns_roce_unregister_sysfs(struct hns_roce_dev *hr_dev);
int hns_roce_register_poe_channel(struct hns_roce_dev *hr_dev, u8 channel,
				  u64 poe_addr);
int hns_roce_unregister_poe_channel(struct hns_roce_dev *hr_dev, u8 channel);
#endif /* _HNS_ROCE_DEVICE_H */
Loading