2012-06-14 20:40:40

by Jiri Olsa

[permalink] [raw]
Subject: [RFC 0/6] perf, tool: Allow to use hw events in PMU syntax

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

The patch 1 makes PERF_TYPE_HARDWARE events translations available
by the sysfs 'events' group attribute under the PMU record.

Once we hit the PERF_TYPE_HARDWARE event mnemonic within the
PMU event term parsing like:
'event=cycles'
we translate the 'cycles' string into specific PERF_TYPE_HARDWARE
translation and assign this value to the 'event' term value.

So given that:
$ cat /sys/devices/cpu/events/instructions
0xc0

following examples are identical:
perf stat -e cpu/event=0xc0/u ls
perf stat -e cpu/event=instructions/u ls

It feels like a hack since it relies on:
- kernel does no more than translating the 'cycles' value and putting it
to the 'attr.config' - I'm not sure this is allways true.
- user uses this translation with terms that fill the attr.config same way
as kernel does, like for 'event':
$ cat /sys/devices/cpu/format/event
config:0-7

This could be ensured by perf tool.. but it smells like CPU specific again.

note, it's not tested much.. ;)

attached patches:
1/6 perf, x86: Making hardware events tranlations sysfs available
2/6 perf tools: Fix generation of pmu list
3/6 perf, tool: Properly free format data
4/6 perf, tool: Add events support for pmu
5/6 perf, tool: event parsing - split PE_VALUE_SYM to SW and HW tokens
6/6 perf, tool: Support translate terms for hw events

thoughts? ;)
jirka
---
arch/x86/kernel/cpu/perf_event.c | 44 +++++++++
tools/perf/util/parse-events.c | 8 ++-
tools/perf/util/parse-events.h | 3 +
tools/perf/util/parse-events.l | 2 +-
tools/perf/util/parse-events.y | 26 +++++-
tools/perf/util/pmu.c | 179 ++++++++++++++++++++++++++++++++-----
tools/perf/util/pmu.h | 2 +
7 files changed, 233 insertions(+), 31 deletions(-)


2012-06-14 20:39:21

by Jiri Olsa

[permalink] [raw]
Subject: [PATCH 6/6] perf, tool: Support translate terms for hw events

Allow to specify HW events mnemonics inside the PMU events
syntax, like:

# perf stat -e cpu/event=instructions/u ls

The term value gets the value of the PERF_TYPE_HARDWARE event
translated for current CPU. The translation is obtained
from PMU sysfs events group attribute.

Above example will fill event term with translated value for
HW instruction event for current CPU model.

Signed-off-by: Jiri Olsa <[email protected]>
---
tools/perf/util/parse-events.c | 8 +++++++-
tools/perf/util/parse-events.h | 3 +++
tools/perf/util/parse-events.y | 11 +++++++++++
tools/perf/util/pmu.c | 34 +++++++++++++++++++++++++++-------
4 files changed, 48 insertions(+), 8 deletions(-)

diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 05dbc8b..7c64f43 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -1057,9 +1057,15 @@ void print_events(const char *event_glob)
print_tracepoint_events(NULL, NULL);
}

+int parse_events__is_translate_term(struct parse_events__term *term)
+{
+ return term->type_term == PARSE_EVENTS__TERM_TYPE_USER_TRANSLATE;
+}
+
int parse_events__is_hardcoded_term(struct parse_events__term *term)
{
- return term->type_term != PARSE_EVENTS__TERM_TYPE_USER;
+ return (term->type_term != PARSE_EVENTS__TERM_TYPE_USER) &&
+ (term->type_term != PARSE_EVENTS__TERM_TYPE_USER_TRANSLATE);
}

