linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCHv3 0/6] perf, tool: Allow to use hw events in PMU syntax
@ 2012-07-09 20:37 Jiri Olsa
  2012-07-09 20:37 ` [PATCH 1/6] perf, x86: Making hardware events translations available in sysfs Jiri Olsa
                   ` (6 more replies)
  0 siblings, 7 replies; 11+ messages in thread
From: Jiri Olsa @ 2012-07-09 20:37 UTC (permalink / raw)
  To: acme, a.p.zijlstra, mingo, paulus, cjashfor, fweisbec, eranian
  Cc: linux-kernel

hi,
here's the change to make following syntax available:
  perf stat -e cpu/event=instructions/u ls

this is identical to:
  perf stat -e instructions:u ls

v3 changes:
  - patches v2 1,5,6,9 are already in
  - patch 1 - sysfs 'events' attribute file names with dashes '-'
            - using 'event/umask/inv/cmask' terms assigments instead simple 'config'
  - patch 2 - undefined events sysfs attributes filtered out

v2 changes:
  - making the hw events translations available under the 'events',
    the userspace trnaslation is then done by existing term aliasing
    code with some little tweeks ;)
  - patches 1-3 are independent fixies

Attached patches:
  1/6 perf, x86: Making hardware events translations available in sysfs
  2/6 perf, x86: Filter out undefined events from sysfs events attribute
  3/6 perf, tool: Fix pmu object alias initialization
  4/6 perf, tool: Properly free format data
  5/6 perf, tool: Add support to specify hw event as pmu event term
  6/6 perf, test: Add automated tests for pmu sysfs translated events

jirka
---
 arch/x86/kernel/cpu/perf_event.c    |   98 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 tools/perf/util/parse-events-test.c |   75 +++++++++++++++++++++++++++++++++++++++++++++++--
 tools/perf/util/parse-events.c      |   13 +++++++++
 tools/perf/util/parse-events.h      |    2 ++
 tools/perf/util/parse-events.y      |    9 ++++++
 tools/perf/util/pmu.c               |   59 ++++++++++++++++++++++++---------------
 6 files changed, 232 insertions(+), 24 deletions(-)

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

* [PATCH 1/6] perf, x86: Making hardware events translations available in sysfs
  2012-07-09 20:37 [PATCHv3 0/6] perf, tool: Allow to use hw events in PMU syntax Jiri Olsa
