Skip to contentSkip to conversation

perf tools: Add support to specify pmu style event

tip:perf/core tip-bot for Jiri Olsa 1 participant 1 message Mar 19, 2012 perf events

lore
Share & tools
lore
#0 lore raw
Commit-ID:  5f537a26590e696466aae7f41e6b77e92c8486d1
Gitweb:     http://git.kernel.org/tip/5f537a26590e696466aae7f41e6b77e92c8486d1
Author:     Jiri Olsa <[email protected]>
AuthorDate: Thu, 15 Mar 2012 20:09:18 +0100
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Fri, 16 Mar 2012 14:30:13 -0300

perf tools: Add support to specify pmu style event

Added new event rule to the event definition grammar:

event_def: event_pmu |

           ...

event_pmu: PE_NAME '/' event_config '/'

Using this rule, event could be now specified like:
cpu/config=1,config1=2,config2=3/u

where pmu name 'cpu' is looked up via following path:
${sysfs_mount}/bus/event_source/devices/${pmu}

and config options are bound to the pmu's format definiton:
${sysfs_mount}/bus/event_source/devices/${pmu}/format

The hardcoded config options still stays and have precedence over any format field defined with same name.

---
 tools/perf/builtin-test.c            |   20 ++++
 tools/perf/util/parse-events-bison.c |  209 ++++++++++++++++++----------------
 tools/perf/util/parse-events.c       |   31 +++++-
 tools/perf/util/parse-events.h       |    2 +
 tools/perf/util/parse-events.y       |   10 ++-
 5 files changed, 172 insertions(+), 100 deletions(-)
tools/perf/builtin-test.c +20 -0
index 58bfe8b..8687423 100644
@@ -877,6 +877,22 @@ static int test__checkevent_genhw_modifier(struct perf_evlist *evlist)
 	return test__checkevent_genhw(evlist);
 }
 
+static int test__checkevent_pmu(struct perf_evlist *evlist)
+{
+
+	struct perf_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 config",    10 == evsel->attr.config);
+	TEST_ASSERT_VAL("wrong config1",    1 == evsel->attr.config1);
+	TEST_ASSERT_VAL("wrong config2",    3 == evsel->attr.config2);
+	TEST_ASSERT_VAL("wrong period",  1000 == evsel->attr.sample_period);
+
+	return 0;
+}
+
 static struct test__event_st {
 	const char *name;
 	__u32 type;
@@ -958,6 +974,10 @@ static struct test__event_st {
 		.name  = "L1-dcache-load-miss:kp",
 		.check = test__checkevent_genhw_modifier,
 	},
+	{
+		.name  = "cpu/config=10,config1,config2=3,period=1000/u",
+		.check = test__checkevent_pmu,
+	},
 };
 
 #define TEST__EVENTS_CNT (sizeof(test__events) / sizeof(struct test__event_st))
tools/perf/util/parse-events-bison.c +111 -98

435 lines not on this page · raw message

tools/perf/util/parse-events.c +30 -1
index 59f5cf6..bec1cc6 100644
@@ -12,6 +12,7 @@
 #include "header.h"
 #include "debugfs.h"
 #include "parse-events-flex.h"
+#include "pmu.h"
 
 #define MAX_NAME_LEN 100
 
@@ -646,6 +647,30 @@ int parse_events_add_numeric(struct list_head *list, int *idx,
 			 (char *) __event_name(type, config));
 }
 
+int parse_events_add_pmu(struct list_head *list, int *idx,
+			 char *name, struct list_head *head_config)
+{
+	struct perf_event_attr attr;
+	struct perf_pmu *pmu;
+
+	pmu = perf_pmu__find(name);
+	if (!pmu)
+		return -EINVAL;
+
+	memset(&attr, 0, sizeof(attr));
+
+	/*
+	 * Configure hardcoded terms first, no need to check
+	 * return value when called with fail == 0 ;)
+	 */
+	config_attr(&attr, head_config, 0);
+
+	if (perf_pmu__config(pmu, &attr, head_config))
+		return -EINVAL;
+
+	return add_event(list, idx, &attr, (char *) "pmu");
+}
+
 int parse_events_modifier(struct list_head *list, char *str)
 {
 	struct perf_evsel *evsel;
@@ -957,8 +982,12 @@ void print_events(const char *event_glob)
 
 	printf("\n");
 	printf("  %-50s [%s]\n",
-		"rNNN (see 'perf list --help' on how to encode it)",
+	       "rNNN",
+	       event_type_descriptors[PERF_TYPE_RAW]);
+	printf("  %-50s [%s]\n",
+	       "cpu/t1=v1[,t2=v2,t3 ...]/modifier",
 	       event_type_descriptors[PERF_TYPE_RAW]);
+	printf("   (see 'perf list --help' on how to encode it)\n");
 	printf("\n");
 
 	printf("  %-50s [%s]\n",
tools/perf/util/parse-events.h +2 -0
index 37a270d..6d7c74b 100644
@@ -74,6 +74,8 @@ int parse_events_add_cache(struct list_head *list, int *idx,
 			   char *type, char *op_result1, char *op_result2);
 int parse_events_add_breakpoint(struct list_head *list, int *idx,
 				void *ptr, char *type);
+int parse_events_add_pmu(struct list_head *list, int *idx,
+			 char *pmu , struct list_head *head_config);
 void parse_events_error(struct list_head *list, int *idx,
 			char const *msg);
 
tools/perf/util/parse-events.y +9 -1
index c88c08e..3a53019 100644
@@ -61,13 +61,21 @@ event_def PE_MODIFIER_EVENT
 |
 event_def
 
-event_def: event_legacy_symbol |
+event_def: event_pmu |
+	   event_legacy_symbol |
 	   event_legacy_cache sep_dc |
 	   event_legacy_mem |
 	   event_legacy_tracepoint sep_dc |
 	   event_legacy_numeric sep_dc |
 	   event_legacy_raw sep_dc
 
+event_pmu:
+PE_NAME '/' event_config '/'
+{
+	ABORT_ON(parse_events_add_pmu(list, idx, $1, $3));
+	parse_events__free_terms($3);
+}
+
 event_legacy_symbol:
 PE_VALUE_SYM '/' event_config '/'
 {