static int new_term(struct parse_events__term **_term, int type_val,
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
index 8cac57a..deae5d7 100644
--- a/tools/perf/util/parse-events.h
+++ b/tools/perf/util/parse-events.h
@@ -44,6 +44,7 @@ enum {

enum {
PARSE_EVENTS__TERM_TYPE_USER,
+ PARSE_EVENTS__TERM_TYPE_USER_TRANSLATE,
PARSE_EVENTS__TERM_TYPE_CONFIG,
PARSE_EVENTS__TERM_TYPE_CONFIG1,
PARSE_EVENTS__TERM_TYPE_CONFIG2,
@@ -60,9 +61,11 @@ struct parse_events__term {
} val;
int type_val;
int type_term;
+ u64 flags;
struct list_head list;
};

+int parse_events__is_translate_term(struct parse_events__term *term);
int parse_events__is_hardcoded_term(struct parse_events__term *term);
int parse_events__term_num(struct parse_events__term **_term,
int type_term, char *config, long num);
diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y
index d3dce39..0541cd1 100644
--- a/tools/perf/util/parse-events.y
+++ b/tools/perf/util/parse-events.y
@@ -235,6 +235,17 @@ PE_NAME '=' PE_VALUE
$$ = term;
}
|
+PE_NAME '=' PE_VALUE_SYM_HW
+{
+ struct parse_events__term *term;
+#define CONFIG_MASK ((1ULL << 16) - 1ULL)
+
+ ABORT_ON(parse_events__term_num(&term,
+ PARSE_EVENTS__TERM_TYPE_USER_TRANSLATE,
+ $1, $3 & CONFIG_MASK));
+ $$ = term;
+}
+|
PE_NAME
{
struct parse_events__term *term;
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index bf2a2a9..e7b3dea 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -315,11 +315,26 @@ static __u64 pmu_format_value(unsigned long *format, __u64 value)
return v;
}

+static int translate_term(struct parse_events__term *term, __u64 *events)
+{
+ unsigned id = (unsigned) term->val.num;
+
+ if (!events)
+ return -EINVAL;
+
+ if (id >= PERF_COUNT_HW_MAX)
+ return -EINVAL;
+
+ term->val.num = events[id];
+ return 0;
+}
+
/*
* Setup one of config[12] attr members based on the
* user input data - temr parameter.
*/
static int pmu_config_term(struct list_head *formats,
+ __u64 *events,
struct perf_event_attr *attr,
struct parse_events__term *term)
{
@@ -356,21 +371,26 @@ static int pmu_config_term(struct list_head *formats,
}

/*
- * XXX If we ever decide to go with string values for
- * non-hardcoded terms, here's the place to translate
- * them into value.
+ * We support translation only for PERF_TYPE_HARDWARE events,
+ * which use config value only.
*/
+ if (parse_events__is_translate_term(term) &&
+ (format->value == PERF_PMU_FORMAT_VALUE_CONFIG))
+ if (translate_term(term, events))
+ return -EINVAL;
+
*vp |= pmu_format_value(format->bits, term->val.num);
return 0;
}

-static int pmu_config(struct list_head *formats, struct perf_event_attr *attr,
+static int pmu_config(struct list_head *formats, __u64 *events,
+ struct perf_event_attr *attr,
struct list_head *head_terms)
{
struct parse_events__term *term;

list_for_each_entry(term, head_terms, list)
- if (pmu_config_term(formats, attr, term))
+ if (pmu_config_term(formats, events, attr, term))
return -EINVAL;

return 0;
@@ -385,7 +405,7 @@ int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr,
struct list_head *head_terms)
{
attr->type = pmu->type;
- return pmu_config(&pmu->format, attr, head_terms);
+ return pmu_config(&pmu->format, pmu->events, attr, head_terms);
}

int perf_pmu__new_format(struct list_head *list, char *name,
@@ -571,7 +591,7 @@ int perf_pmu__test(void)
if (ret)
break;

- ret = pmu_config(&formats, &attr, terms);
+ ret = pmu_config(&formats, NULL, &attr, terms);
if (ret)
break;

--
1.7.7.6

2012-06-14 20:39:27

by Jiri Olsa

[permalink] [raw]
Subject: [PATCH 5/6] perf, tool: event parsing - split PE_VALUE_SYM to SW and HW tokens

Spliting PE_VALUE_SYM token to PE_VALUE_SYM_HW and PE_VALUE_SYM_SW
tokens to separate hardware and software symbols.

This will be usefull in upcomming patches where we want to be able
to parse out only hardware events.

Signed-off-by: Jiri Olsa <[email protected]>
---
tools/perf/util/parse-events.l | 2 +-
tools/perf/util/parse-events.y | 15 +++++++++++----
2 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l
index 618a8e7..f804c91 100644
--- a/tools/perf/util/parse-events.l
+++ b/tools/perf/util/parse-events.l
@@ -40,7 +40,7 @@ static int str(int token)
static int sym(int type, int config)
{
parse_events_lval.num = (type << 16) + config;
- return PE_VALUE_SYM;
+ return type == PERF_TYPE_HARDWARE ? PE_VALUE_SYM_HW : PE_VALUE_SYM_SW;
}

static int term(int type)
diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y
index 362cc59..d3dce39 100644
--- a/tools/perf/util/parse-events.y
+++ b/tools/perf/util/parse-events.y
@@ -23,14 +23,15 @@ do { \

%}

-%token PE_VALUE PE_VALUE_SYM PE_RAW PE_TERM
+%token PE_VALUE PE_VALUE_SYM_HW PE_VALUE_SYM_SW PE_RAW PE_TERM
%token PE_NAME
%token PE_MODIFIER_EVENT PE_MODIFIER_BP
%token PE_NAME_CACHE_TYPE PE_NAME_CACHE_OP_RESULT
%token PE_PREFIX_MEM PE_PREFIX_RAW
%token PE_ERROR
%type <num> PE_VALUE
-%type <num> PE_VALUE_SYM
+%type <num> PE_VALUE_SYM_HW
+%type <num> PE_VALUE_SYM_SW
%type <num> PE_RAW
%type <num> PE_TERM
%type <str> PE_NAME
@@ -38,6 +39,7 @@ do { \
%type <str> PE_NAME_CACHE_OP_RESULT
%type <str> PE_MODIFIER_EVENT
%type <str> PE_MODIFIER_BP
+%type <num> value_sym
%type <head> event_config
%type <term> event_term
%type <head> event_pmu
@@ -96,8 +98,13 @@ PE_NAME '/' event_config '/'
$$ = list;
}

+value_sym:
+PE_VALUE_SYM_HW
+|
+PE_VALUE_SYM_SW
+
event_legacy_symbol:
-PE_VALUE_SYM '/' event_config '/'
+value_sym '/' event_config '/'
{
struct list_head *list = NULL;
int type = $1 >> 16;
@@ -108,7 +115,7 @@ PE_VALUE_SYM '/' event_config '/'
$$ = list;
}
|
-PE_VALUE_SYM sep_slash_dc
+value_sym sep_slash_dc
{
struct list_head *list = NULL;
int type = $1 >> 16;
--
1.7.7.6

2012-06-14 20:39:35

by Jiri Olsa

[permalink] [raw]
Subject: [PATCH 4/6] perf, tool: Add events support for pmu

The pmu sysfs record expose events group attribute with
hardware events translations.

Adding support to read those and make it available throught:
__u64 perf_pmu__event(struct perf_pmu *pmu, unsigned id)

Signed-off-by: Jiri Olsa <[email protected]>
---
tools/perf/util/pmu.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++++-
tools/perf/util/pmu.h | 2 +
2 files changed, 98 insertions(+), 2 deletions(-)

diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index 1d73131..bf2a2a9 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -88,6 +88,94 @@ static int pmu_format(char *name, struct list_head *format)
return 0;
}

+const char *events_files[PERF_COUNT_HW_MAX] = {
+ [PERF_COUNT_HW_CPU_CYCLES] = "cycles",
+ [PERF_COUNT_HW_INSTRUCTIONS] = "instructions",
+ [PERF_COUNT_HW_CACHE_REFERENCES] = "cache_references",
+ [PERF_COUNT_HW_CACHE_MISSES] = "cache_misses",
+ [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = "branch_instructions",
+ [PERF_COUNT_HW_BRANCH_MISSES] = "branch_misses",
+ [PERF_COUNT_HW_BUS_CYCLES] = "bus_cycles",
+ [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = "stalled_cycles_frontend",
+ [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = "stalled_cycles_backend",
+ [PERF_COUNT_HW_REF_CPU_CYCLES] = "ref_cycles",
+};
+
+static int read_events(char *dir, __u64 **_events)
+{
+ unsigned i;
+ int ret = 0;
+ __u64 *events;
+
+ events = malloc(PERF_COUNT_HW_MAX * sizeof(u64));
+ if (!events)
+ return -ENOMEM;
+
+ for (i = 0; (i < ARRAY_SIZE(events_files)) && (!ret); i++) {
+ FILE *file;
+ char path[PATH_MAX];
+
+ snprintf(path, PATH_MAX, "%s/%s", dir, events_files[i]);
+
+ file = fopen(path, "r");
+ if (file) {
+ __u64 val;
+
+ if (1 != fscanf(file, "0x%llx", &val))
+ ret = -EINVAL;
+
+ events[i] = val;
+ fclose(file);
+ } else
+ ret = -EINVAL;
+
+ }
+
+ if (ret)
+ free(events);
+ else
+ *_events = events;
+
+ return ret;
+}
+
+/*
+ * Reading/parsing the default pmu events definition, which should be
+ * located at:
+ * /sys/bus/event_source/devices/<dev>/events as sysfs group attributes.
+ */
+static int pmu_events(char *name, __u64 **events)
+{
+ struct stat st;
+ char path[PATH_MAX];
+ const char *sysfs;
+
+ sysfs = sysfs_find_mountpoint();
+ if (!sysfs)
+ return -1;
+
+ snprintf(path, PATH_MAX,
+ "%s/bus/event_source/devices/%s/events", sysfs, name);
+
+ if (stat(path, &st) < 0)
+ return 0; /* no error if events does not exist */
+
+ return read_events(path, events);
+}
+
+static void pmu_events_release(__u64 *events)
+{
+ free(events);
+}
+
+__u64 perf_pmu__event(struct perf_pmu *pmu, unsigned id)
+{
+ if (pmu->events && (id < PERF_COUNT_HW_MAX))
+ return pmu->events[id];
+
+ return 0;
+}
+
/*
* Reading/parsing the default pmu type value, which should be
* located at:
@@ -125,18 +213,22 @@ static int pmu_type(char *name, __u32 *type)
static struct perf_pmu *pmu_lookup(char *name)
{
struct perf_pmu *pmu;
+ __u64 *events = NULL;
LIST_HEAD(format);
__u32 type;

do {
/*
* The pmu data we store & need consists of the pmu
- * type value and format definitions. Load both right
- * now.
+ * type value, format and events definitions. Load
+ * all of them right now.
*/
if (pmu_format(name, &format))
break;

+ if (pmu_events(name, &events))
+ break;
+
if (pmu_type(name, &type))
break;

@@ -148,12 +240,14 @@ static struct perf_pmu *pmu_lookup(char *name)
list_splice(&format, &pmu->format);
pmu->name = strdup(name);
pmu->type = type;
+ pmu->events = events;
list_add_tail(&pmu->list, &pmus);
return pmu;

} while (0);

pmu_format_release(&format);
+ pmu_events_release(events);
return NULL;
}

diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h
index 68c0db9..554dd6a 100644
--- a/tools/perf/util/pmu.h
+++ b/tools/perf/util/pmu.h
@@ -24,11 +24,13 @@ struct perf_pmu {
__u32 type;
struct list_head format;
struct list_head list;
+ __u64 *events;
};

struct perf_pmu *perf_pmu__find(char *name);
int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr,
struct list_head *head_terms);
+__u64 perf_pmu__event(struct perf_pmu *pmu, unsigned id);

int perf_pmu_wrap(void);
void perf_pmu_error(struct list_head *list, char *name, char const *msg);
--
1.7.7.6

2012-06-14 20:40:00

by Jiri Olsa

[permalink] [raw]
Subject: [PATCH 3/6] perf, tool: Properly free format data

Release format data in case there's failure during PMU load.

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

Signed-off-by: Jiri Olsa <[email protected]>
---
tools/perf/util/pmu.c | 50 +++++++++++++++++++++++++++++++-----------------
1 files changed, 32 insertions(+), 18 deletions(-)

diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index bda0563..1d73131 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.
@@ -120,27 +128,33 @@ static struct perf_pmu *pmu_lookup(char *name)
LIST_HEAD(format);
__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 and format definitions. Load both right
+ * now.
+ */
+ if (pmu_format(name, &format))
+ 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);
- list_splice(&format, &pmu->format);
- pmu->name = strdup(name);
- pmu->type = type;
- list_add_tail(&pmu->list, &pmus);
- return pmu;
+ INIT_LIST_HEAD(&pmu->format);
+ list_splice(&format, &pmu->format);
+ 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.7.6

2012-06-14 20:39:18

by Jiri Olsa

[permalink] [raw]
Subject: [PATCH 1/6] perf, x86: Making hardware events tranlations sysfs available

Making hardware events tranlations available throught 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
cycles
instructions
ref_cycles
stalled_cycles_backend
stalled_cycles_frontend

The file - ID mappings is:

file hw id
----------------------------------------------------------------
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 attribute/file contains HW ID event translation for the currently
running CPU model

# cat /sys/devices/cpu/events/instructions
0xc0

Signed-off-by: Jiri Olsa <[email protected]>
---
arch/x86/kernel/cpu/perf_event.c | 44 ++++++++++++++++++++++++++++++++++++++
1 files changed, 44 insertions(+), 0 deletions(-)

diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c
index 53cc997..aaa8d85 100644
--- a/arch/x86/kernel/cpu/perf_event.c
+++ b/arch/x86/kernel/cpu/perf_event.c
@@ -1666,9 +1666,53 @@ static struct attribute_group x86_pmu_attr_group = {
.attrs = x86_pmu_attrs,
};

+#define PMU_EVENTS_ATTR(_name, _id) \
+static ssize_t \
+_name##_show(struct device *dev, \
+ struct device_attribute *attr, \
+ char *page) \
+{ \
+ u64 val = x86_pmu.event_map(_id); \
+ BUILD_BUG_ON(_id >= PERF_COUNT_HW_MAX); \
+ return sprintf(page, "0x%llx\n", val); \
+} \
+ \
+static struct device_attribute event_attr_##_name = __ATTR_RO(_name)
+
+PMU_EVENTS_ATTR(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_cycles.attr,
+ &event_attr_instructions.attr,
+ &event_attr_cache_references.attr,
+ &event_attr_cache_misses.attr,
+ &event_attr_branch_instructions.attr,
+ &event_attr_branch_misses.attr,
+ &event_attr_bus_cycles.attr,
+ &event_attr_stalled_cycles_frontend.attr,
+ &event_attr_stalled_cycles_backend.attr,
+ &event_attr_ref_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.7.6

2012-06-14 20:39:16

by Jiri Olsa

[permalink] [raw]
Subject: [PATCH 2/6] perf tools: Fix generation of pmu list

From: Robert Richter <[email protected]>

The internal pmu list was never used. With each perf_pmu__find() call
the pmu structure was created new by parsing sysfs. Beside this it
caused memory leaks. We now keep all pmus by adding them to the list.

Also, pmu_lookup() should return pmus that do not expose the format
specifier in sysfs.

We need a valid internal pmu list in a later patch to iterate over all
pmus that exist in the system.

Signed-off-by: Robert Richter <[email protected]>
---
tools/perf/util/pmu.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index a119a53..bda0563 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -72,7 +72,7 @@ static int pmu_format(char *name, struct list_head *format)
"%s/bus/event_source/devices/%s/format", sysfs, name);

if (stat(path, &st) < 0)
- return -1;
+ return 0; /* no error if format does not exist */

if (pmu_format_parse(path, format))
return -1;
@@ -139,6 +139,7 @@ static struct perf_pmu *pmu_lookup(char *name)
list_splice(&format, &pmu->format);
pmu->name = strdup(name);
pmu->type = type;
+ list_add_tail(&pmu->list, &pmus);
return pmu;
}

