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

Configure Feed

Select the types of activity you want to include in your feed.

at v5.1-rc5 714 lines 14 kB view raw
1%pure-parser 2%parse-param {void *_parse_state} 3%parse-param {void *scanner} 4%lex-param {void* scanner} 5%locations 6 7%{ 8 9#define YYDEBUG 1 10 11#include <fnmatch.h> 12#include <linux/compiler.h> 13#include <linux/list.h> 14#include <linux/types.h> 15#include "util.h" 16#include "pmu.h" 17#include "debug.h" 18#include "parse-events.h" 19#include "parse-events-bison.h" 20 21void parse_events_error(YYLTYPE *loc, void *parse_state, void *scanner, char const *msg); 22 23#define ABORT_ON(val) \ 24do { \ 25 if (val) \ 26 YYABORT; \ 27} while (0) 28 29#define ALLOC_LIST(list) \ 30do { \ 31 list = malloc(sizeof(*list)); \ 32 ABORT_ON(!list); \ 33 INIT_LIST_HEAD(list); \ 34} while (0) 35 36static void inc_group_count(struct list_head *list, 37 struct parse_events_state *parse_state) 38{ 39 /* Count groups only have more than 1 members */ 40 if (!list_is_last(list->next, list)) 41 parse_state->nr_groups++; 42} 43 44%} 45 46%token PE_START_EVENTS PE_START_TERMS 47%token PE_VALUE PE_VALUE_SYM_HW PE_VALUE_SYM_SW PE_RAW PE_TERM 48%token PE_EVENT_NAME 49%token PE_NAME 50%token PE_BPF_OBJECT PE_BPF_SOURCE 51%token PE_MODIFIER_EVENT PE_MODIFIER_BP 52%token PE_NAME_CACHE_TYPE PE_NAME_CACHE_OP_RESULT 53%token PE_PREFIX_MEM PE_PREFIX_RAW PE_PREFIX_GROUP 54%token PE_ERROR 55%token PE_PMU_EVENT_PRE PE_PMU_EVENT_SUF PE_KERNEL_PMU_EVENT 56%token PE_ARRAY_ALL PE_ARRAY_RANGE 57%token PE_DRV_CFG_TERM 58%type <num> PE_VALUE 59%type <num> PE_VALUE_SYM_HW 60%type <num> PE_VALUE_SYM_SW 61%type <num> PE_RAW 62%type <num> PE_TERM 63%type <str> PE_NAME 64%type <str> PE_BPF_OBJECT 65%type <str> PE_BPF_SOURCE 66%type <str> PE_NAME_CACHE_TYPE 67%type <str> PE_NAME_CACHE_OP_RESULT 68%type <str> PE_MODIFIER_EVENT 69%type <str> PE_MODIFIER_BP 70%type <str> PE_EVENT_NAME 71%type <str> PE_PMU_EVENT_PRE PE_PMU_EVENT_SUF PE_KERNEL_PMU_EVENT 72%type <str> PE_DRV_CFG_TERM 73%type <num> value_sym 74%type <head> event_config 75%type <head> opt_event_config 76%type <head> opt_pmu_config 77%type <term> event_term 78%type <head> event_pmu 79%type <head> event_legacy_symbol 80%type <head> event_legacy_cache 81%type <head> event_legacy_mem 82%type <head> event_legacy_tracepoint 83%type <tracepoint_name> tracepoint_name 84%type <head> event_legacy_numeric 85%type <head> event_legacy_raw 86%type <head> event_bpf_file 87%type <head> event_def 88%type <head> event_mod 89%type <head> event_name 90%type <head> event 91%type <head> events 92%type <head> group_def 93%type <head> group 94%type <head> groups 95%type <array> array 96%type <array> array_term 97%type <array> array_terms 98 99%union 100{ 101 char *str; 102 u64 num; 103 struct list_head *head; 104 struct parse_events_term *term; 105 struct tracepoint_name { 106 char *sys; 107 char *event; 108 } tracepoint_name; 109 struct parse_events_array array; 110} 111%% 112 113start: 114PE_START_EVENTS start_events 115| 116PE_START_TERMS start_terms 117 118start_events: groups 119{ 120 struct parse_events_state *parse_state = _parse_state; 121 122 parse_events_update_lists($1, &parse_state->list); 123} 124 125groups: 126groups ',' group 127{ 128 struct list_head *list = $1; 129 struct list_head *group = $3; 130 131 parse_events_update_lists(group, list); 132 $$ = list; 133} 134| 135groups ',' event 136{ 137 struct list_head *list = $1; 138 struct list_head *event = $3; 139 140 parse_events_update_lists(event, list); 141 $$ = list; 142} 143| 144group 145| 146event 147 148group: 149group_def ':' PE_MODIFIER_EVENT 150{ 151 struct list_head *list = $1; 152 153 ABORT_ON(parse_events__modifier_group(list, $3)); 154 $$ = list; 155} 156| 157group_def 158 159group_def: 160PE_NAME '{' events '}' 161{ 162 struct list_head *list = $3; 163 164 inc_group_count(list, _parse_state); 165 parse_events__set_leader($1, list, _parse_state); 166 $$ = list; 167} 168| 169'{' events '}' 170{ 171 struct list_head *list = $2; 172 173 inc_group_count(list, _parse_state); 174 parse_events__set_leader(NULL, list, _parse_state); 175 $$ = list; 176} 177 178events: 179events ',' event 180{ 181 struct list_head *event = $3; 182 struct list_head *list = $1; 183 184 parse_events_update_lists(event, list); 185 $$ = list; 186} 187| 188event 189 190event: event_mod 191 192event_mod: 193event_name PE_MODIFIER_EVENT 194{ 195 struct list_head *list = $1; 196 197 /* 198 * Apply modifier on all events added by single event definition 199 * (there could be more events added for multiple tracepoint 200 * definitions via '*?'. 201 */ 202 ABORT_ON(parse_events__modifier_event(list, $2, false)); 203 $$ = list; 204} 205| 206event_name 207 208event_name: 209PE_EVENT_NAME event_def 210{ 211 ABORT_ON(parse_events_name($2, $1)); 212 free($1); 213 $$ = $2; 214} 215| 216event_def 217 218event_def: event_pmu | 219 event_legacy_symbol | 220 event_legacy_cache sep_dc | 221 event_legacy_mem | 222 event_legacy_tracepoint sep_dc | 223 event_legacy_numeric sep_dc | 224 event_legacy_raw sep_dc | 225 event_bpf_file 226 227event_pmu: 228PE_NAME opt_pmu_config 229{ 230 struct parse_events_state *parse_state = _parse_state; 231 struct parse_events_error *error = parse_state->error; 232 struct list_head *list, *orig_terms, *terms; 233 234 if (parse_events_copy_term_list($2, &orig_terms)) 235 YYABORT; 236 237 if (error) 238 error->idx = @1.first_column; 239 240 ALLOC_LIST(list); 241 if (parse_events_add_pmu(_parse_state, list, $1, $2, false, false)) { 242 struct perf_pmu *pmu = NULL; 243 int ok = 0; 244 char *pattern; 245 246 if (asprintf(&pattern, "%s*", $1) < 0) 247 YYABORT; 248 249 while ((pmu = perf_pmu__scan(pmu)) != NULL) { 250 char *name = pmu->name; 251 252 if (!strncmp(name, "uncore_", 7) && 253 strncmp($1, "uncore_", 7)) 254 name += 7; 255 if (!fnmatch(pattern, name, 0)) { 256 if (parse_events_copy_term_list(orig_terms, &terms)) { 257 free(pattern); 258 YYABORT; 259 } 260 if (!parse_events_add_pmu(_parse_state, list, pmu->name, terms, true, false)) 261 ok++; 262 parse_events_terms__delete(terms); 263 } 264 } 265 266 free(pattern); 267 268 if (!ok) 269 YYABORT; 270 } 271 parse_events_terms__delete($2); 272 parse_events_terms__delete(orig_terms); 273 $$ = list; 274} 275| 276PE_KERNEL_PMU_EVENT sep_dc 277{ 278 struct list_head *list; 279 280 if (parse_events_multi_pmu_add(_parse_state, $1, &list) < 0) 281 YYABORT; 282 $$ = list; 283} 284| 285PE_PMU_EVENT_PRE '-' PE_PMU_EVENT_SUF sep_dc 286{ 287 struct list_head *list; 288 char pmu_name[128]; 289 290 snprintf(&pmu_name, 128, "%s-%s", $1, $3); 291 if (parse_events_multi_pmu_add(_parse_state, pmu_name, &list) < 0) 292 YYABORT; 293 $$ = list; 294} 295 296value_sym: 297PE_VALUE_SYM_HW 298| 299PE_VALUE_SYM_SW 300 301event_legacy_symbol: 302value_sym '/' event_config '/' 303{ 304 struct list_head *list; 305 int type = $1 >> 16; 306 int config = $1 & 255; 307 308 ALLOC_LIST(list); 309 ABORT_ON(parse_events_add_numeric(_parse_state, list, type, config, $3)); 310 parse_events_terms__delete($3); 311 $$ = list; 312} 313| 314value_sym sep_slash_slash_dc 315{ 316 struct list_head *list; 317 int type = $1 >> 16; 318 int config = $1 & 255; 319 320 ALLOC_LIST(list); 321 ABORT_ON(parse_events_add_numeric(_parse_state, list, type, config, NULL)); 322 $$ = list; 323} 324 325event_legacy_cache: 326PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT '-' PE_NAME_CACHE_OP_RESULT opt_event_config 327{ 328 struct parse_events_state *parse_state = _parse_state; 329 struct parse_events_error *error = parse_state->error; 330 struct list_head *list; 331 332 ALLOC_LIST(list); 333 ABORT_ON(parse_events_add_cache(list, &parse_state->idx, $1, $3, $5, error, $6)); 334 parse_events_terms__delete($6); 335 $$ = list; 336} 337| 338PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT opt_event_config 339{ 340 struct parse_events_state *parse_state = _parse_state; 341 struct parse_events_error *error = parse_state->error; 342 struct list_head *list; 343 344 ALLOC_LIST(list); 345 ABORT_ON(parse_events_add_cache(list, &parse_state->idx, $1, $3, NULL, error, $4)); 346 parse_events_terms__delete($4); 347 $$ = list; 348} 349| 350PE_NAME_CACHE_TYPE opt_event_config 351{ 352 struct parse_events_state *parse_state = _parse_state; 353 struct parse_events_error *error = parse_state->error; 354 struct list_head *list; 355 356 ALLOC_LIST(list); 357 ABORT_ON(parse_events_add_cache(list, &parse_state->idx, $1, NULL, NULL, error, $2)); 358 parse_events_terms__delete($2); 359 $$ = list; 360} 361 362event_legacy_mem: 363PE_PREFIX_MEM PE_VALUE '/' PE_VALUE ':' PE_MODIFIER_BP sep_dc 364{ 365 struct parse_events_state *parse_state = _parse_state; 366 struct list_head *list; 367 368 ALLOC_LIST(list); 369 ABORT_ON(parse_events_add_breakpoint(list, &parse_state->idx, 370 (void *) $2, $6, $4)); 371 $$ = list; 372} 373| 374PE_PREFIX_MEM PE_VALUE '/' PE_VALUE sep_dc 375{ 376 struct parse_events_state *parse_state = _parse_state; 377 struct list_head *list; 378 379 ALLOC_LIST(list); 380 ABORT_ON(parse_events_add_breakpoint(list, &parse_state->idx, 381 (void *) $2, NULL, $4)); 382 $$ = list; 383} 384| 385PE_PREFIX_MEM PE_VALUE ':' PE_MODIFIER_BP sep_dc 386{ 387 struct parse_events_state *parse_state = _parse_state; 388 struct list_head *list; 389 390 ALLOC_LIST(list); 391 ABORT_ON(parse_events_add_breakpoint(list, &parse_state->idx, 392 (void *) $2, $4, 0)); 393 $$ = list; 394} 395| 396PE_PREFIX_MEM PE_VALUE sep_dc 397{ 398 struct parse_events_state *parse_state = _parse_state; 399 struct list_head *list; 400 401 ALLOC_LIST(list); 402 ABORT_ON(parse_events_add_breakpoint(list, &parse_state->idx, 403 (void *) $2, NULL, 0)); 404 $$ = list; 405} 406 407event_legacy_tracepoint: 408tracepoint_name opt_event_config 409{ 410 struct parse_events_state *parse_state = _parse_state; 411 struct parse_events_error *error = parse_state->error; 412 struct list_head *list; 413 414 ALLOC_LIST(list); 415 if (error) 416 error->idx = @1.first_column; 417 418 if (parse_events_add_tracepoint(list, &parse_state->idx, $1.sys, $1.event, 419 error, $2)) 420 return -1; 421 422 $$ = list; 423} 424 425tracepoint_name: 426PE_NAME '-' PE_NAME ':' PE_NAME 427{ 428 char sys_name[128]; 429 struct tracepoint_name tracepoint; 430 431 snprintf(&sys_name, 128, "%s-%s", $1, $3); 432 tracepoint.sys = &sys_name; 433 tracepoint.event = $5; 434 435 $$ = tracepoint; 436} 437| 438PE_NAME ':' PE_NAME 439{ 440 struct tracepoint_name tracepoint = {$1, $3}; 441 442 $$ = tracepoint; 443} 444 445event_legacy_numeric: 446PE_VALUE ':' PE_VALUE opt_event_config 447{ 448 struct list_head *list; 449 450 ALLOC_LIST(list); 451 ABORT_ON(parse_events_add_numeric(_parse_state, list, (u32)$1, $3, $4)); 452 parse_events_terms__delete($4); 453 $$ = list; 454} 455 456event_legacy_raw: 457PE_RAW opt_event_config 458{ 459 struct list_head *list; 460 461 ALLOC_LIST(list); 462 ABORT_ON(parse_events_add_numeric(_parse_state, list, PERF_TYPE_RAW, $1, $2)); 463 parse_events_terms__delete($2); 464 $$ = list; 465} 466 467event_bpf_file: 468PE_BPF_OBJECT opt_event_config 469{ 470 struct parse_events_state *parse_state = _parse_state; 471 struct parse_events_error *error = parse_state->error; 472 struct list_head *list; 473 474 ALLOC_LIST(list); 475 ABORT_ON(parse_events_load_bpf(parse_state, list, $1, false, $2)); 476 parse_events_terms__delete($2); 477 $$ = list; 478} 479| 480PE_BPF_SOURCE opt_event_config 481{ 482 struct list_head *list; 483 484 ALLOC_LIST(list); 485 ABORT_ON(parse_events_load_bpf(_parse_state, list, $1, true, $2)); 486 parse_events_terms__delete($2); 487 $$ = list; 488} 489 490opt_event_config: 491'/' event_config '/' 492{ 493 $$ = $2; 494} 495| 496'/' '/' 497{ 498 $$ = NULL; 499} 500| 501{ 502 $$ = NULL; 503} 504 505opt_pmu_config: 506'/' event_config '/' 507{ 508 $$ = $2; 509} 510| 511'/' '/' 512{ 513 $$ = NULL; 514} 515 516start_terms: event_config 517{ 518 struct parse_events_state *parse_state = _parse_state; 519 parse_state->terms = $1; 520} 521 522event_config: 523event_config ',' event_term 524{ 525 struct list_head *head = $1; 526 struct parse_events_term *term = $3; 527 528 ABORT_ON(!head); 529 list_add_tail(&term->list, head); 530 $$ = $1; 531} 532| 533event_term 534{ 535 struct list_head *head = malloc(sizeof(*head)); 536 struct parse_events_term *term = $1; 537 538 ABORT_ON(!head); 539 INIT_LIST_HEAD(head); 540 list_add_tail(&term->list, head); 541 $$ = head; 542} 543 544event_term: 545PE_NAME '=' PE_NAME 546{ 547 struct parse_events_term *term; 548 549 ABORT_ON(parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_USER, 550 $1, $3, &@1, &@3)); 551 $$ = term; 552} 553| 554PE_NAME '=' PE_VALUE 555{ 556 struct parse_events_term *term; 557 558 ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER, 559 $1, $3, false, &@1, &@3)); 560 $$ = term; 561} 562| 563PE_NAME '=' PE_VALUE_SYM_HW 564{ 565 struct parse_events_term *term; 566 int config = $3 & 255; 567 568 ABORT_ON(parse_events_term__sym_hw(&term, $1, config)); 569 $$ = term; 570} 571| 572PE_NAME 573{ 574 struct parse_events_term *term; 575 576 ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER, 577 $1, 1, true, &@1, NULL)); 578 $$ = term; 579} 580| 581PE_VALUE_SYM_HW 582{ 583 struct parse_events_term *term; 584 int config = $1 & 255; 585 586 ABORT_ON(parse_events_term__sym_hw(&term, NULL, config)); 587 $$ = term; 588} 589| 590PE_TERM '=' PE_NAME 591{ 592 struct parse_events_term *term; 593 594 ABORT_ON(parse_events_term__str(&term, (int)$1, NULL, $3, &@1, &@3)); 595 $$ = term; 596} 597| 598PE_TERM '=' PE_VALUE 599{ 600 struct parse_events_term *term; 601 602 ABORT_ON(parse_events_term__num(&term, (int)$1, NULL, $3, false, &@1, &@3)); 603 $$ = term; 604} 605| 606PE_TERM 607{ 608 struct parse_events_term *term; 609 610 ABORT_ON(parse_events_term__num(&term, (int)$1, NULL, 1, true, &@1, NULL)); 611 $$ = term; 612} 613| 614PE_NAME array '=' PE_NAME 615{ 616 struct parse_events_term *term; 617 int i; 618 619 ABORT_ON(parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_USER, 620 $1, $4, &@1, &@4)); 621 622 term->array = $2; 623 $$ = term; 624} 625| 626PE_NAME array '=' PE_VALUE 627{ 628 struct parse_events_term *term; 629 630 ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER, 631 $1, $4, false, &@1, &@4)); 632 term->array = $2; 633 $$ = term; 634} 635| 636PE_DRV_CFG_TERM 637{ 638 struct parse_events_term *term; 639 640 ABORT_ON(parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_DRV_CFG, 641 $1, $1, &@1, NULL)); 642 $$ = term; 643} 644 645array: 646'[' array_terms ']' 647{ 648 $$ = $2; 649} 650| 651PE_ARRAY_ALL 652{ 653 $$.nr_ranges = 0; 654 $$.ranges = NULL; 655} 656 657array_terms: 658array_terms ',' array_term 659{ 660 struct parse_events_array new_array; 661 662 new_array.nr_ranges = $1.nr_ranges + $3.nr_ranges; 663 new_array.ranges = malloc(sizeof(new_array.ranges[0]) * 664 new_array.nr_ranges); 665 ABORT_ON(!new_array.ranges); 666 memcpy(&new_array.ranges[0], $1.ranges, 667 $1.nr_ranges * sizeof(new_array.ranges[0])); 668 memcpy(&new_array.ranges[$1.nr_ranges], $3.ranges, 669 $3.nr_ranges * sizeof(new_array.ranges[0])); 670 free($1.ranges); 671 free($3.ranges); 672 $$ = new_array; 673} 674| 675array_term 676 677array_term: 678PE_VALUE 679{ 680 struct parse_events_array array; 681 682 array.nr_ranges = 1; 683 array.ranges = malloc(sizeof(array.ranges[0])); 684 ABORT_ON(!array.ranges); 685 array.ranges[0].start = $1; 686 array.ranges[0].length = 1; 687 $$ = array; 688} 689| 690PE_VALUE PE_ARRAY_RANGE PE_VALUE 691{ 692 struct parse_events_array array; 693 694 ABORT_ON($3 < $1); 695 array.nr_ranges = 1; 696 array.ranges = malloc(sizeof(array.ranges[0])); 697 ABORT_ON(!array.ranges); 698 array.ranges[0].start = $1; 699 array.ranges[0].length = $3 - $1 + 1; 700 $$ = array; 701} 702 703sep_dc: ':' | 704 705sep_slash_slash_dc: '/' '/' | ':' | 706 707%% 708 709void parse_events_error(YYLTYPE *loc, void *parse_state, 710 void *scanner __maybe_unused, 711 char const *msg __maybe_unused) 712{ 713 parse_events_evlist_error(parse_state, loc->last_column, "parser error"); 714}