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

perf parse-events: Remove hard coded legacy hardware and cache parsing

Now that legacy hardware and cache events are in json, having the
lexer match the specific event is no longer necessary and generic PMU
parsing can take place. Because of this remove the specific term
parsing, event adding, and passing of alternate_hw_config which was
now always PERF_COUNT_HW_MAX.

This mirrors a similar change for software events in commit 6e9fa4131abb
("perf parse-events: Remove non-json software events").

With no hard coded legacy hardware or cache events the wild card, case
insensitivity, etc. is consistent for events. This does, however, mean
events like cycles will wild card against all PMUs. A change does the
same was originally posted and merged from:
https://lore.kernel.org/r/20240416061533.921723-10-irogers@google.com
and reverted by Linus in commit 4f1b067359ac ("Revert "perf
parse-events: Prefer sysfs/JSON hardware events over legacy"") due to
his dislike for the cycles behavior on ARM. Earlier patches in this
series make perf record event opening failures non-fatal and hide the
cycles event's failure to open on ARM in perf record, so it is
expected the behavior will now be transparent in perf record. perf
stat with a cycles event will wildcard open the event on all PMUs. As
cycles is a "default event", the perf stat behavior for default events
was updated to only open them on core/software PMUs.

The change to support legacy events with PMUs was done to clean up
Intel's hybrid PMU implementation. Having sysfs/json events with
increased priority to legacy was requested by Mark Rutland
<mark.rutland@arm.com> to fix Apple-M PMU issues wrt broken legacy
events on that PMU. It was requested that RISC-V be able to add events
to the perf tool json so the PMU driver didn't need to map legacy
events to config encodings:
https://lore.kernel.org/lkml/20240217005738.3744121-1-atishp@rivosinc.com/

A previous series of patches decreasing legacy hardware event
priorities was posted in:
https://lore.kernel.org/lkml/20250416045117.876775-1-irogers@google.com/
Namhyung Kim <namhyung@kernel.org> mentioned that hardware and
software events can be implemented similarly:
https://lore.kernel.org/lkml/aIJmJns2lopxf3EK@google.com/

Tested-by: Thomas Richter <tmricht@linux.ibm.com>
Signed-off-by: Ian Rogers <irogers@google.com>
Tested-by: James Clark <james.clark@linaro.org>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>

authored by

Ian Rogers and committed by
Namhyung Kim
b1c5efbf 50062baa