--
1.7.7.6

2012-06-14 21:10:12

by Peter Zijlstra

[permalink] [raw]
Subject: Re: [PATCH 1/6] perf, x86: Making hardware events tranlations sysfs available

On Thu, 2012-06-14 at 22:38 +0200, Jiri Olsa wrote:
> Making hardware events tranlations available throught 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
> cycles
> instructions
> ref_cycles
> stalled_cycles_backend
> stalled_cycles_frontend
>
> The file - ID mappings is:
>
> file hw id
> ----------------------------------------------------------------
> 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 attribute/file contains HW ID event translation for the currently
> running CPU model
>
> # cat /sys/devices/cpu/events/instructions
> 0xc0

Why not have it consistent with the stuff done for uncore where events
read: 'event=0xc0', ie the regular field=value stuff.

2012-06-14 21:36:54

by Stephane Eranian

[permalink] [raw]
Subject: Re: [PATCH 1/6] perf, x86: Making hardware events tranlations sysfs available

On Thu, Jun 14, 2012 at 11:09 PM, Peter Zijlstra <[email protected]> wrote:
> On Thu, 2012-06-14 at 22:38 +0200, Jiri Olsa wrote:
>> Making hardware events tranlations available throught 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
>>   cycles
>>   instructions
>>   ref_cycles
>>   stalled_cycles_backend
>>   stalled_cycles_frontend
>>
>> The file - ID mappings is:
>>
>>   file                      hw id
>>   ----------------------------------------------------------------
>>   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 attribute/file contains HW ID event translation for the currently
>> running CPU model
>>
>>   # cat /sys/devices/cpu/events/instructions
>>   0xc0
>
> Why not have it consistent with the stuff done for uncore where events
> read: 'event=0xc0', ie the regular field=value stuff.
>
Yes, you want that. Because those events may need more than a code.
You want full syntax capability. So return a string.

