[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20251107084320.555979-3-allen.wang@hj-micro.com>
Date: Fri, 7 Nov 2025 16:43:19 +0800
From: Shouping Wang <allen.wang@...micro.com>
To: will@...nel.org,
robin.murphy@....com
Cc: mark.rutland@....com,
linux-arm-kernel@...ts.infradead.org,
linux-kernel@...r.kernel.org,
allen.wang@...micro.com,
andy.xu@...micro.com,
peter.du@...micro.com
Subject: [PATCH 2/2] perf: arm-ni: add topology debug info for the clock domain
When capturing PMU info with perf, it is necessary to know the nodeid of
the interface. Here, we add topology debug info for the clock domain to
display the nodeid of the interfaces.
$ cat /sys/kernel/debug/arm-ni/map_1f3c06
as shown below:
| HSNI #5 || PMNI #6 || PMU #14 |
Signed-off-by: Shouping Wang <allen.wang@...micro.com>
---
drivers/perf/arm-ni.c | 63 ++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 62 insertions(+), 1 deletion(-)
diff --git a/drivers/perf/arm-ni.c b/drivers/perf/arm-ni.c
index 32eabdbe877a..e0f0e18d0120 100644
--- a/drivers/perf/arm-ni.c
+++ b/drivers/perf/arm-ni.c
@@ -13,6 +13,7 @@
#include <linux/perf_event.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
+#include <linux/debugfs.h>
/* Common registers */
#define NI_NODE_TYPE 0x000
@@ -110,6 +111,7 @@ struct arm_ni_cd {
struct arm_ni_unit *units;
struct perf_event *evcnt[NI_NUM_COUNTERS];
struct perf_event *ccnt;
+ struct dentry *debug;
};
struct arm_ni {
@@ -476,6 +478,59 @@ static irqreturn_t arm_ni_handle_irq(int irq, void *dev_id)
}
}
+static struct dentry *arm_ni_cd_debugfs;
+
+#ifdef CONFIG_DEBUG_FS
+static const char *arm_ni_node_type(enum ni_node_type type)
+{
+ switch (type) {
+ case NI_ASNI:
+ return "| ASNI ";
+ case NI_AMNI:
+ return "| AMNI ";
+ case NI_PMU:
+ return "| PMU ";
+ case NI_HSNI:
+ return "| HSNI ";
+ case NI_HMNI:
+ return "| HMNI ";
+ case NI_PMNI:
+ return "| PMNI ";
+ default:
+ return "| ???? ";
+ }
+}
+
+static int arm_ni_cd_map_show(struct seq_file *s, void *data)
+{
+ struct arm_ni_cd *cd = s->private;
+
+ cd_for_each_unit(cd, unit) {
+ seq_printf(s, "%s#%-2d |", arm_ni_node_type(unit->type), unit->id);
+ }
+ seq_puts(s, "\n");
+
+ return 0;
+}
+
+DEFINE_SHOW_ATTRIBUTE(arm_ni_cd_map);
+
+static void arm_ni_cd_debugfs_init(struct arm_ni_cd *cd, u64 res_start)
+{
+ const char *name = "map";
+
+ if (res_start > 0)
+ name = devm_kasprintf(cd_to_ni(cd)->dev, GFP_KERNEL, "map_%llx",
+ res_start >> NI_PMU_PA_SHIFT);
+ if (!name)
+ return;
+
+ cd->debug = debugfs_create_file(name, 0444, arm_ni_cd_debugfs, cd, &arm_ni_cd_map_fops);
+}
+#else
+static void arm_ni_cd_debugfs_init(struct arm_ni_cd *cd, u64 res_start) {}
+#endif
+
static int arm_ni_init_cd(struct arm_ni *ni, struct arm_ni_node *node, u64 res_start)
{
struct arm_ni_cd *cd = ni->cds + node->id;
@@ -563,6 +618,7 @@ static int arm_ni_init_cd(struct arm_ni *ni, struct arm_ni_node *node, u64 res_s
name = devm_kasprintf(ni->dev, GFP_KERNEL, "arm_ni_%llx", res_start >> NI_PMU_PA_SHIFT);
if (!name)
return -ENOMEM;
+ arm_ni_cd_debugfs_init(cd, res_start);
return perf_pmu_register(&cd->pmu, name, -1);
}
@@ -575,6 +631,7 @@ static void arm_ni_remove(struct platform_device *pdev)
writel_relaxed(0, cd->pmu_base + NI_PMCR);
writel_relaxed(U32_MAX, cd->pmu_base + NI_PMINTENCLR);
perf_pmu_unregister(&cd->pmu);
+ debugfs_remove(cd->debug);
}
cpuhp_state_remove_instance_nocalls(arm_ni_hp_state, &ni->cpuhp_node);
}
@@ -787,9 +844,12 @@ static int __init arm_ni_init(void)
arm_ni_hp_state = ret;
+ arm_ni_cd_debugfs = debugfs_create_dir("arm-ni", NULL);
ret = platform_driver_register(&arm_ni_driver);
- if (ret)
+ if (ret) {
cpuhp_remove_multi_state(arm_ni_hp_state);
+ debugfs_remove(arm_ni_cd_debugfs);
+ }
return ret;
}
@@ -797,6 +857,7 @@ static void __exit arm_ni_exit(void)
{
platform_driver_unregister(&arm_ni_driver);
cpuhp_remove_multi_state(arm_ni_hp_state);
+ debugfs_remove(arm_ni_cd_debugfs);
}
module_init(arm_ni_init);
--
2.43.0
Powered by blists - more mailing lists