@ 2012-07-09 20:37 ` Jiri Olsa
  2012-08-20  8:25   ` Stephane Eranian
  2012-07-09 20:37 ` [PATCH 2/6] perf, x86: Filter out undefined events from sysfs events attribute Jiri Olsa
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 11+ messages in thread
From: Jiri Olsa @ 2012-07-09 20:37 UTC (permalink / raw)
  To: acme, a.p.zijlstra, mingo, paulus, cjashfor, fweisbec, eranian
  Cc: linux-kernel, Jiri Olsa

Making hardware events translations available through the sysfs.
Adding 'events' group attribute under the sysfs x86 PMU record
with attribute/file for each hardware event:

  # ls  /sys/devices/cpu/events/
  branch-instructions
  branch-misses
  bus-cycles
  cache-misses
  cache-references
  cpu-cycles
  instructions
  ref-cycles
  stalled-cycles-backend
  stalled-cycles-frontend

The file - hw event ID mappings is:

  file                      hw event ID
  ---------------------------------------------------------------
  cpu-cycles                PERF_COUNT_HW_CPU_CYCLES
  instructions              PERF_COUNT_HW_INSTRUCTIONS
  cache-references          PERF_COUNT_HW_CACHE_REFERENCES
  cache-misses              PERF_COUNT_HW_CACHE_MISSES
  branch-instructions       PERF_COUNT_HW_BRANCH_INSTRUCTIONS
  branch-misses             PERF_COUNT_HW_BRANCH_MISSES
  bus-cycles                PERF_COUNT_HW_BUS_CYCLES
  stalled-cycles-frontend   PERF_COUNT_HW_STALLED_CYCLES_FRONTEND
  stalled-cycles-backend    PERF_COUNT_HW_STALLED_CYCLES_BACKEND
  ref-cycles                PERF_COUNT_HW_REF_CPU_CYCLES

Each file in 'events' directory contains term translation for the
symbolic hw event for the currently running cpu model.

  # cat /sys/devices/cpu/events/stalled-cycles-backend
  event=0xb1,umask=0x01,inv,cmask=0x01

Suggested-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Jiri Olsa <jolsa@redhat.com>
---
 arch/x86/kernel/cpu/perf_event.c |   74 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 74 insertions(+)

diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c
index 29557aa..09452c2 100644
--- a/arch/x86/kernel/cpu/perf_event.c
+++ b/arch/x86/kernel/cpu/perf_event.c
@@ -1638,9 +1638,83 @@ static struct attribute_group x86_pmu_attr_group = {
 	.attrs = x86_pmu_attrs,
 };
 
+static ssize_t event_sysfs_data(char *page, u64 config)
+{
+	u64 event  = (config & ARCH_PERFMON_EVENTSEL_EVENT) |
+		     (config & AMD64_EVENTSEL_EVENT) >> 24;
+	u64 umask  = (config & ARCH_PERFMON_EVENTSEL_UMASK) >> 8;
+	u64 inv    = (config & ARCH_PERFMON_EVENTSEL_INV) >> 23;
+	u64 cmask  = (config & ARCH_PERFMON_EVENTSEL_CMASK) >> 24;
+	ssize_t ret;
+
+	/*
+	 * We have whole page size to spend and just little data
+	 * to write, so we can safely use sprintf.
+	 */
+	ret = sprintf(page, "event=0x%02llx", event);
+
+	if (umask)
+		ret += sprintf(page + ret, ",umask=0x%02llx", umask);
+
+	if (inv)
+		ret += sprintf(page + ret, ",inv");
+
+	if (cmask)
+		ret += sprintf(page + ret, ",cmask=0x%02llx", cmask);
+
+	ret += sprintf(page + ret, "\n");
+
+	return ret;
+}
+
+#define PMU_EVENTS_ATTR(_name, _id)			\
+static ssize_t						\
+_id##_show(struct device *dev,				\
+	   struct device_attribute *attr,		\
+	   char *page)					\
+{							\
+	u64 config = x86_pmu.event_map(_id);		\
+	BUILD_BUG_ON(_id >= PERF_COUNT_HW_MAX);		\
+	return event_sysfs_data(page, config);		\
+}							\
+							\
+static struct device_attribute event_attr_##_id =	\
+	__ATTR(_name, 0444, _id##_show, NULL)
+
+PMU_EVENTS_ATTR(cpu-cycles, PERF_COUNT_HW_CPU_CYCLES);
+PMU_EVENTS_ATTR(instructions, PERF_COUNT_HW_INSTRUCTIONS);
+PMU_EVENTS_ATTR(cache-references, PERF_COUNT_HW_CACHE_REFERENCES);
+PMU_EVENTS_ATTR(cache-misses, PERF_COUNT_HW_CACHE_MISSES);
+PMU_EVENTS_ATTR(branch-instructions, PERF_COUNT_HW_BRANCH_INSTRUCTIONS);
+PMU_EVENTS_ATTR(branch-misses, PERF_COUNT_HW_BRANCH_MISSES);
+PMU_EVENTS_ATTR(bus-cycles, PERF_COUNT_HW_BUS_CYCLES);
+PMU_EVENTS_ATTR(stalled-cycles-frontend, PERF_COUNT_HW_STALLED_CYCLES_FRONTEND);
+PMU_EVENTS_ATTR(stalled-cycles-backend, PERF_COUNT_HW_STALLED_CYCLES_BACKEND);
+PMU_EVENTS_ATTR(ref-cycles, PERF_COUNT_HW_REF_CPU_CYCLES);
+
+static struct attribute *events_attr[] = {
+	&event_attr_PERF_COUNT_HW_CPU_CYCLES.attr,
+	&event_attr_PERF_COUNT_HW_INSTRUCTIONS.attr,
+	&event_attr_PERF_COUNT_HW_CACHE_REFERENCES.attr,
+	&event_attr_PERF_COUNT_HW_CACHE_MISSES.attr,
+	&event_attr_PERF_COUNT_HW_BRANCH_INSTRUCTIONS.attr,
+	&event_attr_PERF_COUNT_HW_BRANCH_MISSES.attr,
+	&event_attr_PERF_COUNT_HW_BUS_CYCLES.attr,
+	&event_attr_PERF_COUNT_HW_STALLED_CYCLES_FRONTEND.attr,
+	&event_attr_PERF_COUNT_HW_STALLED_CYCLES_BACKEND.attr,
+	&event_attr_PERF_COUNT_HW_REF_CPU_CYCLES.attr,
+	NULL,
+};
+
+static struct attribute_group x86_pmu_events_group = {
+	.name = "events",
+	.attrs = events_attr,
+};
+
 static const struct attribute_group *x86_pmu_attr_groups[] = {
 	&x86_pmu_attr_group,
 	&x86_pmu_format_group,
+	&x86_pmu_events_group,
 	NULL,
 };
 
-- 
1.7.10.4


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

* [PATCH 2/6] perf, x86: Filter out undefined events from sysfs events attribute
  2012-07-09 20:37 [PATCHv3 0/6] perf, tool: Allow to use hw events in PMU syntax Jiri Olsa
  2012-07-09 20:37 ` [PATCH 1/6] perf, x86: Making hardware events translations available in sysfs Jiri Olsa
@ 2012-07-09 20:37 ` Jiri Olsa
  2012-07-09 20:37 ` [PATCH 3/6] perf, tool: Fix pmu object alias initialization Jiri Olsa
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 11+ messages in thread
From: Jiri Olsa @ 2012-07-09 20:37 UTC (permalink / raw)
  To: acme, a.p.zijlstra, mingo, paulus, cjashfor, fweisbec, eranian
  Cc: linux-kernel, Jiri Olsa

The sysfs events group attribute currently shows all hw events,
including also undefined ones.

This patch filters out all undefined events out of the sysfs events
group attribute, so they don't even show up.

Suggested-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Jiri Olsa <jolsa@redhat.com>
---
 arch/x86/kernel/cpu/perf_event.c |   24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c
index 09452c2..9fb23dd 100644
--- a/arch/x86/kernel/cpu/perf_event.c
+++ b/arch/x86/kernel/cpu/perf_event.c
@@ -1306,6 +1306,8 @@ static struct attribute_group x86_pmu_format_group = {
 	.attrs = NULL,
 };
 