2012-06-15 07:29:22

by Jiri Olsa

[permalink] [raw]
Subject: Re: [PATCH 1/6] perf, x86: Making hardware events tranlations sysfs available

On Thu, Jun 14, 2012 at 11:36:51PM +0200, Stephane Eranian wrote:
> On Thu, Jun 14, 2012 at 11:09 PM, Peter Zijlstra <[email protected]> wrote:
> > On Thu, 2012-06-14 at 22:38 +0200, Jiri Olsa wrote:
> >> Making hardware events tranlations available throught 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
> >> ? cycles
> >> ? instructions
> >> ? ref_cycles
> >> ? stalled_cycles_backend
> >> ? stalled_cycles_frontend
> >>
> >> The file - ID mappings is:
> >>
> >> ? file ? ? ? ? ? ? ? ? ? ? ?hw id
> >> ? ----------------------------------------------------------------
> >> ? 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 attribute/file contains HW ID event translation for the currently
> >> running CPU model
> >>
> >> ? # cat /sys/devices/cpu/events/instructions
> >> ? 0xc0
> >
> > Why not have it consistent with the stuff done for uncore where events
> > read: 'event=0xc0', ie the regular field=value stuff.
> >
> Yes, you want that. Because those events may need more than a code.
> You want full syntax capability. So return a string.

