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

!2875 Support SRQ Context tracing by debugfs

Merge Pull Request from: @stinft 
 
This pull request submits two patches. The first patch refactors the hns debugfs function, and the second patch supports querying SRQ context by debugfs.
Junxian Huang (1):
   RDMA/hns: Refactor hns RoCE debugfs
https://gitee.com/openeuler/kernel/issues/I8GHCT

wenglianfa (1):
   RDMA/hns: Support SRQ Context tracing by debugfs
https://gitee.com/openeuler/kernel/issues/I8GHD9 
 
Link:https://gitee.com/openeuler/kernel/pulls/2875

 

Reviewed-by: default avatarChengchang Tang <tangchengchang@huawei.com>
Signed-off-by: default avatarJialin Zhang <zhangjialin11@huawei.com>
parents 26187503 0355dea3
Loading
Loading
Loading
Loading
+143 −175
Original line number Diff line number Diff line
@@ -9,18 +9,12 @@
#include "hns_roce_common.h"
#include "hns_roce_device.h"
#include "hns_roce_dca.h"
#include "hns_roce_debugfs.h"

static struct dentry *hns_roce_dbgfs_root;

#define KB 1024

/* debugfs seqfile */
struct hns_debugfs_seqfile {
	struct dentry *entry;
	int (*read)(struct seq_file *seq, void *data);
	void *data;
};
#define SRQN_BUF_SIZE 12

static int hns_debugfs_seqfile_open(struct inode *inode, struct file *f)
{
@@ -29,6 +23,107 @@ static int hns_debugfs_seqfile_open(struct inode *inode, struct file *f)
	return single_open(f, seqfile->read, seqfile->data);
}

static ssize_t srqn_debugfs_store(struct file *file, const char __user *user_buf,
				  size_t size, loff_t *ppos)
{
	struct hns_roce_dev *hr_dev = file->private_data;
	struct hns_srq_debugfs *dbgfs = &hr_dev->dbgfs.srq_root;
	atomic_t *atomic_srqn = &dbgfs->atomic_srqn;
	u32 max = hr_dev->srq_table.srq_ida.max;
	u32 num;
	int ret;

	if (size > SRQN_BUF_SIZE)
		return -EINVAL;

	ret = kstrtou32_from_user(user_buf, size, 0, &num);
	if (ret)
		return ret;

	if (num > max)
		return -ERANGE;

	atomic_set(atomic_srqn, (int)num);

	return size;
}

static ssize_t srqn_debugfs_show(struct file *file, char __user *user_buf,
				 size_t size, loff_t *ppos)
{
	struct hns_roce_dev *hr_dev = file->private_data;
	struct hns_srq_debugfs *dbgfs = &hr_dev->dbgfs.srq_root;
	u32 srqn = (u32)atomic_read(&dbgfs->atomic_srqn);
	char buf[SRQN_BUF_SIZE];
	int ret;

	ret = snprintf(buf, sizeof(buf), "%u\n", srqn);
	if (ret < 0)
		return ret;

	return simple_read_from_buffer(user_buf, size, ppos, buf, ret);
}

static void print_json_srqc(struct ib_device *device,
			    struct seq_file *file,
			    uint8_t *data,
			    u32 srqn,
			    int size)
{
	int i = 0;

	seq_puts(file, "[ {\n");
	seq_printf(file, "\t\"srqn\": %u,\n", srqn);
	seq_printf(file, "\t\"ifindex\": %u,\n", device->index);
	seq_printf(file, "\t\"ifname\": \"%s\",\n", dev_name(&device->dev));
	seq_puts(file, "\t\"data\": [ ");
	while (i < size - 1) {
		seq_printf(file, "%d,", data[i]);
		i++;
	}
	seq_printf(file, "%d", data[i]);
	seq_puts(file, " ]\n");
	seq_puts(file, "} ]\n");
}