+static void __init filter_events_group(void);
+
 static int __init init_hw_perf_events(void)
 {
 	struct x86_pmu_quirk *quirk;
@@ -1352,6 +1354,8 @@ static int __init init_hw_perf_events(void)
 	x86_pmu.attr_rdpmc = 1; /* enable userspace RDPMC usage by default */
 	x86_pmu_format_group.attrs = x86_pmu.format_attrs;
 
+	filter_events_group();
+
 	pr_info("... version:                %d\n",     x86_pmu.version);
 	pr_info("... bit width:              %d\n",     x86_pmu.cntval_bits);
 	pr_info("... generic registers:      %d\n",     x86_pmu.num_counters);
@@ -1718,6 +1722,26 @@ static const struct attribute_group *x86_pmu_attr_groups[] = {
 	NULL,
 };
 
+/*
+ * Remove all undefined events (x86_pmu.event_map(id) == 0)
+ * out of events_attr attributes.
+ */
+static void __init filter_events_group(void)
+{
+	int i, j;
+
+	for (i = 0; events_attr[i]; i++) {
+		if (x86_pmu.event_map(i))
+			continue;
+
+		for (j = i; events_attr[j]; j++)
+			events_attr[j] = events_attr[j + 1];
+
+		/* Check the shifted attr. */
+		i--;
+	}
+}
+
 static void x86_pmu_flush_branch_stack(void)
 {
 	if (x86_pmu.flush_branch_stack)
-- 
1.7.10.4


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

* [PATCH 3/6] perf, tool: Fix pmu object alias initialization
  2012-07-09 20:37 [PATCHv3 0/6] perf, tool: Allow to use hw events in PMU syntax Jiri Olsa
  2012-07-09 20:37 ` [PATCH 1/6] perf, x86: Making hardware events translations available in sysfs Jiri Olsa
  2012-07-09 20:37 ` [PATCH 2/6] perf, x86: Filter out undefined events from sysfs events attribute Jiri Olsa
@ 2012-07-09 20:37 ` Jiri Olsa
  2012-07-09 20:37 ` [PATCH 4/6] perf, tool: Properly free format data Jiri Olsa
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 11+ messages in thread
From: Jiri Olsa @ 2012-07-09 20:37 UTC (permalink / raw)
  To: acme, a.p.zijlstra, mingo, paulus, cjashfor, fweisbec, eranian
  Cc: linux-kernel, Jiri Olsa

The pmu_lookup should return pmus that do not expose the 'events'
group attribute in sysfs. Also it should fail when any other error
during 'events' lookup is hit (pmu_aliases fails).

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
---
 tools/perf/util/pmu.c |    7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index 67715a4..3c86022 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -161,7 +161,7 @@ static int pmu_aliases(char *name, struct list_head *head)
 		 "%s/bus/event_source/devices/%s/events", sysfs, name);
 
 	if (stat(path, &st) < 0)
-		return -1;
+		return 0;	 /* no error if 'events' does not exist */
 
 	if (pmu_aliases_parse(path, head))
 		return -1;
@@ -237,6 +237,9 @@ static struct perf_pmu *pmu_lookup(char *name)
 	if (pmu_format(name, &format))
 		return NULL;
 
+	if (pmu_aliases(name, &aliases))
+		return NULL;
+
 	if (pmu_type(name, &type))
 		return NULL;
 
@@ -244,8 +247,6 @@ static struct perf_pmu *pmu_lookup(char *name)
 	if (!pmu)
 		return NULL;
 
-	pmu_aliases(name, &aliases);
-
 	INIT_LIST_HEAD(&pmu->format);
 	INIT_LIST_HEAD(&pmu->aliases);
 	list_splice(&format, &pmu->format);
-- 
1.7.10.4


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

* [PATCH 4/6] perf, tool: Properly free format data
  2012-07-09 20:37 [PATCHv3 0/6] perf, tool: Allow to use hw events in PMU syntax Jiri Olsa
                   ` (2 preceding siblings ...)
  2012-07-09 20:37 ` [PATCH 3/6] perf, tool: Fix pmu object alias initialization Jiri Olsa
@ 2012-07-09 20:37 ` Jiri Olsa
  2012-07-09 20:37 ` [PATCH 5/6] perf, tool: Add support to specify hw event as pmu event term Jiri Olsa
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 11+ messages in thread
From: Jiri Olsa @ 2012-07-09 20:37 UTC (permalink / raw)
  To: acme, a.p.zijlstra, mingo, paulus, cjashfor, fweisbec, eranian
  Cc: linux-kernel, Jiri Olsa

Format data are allocated during PMU lookup. If the lookup
fails in next steps, we don't release the format data.

This patch ensures that format data get released in case
there's failure during PMU load.

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
---
 tools/perf/util/pmu.c |   58 ++++++++++++++++++++++++++++++-------------------
 1 file changed, 36 insertions(+), 22 deletions(-)

diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index 3c86022..e8cff3d 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -15,6 +15,14 @@ extern FILE *perf_pmu_in;
 
 static LIST_HEAD(pmus);
 
+static void pmu_format_release(struct list_head *head)
+{
+	struct perf_pmu__format *format, *h;
+
+	list_for_each_entry_safe(format, h, head, list)
+		free(format);
+}
+
 /*
  * Parse & process all the sysfs attributes located under
  * the directory specified in 'dir' parameter.
@@ -229,32 +237,38 @@ static struct perf_pmu *pmu_lookup(char *name)
 	LIST_HEAD(aliases);
 	__u32 type;
 
-	/*
-	 * The pmu data we store & need consists of the pmu
-	 * type value and format definitions. Load both right
-	 * now.
-	 */
-	if (pmu_format(name, &format))
-		return NULL;
+	do {
+		/*
+		* The pmu data we store & need consists of the pmu
+		* type value, format and events definitions. Load
+		* all of them right now.
+		*/
+		if (pmu_format(name, &format))
+			break;
 
-	if (pmu_aliases(name, &aliases))
-		return NULL;
+		if (pmu_aliases(name, &aliases))
+			break;
 
-	if (pmu_type(name, &type))
-		return NULL;
+		if (pmu_type(name, &type))
+			break;
 
-	pmu = zalloc(sizeof(*pmu));
-	if (!pmu)
-		return NULL;
+		pmu = zalloc(sizeof(*pmu));
+		if (!pmu)
+			break;
 
-	INIT_LIST_HEAD(&pmu->format);
-	INIT_LIST_HEAD(&pmu->aliases);
-	list_splice(&format, &pmu->format);
-	list_splice(&aliases, &pmu->aliases);
-	pmu->name = strdup(name);
-	pmu->type = type;
-	list_add_tail(&pmu->list, &pmus);
-	return pmu;
+		INIT_LIST_HEAD(&pmu->format);
+		INIT_LIST_HEAD(&pmu->aliases);
+		list_splice(&format, &pmu->format);
+		list_splice(&aliases, &pmu->aliases);
+		pmu->name = strdup(name);
+		pmu->type = type;
+		list_add_tail(&pmu->list, &pmus);
+		return pmu;
+
+	} while (0);
+
+	pmu_format_release(&format);
+	return NULL;
 }
 
 static struct perf_pmu *pmu_find(char *name)