+17 -362
+10 -180
tools/perf/util/parse-events.c
··· 429 429 static int parse_events_add_pmu(struct parse_events_state *parse_state, 430 430 struct list_head *list, struct perf_pmu *pmu, 431 431 const struct parse_events_terms *const_parsed_terms, 432 - struct evsel *first_wildcard_match, u64 alternate_hw_config); 433 - 434 - int parse_events_add_cache(struct list_head *list, int *idx, const char *name, 435 - struct parse_events_state *parse_state, 436 - struct parse_events_terms *parsed_terms, 437 - void *loc_) 438 - { 439 - YYLTYPE *loc = loc_; 440 - struct perf_pmu *pmu = NULL; 441 - bool found_supported = false; 442 - const char *config_name = get_config_name(parsed_terms); 443 - const char *metric_id = get_config_metric_id(parsed_terms); 444 - struct perf_cpu_map *cpus = get_config_cpu(parsed_terms, parse_state->fake_pmu); 445 - int ret = 0; 446 - struct evsel *first_wildcard_match = NULL; 447 - 448 - while ((pmu = perf_pmus__scan_for_event(pmu, name)) != NULL) { 449 - LIST_HEAD(config_terms); 450 - struct perf_event_attr attr; 451 - 452 - if (parse_events__filter_pmu(parse_state, pmu)) 453 - continue; 454 - 455 - if (perf_pmu__have_event(pmu, name)) { 456 - /* 457 - * The PMU has the event so add as not a legacy cache 458 - * event. 459 - */ 460 - struct parse_events_terms temp_terms; 461 - struct parse_events_term *term; 462 - char *config = strdup(name); 463 - 464 - if (!config) 465 - goto out_err; 466 - 467 - parse_events_terms__init(&temp_terms); 468 - if (!parsed_terms) 469 - parsed_terms = &temp_terms; 470 - 471 - if (parse_events_term__num(&term, 472 - PARSE_EVENTS__TERM_TYPE_USER, 473 - config, /*num=*/1, /*novalue=*/true, 474 - loc, /*loc_val=*/NULL) < 0) { 475 - zfree(&config); 476 - goto out_err; 477 - } 478 - list_add(&term->list, &parsed_terms->terms); 479 - 480 - ret = parse_events_add_pmu(parse_state, list, pmu, 481 - parsed_terms, 482 - first_wildcard_match, 483 - /*alternate_hw_config=*/PERF_COUNT_HW_MAX); 484 - list_del_init(&term->list); 485 - parse_events_term__delete(term); 486 - parse_events_terms__exit(&temp_terms); 487 - if (ret) 488 - goto out_err; 489 - found_supported = true; 490 - if (first_wildcard_match == NULL) 491 - first_wildcard_match = 492 - container_of(list->prev, struct evsel, core.node); 493 - continue; 494 - } 495 - 496 - if (!pmu->is_core) { 497 - /* Legacy cache events are only supported by core PMUs. */ 498 - continue; 499 - } 500 - 501 - memset(&attr, 0, sizeof(attr)); 502 - attr.type = PERF_TYPE_HW_CACHE; 503 - 504 - ret = parse_events__decode_legacy_cache(name, pmu->type, &attr.config); 505 - if (ret) 506 - return ret; 507 - 508 - found_supported = true; 509 - 510 - if (parsed_terms) { 511 - if (config_attr(&attr, parsed_terms, parse_state, config_term_common)) { 512 - ret = -EINVAL; 513 - goto out_err; 514 - } 515 - if (get_config_terms(parsed_terms, &config_terms)) { 516 - ret = -ENOMEM; 517 - goto out_err; 518 - } 519 - } 520 - 521 - if (__add_event(list, idx, &attr, /*init_attr*/true, config_name ?: name, 522 - metric_id, pmu, &config_terms, first_wildcard_match, 523 - cpus, /*alternate_hw_config=*/PERF_COUNT_HW_MAX) == NULL) 524 - ret = -ENOMEM; 525 - 526 - if (first_wildcard_match == NULL) 527 - first_wildcard_match = container_of(list->prev, struct evsel, core.node); 528 - free_config_terms(&config_terms); 529 - if (ret) 530 - goto out_err; 531 - } 532 - out_err: 533 - perf_cpu_map__put(cpus); 534 - return found_supported ? 0 : -EINVAL; 535 - } 432 + struct evsel *first_wildcard_match); 536 433 537 434 static void tracepoint_error(struct parse_events_error *e, int err, 538 435 const char *sys, const char *name, int column) ··· 720 823 [PARSE_EVENTS__TERM_TYPE_AUX_SAMPLE_SIZE] = "aux-sample-size", 721 824 [PARSE_EVENTS__TERM_TYPE_METRIC_ID] = "metric-id", 722 825 [PARSE_EVENTS__TERM_TYPE_RAW] = "raw", 723 - [PARSE_EVENTS__TERM_TYPE_LEGACY_CACHE] = "legacy-cache", 724 - [PARSE_EVENTS__TERM_TYPE_HARDWARE] = "hardware", 725 826 [PARSE_EVENTS__TERM_TYPE_LEGACY_HARDWARE_CONFIG] = "legacy-hardware-config", 726 827 [PARSE_EVENTS__TERM_TYPE_LEGACY_CACHE_CONFIG] = "legacy-cache-config", 727 828 [PARSE_EVENTS__TERM_TYPE_CPU] = "cpu", ··· 772 877 case PARSE_EVENTS__TERM_TYPE_AUX_ACTION: 773 878 case PARSE_EVENTS__TERM_TYPE_AUX_SAMPLE_SIZE: 774 879 case PARSE_EVENTS__TERM_TYPE_RAW: 775 - case PARSE_EVENTS__TERM_TYPE_LEGACY_CACHE: 776 - case PARSE_EVENTS__TERM_TYPE_HARDWARE: 777 880 case PARSE_EVENTS__TERM_TYPE_RATIO_TO_PREV: 778 881 case PARSE_EVENTS__TERM_TYPE_LEGACY_HARDWARE_CONFIG: 779 882 case PARSE_EVENTS__TERM_TYPE_LEGACY_CACHE_CONFIG: ··· 945 1052 break; 946 1053 case PARSE_EVENTS__TERM_TYPE_DRV_CFG: 947 1054 case PARSE_EVENTS__TERM_TYPE_USER: 948 - case PARSE_EVENTS__TERM_TYPE_LEGACY_CACHE: 949 - case PARSE_EVENTS__TERM_TYPE_HARDWARE: 950 1055 case PARSE_EVENTS__TERM_TYPE_LEGACY_HARDWARE_CONFIG: 951 1056 case PARSE_EVENTS__TERM_TYPE_LEGACY_CACHE_CONFIG: 952 1057 default: ··· 1031 1140 attr->type = PERF_TYPE_HW_CACHE; 1032 1141 return 0; 1033 1142 } 1034 - if (term->type_term == PARSE_EVENTS__TERM_TYPE_LEGACY_CACHE) { 1035 - struct perf_pmu *pmu = perf_pmus__find_by_type(attr->type); 1036 - 1037 - if (!pmu) { 1038 - char *err_str; 1039 - 1040 - if (asprintf(&err_str, "Failed to find PMU for type %d", attr->type) >= 0) 1041 - parse_events_error__handle(parse_state->error, term->err_term, 1042 - err_str, /*help=*/NULL); 1043 - return -EINVAL; 1044 - } 1045 - /* 1046 - * Rewrite the PMU event to a legacy cache one unless the PMU 1047 - * doesn't support legacy cache events or the event is present 1048 - * within the PMU. 1049 - */ 1050 - if (perf_pmu__supports_legacy_cache(pmu) && 1051 - !perf_pmu__have_event(pmu, term->config)) { 1052 - attr->type = PERF_TYPE_HW_CACHE; 1053 - return parse_events__decode_legacy_cache(term->config, pmu->type, 1054 - &attr->config); 1055 - } else { 1056 - term->type_term = PARSE_EVENTS__TERM_TYPE_USER; 1057 - term->no_value = true; 1058 - } 1059 - } 1060 - if (term->type_term == PARSE_EVENTS__TERM_TYPE_HARDWARE) { 1061 - struct perf_pmu *pmu = perf_pmus__find_by_type(attr->type); 1062 - 1063 - if (!pmu) { 1064 - char *err_str; 1065 - 1066 - if (asprintf(&err_str, "Failed to find PMU for type %d", attr->type) >= 0) 1067 - parse_events_error__handle(parse_state->error, term->err_term, 1068 - err_str, /*help=*/NULL); 1069 - return -EINVAL; 1070 - } 1071 - /* 1072 - * If the PMU has a sysfs or json event prefer it over 1073 - * legacy. ARM requires this. 1074 - */ 1075 - if (perf_pmu__have_event(pmu, term->config)) { 1076 - term->type_term = PARSE_EVENTS__TERM_TYPE_USER; 1077 - term->no_value = true; 1078 - term->alternate_hw_config = true; 1079 - } else { 1080 - attr->type = PERF_TYPE_HARDWARE; 1081 - attr->config = term->val.num; 1082 - if (perf_pmus__supports_extended_type()) 1083 - attr->config |= (__u64)pmu->type << PERF_PMU_TYPE_SHIFT; 1084 - } 1085 - return 0; 1086 - } 1087 1143 if (term->type_term == PARSE_EVENTS__TERM_TYPE_USER || 1088 1144 term->type_term == PARSE_EVENTS__TERM_TYPE_DRV_CFG) { 1089 1145 /* ··· 1075 1237 case PARSE_EVENTS__TERM_TYPE_PERCORE: 1076 1238 case PARSE_EVENTS__TERM_TYPE_METRIC_ID: 1077 1239 case PARSE_EVENTS__TERM_TYPE_RAW: 1078 - case PARSE_EVENTS__TERM_TYPE_LEGACY_CACHE: 1079 - case PARSE_EVENTS__TERM_TYPE_HARDWARE: 1080 1240 case PARSE_EVENTS__TERM_TYPE_CPU: 1081 1241 case PARSE_EVENTS__TERM_TYPE_RATIO_TO_PREV: 1082 1242 default: ··· 1212 1376 case PARSE_EVENTS__TERM_TYPE_NAME: 1213 1377 case PARSE_EVENTS__TERM_TYPE_METRIC_ID: 1214 1378 case PARSE_EVENTS__TERM_TYPE_RAW: 1215 - case PARSE_EVENTS__TERM_TYPE_LEGACY_CACHE: 1216 - case PARSE_EVENTS__TERM_TYPE_HARDWARE: 1217 1379 case PARSE_EVENTS__TERM_TYPE_CPU: 1218 1380 default: 1219 1381 break; ··· 1267 1433 case PARSE_EVENTS__TERM_TYPE_AUX_SAMPLE_SIZE: 1268 1434 case PARSE_EVENTS__TERM_TYPE_METRIC_ID: 1269 1435 case PARSE_EVENTS__TERM_TYPE_RAW: 1270 - case PARSE_EVENTS__TERM_TYPE_LEGACY_CACHE: 1271 - case PARSE_EVENTS__TERM_TYPE_HARDWARE: 1272 1436 case PARSE_EVENTS__TERM_TYPE_CPU: 1273 1437 case PARSE_EVENTS__TERM_TYPE_RATIO_TO_PREV: 1274 1438 default: ··· 1391 1559 static int parse_events_add_pmu(struct parse_events_state *parse_state, 1392 1560 struct list_head *list, struct perf_pmu *pmu, 1393 1561 const struct parse_events_terms *const_parsed_terms, 1394 - struct evsel *first_wildcard_match, u64 alternate_hw_config) 1562 + struct evsel *first_wildcard_match) 1395 1563 { 1564 + u64 alternate_hw_config = PERF_COUNT_HW_MAX; 1396 1565 struct perf_event_attr attr; 1397 1566 struct perf_pmu_info info; 1398 1567 struct evsel *evsel; ··· 1526 1693 } 1527 1694 1528 1695 int parse_events_multi_pmu_add(struct parse_events_state *parse_state, 1529 - const char *event_name, u64 hw_config, 1696 + const char *event_name, 1530 1697 const struct parse_events_terms *const_parsed_terms, 1531 1698 struct list_head **listp, void *loc_) 1532 1699 { ··· 1578 1745 continue; 1579 1746 1580 1747 if (!parse_events_add_pmu(parse_state, list, pmu, 1581 - &parsed_terms, first_wildcard_match, hw_config)) { 1748 + &parsed_terms, first_wildcard_match)) { 1582 1749 struct strbuf sb; 1583 1750 1584 1751 strbuf_init(&sb, /*hint=*/ 0); ··· 1593 1760 1594 1761 if (parse_state->fake_pmu) { 1595 1762 if (!parse_events_add_pmu(parse_state, list, perf_pmus__fake_pmu(), &parsed_terms, 1596 - first_wildcard_match, hw_config)) { 1763 + first_wildcard_match)) { 1597 1764 struct strbuf sb; 1598 1765 1599 1766 strbuf_init(&sb, /*hint=*/ 0); ··· 1635 1802 /* Attempt to add to list assuming event_or_pmu is a PMU name. */ 1636 1803 pmu = perf_pmus__find(event_or_pmu); 1637 1804 if (pmu && !parse_events_add_pmu(parse_state, *listp, pmu, const_parsed_terms, 1638 - first_wildcard_match, 1639 - /*alternate_hw_config=*/PERF_COUNT_HW_MAX)) 1805 + first_wildcard_match)) 1640 1806 return 0; 1641 1807 1642 1808 if (parse_state->fake_pmu) { 1643 1809 if (!parse_events_add_pmu(parse_state, *listp, perf_pmus__fake_pmu(), 1644 1810 const_parsed_terms, 1645 - first_wildcard_match, 1646 - /*alternate_hw_config=*/PERF_COUNT_HW_MAX)) 1811 + first_wildcard_match)) 1647 1812 return 0; 1648 1813 } 1649 1814 ··· 1654 1823 1655 1824 if (!parse_events_add_pmu(parse_state, *listp, pmu, 1656 1825 const_parsed_terms, 1657 - first_wildcard_match, 1658 - /*alternate_hw_config=*/PERF_COUNT_HW_MAX)) { 1826 + first_wildcard_match)) { 1659 1827 ok++; 1660 1828 parse_state->wild_card_pmus = true; 1661 1829 } ··· 1668 1838 1669 1839 /* Failure to add, assume event_or_pmu is an event name. */ 1670 1840 zfree(listp); 1671 - if (!parse_events_multi_pmu_add(parse_state, event_or_pmu, PERF_COUNT_HW_MAX, 1841 + if (!parse_events_multi_pmu_add(parse_state, event_or_pmu, 1672 1842 const_parsed_terms, listp, loc)) 1673 1843 return 0; 1674 1844
+1 -13
tools/perf/util/parse-events.h
··· 79 79 PARSE_EVENTS__TERM_TYPE_AUX_SAMPLE_SIZE, 80 80 PARSE_EVENTS__TERM_TYPE_METRIC_ID, 81 81 PARSE_EVENTS__TERM_TYPE_RAW, 82 - PARSE_EVENTS__TERM_TYPE_LEGACY_CACHE, 83 - PARSE_EVENTS__TERM_TYPE_HARDWARE, 84 82 PARSE_EVENTS__TERM_TYPE_CPU, 85 83 PARSE_EVENTS__TERM_TYPE_RATIO_TO_PREV, 86 84 PARSE_EVENTS__TERM_TYPE_LEGACY_HARDWARE_CONFIG, ··· 131 133 * value is assumed to be 1. An event name also has no value. 132 134 */ 133 135 bool no_value; 134 - /** 135 - * @alternate_hw_config: config is the event name but num is an 136 - * alternate PERF_TYPE_HARDWARE config value which is often nice for the 137 - * sake of quick matching. 138 - */ 139 - bool alternate_hw_config; 140 136 }; 141 137 142 138 struct parse_events_error { ··· 227 235 u32 type, u64 config, 228 236 const struct parse_events_terms *head_config, 229 237 bool wildcard); 230 - int parse_events_add_cache(struct list_head *list, int *idx, const char *name, 231 - struct parse_events_state *parse_state, 232 - struct parse_events_terms *parsed_terms, 233 - void *loc); 234 238 int parse_events__decode_legacy_cache(const char *name, int pmu_type, __u64 *config); 235 239 int parse_events_add_breakpoint(struct parse_events_state *parse_state, 236 240 struct list_head *list, ··· 238 250 struct perf_pmu *pmu); 239 251 240 252 int parse_events_multi_pmu_add(struct parse_events_state *parse_state, 241 - const char *event_name, u64 hw_config, 253 + const char *event_name, 242 254 const struct parse_events_terms *const_parsed_terms, 243 255 struct list_head **listp, void *loc); 244 256
-52
tools/perf/util/parse-events.l
··· 73 73 return token; 74 74 } 75 75 76 - static int lc_str(yyscan_t scanner, const struct parse_events_state *state) 77 - { 78 - return str(scanner, state->match_legacy_cache_terms ? PE_LEGACY_CACHE : PE_NAME); 79 - } 80 - 81 76 /* 82 77 * This function is called when the parser gets two kind of input: 83 78 * ··· 110 115 yyless(0); \ 111 116 } while (0) 112 117 113 - static int sym(yyscan_t scanner, int config) 114 - { 115 - YYSTYPE *yylval = parse_events_get_lval(scanner); 116 - 117 - yylval->num = config; 118 - return PE_VALUE_SYM_HW; 119 - } 120 - 121 118 static int term(yyscan_t scanner, enum parse_events__term_type type) 122 119 { 123 120 YYSTYPE *yylval = parse_events_get_lval(scanner); 124 121 125 122 yylval->term_type = type; 126 123 return PE_TERM; 127 - } 128 - 129 - static int hw_term(yyscan_t scanner, int config) 130 - { 131 - YYSTYPE *yylval = parse_events_get_lval(scanner); 132 - char *text = parse_events_get_text(scanner); 133 - 134 - yylval->hardware_term.str = strdup(text); 135 - yylval->hardware_term.num = PERF_TYPE_HARDWARE + config; 136 - return PE_TERM_HW; 137 124 } 138 125 139 126 static void modifiers_error(struct parse_events_state *parse_state, yyscan_t scanner, ··· 228 251 */ 229 252 modifier_event [ukhpPGHSDIWebRX]{1,17} 230 253 modifier_bp [rwx]{1,3} 231 - lc_type (L1-dcache|l1-d|l1d|L1-data|L1-icache|l1-i|l1i|L1-instruction|LLC|L2|dTLB|d-tlb|Data-TLB|iTLB|i-tlb|Instruction-TLB|branch|branches|bpu|btb|bpc|node) 232 - lc_op_result (load|loads|read|store|stores|write|prefetch|prefetches|speculative-read|speculative-load|refs|Reference|ops|access|misses|miss) 233 254 digit [0-9] 234 255 non_digit [^0-9] 235 256 ··· 309 334 ratio-to-prev { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_RATIO_TO_PREV); } 310 335 legacy-hardware-config { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_LEGACY_HARDWARE_CONFIG); } 311 336 legacy-cache-config { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_LEGACY_CACHE_CONFIG); } 312 - cpu-cycles|cycles { return hw_term(yyscanner, PERF_COUNT_HW_CPU_CYCLES); } 313 - stalled-cycles-frontend|idle-cycles-frontend { return hw_term(yyscanner, PERF_COUNT_HW_STALLED_CYCLES_FRONTEND); } 314 - stalled-cycles-backend|idle-cycles-backend { return hw_term(yyscanner, PERF_COUNT_HW_STALLED_CYCLES_BACKEND); } 315 - instructions { return hw_term(yyscanner, PERF_COUNT_HW_INSTRUCTIONS); } 316 - cache-references { return hw_term(yyscanner, PERF_COUNT_HW_CACHE_REFERENCES); } 317 - cache-misses { return hw_term(yyscanner, PERF_COUNT_HW_CACHE_MISSES); } 318 - branch-instructions|branches { return hw_term(yyscanner, PERF_COUNT_HW_BRANCH_INSTRUCTIONS); } 319 - branch-misses { return hw_term(yyscanner, PERF_COUNT_HW_BRANCH_MISSES); } 320 - bus-cycles { return hw_term(yyscanner, PERF_COUNT_HW_BUS_CYCLES); } 321 - ref-cycles { return hw_term(yyscanner, PERF_COUNT_HW_REF_CPU_CYCLES); } 322 337 r{num_raw_hex} { return str(yyscanner, PE_RAW); } 323 338 r0x{num_raw_hex} { return str(yyscanner, PE_RAW); } 324 339 , { return ','; } 325 340 "/" { BEGIN(INITIAL); return '/'; } 326 - {lc_type} { return lc_str(yyscanner, _parse_state); } 327 - {lc_type}-{lc_op_result} { return lc_str(yyscanner, _parse_state); } 328 - {lc_type}-{lc_op_result}-{lc_op_result} { return lc_str(yyscanner, _parse_state); } 329 341 {num_dec} { return value(_parse_state, yyscanner, 10); } 330 342 {num_hex} { return value(_parse_state, yyscanner, 16); } 331 343 {term_name} { return str(yyscanner, PE_NAME); } ··· 351 389 <<EOF>> { BEGIN(INITIAL); } 352 390 } 353 391 354 - cpu-cycles|cycles { return sym(yyscanner, PERF_COUNT_HW_CPU_CYCLES); } 355 - stalled-cycles-frontend|idle-cycles-frontend { return sym(yyscanner, PERF_COUNT_HW_STALLED_CYCLES_FRONTEND); } 356 - stalled-cycles-backend|idle-cycles-backend { return sym(yyscanner, PERF_COUNT_HW_STALLED_CYCLES_BACKEND); } 357 - instructions { return sym(yyscanner, PERF_COUNT_HW_INSTRUCTIONS); } 358 - cache-references { return sym(yyscanner, PERF_COUNT_HW_CACHE_REFERENCES); } 359 - cache-misses { return sym(yyscanner, PERF_COUNT_HW_CACHE_MISSES); } 360 - branch-instructions|branches { return sym(yyscanner, PERF_COUNT_HW_BRANCH_INSTRUCTIONS); } 361 - branch-misses { return sym(yyscanner, PERF_COUNT_HW_BRANCH_MISSES); } 362 - bus-cycles { return sym(yyscanner, PERF_COUNT_HW_BUS_CYCLES); } 363 - ref-cycles { return sym(yyscanner, PERF_COUNT_HW_REF_CPU_CYCLES); } 364 - 365 - {lc_type} { return str(yyscanner, PE_LEGACY_CACHE); } 366 - {lc_type}-{lc_op_result} { return str(yyscanner, PE_LEGACY_CACHE); } 367 - {lc_type}-{lc_op_result}-{lc_op_result} { return str(yyscanner, PE_LEGACY_CACHE); } 368 392 mem: { BEGIN(mem); return PE_PREFIX_MEM; } 369 393 r{num_raw_hex} { return str(yyscanner, PE_RAW); } 370 394 {num_dec} { return value(_parse_state, yyscanner, 10); }
+3 -111
tools/perf/util/parse-events.y
··· 55 55 %} 56 56 57 57 %token PE_START_EVENTS PE_START_TERMS 58 - %token PE_VALUE PE_VALUE_SYM_HW PE_TERM 58 + %token PE_VALUE PE_TERM 59 59 %token PE_EVENT_NAME 60 60 %token PE_RAW PE_NAME 61 61 %token PE_MODIFIER_EVENT PE_MODIFIER_BP PE_BP_COLON PE_BP_SLASH 62 - %token PE_LEGACY_CACHE 63 62 %token PE_PREFIX_MEM 64 63 %token PE_ERROR 65 64 %token PE_DRV_CFG_TERM 66 - %token PE_TERM_HW 67 65 %type <num> PE_VALUE 68 - %type <num> PE_VALUE_SYM_HW 69 66 %type <mod> PE_MODIFIER_EVENT 70 67 %type <term_type> PE_TERM 71 68 %type <str> PE_RAW 72 69 %type <str> PE_NAME 73 - %type <str> PE_LEGACY_CACHE 74 70 %type <str> PE_MODIFIER_BP 75 71 %type <str> PE_EVENT_NAME 76 72 %type <str> PE_DRV_CFG_TERM ··· 79 83 %type <list_terms> opt_pmu_config 80 84 %destructor { parse_events_terms__delete ($$); } <list_terms> 81 85 %type <list_evsel> event_pmu 82 - %type <list_evsel> event_legacy_symbol 83 - %type <list_evsel> event_legacy_cache 84 86 %type <list_evsel> event_legacy_mem 85 87 %type <list_evsel> event_legacy_tracepoint 86 88 %type <list_evsel> event_legacy_numeric ··· 94 100 %destructor { free_list_evsel ($$); } <list_evsel> 95 101 %type <tracepoint_name> tracepoint_name 96 102 %destructor { free ($$.sys); free ($$.event); } <tracepoint_name> 97 - %type <hardware_term> PE_TERM_HW 98 - %destructor { free ($$.str); } <hardware_term> 99 103 100 104 %union 101 105 { ··· 108 116 char *sys; 109 117 char *event; 110 118 } tracepoint_name; 111 - struct hardware_term { 112 - char *str; 113 - u64 num; 114 - } hardware_term; 115 119 } 116 120 %% 117 121 ··· 250 262 event_def 251 263 252 264 event_def: event_pmu | 253 - event_legacy_symbol | 254 - event_legacy_cache sep_dc | 255 265 event_legacy_mem sep_dc | 256 266 event_legacy_tracepoint sep_dc | 257 267 event_legacy_numeric sep_dc | ··· 274 288 struct list_head *list; 275 289 int err; 276 290 277 - err = parse_events_multi_pmu_add(_parse_state, $1, PERF_COUNT_HW_MAX, NULL, &list, &@1); 291 + err = parse_events_multi_pmu_add(_parse_state, $1, /*const_parsed_terms*/NULL, &list, &@1); 278 292 if (err < 0) { 279 293 struct parse_events_state *parse_state = _parse_state; 280 294 struct parse_events_error *error = parse_state->error; ··· 287 301 PE_ABORT(err); 288 302 } 289 303 free($1); 290 - $$ = list; 291 - } 292 - 293 - event_legacy_symbol: 294 - PE_VALUE_SYM_HW '/' event_config '/' 295 - { 296 - struct list_head *list; 297 - int err; 298 - 299 - list = alloc_list(); 300 - if (!list) 301 - YYNOMEM; 302 - err = parse_events_add_numeric(_parse_state, list, 303 - PERF_TYPE_HARDWARE, $1, 304 - $3, 305 - /*wildcard=*/true); 306 - parse_events_terms__delete($3); 307 - if (err) { 308 - free_list_evsel(list); 309 - PE_ABORT(err); 310 - } 311 - $$ = list; 312 - } 313 - | 314 - PE_VALUE_SYM_HW sep_slash_slash_dc 315 - { 316 - struct list_head *list; 317 - int err; 318 - 319 - list = alloc_list(); 320 - if (!list) 321 - YYNOMEM; 322 - err = parse_events_add_numeric(_parse_state, list, 323 - PERF_TYPE_HARDWARE, $1, 324 - /*head_config=*/NULL, 325 - /*wildcard=*/true); 326 - if (err) 327 - PE_ABORT(err); 328 - $$ = list; 329 - } 330 - 331 - event_legacy_cache: 332 - PE_LEGACY_CACHE opt_event_config 333 - { 334 - struct parse_events_state *parse_state = _parse_state; 335 - struct list_head *list; 336 - int err; 337 - 338 - list = alloc_list(); 339 - if (!list) 340 - YYNOMEM; 341 - 342 - err = parse_events_add_cache(list, &parse_state->idx, $1, parse_state, $2, &@1); 343 - 344 - parse_events_terms__delete($2); 345 - free($1); 346 - if (err) { 347 - free_list_evsel(list); 348 - PE_ABORT(err); 349 - } 350 304 $$ = list; 351 305 } 352 306 ··· 508 582 $$ = head; 509 583 } 510 584 511 - name_or_raw: PE_RAW | PE_NAME | PE_LEGACY_CACHE 512 - | 513 - PE_TERM_HW 514 - { 515 - $$ = $1.str; 516 - } 585 + name_or_raw: PE_RAW | PE_NAME 517 586 518 587 event_term: 519 588 PE_RAW ··· 550 629 $$ = term; 551 630 } 552 631 | 553 - PE_LEGACY_CACHE 554 - { 555 - struct parse_events_term *term; 556 - int err = parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_LEGACY_CACHE, 557 - $1, /*num=*/1, /*novalue=*/true, &@1, /*loc_val=*/NULL); 558 - 559 - if (err) { 560 - free($1); 561 - PE_ABORT(err); 562 - } 563 - $$ = term; 564 - } 565 - | 566 632 PE_NAME 567 633 { 568 634 struct parse_events_term *term; ··· 558 650 559 651 if (err) { 560 652 free($1); 561 - PE_ABORT(err); 562 - } 563 - $$ = term; 564 - } 565 - | 566 - PE_TERM_HW 567 - { 568 - struct parse_events_term *term; 569 - int err = parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_HARDWARE, 570 - $1.str, $1.num & 255, /*novalue=*/false, 571 - &@1, /*loc_val=*/NULL); 572 - 573 - if (err) { 574 - free($1.str); 575 653 PE_ABORT(err); 576 654 } 577 655 $$ = term; ··· 630 736 } 631 737 632 738 sep_dc: ':' | 633 - 634 - sep_slash_slash_dc: '/' '/' | ':' | 635 739 636 740 %% 637 741
+3 -6
tools/perf/util/pmu.c
··· 1920 1920 if (alias->per_pkg) 1921 1921 info->per_pkg = true; 1922 1922 1923 - if (term->alternate_hw_config) 1924 - *alternate_hw_config = term->val.num; 1925 - 1926 1923 info->retirement_latency_mean = alias->retirement_latency_mean; 1927 1924 info->retirement_latency_min = alias->retirement_latency_min; 1928 1925 info->retirement_latency_max = alias->retirement_latency_max; ··· 2027 2030 2028 2031 /* 2029 2032 * max-events and driver-config are missing above as are the internal 2030 - * types user, metric-id, raw, legacy cache and hardware. Assert against 2031 - * the enum parse_events__term_type so they are kept in sync. 2033 + * types user, metric-id, and raw. Assert against the enum 2034 + * parse_events__term_type so they are kept in sync. 2032 2035 */ 2033 - _Static_assert(ARRAY_SIZE(terms) == __PARSE_EVENTS__TERM_TYPE_NR - 6, 2036 + _Static_assert(ARRAY_SIZE(terms) == __PARSE_EVENTS__TERM_TYPE_NR - 4, 2034 2037 "perf_pmu__for_each_format()'s terms must be kept in sync with enum parse_events__term_type"); 2035 2038 list_for_each_entry(format, &pmu->format, list) { 2036 2039 perf_pmu_format__load(pmu, format);