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

Configure Feed

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

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