-- 
1.7.10.4


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

* [PATCH 5/6] perf, tool: Add support to specify hw event as pmu event term
  2012-07-09 20:37 [PATCHv3 0/6] perf, tool: Allow to use hw events in PMU syntax Jiri Olsa
                   ` (3 preceding siblings ...)
  2012-07-09 20:37 ` [PATCH 4/6] perf, tool: Properly free format data Jiri Olsa
@ 2012-07-09 20:37 ` Jiri Olsa
  2012-07-09 20:37 ` [PATCH 6/6] perf, test: Add automated tests for pmu sysfs translated events Jiri Olsa
  2012-08-08 12:42 ` [PATCHv3 0/6] perf, tool: Allow to use hw events in PMU syntax Jiri Olsa
  6 siblings, 0 replies; 11+ messages in thread
From: Jiri Olsa @ 2012-07-09 20:37 UTC (permalink / raw)
  To: acme, a.p.zijlstra, mingo, paulus, cjashfor, fweisbec, eranian
  Cc: linux-kernel, Jiri Olsa

Adding a way to specify hw event as pmu event term like:
 'cpu/event=cpu-cycles/u'
 'cpu/event=instructions,.../u'

The 'event=cpu-cycles' term is replaced/translated by the hw events
term translation, which is exposed by sysfs 'events' group attribute.

Adding parser bits, the rest is already handled by the pmu alias code.

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
---
 tools/perf/util/parse-events.c |   13 +++++++++++++
 tools/perf/util/parse-events.h |    2 ++
 tools/perf/util/parse-events.y |    9 +++++++++
 3 files changed, 24 insertions(+)

diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 1aa721d..780bc45 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -1045,6 +1045,19 @@ int parse_events__term_str(struct parse_events__term **term,
 			config, str, 0);
 }
 
+int parse_events__term_sym_hw(struct parse_events__term **term,
+			      char *config, unsigned idx)
+{
+	struct event_symbol *sym;
+
+	BUG_ON(idx >= PERF_COUNT_HW_MAX);
+	sym = &event_symbols_hw[idx];
+
+	return new_term(term, PARSE_EVENTS__TERM_TYPE_STR,
+			PARSE_EVENTS__TERM_TYPE_USER, config,
+			(char *) sym->symbol, 0);
+}
+
 int parse_events__term_clone(struct parse_events__term **new,
 			     struct parse_events__term *term)
 {
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
index ee9c218..eaf2fd7 100644
--- a/tools/perf/util/parse-events.h
+++ b/tools/perf/util/parse-events.h
@@ -76,6 +76,8 @@ int parse_events__term_num(struct parse_events__term **_term,
 			   int type_term, char *config, long num);
 int parse_events__term_str(struct parse_events__term **_term,
 			   int type_term, char *config, char *str);
+int parse_events__term_sym_hw(struct parse_events__term **term,
+			      char *config, unsigned idx);
 int parse_events__term_clone(struct parse_events__term **new,
 			     struct parse_events__term *term);
 void parse_events__free_terms(struct list_head *terms);
diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y
index 2bc5fbf..9c74d8a 100644
--- a/tools/perf/util/parse-events.y
+++ b/tools/perf/util/parse-events.y
@@ -269,6 +269,15 @@ PE_NAME '=' PE_VALUE
 	$$ = term;
 }
 |
+PE_NAME '=' PE_VALUE_SYM_HW
+{
+	struct parse_events__term *term;
+	int config = $3 & 255;
+
+	ABORT_ON(parse_events__term_sym_hw(&term, $1, config));
+	$$ = term;
+}
+|
 PE_NAME
 {
 	struct parse_events__term *term;
-- 
1.7.10.4


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

* [PATCH 6/6] perf, test: Add automated tests for pmu sysfs translated events
  2012-07-09 20:37 [PATCHv3 0/6] perf, tool: Allow to use hw events in PMU syntax Jiri Olsa
                   ` (4 preceding siblings ...)
  2012-07-09 20:37 ` [PATCH 5/6] perf, tool: Add support to specify hw event as pmu event term Jiri Olsa
@ 2012-07-09 20:37 ` Jiri Olsa
  2012-08-08 12:42 ` [PATCHv3 0/6] perf, tool: Allow to use hw events in PMU syntax Jiri Olsa
  6 siblings, 0 replies; 11+ messages in thread
From: Jiri Olsa @ 2012-07-09 20:37 UTC (permalink / raw)
  To: acme, a.p.zijlstra, mingo, paulus, cjashfor, fweisbec, eranian
  Cc: linux-kernel, Jiri Olsa

Adding automated tests for all events found under PMU/events
directory. Tested events are in 'cpu/event=xxx/u' format,
where 'xxx' is substibuted by every event found.

The 'event=xxx' term is translated to the cpu specific term.
We only check that the event is created (not the real config
numbers) and that modifier is properly set.

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
---
 tools/perf/util/parse-events-test.c |   75 ++++++++++++++++++++++++++++++++++-
 1 file changed, 73 insertions(+), 2 deletions(-)

diff --git a/tools/perf/util/parse-events-test.c b/tools/perf/util/parse-events-test.c
index 1b997d2..a2aac11 100644
--- a/tools/perf/util/parse-events-test.c
+++ b/tools/perf/util/parse-events-test.c
@@ -13,6 +13,8 @@ do { \
 	} \
 } while (0)
 
+static int test_cnt;
+
 static int test__checkevent_tracepoint(struct perf_evlist *evlist)
 {
 	struct perf_evsel *evsel = list_entry(evlist->entries.next,
@@ -470,6 +472,23 @@ static int test__checkevent_pmu_name(struct perf_evlist *evlist)
 	return 0;
 }
 
+static int test__checkevent_pmu_events(struct perf_evlist *evlist)
+{
+	struct perf_evsel *evsel;
+
+	evsel = list_entry(evlist->entries.next, struct perf_evsel, node);
+	TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
+	TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type);
+	TEST_ASSERT_VAL("wrong exclude_user",
+			!evsel->attr.exclude_user);
+	TEST_ASSERT_VAL("wrong exclude_kernel",
+			evsel->attr.exclude_kernel);
+	TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
+	TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
+
+	return 0;
+}
+
 static int test__checkterms_simple(struct list_head *terms)
 {
 	struct parse_events__term *term;
@@ -666,6 +685,8 @@ static int test_event(struct test__event_st *e)
 	struct perf_evlist *evlist;
 	int ret;
 
+	pr_debug("running test %4d '%s'\n", test_cnt++, e->name);
+
 	evlist = perf_evlist__new(NULL, NULL);
 	if (evlist == NULL)
 		return -ENOMEM;
@@ -691,7 +712,6 @@ static int test_events(struct test__event_st *events, unsigned cnt)
 	for (i = 0; i < cnt; i++) {
 		struct test__event_st *e = &events[i];
 
-		pr_debug("running test %d '%s'\n", i, e->name);
 		ret = test_event(e);
 		if (ret)
 			break;
@@ -732,7 +752,7 @@ static int test_terms(struct test__term *terms, unsigned cnt)
 	for (i = 0; i < cnt; i++) {
 		struct test__term *t = &terms[i];
 
-		pr_debug("running test %d '%s'\n", i, t->str);
+		pr_debug("running test %4d '%s'\n", test_cnt, t->str);
 		ret = test_term(t);
 		if (ret)
 			break;
@@ -756,6 +776,51 @@ static int test_pmu(void)
 	return !ret;
 }
 
+static int test_pmu_events(void)
+{
+	struct stat st;
+	char path[PATH_MAX];
+	struct dirent *ent;
+	DIR *dir;
+	int ret;
+
+	snprintf(path, PATH_MAX, "%s/bus/event_source/devices/cpu/events/",
+		 sysfs_find_mountpoint());
+
+	ret = stat(path, &st);
+	if (ret) {
+		pr_debug("ommiting PMU cpu events tests\n");
+		return 0;
+	}
+
+	dir = opendir(path);
+	if (!dir) {
+		pr_debug("can't open pmu event dir");
+		return -1;
+	}
+
+	while (!ret && (ent = readdir(dir))) {
+#define MAX_NAME 100
+		struct test__event_st e;
+		char name[MAX_NAME];
+
+		if (!strcmp(ent->d_name, ".") ||
+		    !strcmp(ent->d_name, ".."))
+			continue;
+
+		snprintf(name, MAX_NAME, "cpu/event=%s/u", ent->d_name);
+
+		e.name  = name;
+		e.check = test__checkevent_pmu_events;
+
+		ret = test_event(&e);
+#undef MAX_NAME
+	}
+
+	closedir(dir);
+	return ret;
+}
+
 int parse_events__test(void)
 {
 	int ret;
@@ -772,5 +837,11 @@ do {							\
 	if (test_pmu())
 		TEST_EVENTS(test__events_pmu);
 
+	if (test_pmu()) {
+		ret = test_pmu_events();
+		if (ret)
+			return ret;
+	}
+
 	return test_terms(test__terms, ARRAY_SIZE(test__terms));
 }
-- 
1.7.10.4


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

* Re: [PATCHv3 0/6] perf, tool: Allow to use hw events in PMU syntax
  2012-07-09 20:37 [PATCHv3 0/6] perf, tool: Allow to use hw events in PMU syntax Jiri Olsa
                   ` (5 preceding siblings ...)
  2012-07-09 20:37 ` [PATCH 6/6] perf, test: Add automated tests for pmu sysfs translated events Jiri Olsa
@ 2012-08-08 12:42 ` Jiri Olsa
  2012-08-16 13:44   ` Jiri Olsa
  6 siblings, 1 reply; 11+ messages in thread
From: Jiri Olsa @ 2012-08-08 12:42 UTC (permalink / raw)
  To: acme, a.p.zijlstra, mingo, paulus, cjashfor, fweisbec, eranian
  Cc: linux-kernel

On Mon, Jul 09, 2012 at 10:37:44PM +0200, Jiri Olsa wrote:
> hi,
> here's the change to make following syntax available:
>   perf stat -e cpu/event=instructions/u ls
> 
> this is identical to:
>   perf stat -e instructions:u ls
> 
> v3 changes:
>   - patches v2 1,5,6,9 are already in
>   - patch 1 - sysfs 'events' attribute file names with dashes '-'
>             - using 'event/umask/inv/cmask' terms assigments instead simple 'config'
>   - patch 2 - undefined events sysfs attributes filtered out
> 
> v2 changes:
>   - making the hw events translations available under the 'events',
>     the userspace trnaslation is then done by existing term aliasing
>     code with some little tweeks ;)
>   - patches 1-3 are independent fixies
> 
> Attached patches:
>   1/6 perf, x86: Making hardware events translations available in sysfs
>   2/6 perf, x86: Filter out undefined events from sysfs events attribute
>   3/6 perf, tool: Fix pmu object alias initialization
>   4/6 perf, tool: Properly free format data
>   5/6 perf, tool: Add support to specify hw event as pmu event term
>   6/6 perf, test: Add automated tests for pmu sysfs translated events
> 
> jirka
> ---
>  arch/x86/kernel/cpu/perf_event.c    |   98 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  tools/perf/util/parse-events-test.c |   75 +++++++++++++++++++++++++++++++++++++++++++++++--
>  tools/perf/util/parse-events.c      |   13 +++++++++
>  tools/perf/util/parse-events.h      |    2 ++
>  tools/perf/util/parse-events.y      |    9 ++++++
>  tools/perf/util/pmu.c               |   59 ++++++++++++++++++++++++---------------
>  6 files changed, 232 insertions(+), 24 deletions(-)

hi,
any feedback on this?
you can check rebased version (on Arnaldo's perf/core) here:

git://git.kernel.org/pub/scm/linux/kernel/git/jolsa/linux.git
perf/sysfs_events1

thanks,
jirka

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

* Re: [PATCHv3 0/6] perf, tool: Allow to use hw events in PMU syntax
  2012-08-08 12:42 ` [PATCHv3 0/6] perf, tool: Allow to use hw events in PMU syntax Jiri Olsa
