* [PATCH V7 1/4] Revert "perf tools: Default to cpu// for events v5"
2014-10-03 16:09 [PATCH V7 0/4] perf tools: pmu event new style format fix kan.liang
@ 2014-10-03 16:09 ` kan.liang
2014-10-03 16:09 ` [PATCH V7 2/4] perf tools: parse the pmu event prefix and suffix kan.liang
` (3 subsequent siblings)
4 siblings, 0 replies; 8+ messages in thread
From: kan.liang @ 2014-10-03 16:09 UTC (permalink / raw)
To: jolsa; +Cc: linux-kernel, ak, acme, Kan Liang
From: Kan Liang <kan.liang@intel.com>
This reverts commit 50e200f07948 ("perf tools: Default to cpu// for
events v5")
The fixup cannot handle the case that
new style format(which without //) mixed with
other different formats.
For example,
group events with new style format: {mem-stores,mem-loads}
some hardware event + new style event: cycles,mem-loads
Cache event + new style event: LLC-loads,mem-loads
Raw event + new style event:
cpu/event=0xc8,umask=0x08/,mem-loads
old style event and new stytle mixture: mem-stores,cpu/mem-loads/
Signed-off-by: Kan Liang <kan.liang@intel.com>
---
tools/perf/util/include/linux/string.h | 1 -
tools/perf/util/parse-events.c | 30 +-----------------------------
tools/perf/util/string.c | 24 ------------------------
3 files changed, 1 insertion(+), 54 deletions(-)
diff --git a/tools/perf/util/include/linux/string.h b/tools/perf/util/include/linux/string.h
index 97a8007..6f19c54 100644
--- a/tools/perf/util/include/linux/string.h
+++ b/tools/perf/util/include/linux/string.h
@@ -1,4 +1,3 @@
#include <string.h>
void *memdup(const void *src, size_t len);
-int str_append(char **s, int *len, const char *a);
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index d76aa30..c5642e6 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -6,7 +6,7 @@
#include "parse-options.h"
#include "parse-events.h"
#include "exec_cmd.h"
-#include "linux/string.h"
+#include "string.h"
#include "symbol.h"
#include "cache.h"
#include "header.h"
@@ -863,32 +863,6 @@ int parse_events_name(struct list_head *list, char *name)
return 0;
}
-static int parse_events__scanner(const char *str, void *data, int start_token);
-
-static int parse_events_fixup(int ret, const char *str, void *data,
- int start_token)
-{
- char *o = strdup(str);
- char *s = NULL;
- char *t = o;
- char *p;
- int len = 0;
-
- if (!o)
- return ret;
- while ((p = strsep(&t, ",")) != NULL) {
- if (s)
- str_append(&s, &len, ",");
- str_append(&s, &len, "cpu/");
- str_append(&s, &len, p);
- str_append(&s, &len, "/");
- }
- free(o);
- if (!s)
- return -ENOMEM;
- return parse_events__scanner(s, data, start_token);
-}
-
static int parse_events__scanner(const char *str, void *data, int start_token)
{
YY_BUFFER_STATE buffer;
@@ -909,8 +883,6 @@ static int parse_events__scanner(const char *str, void *data, int start_token)
parse_events__flush_buffer(buffer, scanner);
parse_events__delete_buffer(buffer, scanner);
parse_events_lex_destroy(scanner);
- if (ret && !strchr(str, '/'))
- ret = parse_events_fixup(ret, str, data, start_token);
return ret;
}
diff --git a/tools/perf/util/string.c b/tools/perf/util/string.c
index 2553e5b..4b0ff22 100644
--- a/tools/perf/util/string.c
+++ b/tools/perf/util/string.c
@@ -387,27 +387,3 @@ void *memdup(const void *src, size_t len)
return p;
}
-
-/**
- * str_append - reallocate string and append another
- * @s: pointer to string pointer
- * @len: pointer to len (initialized)
- * @a: string to append.
- */
-int str_append(char **s, int *len, const char *a)
-{
- int olen = *s ? strlen(*s) : 0;
- int nlen = olen + strlen(a) + 1;
- if (*len < nlen) {
- *len = *len * 2;
- if (*len < nlen)
- *len = nlen;
- *s = realloc(*s, *len);
- if (!*s)
- return -ENOMEM;
- if (olen == 0)
- **s = 0;
- }
- strcat(*s, a);
- return 0;
-}
--
1.8.3.2
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH V7 2/4] perf tools: parse the pmu event prefix and suffix
2014-10-03 16:09 [PATCH V7 0/4] perf tools: pmu event new style format fix kan.liang
2014-10-03 16:09 ` [PATCH V7 1/4] Revert "perf tools: Default to cpu// for events v5" kan.liang
@ 2014-10-03 16:09 ` kan.liang
2014-10-05 19:02 ` Jiri Olsa
2014-10-03 16:09 ` [PATCH V7 3/4] perf tools: Add support to new style format of kernel PMU event kan.liang
` (2 subsequent siblings)
4 siblings, 1 reply; 8+ messages in thread
From: kan.liang @ 2014-10-03 16:09 UTC (permalink / raw)
To: jolsa; +Cc: linux-kernel, ak, acme, Kan Liang
From: Kan Liang <kan.liang@intel.com>
There are two types of event formats for PMU events. E.g. el-abort OR
cpu/el-abort/. However, the lexer mistakenly recognizes the simple style
format as two events.
The parse_events_pmu_check function uses bsearch to search the name in
known pmu event list. It can tell the lexer that the name is a PE_NAME
or a PMU event name prefix or a PMU event name suffix. All these
information will be used for accurately parsing kernel PMU events.
The pmu events list will be read from sysfs at runtime.
Note: Currently, the patch only want to handle the PMU event name as
"a-b" and "a". The only exception, "stalled-cycles-frontend" and
"stalled-cycles-fronted", are already hardcoded in lexer.
Signed-off-by: Kan Liang <kan.liang@intel.com>
---
tools/perf/util/parse-events.c | 115 +++++++++++++++++++++++++++++++++++++++++
tools/perf/util/parse-events.h | 14 +++++
tools/perf/util/pmu.c | 10 ----
tools/perf/util/pmu.h | 10 ++++
4 files changed, 139 insertions(+), 10 deletions(-)
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index c5642e6..571bbaf 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -30,6 +30,15 @@ extern int parse_events_debug;
#endif
int parse_events_parse(void *data, void *scanner);
+static struct perf_pmu_event_symbol *perf_pmu_events_list;
+/*
+ * The variable indicates the number of supported pmu event symbols.
+ * 0 means not initialized and ready to init
+ * -1 means failed to init, don't try anymore
+ * >0 is the number of supported pmu event symbols
+ */
+static int perf_pmu_events_list_num;
+
static struct event_symbol event_symbols_hw[PERF_COUNT_HW_MAX] = {
[PERF_COUNT_HW_CPU_CYCLES] = {
.symbol = "cpu-cycles",
@@ -863,6 +872,111 @@ int parse_events_name(struct list_head *list, char *name)
return 0;
}
+static int
+comp_pmu(const void *p1, const void *p2)
+{
+ struct perf_pmu_event_symbol *pmu1 = (struct perf_pmu_event_symbol *) p1;
+ struct perf_pmu_event_symbol *pmu2 = (struct perf_pmu_event_symbol *) p2;
+
+ return strcmp(pmu1->symbol, pmu2->symbol);
+}
+
+static void perf_pmu__parse_cleanup(void)
+{
+ if (perf_pmu_events_list_num > 0) {
+ struct perf_pmu_event_symbol *p;
+ int i;
+
+ for (i = 0; i < perf_pmu_events_list_num; i++) {
+ p = perf_pmu_events_list + i;
+ free(p->symbol);
+ }
+ free(perf_pmu_events_list);
+ perf_pmu_events_list = NULL;
+ perf_pmu_events_list_num = 0;
+ }
+}
+
+#define SET_SYMBOL(str, stype) \
+do { \
+ p->symbol = str; \
+ if (!p->symbol) \
+ goto err; \
+ p->type = stype; \
+} while (0)
+
+/*
+ * Read the pmu events list from sysfs
+ * Save it into perf_pmu_events_list
+ */
+static void perf_pmu__parse_init(void)
+{
+
+ struct perf_pmu *pmu = NULL;
+ struct perf_pmu_alias *alias;
+ int len = 0;
+
+ pmu = perf_pmu__find("cpu");
+ if ((pmu == NULL) || list_empty(&pmu->aliases)) {
+ perf_pmu_events_list_num = -1;
+ return;
+ }
+ list_for_each_entry(alias, &pmu->aliases, list) {
+ if (strchr(alias->name, '-'))
+ len++;
+ len++;
+ }
+ perf_pmu_events_list = malloc(sizeof(struct perf_pmu_event_symbol) * len);
+ perf_pmu_events_list_num = len;
+
+ len = 0;
+ list_for_each_entry(alias, &pmu->aliases, list) {
+ struct perf_pmu_event_symbol *p = perf_pmu_events_list + len;
+ char *tmp = strchr(alias->name, '-');
+
+ if (tmp != NULL) {
+ SET_SYMBOL(strndup(alias->name, tmp - alias->name),
+ PMU_EVENT_SYMBOL_PREFIX);
+ p++;
+ SET_SYMBOL(strdup(++tmp), PMU_EVENT_SYMBOL_SUFFIX);
+ len += 2;
+ } else {
+ SET_SYMBOL(strdup(alias->name), PMU_EVENT_SYMBOL);
+ len++;
+ }
+ }
+ qsort(perf_pmu_events_list, len,
+ sizeof(struct perf_pmu_event_symbol), comp_pmu);
+
+ return;
+err:
+ perf_pmu__parse_cleanup();
+}
+
+enum perf_pmu_event_symbol_type
+perf_pmu__parse_check(const char *name)
+{
+ struct perf_pmu_event_symbol p, *r;
+
+ /* scan kernel pmu events from sysfs if needed */
+ if (perf_pmu_events_list_num == 0)
+ perf_pmu__parse_init();
+ /*
+ * name "cpu" could be prefix of cpu-cycles or cpu// events.
+ * cpu-cycles has been handled by hardcode.
+ * So it must be cpu// events, not kernel pmu event.
+ */
+ if ((perf_pmu_events_list_num <= 0) || !strcmp(name, "cpu"))
+ return PMU_EVENT_SYMBOL_ERR;
+
+ p.symbol = strdup(name);
+ r = bsearch(&p, perf_pmu_events_list,
+ (size_t) perf_pmu_events_list_num,
+ sizeof(struct perf_pmu_event_symbol), comp_pmu);
+ free(p.symbol);
+ return r ? r->type : PMU_EVENT_SYMBOL_ERR;
+}
+
static int parse_events__scanner(const char *str, void *data, int start_token)
{
YY_BUFFER_STATE buffer;
@@ -917,6 +1031,7 @@ int parse_events(struct perf_evlist *evlist, const char *str)
int ret;
ret = parse_events__scanner(str, &data, PE_START_EVENTS);
+ perf_pmu__parse_cleanup();
if (!ret) {
int entries = data.idx - evlist->nr_entries;
perf_evlist__splice_list_tail(evlist, &data.list, entries);
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
index df094b4..db2cf78 100644
--- a/tools/perf/util/parse-events.h
+++ b/tools/perf/util/parse-events.h
@@ -35,6 +35,18 @@ extern int parse_filter(const struct option *opt, const char *str, int unset);
#define EVENTS_HELP_MAX (128*1024)
+enum perf_pmu_event_symbol_type {
+ PMU_EVENT_SYMBOL_ERR, /* not a PMU EVENT */
+ PMU_EVENT_SYMBOL, /* normal style PMU event */
+ PMU_EVENT_SYMBOL_PREFIX, /* prefix of pre-suf style event */
+ PMU_EVENT_SYMBOL_SUFFIX, /* suffix of pre-suf style event */
+};
+
+struct perf_pmu_event_symbol {
+ char *symbol;
+ enum perf_pmu_event_symbol_type type;
+};
+
enum {
PARSE_EVENTS__TERM_TYPE_NUM,
PARSE_EVENTS__TERM_TYPE_STR,
@@ -95,6 +107,8 @@ 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);
+enum perf_pmu_event_symbol_type
+perf_pmu__parse_check(const char *name);
void parse_events__set_leader(char *name, struct list_head *list);
void parse_events_update_lists(struct list_head *list_event,
struct list_head *list_all);
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index 93a41ca..e243ad9 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -12,16 +12,6 @@
#include "parse-events.h"
#include "cpumap.h"
-#define UNIT_MAX_LEN 31 /* max length for event unit name */
-
-struct perf_pmu_alias {
- char *name;
- struct list_head terms; /* HEAD struct parse_events_term -> list */
- struct list_head list; /* ELEM */
- char unit[UNIT_MAX_LEN+1];
- double scale;
-};
-
struct perf_pmu_format {
char *name;
int value;
diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h
index fe90a01..fe9dfbe 100644
--- a/tools/perf/util/pmu.h
+++ b/tools/perf/util/pmu.h
@@ -30,6 +30,16 @@ struct perf_pmu_info {
double scale;
};
+#define UNIT_MAX_LEN 31 /* max length for event unit name */
+
+struct perf_pmu_alias {
+ char *name;
+ struct list_head terms; /* HEAD struct parse_events_term -> list */
+ struct list_head list; /* ELEM */
+ char unit[UNIT_MAX_LEN+1];
+ double scale;
+};
+
struct perf_pmu *perf_pmu__find(const char *name);
int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr,
struct list_head *head_terms);
--
1.8.3.2
^ permalink raw reply related [flat|nested] 8+ messages in thread* Re: [PATCH V7 2/4] perf tools: parse the pmu event prefix and suffix
2014-10-03 16:09 ` [PATCH V7 2/4] perf tools: parse the pmu event prefix and suffix kan.liang
@ 2014-10-05 19:02 ` Jiri Olsa
0 siblings, 0 replies; 8+ messages in thread
From: Jiri Olsa @ 2014-10-05 19:02 UTC (permalink / raw)
To: kan.liang; +Cc: linux-kernel, ak, acme
On Fri, Oct 03, 2014 at 12:09:06PM -0400, kan.liang@intel.com wrote:
> From: Kan Liang <kan.liang@intel.com>
SNIP
> +/*
> + * Read the pmu events list from sysfs
> + * Save it into perf_pmu_events_list
> + */
> +static void perf_pmu__parse_init(void)
> +{
> +
> + struct perf_pmu *pmu = NULL;
> + struct perf_pmu_alias *alias;
> + int len = 0;
> +
> + pmu = perf_pmu__find("cpu");
> + if ((pmu == NULL) || list_empty(&pmu->aliases)) {
> + perf_pmu_events_list_num = -1;
> + return;
> + }
> + list_for_each_entry(alias, &pmu->aliases, list) {
> + if (strchr(alias->name, '-'))
> + len++;
> + len++;
> + }
> + perf_pmu_events_list = malloc(sizeof(struct perf_pmu_event_symbol) * len);
> + perf_pmu_events_list_num = len;
missing allocation failure check
jirka
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH V7 3/4] perf tools: Add support to new style format of kernel PMU event
2014-10-03 16:09 [PATCH V7 0/4] perf tools: pmu event new style format fix kan.liang
2014-10-03 16:09 ` [PATCH V7 1/4] Revert "perf tools: Default to cpu// for events v5" kan.liang
2014-10-03 16:09 ` [PATCH V7 2/4] perf tools: parse the pmu event prefix and suffix kan.liang
@ 2014-10-03 16:09 ` kan.liang
2014-10-03 16:09 ` [PATCH V7 4/4] perf tools: Add test case for pmu event new style format kan.liang
2014-10-05 19:08 ` [PATCH V7 0/4] perf tools: pmu event new style format fix Jiri Olsa
4 siblings, 0 replies; 8+ messages in thread
From: kan.liang @ 2014-10-03 16:09 UTC (permalink / raw)
To: jolsa; +Cc: linux-kernel, ak, acme, Kan Liang
From: Kan Liang <kan.liang@intel.com>
Add new rules for kernel PMU event.
Currently, the patch only want to handle the PMU event name as "a-b" and
"a".
event_pmu:
PE_KERNEL_PMU_EVENT sep_dc
|
PE_PMU_EVENT_PRE '-' PE_PMU_EVENT_SUF sep_dc
PE_KERNEL_PMU_EVENT token is for
cycles-ct/cycles-t/mem-loads/mem-stores.
The prefix cycles is mixed up with cpu-cycles.
loads and stores are mixed up with cache event
So they have to be hardcode in lex.
PE_PMU_EVENT_PRE and PE_PMU_EVENT_SUF tokens are for other PMU
events.
The lex looks generic identifier up in the table and return the matched
token. If there is no match, generic PE_NAME token will be return.
Using the rules, kernel PMU event could use new style format without //
so you can use
perf record -e mem-loads ...
instead of
perf record -e cpu/mem-loads/
Signed-off-by: Kan Liang <kan.liang@intel.com>
---
tools/perf/util/parse-events.l | 30 +++++++++++++++++++++++++++++-
tools/perf/util/parse-events.y | 40 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 69 insertions(+), 1 deletion(-)
diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l
index 3432995..906630b 100644
--- a/tools/perf/util/parse-events.l
+++ b/tools/perf/util/parse-events.l
@@ -51,6 +51,24 @@ static int str(yyscan_t scanner, int token)
return token;
}
+static int pmu_str_check(yyscan_t scanner)
+{
+ YYSTYPE *yylval = parse_events_get_lval(scanner);
+ char *text = parse_events_get_text(scanner);
+
+ yylval->str = strdup(text);
+ switch (perf_pmu__parse_check(text)) {
+ case PMU_EVENT_SYMBOL_PREFIX:
+ return PE_PMU_EVENT_PRE;
+ case PMU_EVENT_SYMBOL_SUFFIX:
+ return PE_PMU_EVENT_SUF;
+ case PMU_EVENT_SYMBOL:
+ return PE_KERNEL_PMU_EVENT;
+ default:
+ return PE_NAME;
+ }
+}
+
static int sym(yyscan_t scanner, int type, int config)
{
YYSTYPE *yylval = parse_events_get_lval(scanner);
@@ -178,6 +196,16 @@ alignment-faults { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_AL
emulation-faults { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_EMULATION_FAULTS); }
dummy { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_DUMMY); }
+ /*
+ * We have to handle the kernel PMU event cycles-ct/cycles-t/mem-loads/mem-stores separately.
+ * Because the prefix cycles is mixed up with cpu-cycles.
+ * loads and stores are mixed up with cache event
+ */
+cycles-ct { return str(yyscanner, PE_KERNEL_PMU_EVENT); }
+cycles-t { return str(yyscanner, PE_KERNEL_PMU_EVENT); }
+mem-loads { return str(yyscanner, PE_KERNEL_PMU_EVENT); }
+mem-stores { return str(yyscanner, PE_KERNEL_PMU_EVENT); }
+
L1-dcache|l1-d|l1d|L1-data |
L1-icache|l1-i|l1i|L1-instruction |
LLC|L2 |
@@ -199,7 +227,7 @@ r{num_raw_hex} { return raw(yyscanner); }
{num_hex} { return value(yyscanner, 16); }
{modifier_event} { return str(yyscanner, PE_MODIFIER_EVENT); }
-{name} { return str(yyscanner, PE_NAME); }
+{name} { return pmu_str_check(yyscanner); }
"/" { BEGIN(config); return '/'; }
- { return '-'; }
, { BEGIN(event); return ','; }
diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y
index 55fab6a..93c4c9f 100644
--- a/tools/perf/util/parse-events.y
+++ b/tools/perf/util/parse-events.y
@@ -47,6 +47,7 @@ static inc_group_count(struct list_head *list,
%token PE_NAME_CACHE_TYPE PE_NAME_CACHE_OP_RESULT
%token PE_PREFIX_MEM PE_PREFIX_RAW PE_PREFIX_GROUP
%token PE_ERROR
+%token PE_PMU_EVENT_PRE PE_PMU_EVENT_SUF PE_KERNEL_PMU_EVENT
%type <num> PE_VALUE
%type <num> PE_VALUE_SYM_HW
%type <num> PE_VALUE_SYM_SW
@@ -58,6 +59,7 @@ static inc_group_count(struct list_head *list,
%type <str> PE_MODIFIER_EVENT
%type <str> PE_MODIFIER_BP
%type <str> PE_EVENT_NAME
+%type <str> PE_PMU_EVENT_PRE PE_PMU_EVENT_SUF PE_KERNEL_PMU_EVENT
%type <num> value_sym
%type <head> event_config
%type <term> event_term
@@ -220,6 +222,44 @@ PE_NAME '/' '/'
ABORT_ON(parse_events_add_pmu(list, &data->idx, $1, NULL));
$$ = list;
}
+|
+PE_KERNEL_PMU_EVENT sep_dc
+{
+ struct parse_events_evlist *data = _data;
+ struct list_head *head;
+ struct parse_events_term *term;
+ struct list_head *list;
+
+ ALLOC_LIST(head);
+ ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
+ $1, 1));
+ list_add_tail(&term->list, head);
+
+ ALLOC_LIST(list);
+ ABORT_ON(parse_events_add_pmu(list, &data->idx, "cpu", head));
+ parse_events__free_terms(head);
+ $$ = list;
+}
+|
+PE_PMU_EVENT_PRE '-' PE_PMU_EVENT_SUF sep_dc
+{
+ struct parse_events_evlist *data = _data;
+ struct list_head *head;
+ struct parse_events_term *term;
+ struct list_head *list;
+ char pmu_name[128];
+ snprintf(&pmu_name, 128, "%s-%s", $1, $3);
+
+ ALLOC_LIST(head);
+ ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
+ &pmu_name, 1));
+ list_add_tail(&term->list, head);
+
+ ALLOC_LIST(list);
+ ABORT_ON(parse_events_add_pmu(list, &data->idx, "cpu", head));
+ parse_events__free_terms(head);
+ $$ = list;
+}
value_sym:
PE_VALUE_SYM_HW
--
1.8.3.2
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH V7 4/4] perf tools: Add test case for pmu event new style format
2014-10-03 16:09 [PATCH V7 0/4] perf tools: pmu event new style format fix kan.liang
` (2 preceding siblings ...)
2014-10-03 16:09 ` [PATCH V7 3/4] perf tools: Add support to new style format of kernel PMU event kan.liang
@ 2014-10-03 16:09 ` kan.liang
2014-10-05 19:08 ` [PATCH V7 0/4] perf tools: pmu event new style format fix Jiri Olsa
4 siblings, 0 replies; 8+ messages in thread
From: kan.liang @ 2014-10-03 16:09 UTC (permalink / raw)
To: jolsa; +Cc: linux-kernel, ak, acme, Kan Liang
From: Kan Liang <kan.liang@intel.com>
Add test case in automated tests suite. It checks not only the two types
of pmu event stytle formats "pmu_event_name" and "cpu/pmu_event_name/",
but also the different formats mixtures which are more likely to trigger
parse issue.
Signed-off-by: Kan Liang <kan.liang@intel.com>
---
tools/perf/tests/parse-events.c | 36 ++++++++++++++++++++++++++++++++++++
1 file changed, 36 insertions(+)
diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c
index 5941927..7f2f51f 100644
--- a/tools/perf/tests/parse-events.c
+++ b/tools/perf/tests/parse-events.c
@@ -457,6 +457,36 @@ static int test__checkevent_pmu_events(struct perf_evlist *evlist)
return 0;
}
+
+static int test__checkevent_pmu_events_mix(struct perf_evlist *evlist)
+{
+ struct perf_evsel *evsel = perf_evlist__first(evlist);
+
+ /* pmu-event:u */
+ TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->nr_entries);
+ 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);
+ TEST_ASSERT_VAL("wrong pinned", !evsel->attr.pinned);
+
+ /* cpu/pmu-event/u*/
+ evsel = perf_evsel__next(evsel);
+ TEST_ASSERT_VAL("wrong number of entries", 2 == 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);
+ TEST_ASSERT_VAL("wrong pinned", !evsel->attr.pinned);
+
+ return 0;
+}
+
static int test__checkterms_simple(struct list_head *terms)
{
struct parse_events_term *term;
@@ -1554,6 +1584,12 @@ static int test_pmu_events(void)
e.check = test__checkevent_pmu_events;
ret = test_event(&e);
+ if (ret)
+ break;
+ snprintf(name, MAX_NAME, "%s:u,cpu/event=%s/u", ent->d_name, ent->d_name);
+ e.name = name;
+ e.check = test__checkevent_pmu_events_mix;
+ ret = test_event(&e);
#undef MAX_NAME
}
--
1.8.3.2
^ permalink raw reply related [flat|nested] 8+ messages in thread* Re: [PATCH V7 0/4] perf tools: pmu event new style format fix
2014-10-03 16:09 [PATCH V7 0/4] perf tools: pmu event new style format fix kan.liang
` (3 preceding siblings ...)
2014-10-03 16:09 ` [PATCH V7 4/4] perf tools: Add test case for pmu event new style format kan.liang
@ 2014-10-05 19:08 ` Jiri Olsa
2014-10-06 2:42 ` Liang, Kan
4 siblings, 1 reply; 8+ messages in thread
From: Jiri Olsa @ 2014-10-05 19:08 UTC (permalink / raw)
To: kan.liang; +Cc: linux-kernel, ak, acme
On Fri, Oct 03, 2014 at 12:09:04PM -0400, kan.liang@intel.com wrote:
> From: Kan Liang <kan.liang@intel.com>
>
> There are two types of pmu event stytle formats, "pmu_event_name"
> or "cpu/pmu_event_name/". However, there is a bug on supporting these
> two formats, especially when they mixed with other perf events.
> The patch set intends to fix this issue.
>
> The patch set has been tested on my haswell.
> Here is the test script I used for this issue.
> (Note: please make sure that your test system support TSX and
> L1-dcache-loads events. Otherwise, you may want to change the events
> to other pmu events.)
>
> [lk@localhost ~]$ cat perf_style_test.sh
> #hardware events + kernel pmu event with different style
> perf stat -x, -e cycles,mem-stores,tx-start sleep 2
> perf stat -x, -e cpu-cycles,cycles-ct,cycles-t sleep 2
> perf stat -x, -e cycles,cpu/cycles-ct/,cpu/cycles-t/ sleep 2
> perf stat -x, -e instructions,cpu/tx-start/ sleep 2
> perf stat -x, -e '{cycles,tx-start}' sleep 2
> perf stat -x, -e '{cycles,cpu/tx-start/}' sleep 2
>
> #HW Cache event + kernel pmu event with different style
> perf stat -x, -e L1-dcache-loads,cpu/mem-stores/,tx-start sleep 2
> perf stat -x, -e L1-dcache-loads,mem-stores,cpu/tx-start/ sleep 2
> perf stat -x, -e '{L1-dcache-loads,mem-stores}' sleep 2
> perf stat -x, -e '{L1-dcache-loads,cpu/tx-start/}' sleep 2
>
> #Raw event + kernel pmu event with different style:
> perf stat -x, -e cpu/event=0xc0,umask=0x00/,mem-loads,cpu/mem-stores/ sleep 2
> perf stat -x, -e cpu/event=0xc0,umask=0x00/,tx-start,cpu/el-start/ sleep 2
> perf stat -x, -e '{cpu/event=0xc0,umask=0x00/,tx-start}' sleep 2
>
> Changes since V1:
> Read kernel PMU events from sysfs at runtime
>
> Changes since V2:
> Use strlcpy to replace strncpy
>
> Changes since V3:
> rebase to git.kernel.org/pub/scm/linux/kernel/git/acme/linux perf/core
>
> Changes since V4:
> scan kernel pmu events from sysfs only needed
> rename the init/check/clenup functions and related struct.
> allocate each symbol string separatelly
> Use ALLOC_LIST
>
> Changes since V5:
> Using perf_pmu__find to instead of perf_pmu__scan
> Don't scan all the time if the system doesn't support kernel pmu events
>
> Changes since V6:
> Add test case in automated tests suite
> Use strdup and macro to refine the code
> Add sep_dc for PMU event to support PE_MODIFIER_EVENT
> Some minor changes for code style
>
> Kan Liang (4):
> Revert "perf tools: Default to cpu// for events v5"
> perf tools: parse the pmu event prefix and suffix
> perf tools: Add support to new style format of kernel PMU event
> perf tools: Add test case for pmu event new style format
got test failure with your patchset:
[jolsa@krava perf]$ sudo ./perf test parse -v
5: parse events tests :
--- start ---
test child forked, pid 9972
running test 0 'syscalls:sys_enter_open'
registering plugin: /root/.traceevent/plugins/plugin_kvm.so
registering plugin: /root/.traceevent/plugins/plugin_scsi.so
registering plugin: /root/.traceevent/plugins/plugin_mac80211.so
registering plugin: /root/.traceevent/plugins/plugin_hrtimer.so
SNIP
running test 6 'faults'
running test 7 'L1-dcache-load-miss'
running test 8 'mem:0'
running test 9 'mem:0:x'
running test 10 'mem:0:r'
running test 11 'mem:0:w'
running test 12 'syscalls:sys_enter_open:k'
running test 13 'syscalls:*:u'
test child interrupted
---- end ----
parse events tests: FAILED!
jirka
^ permalink raw reply [flat|nested] 8+ messages in thread* RE: [PATCH V7 0/4] perf tools: pmu event new style format fix
2014-10-05 19:08 ` [PATCH V7 0/4] perf tools: pmu event new style format fix Jiri Olsa
@ 2014-10-06 2:42 ` Liang, Kan
0 siblings, 0 replies; 8+ messages in thread
From: Liang, Kan @ 2014-10-06 2:42 UTC (permalink / raw)
To: Jiri Olsa
Cc: linux-kernel@vger.kernel.org, ak@linux.intel.com, acme@kernel.org
> > Kan Liang (4):
> > Revert "perf tools: Default to cpu// for events v5"
> > perf tools: parse the pmu event prefix and suffix
> > perf tools: Add support to new style format of kernel PMU event
> > perf tools: Add test case for pmu event new style format
>
> got test failure with your patchset:
>
The test passed on my machine.
It looks your test failed with test 13/14. But my patch should not impact these two cases. Could you please double check?
(I also manually test 13 and 14, they all passed on my machine.)
[root@localhost perf]# ./perf test parse -v
5: parse events tests :
--- start ---
test child forked, pid 6966
running test 0 'syscalls:sys_enter_open'
running test 1 'syscalls:*'
running test 2 'r1a'
running test 3 '1:1'
running test 4 'instructions'
running test 5 'cycles/period=100000,config2/'
running test 6 'faults'
running test 7 'L1-dcache-load-miss'
running test 8 'mem:0'
running test 9 'mem:0:x'
running test 10 'mem:0:r'
running test 11 'mem:0:w'
running test 12 'syscalls:sys_enter_open:k'
running test 13 'syscalls:*:u'
running test 14 'r1a:kp'
SNIP
running test 39 '{instructions,branch-misses}:Su'
running test 40 'instructions:uDp'
running test 41 '{cycles,cache-misses,branch-misses}:D'
running test 0 'cpu/config=10,config1,config2=3,period=1000/u'
running test 1 'cpu/config=1,name=krava/u,cpu/config=2/u'
running test 0 'config=10,config1,config2=3,umask=1'
test child finished with 0
---- end ----
parse events tests: Ok
Kan
> [jolsa@krava perf]$ sudo ./perf test parse -v
> 5: parse events tests :
> --- start ---
> test child forked, pid 9972
> running test 0 'syscalls:sys_enter_open'
> registering plugin: /root/.traceevent/plugins/plugin_kvm.so
> registering plugin: /root/.traceevent/plugins/plugin_scsi.so
> registering plugin: /root/.traceevent/plugins/plugin_mac80211.so
> registering plugin: /root/.traceevent/plugins/plugin_hrtimer.so
>
> SNIP
>
> running test 6 'faults'
> running test 7 'L1-dcache-load-miss'
> running test 8 'mem:0'
> running test 9 'mem:0:x'
> running test 10 'mem:0:r'
> running test 11 'mem:0:w'
> running test 12 'syscalls:sys_enter_open:k'
> running test 13 'syscalls:*:u'
> test child interrupted
> ---- end ----
> parse events tests: FAILED!
>
>
> jirka
^ permalink raw reply [flat|nested] 8+ messages in thread