static int srqc_debugfs_show(struct seq_file *file, void *offset)
{
	struct hns_roce_dev *hr_dev = file->private;
	struct hns_srq_debugfs *dbgfs = &hr_dev->dbgfs.srq_root;
	int srqc_size = hr_dev->caps.srqc_entry_sz;
	u32 srqn = (u32)atomic_read(&dbgfs->atomic_srqn);
	void *data;
	int ret;

	if (!hns_roce_is_srq_exist(hr_dev, srqn))
		return -EINVAL;

	if (!hr_dev->hw->query_srqc)
		return -EOPNOTSUPP;

	data = kvcalloc(1, srqc_size, GFP_KERNEL);
	if (!data)
		return -ENOMEM;

	ret = hr_dev->hw->query_srqc(hr_dev, srqn, data);
	if (ret)
		goto out;

	print_json_srqc(&hr_dev->ib_dev, file, data, srqn, srqc_size);

out:
	kvfree(data);

	return ret;
}

static const struct file_operations hns_srqn_fops = {
	.owner = THIS_MODULE,
	.open	= simple_open,
	.write	= srqn_debugfs_store,
	.read = srqn_debugfs_show,
};

static const struct file_operations hns_debugfs_seqfile_fops = {
	.owner = THIS_MODULE,
	.open = hns_debugfs_seqfile_open,
@@ -52,50 +147,6 @@ static void init_debugfs_seqfile(struct hns_debugfs_seqfile *seq,
	seq->entry = entry;
}

static void cleanup_debugfs_seqfile(struct hns_debugfs_seqfile *seq)
{
	debugfs_remove(seq->entry);
	seq->entry = NULL;
}

/* DCA debugfs */
struct hns_dca_ctx_debugfs {
	struct dentry *root; /* pool debugfs entry */
	struct hns_debugfs_seqfile mem; /* mems in pool */
	struct hns_debugfs_seqfile qp; /* QPs stats in pool */
};

struct hns_dca_debugfs {
	struct dentry *root; /* dev debugfs entry */
	struct hns_debugfs_seqfile pool; /* pools stats on device */
	struct hns_debugfs_seqfile qp; /* QPs stats on device */
	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 */
};

struct hns_sw_stat_debugfs {
	struct dentry *root;
	struct hns_debugfs_seqfile sw_stat;
};

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

struct dca_mem_stats {
	unsigned int total_mems;
	unsigned int clean_mems;
@@ -464,21 +515,11 @@ static void init_dca_ctx_debugfs(struct hns_dca_ctx_debugfs *dbgfs,
	}
}

static void cleanup_dca_ctx_debugfs(struct hns_dca_ctx_debugfs *ctx_dbgfs)
{
	cleanup_debugfs_seqfile(&ctx_dbgfs->qp);
	cleanup_debugfs_seqfile(&ctx_dbgfs->mem);
	debugfs_remove_recursive(ctx_dbgfs->root);
}

static struct hns_dca_debugfs *
create_dca_debugfs(struct hns_roce_dev *hr_dev, struct dentry *parent)
static void create_dca_debugfs(struct hns_roce_dev *hr_dev,
			       struct dentry *parent)
{
	struct hns_dca_debugfs *dbgfs;

	dbgfs = kzalloc(sizeof(*dbgfs), GFP_KERNEL);
	if (!dbgfs)
		return NULL;
	struct hns_dca_debugfs *dbgfs = &hr_dev->dbgfs.dca_root;

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

@@ -488,17 +529,6 @@ create_dca_debugfs(struct hns_roce_dev *hr_dev, struct dentry *parent)
			     dca_debugfs_qp_show, hr_dev);

	init_dca_ctx_debugfs(&dbgfs->kctx, dbgfs->root, hr_dev, NULL);

	return dbgfs;
}

static void destroy_dca_debugfs(struct hns_dca_debugfs *dca_dbgfs)
{
	cleanup_dca_ctx_debugfs(&dca_dbgfs->kctx);
	cleanup_debugfs_seqfile(&dca_dbgfs->pool);
	cleanup_debugfs_seqfile(&dca_dbgfs->qp);
	debugfs_remove_recursive(dca_dbgfs->root);
	kfree(dca_dbgfs);
}

static int poe_debugfs_en_show(struct seq_file *file, void *offset)
@@ -547,83 +577,40 @@ static void init_poe_ch_debugfs(struct hns_roce_dev *hr_dev, uint8_t index,
			     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)
