parse-events.y 13 KB

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