@ 2012-08-16 13:44   ` Jiri Olsa
  0 siblings, 0 replies; 11+ messages in thread
From: Jiri Olsa @ 2012-08-16 13:44 UTC (permalink / raw)
  To: acme, a.p.zijlstra, mingo, paulus, cjashfor, fweisbec, eranian
  Cc: linux-kernel

On Wed, Aug 08, 2012 at 02:42:14PM +0200, Jiri Olsa wrote:
> On Mon, Jul 09, 2012 at 10:37:44PM +0200, Jiri Olsa wrote:
> > hi,
> > here's the change to make following syntax available:
> >   perf stat -e cpu/event=instructions/u ls
> > 
> > this is identical to:
> >   perf stat -e instructions:u ls
> > 
> > v3 changes:
> >   - patches v2 1,5,6,9 are already in
> >   - patch 1 - sysfs 'events' attribute file names with dashes '-'
> >             - using 'event/umask/inv/cmask' terms assigments instead simple 'config'
> >   - patch 2 - undefined events sysfs attributes filtered out
> > 
> > v2 changes:
> >   - making the hw events translations available under the 'events',
> >     the userspace trnaslation is then done by existing term aliasing
> >     code with some little tweeks ;)
> >   - patches 1-3 are independent fixies
> > 
> > Attached patches:
> >   1/6 perf, x86: Making hardware events translations available in sysfs
> >   2/6 perf, x86: Filter out undefined events from sysfs events attribute
> >   3/6 perf, tool: Fix pmu object alias initialization
> >   4/6 perf, tool: Properly free format data
> >   5/6 perf, tool: Add support to specify hw event as pmu event term
> >   6/6 perf, test: Add automated tests for pmu sysfs translated events
> > 
> > jirka
> > ---
> >  arch/x86/kernel/cpu/perf_event.c    |   98 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> >  tools/perf/util/parse-events-test.c |   75 +++++++++++++++++++++++++++++++++++++++++++++++--
> >  tools/perf/util/parse-events.c      |   13 +++++++++
> >  tools/perf/util/parse-events.h      |    2 ++
> >  tools/perf/util/parse-events.y      |    9 ++++++
> >  tools/perf/util/pmu.c               |   59 ++++++++++++++++++++++++---------------
> >  6 files changed, 232 insertions(+), 24 deletions(-)
> 
> hi,
> any feedback on this?
> you can check rebased version (on Arnaldo's perf/core) here:
> 
> git://git.kernel.org/pub/scm/linux/kernel/git/jolsa/linux.git
> perf/sysfs_events1

please use: perf/sysfs_events2

thanks,
jirka

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

* Re: [PATCH 1/6] perf, x86: Making hardware events translations available in sysfs
  2012-07-09 20:37 ` [PATCH 1/6] perf, x86: Making hardware events translations available in sysfs Jiri Olsa