static void create_poe_debugfs(struct hns_roce_dev *hr_dev,
			       struct dentry *parent)
{
	struct hns_poe_debugfs *dbgfs;
	struct hns_poe_debugfs *dbgfs = &hr_dev->dbgfs.poe_root;
	u8 poe_num = hr_dev->poe_ctx.poe_num;
	int i;

	dbgfs = kvzalloc(sizeof(*dbgfs), GFP_KERNEL);
	if (!dbgfs)
		return NULL;
	dbgfs->poe_ch = kvcalloc(poe_num, sizeof(*dbgfs->poe_ch), GFP_KERNEL);
	if (!dbgfs->poe_ch)
		return;

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

	for (i = 0; i < hr_dev->poe_ctx.poe_num; i++)
	for (i = 0; i < 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)
{
	struct hns_roce_dev_debugfs *dev_dbgfs = hr_dev->dbgfs;
	struct hns_dca_debugfs *dca_dbgfs;

	if (!dev_dbgfs)
		return;
	struct hns_dca_debugfs *dca_dbgfs = &hr_dev->dbgfs.dca_root;

	dca_dbgfs = dev_dbgfs->dca_root;
	if (dca_dbgfs && (uctx->config & HNS_ROCE_UCTX_CONFIG_DCA)) {
		uctx->dca_dbgfs = kzalloc(sizeof(struct hns_dca_ctx_debugfs),
					  GFP_KERNEL);
		if (!uctx->dca_dbgfs)
			return;

		init_dca_ctx_debugfs(uctx->dca_dbgfs, dca_dbgfs->root,
	if (uctx->config & HNS_ROCE_UCTX_CONFIG_DCA)
		init_dca_ctx_debugfs(&uctx->dca_dbgfs, dca_dbgfs->root,
				     hr_dev, uctx);
}
}

void hns_roce_unregister_uctx_debugfs(struct hns_roce_dev *hr_dev,
				      struct hns_roce_ucontext *uctx)
{
	struct hns_dca_ctx_debugfs *dbgfs = uctx->dca_dbgfs;

	if (dbgfs) {
		cleanup_dca_ctx_debugfs(dbgfs);
		uctx->dca_dbgfs = NULL;
		kfree(dbgfs);
	}
	debugfs_remove_recursive(uctx->dca_dbgfs.root);
}

static const char * const sw_stat_info[] = {
@@ -660,79 +647,60 @@ static int sw_stat_debugfs_show(struct seq_file *file, void *offset)
	return 0;
}

static struct hns_sw_stat_debugfs
	*create_sw_stat_debugfs(struct hns_roce_dev *hr_dev,
static void create_sw_stat_debugfs(struct hns_roce_dev *hr_dev,
				   struct dentry *parent)
{
	struct hns_sw_stat_debugfs *dbgfs;

	dbgfs = kvzalloc(sizeof(*dbgfs), GFP_KERNEL);
	if (!dbgfs)
		return NULL;
	struct hns_sw_stat_debugfs *dbgfs = &hr_dev->dbgfs.sw_stat_root;

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

	init_debugfs_seqfile(&dbgfs->sw_stat, "sw_stat", dbgfs->root,
			     sw_stat_debugfs_show, hr_dev);
	return dbgfs;
}

static void destroy_sw_stat_debugfs(struct hns_sw_stat_debugfs *sw_stat_dbgfs)
static void create_srq_debugfs(struct hns_roce_dev *hr_dev,
				struct dentry *parent)
{
	cleanup_debugfs_seqfile(&sw_stat_dbgfs->sw_stat);
	debugfs_remove_recursive(sw_stat_dbgfs->root);
	kvfree(sw_stat_dbgfs);
	struct hns_srq_debugfs *dbgfs = &hr_dev->dbgfs.srq_root;

	atomic_set(&dbgfs->atomic_srqn, 0);

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

	dbgfs->srqn.entry = debugfs_create_file("srqn", 0600, dbgfs->root,
						hr_dev, &hns_srqn_fops);

	init_debugfs_seqfile(&dbgfs->srqc, "srqc", dbgfs->root,
			     srqc_debugfs_show, hr_dev);
}

/* debugfs for device */
void hns_roce_register_debugfs(struct hns_roce_dev *hr_dev)
{
	struct hns_roce_dev_debugfs *dbgfs;

	dbgfs = kzalloc(sizeof(*dbgfs), GFP_KERNEL);
	if (!dbgfs)
		return;
	struct hns_roce_dev_debugfs *dbgfs = &hr_dev->dbgfs;

	dbgfs->root = debugfs_create_dir(dev_name(&hr_dev->ib_dev.dev),
					 hns_roce_dbgfs_root);

	if (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_DCA_MODE)
		dbgfs->dca_root = create_dca_debugfs(hr_dev, dbgfs->root);
		create_dca_debugfs(hr_dev, dbgfs->root);

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

	dbgfs->sw_stat_root = create_sw_stat_debugfs(hr_dev, dbgfs->root);

	hr_dev->dbgfs = dbgfs;
	create_sw_stat_debugfs(hr_dev, dbgfs->root);
	create_srq_debugfs(hr_dev, dbgfs->root);
}

void hns_roce_unregister_debugfs(struct hns_roce_dev *hr_dev)
{
	struct hns_roce_dev_debugfs *dbgfs;

	dbgfs = hr_dev->dbgfs;
	if (!dbgfs)
		return;

	if (dbgfs->dca_root) {
		destroy_dca_debugfs(dbgfs->dca_root);
		dbgfs->dca_root = NULL;
	}
	debugfs_remove_recursive(hr_dev->dbgfs.root);

	if (dbgfs->poe_root) {
		destroy_poe_debugfs(hr_dev, dbgfs->poe_root);
		dbgfs->poe_root = NULL;
	if (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_POE &&
	    hr_dev->dbgfs.poe_root.poe_ch) {
		kvfree(hr_dev->dbgfs.poe_root.poe_ch);
		hr_dev->dbgfs.poe_root.poe_ch = NULL;
	}

	if (dbgfs->sw_stat_root) {
		destroy_sw_stat_debugfs(dbgfs->sw_stat_root);
		dbgfs->sw_stat_root = NULL;
	}

	debugfs_remove_recursive(dbgfs->root);
	hr_dev->dbgfs = NULL;
	kfree(dbgfs);
}

/* debugfs for hns module */
+57 −0
Original line number Diff line number Diff line
@@ -4,6 +4,63 @@
#ifndef __HNS_ROCE_DEBUGFS_H
#define __HNS_ROCE_DEBUGFS_H

/* debugfs seqfile */
struct hns_debugfs_seqfile {
	struct dentry *entry;
	int (*read)(struct seq_file *seq, void *data);
	void *data;
};

/* DCA debugfs */
struct hns_dca_ctx_debugfs {
	struct dentry *root; /* pool debugfs entry */
	struct hns_debugfs_seqfile mem; /* mems in pool */
	struct hns_debugfs_seqfile qp; /* QPs stats in pool */
};

struct hns_dca_debugfs {
	struct dentry *root; /* dev debugfs entry */
	struct hns_debugfs_seqfile pool; /* pools stats on device */
	struct hns_debugfs_seqfile qp; /* QPs stats on device */
	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 */
	struct hns_poe_ch_debugfs *poe_ch;
};

struct hns_sw_stat_debugfs {
	struct dentry *root;
	struct hns_debugfs_seqfile sw_stat;
};

struct hns_srq_debugfs {
	struct dentry *root;
	struct hns_debugfs_seqfile srqc;
	struct hns_debugfs_seqfile srqn;
	atomic_t atomic_srqn;
};

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

struct hns_roce_dev;
struct hns_roce_ucontext;

void hns_roce_init_debugfs(void);
void hns_roce_cleanup_debugfs(void);
void hns_roce_register_debugfs(struct hns_roce_dev *hr_dev);
+5 −2
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@
#include <rdma/hns-abi.h>
#include "hns_roce_bond.h"
#include "hns_roce_ext.h"
#include "hns_roce_debugfs.h"

#define PCI_REVISION_ID_HIP08			0x21
#define PCI_REVISION_ID_HIP09			0x30
@@ -278,7 +279,7 @@ struct hns_roce_ucontext {
	struct hns_user_mmap_entry *reset_mmap_entry;
	u32			config;
	struct hns_roce_dca_ctx	dca_ctx;
	void *dca_dbgfs;
	struct hns_dca_ctx_debugfs dca_dbgfs;
};

struct hns_roce_pd {
@@ -1062,6 +1063,7 @@ struct hns_roce_hw {
	int (*write_srqc)(struct hns_roce_srq *srq, void *mb_buf);
	int (*query_cqc)(struct hns_roce_dev *hr_dev, u32 cqn, void *buffer);
	int (*query_qpc)(struct hns_roce_dev *hr_dev, u32 qpn, void *buffer);
	int (*query_srqc)(struct hns_roce_dev *hr_dev, u32 srqn, void *buffer);
	int (*query_mpt)(struct hns_roce_dev *hr_dev, u32 key, void *buffer);
	int (*query_sccc)(struct hns_roce_dev *hr_dev, u32 qpn, void *buffer);
	int (*get_dscp)(struct hns_roce_dev *hr_dev, u8 dscp,
@@ -1102,7 +1104,7 @@ struct hns_roce_dev {
	struct ib_device	ib_dev;
	struct pci_dev		*pci_dev;
	struct device		*dev;
	void			*dbgfs; /* debugfs for this dev */
	struct hns_roce_dev_debugfs dbgfs; /* debugfs for this dev */

	struct list_head	uctx_list; /* list of all uctx on this dev */
	spinlock_t		uctx_list_lock; /* protect @uctx_list */
@@ -1492,4 +1494,5 @@ 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);
bool hns_roce_is_srq_exist(struct hns_roce_dev *hr_dev, u32 srqn);
#endif /* _HNS_ROCE_DEVICE_H */
+25 −1
Original line number Diff line number Diff line
@@ -50,7 +50,6 @@
#include "hns_roce_hem.h"
#include "hns_roce_dca.h"
#include "hns_roce_hw_v2.h"
#include "hns_roce_debugfs.h"

enum {
	CMD_RST_PRC_OTHERS,
@@ -5774,6 +5773,30 @@ static int hns_roce_v2_query_qpc(struct hns_roce_dev *hr_dev, u32 qpn,
	return ret;
}

static int hns_roce_v2_query_srqc(struct hns_roce_dev *hr_dev, u32 srqn,
				 void *buffer)
{
	struct hns_roce_srq_context *context;
	struct hns_roce_cmd_mailbox *mailbox;
	int ret;

	mailbox = hns_roce_alloc_cmd_mailbox(hr_dev);
	if (IS_ERR(mailbox))
		return PTR_ERR(mailbox);

	context  = mailbox->buf;
	ret = hns_roce_cmd_mbox(hr_dev, 0, mailbox->dma, HNS_ROCE_CMD_QUERY_SRQC,
				srqn);
	if (ret)
		goto out;

	memcpy(buffer, context, sizeof(*context));

out:
	hns_roce_free_cmd_mailbox(hr_dev, mailbox);
	return ret;
}

static int hns_roce_v2_query_sccc(struct hns_roce_dev *hr_dev, u32 qpn,
				  void *buffer)
{
@@ -7351,6 +7374,7 @@ static const struct hns_roce_hw hns_roce_hw_v2 = {
	.query_cqc = hns_roce_v2_query_cqc,
	.query_qpc = hns_roce_v2_query_qpc,
	.query_mpt = hns_roce_v2_query_mpt,
	.query_srqc = hns_roce_v2_query_srqc,
	.query_sccc = hns_roce_v2_query_sccc,
	.get_dscp = hns_roce_hw_v2_get_dscp,
	.hns_roce_dev_ops = &hns_roce_v2_dev_ops,
+0 −1
Original line number Diff line number Diff line
@@ -44,7 +44,6 @@
#include "hns_roce_hem.h"
#include "hns_roce_hw_v2.h"
#include "hns_roce_dca.h"
#include "hns_roce_debugfs.h"

static struct net_device *hns_roce_get_netdev(struct ib_device *ib_dev,
					      u8 port_num)
Loading