[PATCH 5/7] perf, tools: Add raw event support for dynamic allocated pmus

From: Robert Richter
Date: Wed May 02 2012 - 14:27:37 EST


This patch extends the event parser to pass raw config values to a
dynamic allocated pmu. The following event syntax is supported now:

<pmu_name>:<raw_config_value>:<modifier>

Example for the ibs pmu:

# perf record -a -e ibs_op:r000 ...

Signed-off-by: Robert Richter <robert.richter@xxxxxxx>
---
tools/perf/util/parse-events.c | 20 +++++++++++++++-----
tools/perf/util/parse-events.h | 2 +-
tools/perf/util/parse-events.y | 7 ++++++-
tools/perf/util/pmu-ibs.c | 4 ++++
4 files changed, 26 insertions(+), 7 deletions(-)

diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index d572204..8ad536c 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -524,6 +524,9 @@ static int parse_events_add_tracepoint(struct list_head *list, int *idx,
{
int ret;

+ if (!event)
+ return -ENOENT;
+
ret = debugfs_valid_mountpoint(tracing_events_path);
if (ret)
return ret;
@@ -533,8 +536,9 @@ static int parse_events_add_tracepoint(struct list_head *list, int *idx,
add_tracepoint(list, idx, sys, event);
}

-static int __parse_events_add_generic_event(struct list_head *list, int *idx,
- char *sys, char *event)
+static int
+__parse_events_add_generic_event(struct list_head *list, int *idx, char *sys,
+ char *event, unsigned long config)
{
struct perf_event_attr attr;
char name[MAX_NAME_LEN];
@@ -545,12 +549,18 @@ static int __parse_events_add_generic_event(struct list_head *list, int *idx,
if (ret)
return ret;

- snprintf(name, MAX_NAME_LEN, "%s:%s", sys, event);
+ if (event)
+ snprintf(name, MAX_NAME_LEN, "%s:%s", sys, event);
+ else
+ snprintf(name, MAX_NAME_LEN, "%s:r%lx", sys, config);
+
+ attr.config |= config;
+
return add_event(list, idx, &attr, name);
}

int parse_events_add_generic_event(struct list_head *list, int *idx,
- char *sys, char *event)
+ char *sys, char *event, unsigned long config)
{
int ret1, ret2;

@@ -558,7 +568,7 @@ int parse_events_add_generic_event(struct list_head *list, int *idx,
if (!ret1)
return 0;

- ret2 = __parse_events_add_generic_event(list, idx, sys, event);
+ ret2 = __parse_events_add_generic_event(list, idx, sys, event, config);
if (!ret2)
return 0;

diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
index e9df741..88950d8 100644
--- a/tools/perf/util/parse-events.h
+++ b/tools/perf/util/parse-events.h
@@ -63,7 +63,7 @@ int parse_events__new_term(struct parse_events__term **term, int type,
void parse_events__free_terms(struct list_head *terms);
int parse_events_modifier(struct list_head *list __used, char *str __used);
int parse_events_add_generic_event(struct list_head *list, int *idx,
- char *sys, char *event);
+ char *sys, char *event, unsigned long config);
int parse_events_add_raw(struct perf_evlist *evlist, unsigned long config,
unsigned long config1, unsigned long config2,
char *mod);
diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y
index 659b5e8..d07fddd 100644
--- a/tools/perf/util/parse-events.y
+++ b/tools/perf/util/parse-events.y
@@ -134,7 +134,12 @@ PE_PREFIX_MEM PE_VALUE sep_dc
event_legacy_generic:
PE_NAME ':' PE_NAME
{
- ABORT_ON(parse_events_add_generic_event(list_event, idx, $1, $3));
+ ABORT_ON(parse_events_add_generic_event(list_event, idx, $1, $3, 0));
+}
+|
+PE_NAME ':' PE_RAW
+{
+ ABORT_ON(parse_events_add_generic_event(list_event, idx, $1, NULL, $3));
}

event_legacy_numeric:
diff --git a/tools/perf/util/pmu-ibs.c b/tools/perf/util/pmu-ibs.c
index 604cb8c..a5468c8 100644
--- a/tools/perf/util/pmu-ibs.c
+++ b/tools/perf/util/pmu-ibs.c
@@ -375,6 +375,9 @@ static int ibs_parse_event(struct perf_event_attr *attr, char *sys, char *name)
if (strcmp("ibs_op", sys) && strcmp("ibs_fetch", sys))
return -ENOENT;

+ if (!name)
+ goto out; /* raw event if name is NULL */
+
for (event = events; event->id; event++) {
if (!strcmp(event->name + strlen(sys) + 1, name))
goto match;
@@ -384,6 +387,7 @@ static int ibs_parse_event(struct perf_event_attr *attr, char *sys, char *name)
match:
/* pseudo event found */
attr->config1 = event->config;
+out:
attr->sample_type = PERF_SAMPLE_CPU;

return 0;
--
1.7.8.4


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/