@ 2012-08-20  8:25   ` Stephane Eranian
  2012-08-20  9:55     ` Jiri Olsa
  0 siblings, 1 reply; 11+ messages in thread
From: Stephane Eranian @ 2012-08-20  8:25 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: acme, a.p.zijlstra, mingo, paulus, cjashfor, fweisbec, linux-kernel

On Mon, Jul 9, 2012 at 10:37 PM, Jiri Olsa <jolsa@redhat.com> wrote:
> Making hardware events translations available through the sysfs.
> Adding 'events' group attribute under the sysfs x86 PMU record
> with attribute/file for each hardware event:
>
>   # ls  /sys/devices/cpu/events/
>   branch-instructions
>   branch-misses
>   bus-cycles
>   cache-misses
>   cache-references
>   cpu-cycles
>   instructions
>   ref-cycles
>   stalled-cycles-backend
>   stalled-cycles-frontend
>
> The file - hw event ID mappings is:
>
>   file                      hw event ID
>   ---------------------------------------------------------------
>   cpu-cycles                PERF_COUNT_HW_CPU_CYCLES
>   instructions              PERF_COUNT_HW_INSTRUCTIONS
>   cache-references          PERF_COUNT_HW_CACHE_REFERENCES
>   cache-misses              PERF_COUNT_HW_CACHE_MISSES
>   branch-instructions       PERF_COUNT_HW_BRANCH_INSTRUCTIONS
>   branch-misses             PERF_COUNT_HW_BRANCH_MISSES
>   bus-cycles                PERF_COUNT_HW_BUS_CYCLES
>   stalled-cycles-frontend   PERF_COUNT_HW_STALLED_CYCLES_FRONTEND
>   stalled-cycles-backend    PERF_COUNT_HW_STALLED_CYCLES_BACKEND
>   ref-cycles                PERF_COUNT_HW_REF_CPU_CYCLES
>
> Each file in 'events' directory contains term translation for the
> symbolic hw event for the currently running cpu model.
>
>   # cat /sys/devices/cpu/events/stalled-cycles-backend
>   event=0xb1,umask=0x01,inv,cmask=0x01
>
> Suggested-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
> Signed-off-by: Jiri Olsa <jolsa@redhat.com>
> ---
>  arch/x86/kernel/cpu/perf_event.c |   74 ++++++++++++++++++++++++++++++++++++++
>  1 file changed, 74 insertions(+)
>
> diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c
> index 29557aa..09452c2 100644
> --- a/arch/x86/kernel/cpu/perf_event.c
> +++ b/arch/x86/kernel/cpu/perf_event.c
> @@ -1638,9 +1638,83 @@ static struct attribute_group x86_pmu_attr_group = {
>         .attrs = x86_pmu_attrs,
>  };
>
> +static ssize_t event_sysfs_data(char *page, u64 config)
> +{
> +       u64 event  = (config & ARCH_PERFMON_EVENTSEL_EVENT) |
> +                    (config & AMD64_EVENTSEL_EVENT) >> 24;
> +       u64 umask  = (config & ARCH_PERFMON_EVENTSEL_UMASK) >> 8;
> +       u64 inv    = (config & ARCH_PERFMON_EVENTSEL_INV) >> 23;
> +       u64 cmask  = (config & ARCH_PERFMON_EVENTSEL_CMASK) >> 24;
> +       ssize_t ret;
> +
> +       /*
> +        * We have whole page size to spend and just little data
> +        * to write, so we can safely use sprintf.
> +        */
> +       ret = sprintf(page, "event=0x%02llx", event);
> +
> +       if (umask)
> +               ret += sprintf(page + ret, ",umask=0x%02llx", umask);
> +
> +       if (inv)
> +               ret += sprintf(page + ret, ",inv");
> +
> +       if (cmask)
> +               ret += sprintf(page + ret, ",cmask=0x%02llx", cmask);
> +

You are not handling the model specific modifiers such as any_thread on Intel.
It's not used right now. But you should handle the case now. That will avoid
problems in the future.

> +       ret += sprintf(page + ret, "\n");
> +
> +       return ret;
> +}
> +
> +#define PMU_EVENTS_ATTR(_name, _id)                    \
> +static ssize_t                                         \
> +_id##_show(struct device *dev,                         \
> +          struct device_attribute *attr,               \
> +          char *page)                                  \
> +{                                                      \
> +       u64 config = x86_pmu.event_map(_id);            \
> +       BUILD_BUG_ON(_id >= PERF_COUNT_HW_MAX);         \
> +       return event_sysfs_data(page, config);          \
> +}                                                      \
> +                                                       \
> +static struct device_attribute event_attr_##_id =      \
> +       __ATTR(_name, 0444, _id##_show, NULL)
> +
> +PMU_EVENTS_ATTR(cpu-cycles, PERF_COUNT_HW_CPU_CYCLES);
> +PMU_EVENTS_ATTR(instructions, PERF_COUNT_HW_INSTRUCTIONS);
> +PMU_EVENTS_ATTR(cache-references, PERF_COUNT_HW_CACHE_REFERENCES);
> +PMU_EVENTS_ATTR(cache-misses, PERF_COUNT_HW_CACHE_MISSES);
> +PMU_EVENTS_ATTR(branch-instructions, PERF_COUNT_HW_BRANCH_INSTRUCTIONS);
> +PMU_EVENTS_ATTR(branch-misses, PERF_COUNT_HW_BRANCH_MISSES);
> +PMU_EVENTS_ATTR(bus-cycles, PERF_COUNT_HW_BUS_CYCLES);
> +PMU_EVENTS_ATTR(stalled-cycles-frontend, PERF_COUNT_HW_STALLED_CYCLES_FRONTEND);
> +PMU_EVENTS_ATTR(stalled-cycles-backend, PERF_COUNT_HW_STALLED_CYCLES_BACKEND);
> +PMU_EVENTS_ATTR(ref-cycles, PERF_COUNT_HW_REF_CPU_CYCLES);
> +
> +static struct attribute *events_attr[] = {
> +       &event_attr_PERF_COUNT_HW_CPU_CYCLES.attr,
> +       &event_attr_PERF_COUNT_HW_INSTRUCTIONS.attr,
> +       &event_attr_PERF_COUNT_HW_CACHE_REFERENCES.attr,
> +       &event_attr_PERF_COUNT_HW_CACHE_MISSES.attr,
> +       &event_attr_PERF_COUNT_HW_BRANCH_INSTRUCTIONS.attr,
> +       &event_attr_PERF_COUNT_HW_BRANCH_MISSES.attr,
> +       &event_attr_PERF_COUNT_HW_BUS_CYCLES.attr,
> +       &event_attr_PERF_COUNT_HW_STALLED_CYCLES_FRONTEND.attr,
> +       &event_attr_PERF_COUNT_HW_STALLED_CYCLES_BACKEND.attr,
> +       &event_attr_PERF_COUNT_HW_REF_CPU_CYCLES.attr,
> +       NULL,
> +};
> +
> +static struct attribute_group x86_pmu_events_group = {
> +       .name = "events",
> +       .attrs = events_attr,
> +};
> +
>  static const struct attribute_group *x86_pmu_attr_groups[] = {
>         &x86_pmu_attr_group,
>         &x86_pmu_format_group,
> +       &x86_pmu_events_group,
>         NULL,
>  };
>
You are not checking whether or not the generic event is even available on the
host core PMU. You don't want to expose generic events which are not available.

And if you do this, then you need to take care of the other arch as well. They
also deserve the extended syntax.

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

* Re: [PATCH 1/6] perf, x86: Making hardware events translations available in sysfs
  2012-08-20  8:25   ` Stephane Eranian
@ 2012-08-20  9:55     ` Jiri Olsa
  0 siblings, 0 replies; 11+ messages in thread
From: Jiri Olsa @ 2012-08-20  9:55 UTC (permalink / raw)
  To: Stephane Eranian
  Cc: acme, a.p.zijlstra, mingo, paulus, cjashfor, fweisbec, linux-kernel

On Mon, Aug 20, 2012 at 10:25:42AM +0200, Stephane Eranian wrote:
> On Mon, Jul 9, 2012 at 10:37 PM, Jiri Olsa <jolsa@redhat.com> wrote:

SNIP

> > +static ssize_t event_sysfs_data(char *page, u64 config)
> > +{
> > +       u64 event  = (config & ARCH_PERFMON_EVENTSEL_EVENT) |
> > +                    (config & AMD64_EVENTSEL_EVENT) >> 24;
> > +       u64 umask  = (config & ARCH_PERFMON_EVENTSEL_UMASK) >> 8;
> > +       u64 inv    = (config & ARCH_PERFMON_EVENTSEL_INV) >> 23;
> > +       u64 cmask  = (config & ARCH_PERFMON_EVENTSEL_CMASK) >> 24;
> > +       ssize_t ret;
> > +
> > +       /*
> > +        * We have whole page size to spend and just little data
> > +        * to write, so we can safely use sprintf.
> > +        */
> > +       ret = sprintf(page, "event=0x%02llx", event);
> > +
> > +       if (umask)
> > +               ret += sprintf(page + ret, ",umask=0x%02llx", umask);
> > +
> > +       if (inv)
> > +               ret += sprintf(page + ret, ",inv");
> > +
> > +       if (cmask)
> > +               ret += sprintf(page + ret, ",cmask=0x%02llx", cmask);
> > +
> 
> You are not handling the model specific modifiers such as any_thread on Intel.
> It's not used right now. But you should handle the case now. That will avoid
> problems in the future.

ok, will add those

> 
> > +       ret += sprintf(page + ret, "\n");
> > +
> > +       return ret;
> > +}

SNIP

> >  static const struct attribute_group *x86_pmu_attr_groups[] = {
> >         &x86_pmu_attr_group,
> >         &x86_pmu_format_group,
> > +       &x86_pmu_events_group,
> >         NULL,
> >  };
> >
> You are not checking whether or not the generic event is even available on the
> host core PMU. You don't want to expose generic events which are not available.

thats what patch 2 does

> And if you do this, then you need to take care of the other arch as well. They
> also deserve the extended syntax.

hm, I could try to add something for ppc, but that's where my arch
hw availability ends

thanks,
jirka

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

end of thread, other threads:[~2012-08-20  9:56 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-07-09 20:37 [PATCHv3 0/6] perf, tool: Allow to use hw events in PMU syntax Jiri Olsa
2012-07-09 20:37 ` [PATCH 1/6] perf, x86: Making hardware events translations available in sysfs Jiri Olsa
2012-08-20  8:25   ` Stephane Eranian
2012-08-20  9:55     ` Jiri Olsa
2012-07-09 20:37 ` [PATCH 2/6] perf, x86: Filter out undefined events from sysfs events attribute Jiri Olsa
2012-07-09 20:37 ` [PATCH 3/6] perf, tool: Fix pmu object alias initialization Jiri Olsa
2012-07-09 20:37 ` [PATCH 4/6] perf, tool: Properly free format data Jiri Olsa
2012-07-09 20:37 ` [PATCH 5/6] perf, tool: Add support to specify hw event as pmu event term Jiri Olsa
2012-07-09 20:37 ` [PATCH 6/6] perf, test: Add automated tests for pmu sysfs translated events Jiri Olsa
2012-08-08 12:42 ` [PATCHv3 0/6] perf, tool: Allow to use hw events in PMU syntax Jiri Olsa
2012-08-16 13:44   ` Jiri Olsa

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).