linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC][PATCH v2 06/11] perf: core, export pmus via sysfs
@ 2010-05-19  1:46 Lin Ming
  2010-05-18 20:05 ` Greg KH
  2010-05-18 20:07 ` Greg KH
  0 siblings, 2 replies; 46+ messages in thread
From: Lin Ming @ 2010-05-19  1:46 UTC (permalink / raw)
  To: Peter Zijlstra, Ingo Molnar, Corey Ashford
  Cc: Frederic Weisbecker, Paul Mundt, eranian, Gary.Mohr@Bull.com,
	arjan, Zhang, Yanmin, Paul Mackerras, David S. Miller,
	Russell King, Arnaldo Carvalho de Melo, Will Deacon,
	Maynard Johnson, Carl Love, greg, Kay Sievers, lkml

Now only exports cpu hardware events.

For each PMU, there are 2 sysfs dirs: event_source and events.

For example,
/sys/devices/system/cpu/event_source/
/sys/devices/system/cpu/events/

$ tree /sys/devices/system/cpu/event_source/
/sys/devices/system/cpu/event_source/
`-- id

$ tree /sys/devices/system/cpu/events/
/sys/devices/system/cpu/events/
|-- L1-dcache-load-misses
|   |-- event_source -> ../../event_source
|   `-- id
|-- LLC-load-misses
|   |-- event_source -> ../../event_source
|   `-- id
|-- branch-misses
|   |-- event_source -> ../../event_source
|   `-- id
|-- branches
|   |-- event_source -> ../../event_source
|   `-- id
|-- bus-cycles
|   |-- event_source -> ../../event_source
|   `-- id
|-- cache-misses
|   |-- event_source -> ../../event_source
|   `-- id
|-- cache-references
|   |-- event_source -> ../../event_source
|   `-- id
|-- cycles
|   |-- event_source -> ../../event_source
|   `-- id
|-- dTLB-load-misses
|   |-- event_source -> ../../event_source
|   `-- id
|-- dTLB-store-misses
|   |-- event_source -> ../../event_source
|   `-- id
|-- iTLB-load-misses
|   |-- event_source -> ../../event_source
|   `-- id
|-- iTLB-load-refs
|   |-- event_source -> ../../event_source
|   `-- id
`-- instructions
    |-- event_source -> ../../event_source
    `-- id

Signed-off-by: Lin Ming <ming.m.lin@intel.com> 
---
 drivers/base/node.c        |    3 +-
 include/linux/node.h       |    2 +
 include/linux/perf_event.h |   10 +++
 kernel/perf_event.c        |  169 ++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 183 insertions(+), 1 deletions(-)

diff --git a/drivers/base/node.c b/drivers/base/node.c
index 057979a..3b77585 100644
--- a/drivers/base/node.c
+++ b/drivers/base/node.c
@@ -19,10 +19,11 @@
 
 static struct sysdev_class_attribute *node_state_attrs[];
 
-static struct sysdev_class node_class = {
+struct sysdev_class node_class = {
 	.name = "node",
 	.attrs = node_state_attrs,
 };
+EXPORT_SYMBOL(node_class);
 

 static ssize_t node_read_cpumap(struct sys_device *dev, int type, char *buf)
diff --git a/include/linux/node.h b/include/linux/node.h
index 06292da..43e4422 100644
--- a/include/linux/node.h
+++ b/include/linux/node.h
@@ -50,6 +50,8 @@ extern int unregister_mem_sect_under_nodes(struct memory_block *mem_blk);
 extern void register_hugetlbfs_with_node(node_registration_func_t doregister,
 					 node_registration_func_t unregister);
 #endif
+
+extern struct sysdev_class node_class;
 #else
 static inline int register_one_node(int nid)
 {
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index ad2aea3..ef519d2 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -552,12 +552,18 @@ struct perf_event;
 #define PMU_TYPE_CPU 0
 #define PMU_TYPE_NODE 1
 
+struct perf_event_kobject {
+	struct kobject			kobj;
+	u64				id;
+};
+
 /**
  * struct pmu - generic performance monitoring unit
  */
 struct pmu {
 	int				id;
 	struct list_head		entry;
+	struct kobject			kobj;
 
 	int (*enable)			(struct perf_event *event);
 	void (*disable)			(struct perf_event *event);
@@ -577,6 +583,7 @@ struct pmu {
 	int  (*commit_txn)	(struct pmu *pmu);
 
 	int  (*init_event)	(struct perf_event *event);
+	int  (*register_events)	(struct pmu *pmu, struct kobject *events_kobj);
 };
 
 /**
@@ -1022,6 +1029,9 @@ extern void perf_event_disable(struct perf_event *event);
 
 extern int perf_event_register_pmu(struct pmu *pmu);
 extern void perf_event_unregister_pmu(int id);
+char *perf_hw_event_name(int id);
+char *perf_hw_cache_event_name(u8 type, u8 op, u8 result);
+extern struct kobj_type event_ktype;
 #else
 static inline void
 perf_event_task_sched_in(struct task_struct *task)			{ }
diff --git a/kernel/perf_event.c b/kernel/perf_event.c
index 44e35ad..f6df0f8 100644
--- a/kernel/perf_event.c
+++ b/kernel/perf_event.c
@@ -12,6 +12,7 @@
 #include <linux/fs.h>
 #include <linux/mm.h>
 #include <linux/cpu.h>
+#include <linux/node.h>
 #include <linux/smp.h>
 #include <linux/file.h>
 #include <linux/poll.h>
@@ -5767,6 +5768,174 @@ static int __init perf_event_sysfs_init(void)
 }
 device_initcall(perf_event_sysfs_init);
 
+static char *hw_event_names[] = {
+	"cycles",
+	"instructions",
+	"cache-references",
+	"cache-misses",
+	"branches",
+	"branch-misses",
+	"bus-cycles",
+};
+
+static char *hw_cache[] = {
+	"L1-dcache",
+	"L1-icache",
+	"LLC",
+	"dTLB",
+	"iTLB",
+	"branch",
+};
+
+static char *hw_cache_op[] = {
+	"load",
+	"store",
+	"prefetch",
+};
+
+static char *hw_cache_result[] = {
+	"refs",
+	"misses",
+};
+
+char *perf_hw_event_name(int id)
+{
+	if (id >= ARRAY_SIZE(hw_event_names))
+		return NULL;
+
+	return hw_event_names[id];
+}
+
+char *perf_hw_cache_event_name(u8 cache_type, u8 cache_op, u8 cache_result)
+{
+	static char name[50];
+
+	sprintf(name, "%s-%s-%s", hw_cache[cache_type],
+		hw_cache_op[cache_op],
+		hw_cache_result[cache_result]);
+
+	return name;
+}
+
+static ssize_t event_show(struct kobject *kobj,
+		struct attribute *attr, char *buf)
+{
+	int n;
+	struct perf_event_kobject *event_kobj =
+		container_of(kobj, struct perf_event_kobject, kobj);
+
+	n = sprintf(buf, "0x%llx\n", event_kobj->id);
+
+	return n;
+}
+
+static const struct sysfs_ops event_sysfs_ops = {
+	.show	= event_show,
+	.store	= NULL,
+};
+
+struct kobj_type event_ktype = {
+	.sysfs_ops	= &event_sysfs_ops,
+};
+
+static ssize_t event_source_show(struct kobject *kobj,
+		struct attribute *attr, char *buf)
+{
+	int n;
+	struct pmu *pmu = container_of(kobj, struct pmu, kobj);
+
+	n = sprintf(buf, "%d\n", pmu->id);
+
+	return n;
+}
+
+static const struct sysfs_ops event_source_sysfs_ops = {
+	.show	= event_source_show,
+	.store	= NULL,
+};
+
+static struct kobj_type event_source_ktype = {
+	.sysfs_ops	= &event_source_sysfs_ops,
+};
+
+static struct attribute event_source_id_attr = {
+	.name = "id",
+	.mode = 0444,
+};
+
+static int __init perf_pmu_sysfs_init(void)
+{
+	struct pmu *pmu;
+	struct kobject *parent_kobj, *events_kobj;
+	int err = 0;
+
+	rcu_read_lock();
+
+	list_for_each_entry_rcu(pmu, &pmus, entry) {
+		switch (pmu->id) {
+		case PMU_TYPE_CPU:
+			parent_kobj = &cpu_sysdev_class.kset.kobj;
+			break;
+#ifdef CONFIG_NUMA
+		case PMU_TYPE_NODE:
+			parent_kobj = &node_class.kset.kobj;
+			break;
+#endif
+
+		/* TBD: add other pmu types later */
+		default:
+			parent_kobj = NULL;
+			break;
+		}
+
+		if (!parent_kobj)
+			continue;
+
+		/*
+		 * Create event_source sysfs dir, for example
+		 * /sys/devices/system/cpu/event_source
+		 */
+		err = kobject_init_and_add(&pmu->kobj,
+			&event_source_ktype, parent_kobj, "event_source");
+		if (err)
+			break;
+
+		/*
+		 * Create event_source/id attribute, for example
+		 * /sys/devices/system/cpu/event_source/id
+		 */
+		err = sysfs_create_file(&pmu->kobj, &event_source_id_attr);
+		if (err)
+			break;
+
+		/*
+		 * Create events sysfs dir, for example
+		 * /sys/devices/system/cpu/events
+		 */
+		events_kobj = kobject_create_and_add("events", parent_kobj);
+		if (!events_kobj) {
+			err = -ENOMEM;
+			break;
+		}
+
+		/*
+		 * Register all events under events dir, for example
+		 * /sys/devices/system/cpu/events/cycles
+		 * /sys/devices/system/cpu/events/instructions
+		 */
+		if (pmu->register_events) {
+			err = pmu->register_events(pmu, events_kobj);
+			if (err)
+				break;
+		}
+	}
+
+	rcu_read_unlock();
+
+	return err;
+}
+device_initcall(perf_pmu_sysfs_init);
+
 int perf_event_register_pmu(struct pmu *pmu)
 {
 	struct pmu *tmp;






^ permalink raw reply related	[flat|nested] 46+ messages in thread

end of thread, other threads:[~2010-07-20 21:18 UTC | newest]

Thread overview: 46+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-05-19  1:46 [RFC][PATCH v2 06/11] perf: core, export pmus via sysfs Lin Ming
2010-05-18 20:05 ` Greg KH
2010-05-19  2:34   ` Lin Ming
2010-05-19  2:48     ` Greg KH
2010-05-19  3:40       ` Lin Ming
2010-05-19  5:00         ` Greg KH
2010-05-19  6:32           ` Lin Ming
2010-05-19  7:14       ` Peter Zijlstra
2010-05-20 18:42         ` Greg KH
2010-05-20 19:52           ` Peter Zijlstra
2010-05-20 20:19             ` Greg KH
2010-05-20 20:14           ` Ingo Molnar
2010-05-20 23:12             ` Greg KH
2010-05-21  8:03               ` Peter Zijlstra
2010-05-21  9:40                 ` [rfc] Describe events in a structured way " Ingo Molnar
     [not found]                   ` <AANLkTinJeYJtCg2aRWhHTcf5E2-dN2-oAfEJ8tAtFjb9@mail.gmail.com>