humm... right :)

how about the term name 'event=...', could I always assume it's 'event',
or do we want some arch specific connection for that?

jirka

2012-06-15 07:32:24

by Stephane Eranian

[permalink] [raw]
Subject: Re: [PATCH 1/6] perf, x86: Making hardware events tranlations sysfs available

On Fri, Jun 15, 2012 at 9:29 AM, Jiri Olsa <[email protected]> wrote:
> On Thu, Jun 14, 2012 at 11:36:51PM +0200, Stephane Eranian wrote:
>> On Thu, Jun 14, 2012 at 11:09 PM, Peter Zijlstra <[email protected]> wrote:
>> > On Thu, 2012-06-14 at 22:38 +0200, Jiri Olsa wrote:
>> >> Making hardware events tranlations available throught 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
>> >>   cycles
>> >>   instructions
>> >>   ref_cycles
>> >>   stalled_cycles_backend
>> >>   stalled_cycles_frontend
>> >>
>> >> The file - ID mappings is:
>> >>
>> >>   file                      hw id
>> >>   ----------------------------------------------------------------
>> >>   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 attribute/file contains HW ID event translation for the currently
>> >> running CPU model
>> >>
>> >>   # cat /sys/devices/cpu/events/instructions
>> >>   0xc0
>> >
>> > Why not have it consistent with the stuff done for uncore where events
>> > read: 'event=0xc0', ie the regular field=value stuff.
>> >
>> Yes, you want that. Because those events may need more than a code.
>> You want full syntax capability. So return a string.
>
> humm... right :)
>
> how about the term name 'event=...', could I always assume it's 'event',
> or do we want some arch specific connection for that?
>
You should not assume anything. You grab the string from sysfs and put it
through your regular parser. It could have arch specific terms in it. That's
how I suspect this is done for uncore.

