diff options
author | Kan Liang <kan.liang@intel.com> | 2014-10-07 11:08:51 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2014-10-15 15:05:45 -0400 |
commit | ba32a4511c65e41958384d2f7a046a6ec6e151e5 (patch) | |
tree | d3fb7e8d38f0aaba0cbd611215d1826f81800a4f /tools | |
parent | dcb4e1022b40d886027500821a592dd8f8ccde8f (diff) |
perf tools: Add support to new style format of kernel PMU event
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>
Acked-by: Jiri Olsa <jolsa@redhat.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Link: http://lkml.kernel.org/r/1412694532-23391-4-git-send-email-kan.liang@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/perf/util/parse-events.l | 30 | ||||
-rw-r--r-- | tools/perf/util/parse-events.y | 40 |
2 files changed, 69 insertions, 1 deletions
diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l index 343299575b30..906630bbf8eb 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) | |||
51 | return token; | 51 | return token; |
52 | } | 52 | } |
53 | 53 | ||
54 | static int pmu_str_check(yyscan_t scanner) | ||
55 | { | ||
56 | YYSTYPE *yylval = parse_events_get_lval(scanner); | ||
57 | char *text = parse_events_get_text(scanner); | ||
58 | |||
59 | yylval->str = strdup(text); | ||
60 | switch (perf_pmu__parse_check(text)) { | ||
61 | case PMU_EVENT_SYMBOL_PREFIX: | ||
62 | return PE_PMU_EVENT_PRE; | ||
63 | case PMU_EVENT_SYMBOL_SUFFIX: | ||
64 | return PE_PMU_EVENT_SUF; | ||
65 | case PMU_EVENT_SYMBOL: | ||
66 | return PE_KERNEL_PMU_EVENT; | ||
67 | default: | ||
68 | return PE_NAME; | ||
69 | } | ||
70 | } | ||
71 | |||
54 | static int sym(yyscan_t scanner, int type, int config) | 72 | static int sym(yyscan_t scanner, int type, int config) |
55 | { | 73 | { |
56 | YYSTYPE *yylval = parse_events_get_lval(scanner); | 74 | YYSTYPE *yylval = parse_events_get_lval(scanner); |
@@ -178,6 +196,16 @@ alignment-faults { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_AL | |||
178 | emulation-faults { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_EMULATION_FAULTS); } | 196 | emulation-faults { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_EMULATION_FAULTS); } |
179 | dummy { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_DUMMY); } | 197 | dummy { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_DUMMY); } |
180 | 198 | ||
199 | /* | ||
200 | * We have to handle the kernel PMU event cycles-ct/cycles-t/mem-loads/mem-stores separately. | ||
201 | * Because the prefix cycles is mixed up with cpu-cycles. | ||
202 | * loads and stores are mixed up with cache event | ||
203 | */ | ||
204 | cycles-ct { return str(yyscanner, PE_KERNEL_PMU_EVENT); } | ||
205 | cycles-t { return str(yyscanner, PE_KERNEL_PMU_EVENT); } | ||
206 | mem-loads { return str(yyscanner, PE_KERNEL_PMU_EVENT); } | ||
207 | mem-stores { return str(yyscanner, PE_KERNEL_PMU_EVENT); } | ||
208 | |||
181 | L1-dcache|l1-d|l1d|L1-data | | 209 | L1-dcache|l1-d|l1d|L1-data | |
182 | L1-icache|l1-i|l1i|L1-instruction | | 210 | L1-icache|l1-i|l1i|L1-instruction | |
183 | LLC|L2 | | 211 | LLC|L2 | |
@@ -199,7 +227,7 @@ r{num_raw_hex} { return raw(yyscanner); } | |||
199 | {num_hex} { return value(yyscanner, 16); } | 227 | {num_hex} { return value(yyscanner, 16); } |
200 | 228 | ||
201 | {modifier_event} { return str(yyscanner, PE_MODIFIER_EVENT); } | 229 | {modifier_event} { return str(yyscanner, PE_MODIFIER_EVENT); } |
202 | {name} { return str(yyscanner, PE_NAME); } | 230 | {name} { return pmu_str_check(yyscanner); } |
203 | "/" { BEGIN(config); return '/'; } | 231 | "/" { BEGIN(config); return '/'; } |
204 | - { return '-'; } | 232 | - { return '-'; } |
205 | , { BEGIN(event); return ','; } | 233 | , { BEGIN(event); return ','; } |
diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y index 55fab6ad609a..93c4c9fbc922 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, | |||
47 | %token PE_NAME_CACHE_TYPE PE_NAME_CACHE_OP_RESULT | 47 | %token PE_NAME_CACHE_TYPE PE_NAME_CACHE_OP_RESULT |
48 | %token PE_PREFIX_MEM PE_PREFIX_RAW PE_PREFIX_GROUP | 48 | %token PE_PREFIX_MEM PE_PREFIX_RAW PE_PREFIX_GROUP |
49 | %token PE_ERROR | 49 | %token PE_ERROR |
50 | %token PE_PMU_EVENT_PRE PE_PMU_EVENT_SUF PE_KERNEL_PMU_EVENT | ||
50 | %type <num> PE_VALUE | 51 | %type <num> PE_VALUE |
51 | %type <num> PE_VALUE_SYM_HW | 52 | %type <num> PE_VALUE_SYM_HW |
52 | %type <num> PE_VALUE_SYM_SW | 53 | %type <num> PE_VALUE_SYM_SW |
@@ -58,6 +59,7 @@ static inc_group_count(struct list_head *list, | |||
58 | %type <str> PE_MODIFIER_EVENT | 59 | %type <str> PE_MODIFIER_EVENT |
59 | %type <str> PE_MODIFIER_BP | 60 | %type <str> PE_MODIFIER_BP |
60 | %type <str> PE_EVENT_NAME | 61 | %type <str> PE_EVENT_NAME |
62 | %type <str> PE_PMU_EVENT_PRE PE_PMU_EVENT_SUF PE_KERNEL_PMU_EVENT | ||
61 | %type <num> value_sym | 63 | %type <num> value_sym |
62 | %type <head> event_config | 64 | %type <head> event_config |
63 | %type <term> event_term | 65 | %type <term> event_term |
@@ -220,6 +222,44 @@ PE_NAME '/' '/' | |||
220 | ABORT_ON(parse_events_add_pmu(list, &data->idx, $1, NULL)); | 222 | ABORT_ON(parse_events_add_pmu(list, &data->idx, $1, NULL)); |
221 | $$ = list; | 223 | $$ = list; |
222 | } | 224 | } |
225 | | | ||
226 | PE_KERNEL_PMU_EVENT sep_dc | ||
227 | { | ||
228 | struct parse_events_evlist *data = _data; | ||
229 | struct list_head *head; | ||
230 | struct parse_events_term *term; | ||
231 | struct list_head *list; | ||
232 | |||
233 | ALLOC_LIST(head); | ||
234 | ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER, | ||
235 | $1, 1)); | ||
236 | list_add_tail(&term->list, head); | ||
237 | |||
238 | ALLOC_LIST(list); | ||
239 | ABORT_ON(parse_events_add_pmu(list, &data->idx, "cpu", head)); | ||
240 | parse_events__free_terms(head); | ||
241 | $$ = list; | ||
242 | } | ||
243 | | | ||
244 | PE_PMU_EVENT_PRE '-' PE_PMU_EVENT_SUF sep_dc | ||
245 | { | ||
246 | struct parse_events_evlist *data = _data; | ||
247 | struct list_head *head; | ||
248 | struct parse_events_term *term; | ||
249 | struct list_head *list; | ||
250 | char pmu_name[128]; | ||
251 | snprintf(&pmu_name, 128, "%s-%s", $1, $3); | ||
252 | |||
253 | ALLOC_LIST(head); | ||
254 | ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER, | ||
255 | &pmu_name, 1)); | ||
256 | list_add_tail(&term->list, head); | ||
257 | |||
258 | ALLOC_LIST(list); | ||
259 | ABORT_ON(parse_events_add_pmu(list, &data->idx, "cpu", head)); | ||
260 | parse_events__free_terms(head); | ||
261 | $$ = list; | ||
262 | } | ||
223 | 263 | ||
224 | value_sym: | 264 | value_sym: |
225 | PE_VALUE_SYM_HW | 265 | PE_VALUE_SYM_HW |