2010-06-01  2:34                     ` Lin Ming
2010-06-08 18:43                       ` Ingo Molnar
     [not found]                   ` <AANLkTimf1Z0N9cv2Pu2qTTUscn4utC37zOPelCbqQoPv@mail.gmail.com>
2010-06-21  8:55                     ` Lin Ming
     [not found]                       ` <1277112858.3618.16.camel@jlt3.sipsolutions.net>
     [not found]                         ` <1277187920.4467.3.camel@minggr.sh.intel.com>
     [not found]                           ` <1277189971.3637.5.camel@jlt3.sipsolutions.net>
2010-06-22  7:22                             ` Lin Ming
2010-06-22  7:33                               ` Johannes Berg
2010-06-22  7:39                                 ` Johannes Berg
2010-06-22  8:04                                   ` Lin Ming
2010-06-22  8:16                                     ` Johannes Berg
2010-06-22  7:47                                 ` Lin Ming
2010-06-22  7:52                                   ` Johannes Berg
2010-06-24  9:36                                 ` Ingo Molnar
2010-06-24 16:14                                   ` Johannes Berg
2010-06-24 17:33                                     ` Ingo Molnar
2010-06-29  6:15                                       ` Lin Ming
2010-06-29  8:55                                         ` Ingo Molnar
2010-06-29  9:20                                           ` Lin Ming
2010-06-29 10:26                                             ` Ingo Molnar
2010-07-02  8:06                                               ` Lin Ming
2010-07-03 12:54                                                 ` Ingo Molnar
2010-07-17  0:20                                                 ` Corey Ashford
2010-07-20  5:48                                                   ` Lin Ming
2010-07-20 15:19                                                     ` Robert Richter
2010-07-20 17:50                                                       ` Corey Ashford
2010-07-20 18:30                                                         ` Robert Richter
2010-07-20 21:18                                                           ` Corey Ashford
2010-07-20 17:43                                                     ` Corey Ashford
2010-05-19  7:06     ` [RFC][PATCH v2 06/11] perf: core, export pmus " Borislav Petkov
2010-05-19  7:17       ` Peter Zijlstra
2010-05-19  7:23         ` Ingo Molnar
2010-05-18 20:07 ` Greg KH
2010-05-19  2:37   ` Lin Ming

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).