Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Kan Liang and committed by
Arnaldo Carvalho de Melo
ba32a451 dcb4e102

+69 -1
+29 -1
tools/perf/util/parse-events.l
··· 51 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 72 static int sym(yyscan_t scanner, int type, int config) 55 73 { 56 74 YYSTYPE *yylval = parse_events_get_lval(scanner); ··· 196 178 emulation-faults { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_EMULATION_FAULTS); } 197 179 dummy { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_DUMMY); } 198 180 181 + /* 182 + * We have to handle the kernel PMU event cycles-ct/cycles-t/mem-loads/mem-stores separately. 183 + * Because the prefix cycles is mixed up with cpu-cycles. 184 + * loads and stores are mixed up with cache event 185 + */ 186 + cycles-ct { return str(yyscanner, PE_KERNEL_PMU_EVENT); } 187 + cycles-t { return str(yyscanner, PE_KERNEL_PMU_EVENT); } 188 + mem-loads { return str(yyscanner, PE_KERNEL_PMU_EVENT); } 189 + mem-stores { return str(yyscanner, PE_KERNEL_PMU_EVENT); } 190 + 199 191 L1-dcache|l1-d|l1d|L1-data | 200 192 L1-icache|l1-i|l1i|L1-instruction | 201 193 LLC|L2 | ··· 227 199 {num_hex} { return value(yyscanner, 16); } 228 200 229 201 {modifier_event} { return str(yyscanner, PE_MODIFIER_EVENT); } 230 - {name} { return str(yyscanner, PE_NAME); } 202 + {name} { return pmu_str_check(yyscanner); } 231 203 "/" { BEGIN(config); return '/'; } 232 204 - { return '-'; } 233 205 , { BEGIN(event); return ','; }
+40
tools/perf/util/parse-events.y
··· 47 47 %token PE_NAME_CACHE_TYPE PE_NAME_CACHE_OP_RESULT 48 48 %token PE_PREFIX_MEM PE_PREFIX_RAW PE_PREFIX_GROUP 49 49 %token PE_ERROR 50 + %token PE_PMU_EVENT_PRE PE_PMU_EVENT_SUF PE_KERNEL_PMU_EVENT 50 51 %type <num> PE_VALUE 51 52 %type <num> PE_VALUE_SYM_HW 52 53 %type <num> PE_VALUE_SYM_SW ··· 59 58 %type <str> PE_MODIFIER_EVENT 60 59 %type <str> PE_MODIFIER_BP 61 60 %type <str> PE_EVENT_NAME 61 + %type <str> PE_PMU_EVENT_PRE PE_PMU_EVENT_SUF PE_KERNEL_PMU_EVENT 62 62 %type <num> value_sym 63 63 %type <head> event_config 64 64 %type <term> event_term ··· 220 218 221 219 ALLOC_LIST(list); 222 220 ABORT_ON(parse_events_add_pmu(list, &data->idx, $1, NULL)); 221 + $$ = list; 222 + } 223 + | 224 + PE_KERNEL_PMU_EVENT sep_dc 225 + { 226 + struct parse_events_evlist *data = _data; 227 + struct list_head *head; 228 + struct parse_events_term *term; 229 + struct list_head *list; 230 + 231 + ALLOC_LIST(head); 232 + ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER, 233 + $1, 1)); 234 + list_add_tail(&term->list, head); 235 + 236 + ALLOC_LIST(list); 237 + ABORT_ON(parse_events_add_pmu(list, &data->idx, "cpu", head)); 238 + parse_events__free_terms(head); 239 + $$ = list; 240 + } 241 + | 242 + PE_PMU_EVENT_PRE '-' PE_PMU_EVENT_SUF sep_dc 243 + { 244 + struct parse_events_evlist *data = _data; 245 + struct list_head *head; 246 + struct parse_events_term *term; 247 + struct list_head *list; 248 + char pmu_name[128]; 249 + snprintf(&pmu_name, 128, "%s-%s", $1, $3); 250 + 251 + ALLOC_LIST(head); 252 + ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER, 253 + &pmu_name, 1)); 254 + list_add_tail(&term->list, head); 255 + 256 + ALLOC_LIST(list); 257 + ABORT_ON(parse_events_add_pmu(list, &data->idx, "cpu", head)); 258 + parse_events__free_terms(head); 223 259 $$ = list; 224 260 } 225 261