> jirka

2012-06-15 07:43:28

by Jiri Olsa

[permalink] [raw]
Subject: Re: [PATCH 1/6] perf, x86: Making hardware events tranlations sysfs available

On Fri, Jun 15, 2012 at 09:32:20AM +0200, Stephane Eranian wrote:
> On Fri, Jun 15, 2012 at 9:29 AM, Jiri Olsa <[email protected]> wrote:
> > On Thu, Jun 14, 2012 at 11:36:51PM +0200, Stephane Eranian wrote:
> >> On Thu, Jun 14, 2012 at 11:09 PM, Peter Zijlstra <[email protected]> wrote:
> >> > On Thu, 2012-06-14 at 22:38 +0200, Jiri Olsa wrote:
> >> >> Making hardware events tranlations available throught 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
> >> >> ? cycles
> >> >> ? instructions
> >> >> ? ref_cycles
> >> >> ? stalled_cycles_backend
> >> >> ? stalled_cycles_frontend
> >> >>
> >> >> The file - ID mappings is:
> >> >>
> >> >> ? file ? ? ? ? ? ? ? ? ? ? ?hw id
> >> >> ? ----------------------------------------------------------------
> >> >> ? 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 attribute/file contains HW ID event translation for the currently
> >> >> running CPU model
> >> >>
> >> >> ? # cat /sys/devices/cpu/events/instructions
> >> >> ? 0xc0
> >> >
> >> > Why not have it consistent with the stuff done for uncore where events
> >> > read: 'event=0xc0', ie the regular field=value stuff.
> >> >
> >> Yes, you want that. Because those events may need more than a code.
> >> You want full syntax capability. So return a string.
> >
> > humm... right :)
> >
> > how about the term name 'event=...', could I always assume it's 'event',
> > or do we want some arch specific connection for that?
> >
> You should not assume anything. You grab the string from sysfs and put it
> through your regular parser. It could have arch specific terms in it. That's
> how I suspect this is done for uncore.

