parse-events.y 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714
  1. %define api.pure full
  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 parse_events_state *parse_state = _parse_state;
  202. struct parse_events_error *error = parse_state->error;
  203. struct list_head *list, *orig_terms, *terms;
  204. if (parse_events_copy_term_list($2, &orig_terms))
  205. YYABORT;
  206. if (error)
  207. error->idx = @1.first_column;
  208. ALLOC_LIST(list);
  209. if (parse_events_add_pmu(_parse_state, list, $1, $2, false, false)) {
  210. struct perf_pmu *pmu = NULL;
  211. int ok = 0;
  212. char *pattern;
  213. if (asprintf(&pattern, "%s*", $1) < 0)
  214. YYABORT;
  215. while ((pmu = perf_pmu__scan(pmu)) != NULL) {
  216. char *name = pmu->name;
  217. if (!strncmp(name, "uncore_", 7) &&
  218. strncmp($1, "uncore_", 7))
  219. name += 7;
  220. if (!fnmatch(pattern, name, 0)) {
  221. if (parse_events_copy_term_list(orig_terms, &terms)) {
  222. free(pattern);
  223. YYABORT;
  224. }
  225. if (!parse_events_add_pmu(_parse_state, list, pmu->name, terms, true, false))
  226. ok++;
  227. parse_events_terms__delete(terms);
  228. }
  229. }
  230. free(pattern);
  231. if (!ok)
  232. YYABORT;
  233. }
  234. parse_events_terms__delete($2);
  235. parse_events_terms__delete(orig_terms);
  236. $$ = list;
  237. }
  238. |
  239. PE_KERNEL_PMU_EVENT sep_dc
  240. {
  241. struct list_head *list;
  242. if (parse_events_multi_pmu_add(_parse_state, $1, &list) < 0)
  243. YYABORT;
  244. $$ = list;
  245. }
  246. |
  247. PE_PMU_EVENT_PRE '-' PE_PMU_EVENT_SUF sep_dc
  248. {
  249. struct list_head *list;
  250. char pmu_name[128];
  251. snprintf(&pmu_name, 128, "%s-%s", $1, $3);
  252. if (parse_events_multi_pmu_add(_parse_state, pmu_name, &list) < 0)
  253. YYABORT;
  254. $$ = list;
  255. }
  256. value_sym:
  257. PE_VALUE_SYM_HW
  258. |
  259. PE_VALUE_SYM_SW
  260. event_legacy_symbol:
  261. value_sym '/' event_config '/'
  262. {
  263. struct list_head *list;
  264. int type = $1 >> 16;
  265. int config = $1 & 255;
  266. ALLOC_LIST(list);
  267. ABORT_ON(parse_events_add_numeric(_parse_state, list, type, config, $3));
  268. parse_events_terms__delete($3);
  269. $$ = list;
  270. }
  271. |
  272. value_sym sep_slash_dc
  273. {
  274. struct list_head *list;
  275. int type = $1 >> 16;
  276. int config = $1 & 255;
  277. ALLOC_LIST(list);
  278. ABORT_ON(parse_events_add_numeric(_parse_state, list, type, config, NULL));
  279. $$ = list;
  280. }
  281. event_legacy_cache:
  282. PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT '-' PE_NAME_CACHE_OP_RESULT opt_event_config
  283. {
  284. struct parse_events_state *parse_state = _parse_state;
  285. struct parse_events_error *error = parse_state->error;
  286. struct list_head *list;
  287. ALLOC_LIST(list);
  288. ABORT_ON(parse_events_add_cache(list, &parse_state->idx, $1, $3, $5, error, $6));
  289. parse_events_terms__delete($6);
  290. $$ = list;
  291. }
  292. |
  293. PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT opt_event_config
  294. {
  295. struct parse_events_state *parse_state = _parse_state;
  296. struct parse_events_error *error = parse_state->error;
  297. struct list_head *list;
  298. ALLOC_LIST(list);
  299. ABORT_ON(parse_events_add_cache(list, &parse_state->idx, $1, $3, NULL, error, $4));
  300. parse_events_terms__delete($4);
  301. $$ = list;
  302. }
  303. |
  304. PE_NAME_CACHE_TYPE opt_event_config
  305. {
  306. struct parse_events_state *parse_state = _parse_state;
  307. struct parse_events_error *error = parse_state->error;
  308. struct list_head *list;
  309. ALLOC_LIST(list);
  310. ABORT_ON(parse_events_add_cache(list, &parse_state->idx, $1, NULL, NULL, error, $2));
  311. parse_events_terms__delete($2);
  312. $$ = list;
  313. }
  314. event_legacy_mem:
  315. PE_PREFIX_MEM PE_VALUE '/' PE_VALUE ':' PE_MODIFIER_BP sep_dc
  316. {
  317. struct parse_events_state *parse_state = _parse_state;
  318. struct list_head *list;
  319. ALLOC_LIST(list);
  320. ABORT_ON(parse_events_add_breakpoint(list, &parse_state->idx,
  321. (void *) $2, $6, $4));
  322. $$ = list;
  323. }
  324. |
  325. PE_PREFIX_MEM PE_VALUE '/' PE_VALUE sep_dc
  326. {
  327. struct parse_events_state *parse_state = _parse_state;
  328. struct list_head *list;
  329. ALLOC_LIST(list);
  330. ABORT_ON(parse_events_add_breakpoint(list, &parse_state->idx,
  331. (void *) $2, NULL, $4));
  332. $$ = list;
  333. }
  334. |
  335. PE_PREFIX_MEM PE_VALUE ':' PE_MODIFIER_BP sep_dc
  336. {
  337. struct parse_events_state *parse_state = _parse_state;
  338. struct list_head *list;
  339. ALLOC_LIST(list);
  340. ABORT_ON(parse_events_add_breakpoint(list, &parse_state->idx,
  341. (void *) $2, $4, 0));
  342. $$ = list;
  343. }
  344. |
  345. PE_PREFIX_MEM PE_VALUE sep_dc
  346. {
  347. struct parse_events_state *parse_state = _parse_state;
  348. struct list_head *list;
  349. ALLOC_LIST(list);
  350. ABORT_ON(parse_events_add_breakpoint(list, &parse_state->idx,
  351. (void *) $2, NULL, 0));
  352. $$ = list;
  353. }
  354. event_legacy_tracepoint:
  355. tracepoint_name opt_event_config
  356. {
  357. struct parse_events_state *parse_state = _parse_state;
  358. struct parse_events_error *error = parse_state->error;
  359. struct list_head *list;
  360. ALLOC_LIST(list);
  361. if (error)
  362. error->idx = @1.first_column;
  363. if (parse_events_add_tracepoint(list, &parse_state->idx, $1.sys, $1.event,
  364. error, $2))
  365. return -1;
  366. $$ = list;
  367. }
  368. tracepoint_name:
  369. PE_NAME '-' PE_NAME ':' PE_NAME
  370. {
  371. char sys_name[128];
  372. struct tracepoint_name tracepoint;
  373. snprintf(&sys_name, 128, "%s-%s", $1, $3);
  374. tracepoint.sys = &sys_name;
  375. tracepoint.event = $5;
  376. $$ = tracepoint;
  377. }
  378. |
  379. PE_NAME ':' PE_NAME
  380. {
  381. struct tracepoint_name tracepoint = {$1, $3};
  382. $$ = tracepoint;
  383. }
  384. event_legacy_numeric:
  385. PE_VALUE ':' PE_VALUE opt_event_config
  386. {
  387. struct list_head *list;
  388. ALLOC_LIST(list);
  389. ABORT_ON(parse_events_add_numeric(_parse_state, list, (u32)$1, $3, $4));
  390. parse_events_terms__delete($4);
  391. $$ = list;
  392. }
  393. event_legacy_raw:
  394. PE_RAW opt_event_config
  395. {
  396. struct list_head *list;
  397. ALLOC_LIST(list);
  398. ABORT_ON(parse_events_add_numeric(_parse_state, list, PERF_TYPE_RAW, $1, $2));
  399. parse_events_terms__delete($2);
  400. $$ = list;
  401. }
  402. event_bpf_file:
  403. PE_BPF_OBJECT opt_event_config
  404. {
  405. struct parse_events_state *parse_state = _parse_state;
  406. struct parse_events_error *error = parse_state->error;
  407. struct list_head *list;
  408. ALLOC_LIST(list);
  409. ABORT_ON(parse_events_load_bpf(parse_state, list, $1, false, $2));
  410. parse_events_terms__delete($2);
  411. $$ = list;
  412. }
  413. |
  414. PE_BPF_SOURCE opt_event_config
  415. {
  416. struct list_head *list;
  417. ALLOC_LIST(list);
  418. ABORT_ON(parse_events_load_bpf(_parse_state, list, $1, true, $2));
  419. parse_events_terms__delete($2);
  420. $$ = list;
  421. }
  422. opt_event_config:
  423. '/' event_config '/'
  424. {
  425. $$ = $2;
  426. }
  427. |
  428. '/' '/'
  429. {
  430. $$ = NULL;
  431. }
  432. |
  433. {
  434. $$ = NULL;
  435. }
  436. opt_pmu_config:
  437. '/' event_config '/'
  438. {
  439. $$ = $2;
  440. }
  441. |
  442. '/' '/'
  443. {
  444. $$ = NULL;
  445. }
  446. start_terms: event_config
  447. {
  448. struct parse_events_state *parse_state = _parse_state;
  449. parse_state->terms = $1;
  450. }
  451. event_config:
  452. event_config ',' event_term
  453. {
  454. struct list_head *head = $1;
  455. struct parse_events_term *term = $3;
  456. ABORT_ON(!head);
  457. list_add_tail(&term->list, head);
  458. $$ = $1;
  459. }
  460. |
  461. event_term
  462. {
  463. struct list_head *head = malloc(sizeof(*head));
  464. struct parse_events_term *term = $1;
  465. ABORT_ON(!head);
  466. INIT_LIST_HEAD(head);
  467. list_add_tail(&term->list, head);
  468. $$ = head;
  469. }
  470. event_term:
  471. PE_NAME '=' PE_NAME
  472. {
  473. struct parse_events_term *term;
  474. ABORT_ON(parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_USER,
  475. $1, $3, &@1, &@3));
  476. $$ = term;
  477. }
  478. |
  479. PE_NAME '=' PE_VALUE
  480. {
  481. struct parse_events_term *term;
  482. ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
  483. $1, $3, false, &@1, &@3));
  484. $$ = term;
  485. }
  486. |
  487. PE_NAME '=' PE_VALUE_SYM_HW
  488. {
  489. struct parse_events_term *term;
  490. int config = $3 & 255;
  491. ABORT_ON(parse_events_term__sym_hw(&term, $1, config));
  492. $$ = term;
  493. }
  494. |
  495. PE_NAME
  496. {
  497. struct parse_events_term *term;
  498. ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
  499. $1, 1, true, &@1, NULL));
  500. $$ = term;
  501. }
  502. |
  503. PE_VALUE_SYM_HW
  504. {
  505. struct parse_events_term *term;
  506. int config = $1 & 255;
  507. ABORT_ON(parse_events_term__sym_hw(&term, NULL, config));
  508. $$ = term;
  509. }
  510. |
  511. PE_TERM '=' PE_NAME
  512. {
  513. struct parse_events_term *term;
  514. ABORT_ON(parse_events_term__str(&term, (int)$1, NULL, $3, &@1, &@3));
  515. $$ = term;
  516. }
  517. |
  518. PE_TERM '=' PE_VALUE
  519. {
  520. struct parse_events_term *term;
  521. ABORT_ON(parse_events_term__num(&term, (int)$1, NULL, $3, false, &@1, &@3));
  522. $$ = term;
  523. }
  524. |
  525. PE_TERM
  526. {
  527. struct parse_events_term *term;
  528. ABORT_ON(parse_events_term__num(&term, (int)$1, NULL, 1, true, &@1, NULL));
  529. $$ = term;
  530. }
  531. |
  532. PE_NAME array '=' PE_NAME
  533. {
  534. struct parse_events_term *term;
  535. int i;
  536. ABORT_ON(parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_USER,
  537. $1, $4, &@1, &@4));
  538. term->array = $2;
  539. $$ = term;
  540. }
  541. |
  542. PE_NAME array '=' PE_VALUE
  543. {
  544. struct parse_events_term *term;
  545. ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
  546. $1, $4, false, &@1, &@4));
  547. term->array = $2;
  548. $$ = term;
  549. }
  550. |
  551. PE_DRV_CFG_TERM
  552. {
  553. struct parse_events_term *term;
  554. ABORT_ON(parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_DRV_CFG,
  555. $1, $1, &@1, NULL));
  556. $$ = term;
  557. }
  558. array:
  559. '[' array_terms ']'
  560. {
  561. $$ = $2;
  562. }
  563. |
  564. PE_ARRAY_ALL
  565. {
  566. $$.nr_ranges = 0;
  567. $$.ranges = NULL;
  568. }
  569. array_terms:
  570. array_terms ',' array_term
  571. {
  572. struct parse_events_array new_array;
  573. new_array.nr_ranges = $1.nr_ranges + $3.nr_ranges;
  574. new_array.ranges = malloc(sizeof(new_array.ranges[0]) *
  575. new_array.nr_ranges);
  576. ABORT_ON(!new_array.ranges);
  577. memcpy(&new_array.ranges[0], $1.ranges,
  578. $1.nr_ranges * sizeof(new_array.ranges[0]));
  579. memcpy(&new_array.ranges[$1.nr_ranges], $3.ranges,
  580. $3.nr_ranges * sizeof(new_array.ranges[0]));
  581. free($1.ranges);
  582. free($3.ranges);
  583. $$ = new_array;
  584. }
  585. |
  586. array_term
  587. array_term:
  588. PE_VALUE
  589. {
  590. struct parse_events_array array;
  591. array.nr_ranges = 1;
  592. array.ranges = malloc(sizeof(array.ranges[0]));
  593. ABORT_ON(!array.ranges);
  594. array.ranges[0].start = $1;
  595. array.ranges[0].length = 1;
  596. $$ = array;
  597. }
  598. |
  599. PE_VALUE PE_ARRAY_RANGE PE_VALUE
  600. {
  601. struct parse_events_array array;
  602. ABORT_ON($3 < $1);
  603. array.nr_ranges = 1;
  604. array.ranges = malloc(sizeof(array.ranges[0]));
  605. ABORT_ON(!array.ranges);
  606. array.ranges[0].start = $1;
  607. array.ranges[0].length = $3 - $1 + 1;
  608. $$ = array;
  609. }
  610. sep_dc: ':' |
  611. sep_slash_dc: '/' | ':' |
  612. %%
  613. void parse_events_error(YYLTYPE *loc, void *parse_state,
  614. void *scanner __maybe_unused,
  615. char const *msg __maybe_unused)
  616. {
  617. parse_events_evlist_error(parse_state, loc->last_column, "parser error");
  618. }