parse-events.y 14 KB

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