I was talking about the kernel part

jirka

2012-06-15 07:46:28

by Stephane Eranian

[permalink] [raw]
Subject: Re: [PATCH 1/6] perf, x86: Making hardware events tranlations sysfs available

On Fri, Jun 15, 2012 at 9:43 AM, Jiri Olsa <[email protected]> wrote:
> On Fri, Jun 15, 2012 at 09:32:20AM +0200, Stephane Eranian wrote:
>> On Fri, Jun 15, 2012 at 9:29 AM, Jiri Olsa <[email protected]> wrote:
>> > On Thu, Jun 14, 2012 at 11:36:51PM +0200, Stephane Eranian wrote:
>> >> On Thu, Jun 14, 2012 at 11:09 PM, Peter Zijlstra <[email protected]> wrote:
>> >> > On Thu, 2012-06-14 at 22:38 +0200, Jiri Olsa wrote:
>> >> >> Making hardware events tranlations available throught 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
>> >> >>   cycles
>> >> >>   instructions
>> >> >>   ref_cycles
>> >> >>   stalled_cycles_backend
>> >> >>   stalled_cycles_frontend
>> >> >>
>> >> >> The file - ID mappings is:
>> >> >>
>> >> >>   file                      hw id
>> >> >>   ----------------------------------------------------------------
>> >> >>   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 attribute/file contains HW ID event translation for the currently
>> >> >> running CPU model
>> >> >>
>> >> >>   # cat /sys/devices/cpu/events/instructions
>> >> >>   0xc0
>> >> >
>> >> > Why not have it consistent with the stuff done for uncore where events
>> >> > read: 'event=0xc0', ie the regular field=value stuff.
>> >> >
>> >> Yes, you want that. Because those events may need more than a code.
>> >> You want full syntax capability. So return a string.
>> >
>> > humm... right :)
>> >
>> > how about the term name 'event=...', could I always assume it's 'event',
>> > or do we want some arch specific connection for that?
>> >
>> You should not assume anything. You grab the string from sysfs and put it
>> through your regular parser. It could have arch specific terms in it. That's
>> how I suspect this is done for uncore.
>
> I was talking about the kernel part
>
The kernel part should export the event with any of the terms that it exports
thru sysfs for that CPU.

> jirka

2012-06-15 09:26:43

by Peter Zijlstra

[permalink] [raw]
Subject: Re: [PATCH 1/6] perf, x86: Making hardware events tranlations sysfs available

On Fri, 2012-06-15 at 09:46 +0200, Stephane Eranian wrote:
> The kernel part should export the event with any of the terms that it exports
> thru sysfs for that CPU.

ack

2012-06-29 16:36:24

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: Re: [PATCH 4/6] perf, tool: Add events support for pmu

Em Thu, Jun 14, 2012 at 10:38:39PM +0200, Jiri Olsa escreveu:
> The pmu sysfs record expose events group attribute with
> hardware events translations.
>
> Adding support to read those and make it available throught:
> __u64 perf_pmu__event(struct perf_pmu *pmu, unsigned id)
>
> Signed-off-by: Jiri Olsa <[email protected]>
> ---
> tools/perf/util/pmu.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++++-
> tools/perf/util/pmu.h | 2 +
> 2 files changed, 98 insertions(+), 2 deletions(-)
>
> diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
> index 1d73131..bf2a2a9 100644
> --- a/tools/perf/util/pmu.c
> +++ b/tools/perf/util/pmu.c
> @@ -88,6 +88,94 @@ static int pmu_format(char *name, struct list_head *format)
> return 0;
> }
>
> +const char *events_files[PERF_COUNT_HW_MAX] = {
> + [PERF_COUNT_HW_CPU_CYCLES] = "cycles",
> + [PERF_COUNT_HW_INSTRUCTIONS] = "instructions",
> + [PERF_COUNT_HW_CACHE_REFERENCES] = "cache_references",
> + [PERF_COUNT_HW_CACHE_MISSES] = "cache_misses",
> + [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = "branch_instructions",
> + [PERF_COUNT_HW_BRANCH_MISSES] = "branch_misses",
> + [PERF_COUNT_HW_BUS_CYCLES] = "bus_cycles",
> + [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = "stalled_cycles_frontend",
> + [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = "stalled_cycles_backend",
> + [PERF_COUNT_HW_REF_CPU_CYCLES] = "ref_cycles",

we have this one:

static const char *perf_evsel__hw_names[PERF_COUNT_HW_MAX] = {

Can't it be used?

- Arnaldo

2012-06-29 16:43:19

by Jiri Olsa

[permalink] [raw]
Subject: Re: [PATCH 4/6] perf, tool: Add events support for pmu

On Fri, Jun 29, 2012 at 01:36:07PM -0300, Arnaldo Carvalho de Melo wrote:
> Em Thu, Jun 14, 2012 at 10:38:39PM +0200, Jiri Olsa escreveu:
> > The pmu sysfs record expose events group attribute with
> > hardware events translations.
> >
> > Adding support to read those and make it available throught:
> > __u64 perf_pmu__event(struct perf_pmu *pmu, unsigned id)
> >
> > Signed-off-by: Jiri Olsa <[email protected]>
> > ---
> > tools/perf/util/pmu.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++++-
> > tools/perf/util/pmu.h | 2 +
> > 2 files changed, 98 insertions(+), 2 deletions(-)
> >
> > diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
> > index 1d73131..bf2a2a9 100644
> > --- a/tools/perf/util/pmu.c
> > +++ b/tools/perf/util/pmu.c
> > @@ -88,6 +88,94 @@ static int pmu_format(char *name, struct list_head *format)
> > return 0;
> > }
> >
> > +const char *events_files[PERF_COUNT_HW_MAX] = {
> > + [PERF_COUNT_HW_CPU_CYCLES] = "cycles",
> > + [PERF_COUNT_HW_INSTRUCTIONS] = "instructions",
> > + [PERF_COUNT_HW_CACHE_REFERENCES] = "cache_references",
> > + [PERF_COUNT_HW_CACHE_MISSES] = "cache_misses",
> > + [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = "branch_instructions",
> > + [PERF_COUNT_HW_BRANCH_MISSES] = "branch_misses",
> > + [PERF_COUNT_HW_BUS_CYCLES] = "bus_cycles",
> > + [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = "stalled_cycles_frontend",
> > + [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = "stalled_cycles_backend",
> > + [PERF_COUNT_HW_REF_CPU_CYCLES] = "ref_cycles",
>
> we have this one:
>
> static const char *perf_evsel__hw_names[PERF_COUNT_HW_MAX] = {
>
> Can't it be used?

right, probably yes... I need to redesign the patch anyway,
I'll see if I can use it

thanks,
jirka