pmu.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914
  1. #include <linux/list.h>
  2. #include <sys/types.h>
  3. #include <unistd.h>
  4. #include <stdio.h>
  5. #include <stdbool.h>
  6. #include <stdarg.h>
  7. #include <dirent.h>
  8. #include <api/fs/fs.h>
  9. #include <locale.h>
  10. #include "util.h"
  11. #include "pmu.h"
  12. #include "parse-events.h"
  13. #include "cpumap.h"
  14. struct perf_pmu_format {
  15. char *name;
  16. int value;
  17. DECLARE_BITMAP(bits, PERF_PMU_FORMAT_BITS);
  18. struct list_head list;
  19. };
  20. #define EVENT_SOURCE_DEVICE_PATH "/bus/event_source/devices/"
  21. int perf_pmu_parse(struct list_head *list, char *name);
  22. extern FILE *perf_pmu_in;
  23. static LIST_HEAD(pmus);
  24. /*
  25. * Parse & process all the sysfs attributes located under
  26. * the directory specified in 'dir' parameter.
  27. */
  28. int perf_pmu__format_parse(char *dir, struct list_head *head)
  29. {
  30. struct dirent *evt_ent;
  31. DIR *format_dir;
  32. int ret = 0;
  33. format_dir = opendir(dir);
  34. if (!format_dir)
  35. return -EINVAL;
  36. while (!ret && (evt_ent = readdir(format_dir))) {
  37. char path[PATH_MAX];
  38. char *name = evt_ent->d_name;
  39. FILE *file;
  40. if (!strcmp(name, ".") || !strcmp(name, ".."))
  41. continue;
  42. snprintf(path, PATH_MAX, "%s/%s", dir, name);
  43. ret = -EINVAL;
  44. file = fopen(path, "r");
  45. if (!file)
  46. break;
  47. perf_pmu_in = file;
  48. ret = perf_pmu_parse(head, name);
  49. fclose(file);
  50. }
  51. closedir(format_dir);
  52. return ret;
  53. }
  54. /*
  55. * Reading/parsing the default pmu format definition, which should be
  56. * located at:
  57. * /sys/bus/event_source/devices/<dev>/format as sysfs group attributes.
  58. */
  59. static int pmu_format(const char *name, struct list_head *format)
  60. {
  61. struct stat st;
  62. char path[PATH_MAX];
  63. const char *sysfs = sysfs__mountpoint();
  64. if (!sysfs)
  65. return -1;
  66. snprintf(path, PATH_MAX,
  67. "%s" EVENT_SOURCE_DEVICE_PATH "%s/format", sysfs, name);
  68. if (stat(path, &st) < 0)
  69. return 0; /* no error if format does not exist */
  70. if (perf_pmu__format_parse(path, format))
  71. return -1;
  72. return 0;
  73. }
  74. static int perf_pmu__parse_scale(struct perf_pmu_alias *alias, char *dir, char *name)
  75. {
  76. struct stat st;
  77. ssize_t sret;
  78. char scale[128];
  79. int fd, ret = -1;
  80. char path[PATH_MAX];
  81. const char *lc;
  82. snprintf(path, PATH_MAX, "%s/%s.scale", dir, name);
  83. fd = open(path, O_RDONLY);
  84. if (fd == -1)
  85. return -1;
  86. if (fstat(fd, &st) < 0)
  87. goto error;
  88. sret = read(fd, scale, sizeof(scale)-1);
  89. if (sret < 0)
  90. goto error;
  91. scale[sret] = '\0';
  92. /*
  93. * save current locale
  94. */
  95. lc = setlocale(LC_NUMERIC, NULL);
  96. /*
  97. * force to C locale to ensure kernel
  98. * scale string is converted correctly.
  99. * kernel uses default C locale.
  100. */
  101. setlocale(LC_NUMERIC, "C");
  102. alias->scale = strtod(scale, NULL);
  103. /* restore locale */
  104. setlocale(LC_NUMERIC, lc);
  105. ret = 0;
  106. error:
  107. close(fd);
  108. return ret;
  109. }
  110. static int perf_pmu__parse_unit(struct perf_pmu_alias *alias, char *dir, char *name)
  111. {
  112. char path[PATH_MAX];
  113. ssize_t sret;
  114. int fd;
  115. snprintf(path, PATH_MAX, "%s/%s.unit", dir, name);
  116. fd = open(path, O_RDONLY);
  117. if (fd == -1)
  118. return -1;
  119. sret = read(fd, alias->unit, UNIT_MAX_LEN);
  120. if (sret < 0)
  121. goto error;
  122. close(fd);
  123. alias->unit[sret] = '\0';
  124. return 0;
  125. error:
  126. close(fd);
  127. alias->unit[0] = '\0';
  128. return -1;
  129. }
  130. static int
  131. perf_pmu__parse_per_pkg(struct perf_pmu_alias *alias, char *dir, char *name)
  132. {
  133. char path[PATH_MAX];
  134. int fd;
  135. snprintf(path, PATH_MAX, "%s/%s.per-pkg", dir, name);
  136. fd = open(path, O_RDONLY);
  137. if (fd == -1)
  138. return -1;
  139. close(fd);
  140. alias->per_pkg = true;
  141. return 0;
  142. }
  143. static int perf_pmu__parse_snapshot(struct perf_pmu_alias *alias,
  144. char *dir, char *name)
  145. {
  146. char path[PATH_MAX];
  147. int fd;
  148. snprintf(path, PATH_MAX, "%s/%s.snapshot", dir, name);
  149. fd = open(path, O_RDONLY);
  150. if (fd == -1)
  151. return -1;
  152. alias->snapshot = true;
  153. close(fd);
  154. return 0;
  155. }
  156. static int perf_pmu__new_alias(struct list_head *list, char *dir, char *name, FILE *file)
  157. {
  158. struct perf_pmu_alias *alias;
  159. char buf[256];
  160. int ret;
  161. ret = fread(buf, 1, sizeof(buf), file);
  162. if (ret == 0)
  163. return -EINVAL;
  164. buf[ret] = 0;
  165. alias = malloc(sizeof(*alias));
  166. if (!alias)
  167. return -ENOMEM;
  168. INIT_LIST_HEAD(&alias->terms);
  169. alias->scale = 1.0;
  170. alias->unit[0] = '\0';
  171. alias->per_pkg = false;
  172. ret = parse_events_terms(&alias->terms, buf);
  173. if (ret) {
  174. free(alias);
  175. return ret;
  176. }
  177. alias->name = strdup(name);
  178. /*
  179. * load unit name and scale if available
  180. */
  181. perf_pmu__parse_unit(alias, dir, name);
  182. perf_pmu__parse_scale(alias, dir, name);
  183. perf_pmu__parse_per_pkg(alias, dir, name);
  184. perf_pmu__parse_snapshot(alias, dir, name);
  185. list_add_tail(&alias->list, list);
  186. return 0;
  187. }
  188. static inline bool pmu_alias_info_file(char *name)
  189. {
  190. size_t len;
  191. len = strlen(name);
  192. if (len > 5 && !strcmp(name + len - 5, ".unit"))
  193. return true;
  194. if (len > 6 && !strcmp(name + len - 6, ".scale"))
  195. return true;
  196. if (len > 8 && !strcmp(name + len - 8, ".per-pkg"))
  197. return true;
  198. if (len > 9 && !strcmp(name + len - 9, ".snapshot"))
  199. return true;
  200. return false;
  201. }
  202. /*
  203. * Process all the sysfs attributes located under the directory
  204. * specified in 'dir' parameter.
  205. */
  206. static int pmu_aliases_parse(char *dir, struct list_head *head)
  207. {
  208. struct dirent *evt_ent;
  209. DIR *event_dir;
  210. int ret = 0;
  211. event_dir = opendir(dir);
  212. if (!event_dir)
  213. return -EINVAL;
  214. while (!ret && (evt_ent = readdir(event_dir))) {
  215. char path[PATH_MAX];
  216. char *name = evt_ent->d_name;
  217. FILE *file;
  218. if (!strcmp(name, ".") || !strcmp(name, ".."))
  219. continue;
  220. /*
  221. * skip info files parsed in perf_pmu__new_alias()
  222. */
  223. if (pmu_alias_info_file(name))
  224. continue;
  225. snprintf(path, PATH_MAX, "%s/%s", dir, name);
  226. ret = -EINVAL;
  227. file = fopen(path, "r");
  228. if (!file)
  229. break;
  230. ret = perf_pmu__new_alias(head, dir, name, file);
  231. fclose(file);
  232. }
  233. closedir(event_dir);
  234. return ret;
  235. }
  236. /*
  237. * Reading the pmu event aliases definition, which should be located at:
  238. * /sys/bus/event_source/devices/<dev>/events as sysfs group attributes.
  239. */
  240. static int pmu_aliases(const char *name, struct list_head *head)
  241. {
  242. struct stat st;
  243. char path[PATH_MAX];
  244. const char *sysfs = sysfs__mountpoint();
  245. if (!sysfs)
  246. return -1;
  247. snprintf(path, PATH_MAX,
  248. "%s/bus/event_source/devices/%s/events", sysfs, name);
  249. if (stat(path, &st) < 0)
  250. return 0; /* no error if 'events' does not exist */
  251. if (pmu_aliases_parse(path, head))
  252. return -1;
  253. return 0;
  254. }
  255. static int pmu_alias_terms(struct perf_pmu_alias *alias,
  256. struct list_head *terms)
  257. {
  258. struct parse_events_term *term, *cloned;
  259. LIST_HEAD(list);
  260. int ret;
  261. list_for_each_entry(term, &alias->terms, list) {
  262. ret = parse_events_term__clone(&cloned, term);
  263. if (ret) {
  264. parse_events__free_terms(&list);
  265. return ret;
  266. }
  267. list_add_tail(&cloned->list, &list);
  268. }
  269. list_splice(&list, terms);
  270. return 0;
  271. }
  272. /*
  273. * Reading/parsing the default pmu type value, which should be
  274. * located at:
  275. * /sys/bus/event_source/devices/<dev>/type as sysfs attribute.
  276. */
  277. static int pmu_type(const char *name, __u32 *type)
  278. {
  279. struct stat st;
  280. char path[PATH_MAX];
  281. FILE *file;
  282. int ret = 0;
  283. const char *sysfs = sysfs__mountpoint();
  284. if (!sysfs)
  285. return -1;
  286. snprintf(path, PATH_MAX,
  287. "%s" EVENT_SOURCE_DEVICE_PATH "%s/type", sysfs, name);
  288. if (stat(path, &st) < 0)
  289. return -1;
  290. file = fopen(path, "r");
  291. if (!file)
  292. return -EINVAL;
  293. if (1 != fscanf(file, "%u", type))
  294. ret = -1;
  295. fclose(file);
  296. return ret;
  297. }
  298. /* Add all pmus in sysfs to pmu list: */
  299. static void pmu_read_sysfs(void)
  300. {
  301. char path[PATH_MAX];
  302. DIR *dir;
  303. struct dirent *dent;
  304. const char *sysfs = sysfs__mountpoint();
  305. if (!sysfs)
  306. return;
  307. snprintf(path, PATH_MAX,
  308. "%s" EVENT_SOURCE_DEVICE_PATH, sysfs);
  309. dir = opendir(path);
  310. if (!dir)
  311. return;
  312. while ((dent = readdir(dir))) {
  313. if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, ".."))
  314. continue;
  315. /* add to static LIST_HEAD(pmus): */
  316. perf_pmu__find(dent->d_name);
  317. }
  318. closedir(dir);
  319. }
  320. static struct cpu_map *pmu_cpumask(const char *name)
  321. {
  322. struct stat st;
  323. char path[PATH_MAX];
  324. FILE *file;
  325. struct cpu_map *cpus;
  326. const char *sysfs = sysfs__mountpoint();
  327. if (!sysfs)
  328. return NULL;
  329. snprintf(path, PATH_MAX,
  330. "%s/bus/event_source/devices/%s/cpumask", sysfs, name);
  331. if (stat(path, &st) < 0)
  332. return NULL;
  333. file = fopen(path, "r");
  334. if (!file)
  335. return NULL;
  336. cpus = cpu_map__read(file);
  337. fclose(file);
  338. return cpus;
  339. }
  340. struct perf_event_attr *__attribute__((weak))
  341. perf_pmu__get_default_config(struct perf_pmu *pmu __maybe_unused)
  342. {
  343. return NULL;
  344. }
  345. static struct perf_pmu *pmu_lookup(const char *name)
  346. {
  347. struct perf_pmu *pmu;
  348. LIST_HEAD(format);
  349. LIST_HEAD(aliases);
  350. __u32 type;
  351. /*
  352. * The pmu data we store & need consists of the pmu
  353. * type value and format definitions. Load both right
  354. * now.
  355. */
  356. if (pmu_format(name, &format))
  357. return NULL;
  358. if (pmu_aliases(name, &aliases))
  359. return NULL;
  360. if (pmu_type(name, &type))
  361. return NULL;
  362. pmu = zalloc(sizeof(*pmu));
  363. if (!pmu)
  364. return NULL;
  365. pmu->cpus = pmu_cpumask(name);
  366. INIT_LIST_HEAD(&pmu->format);
  367. INIT_LIST_HEAD(&pmu->aliases);
  368. list_splice(&format, &pmu->format);
  369. list_splice(&aliases, &pmu->aliases);
  370. pmu->name = strdup(name);
  371. pmu->type = type;
  372. list_add_tail(&pmu->list, &pmus);
  373. pmu->default_config = perf_pmu__get_default_config(pmu);
  374. return pmu;
  375. }
  376. static struct perf_pmu *pmu_find(const char *name)
  377. {
  378. struct perf_pmu *pmu;
  379. list_for_each_entry(pmu, &pmus, list)
  380. if (!strcmp(pmu->name, name))
  381. return pmu;
  382. return NULL;
  383. }
  384. struct perf_pmu *perf_pmu__scan(struct perf_pmu *pmu)
  385. {
  386. /*
  387. * pmu iterator: If pmu is NULL, we start at the begin,
  388. * otherwise return the next pmu. Returns NULL on end.
  389. */
  390. if (!pmu) {
  391. pmu_read_sysfs();
  392. pmu = list_prepare_entry(pmu, &pmus, list);
  393. }
  394. list_for_each_entry_continue(pmu, &pmus, list)
  395. return pmu;
  396. return NULL;
  397. }
  398. struct perf_pmu *perf_pmu__find(const char *name)
  399. {
  400. struct perf_pmu *pmu;
  401. /*
  402. * Once PMU is loaded it stays in the list,
  403. * so we keep us from multiple reading/parsing
  404. * the pmu format definitions.
  405. */
  406. pmu = pmu_find(name);
  407. if (pmu)
  408. return pmu;
  409. return pmu_lookup(name);
  410. }
  411. static struct perf_pmu_format *
  412. pmu_find_format(struct list_head *formats, char *name)
  413. {
  414. struct perf_pmu_format *format;
  415. list_for_each_entry(format, formats, list)
  416. if (!strcmp(format->name, name))
  417. return format;
  418. return NULL;
  419. }
  420. /*
  421. * Sets value based on the format definition (format parameter)
  422. * and unformated value (value parameter).
  423. */
  424. static void pmu_format_value(unsigned long *format, __u64 value, __u64 *v,
  425. bool zero)
  426. {
  427. unsigned long fbit, vbit;
  428. for (fbit = 0, vbit = 0; fbit < PERF_PMU_FORMAT_BITS; fbit++) {
  429. if (!test_bit(fbit, format))
  430. continue;
  431. if (value & (1llu << vbit++))
  432. *v |= (1llu << fbit);
  433. else if (zero)
  434. *v &= ~(1llu << fbit);
  435. }
  436. }
  437. /*
  438. * Setup one of config[12] attr members based on the
  439. * user input data - term parameter.
  440. */
  441. static int pmu_config_term(struct list_head *formats,
  442. struct perf_event_attr *attr,
  443. struct parse_events_term *term,
  444. bool zero)
  445. {
  446. struct perf_pmu_format *format;
  447. __u64 *vp;
  448. /*
  449. * Support only for hardcoded and numnerial terms.
  450. * Hardcoded terms should be already in, so nothing
  451. * to be done for them.
  452. */
  453. if (parse_events__is_hardcoded_term(term))
  454. return 0;
  455. if (term->type_val != PARSE_EVENTS__TERM_TYPE_NUM)
  456. return -EINVAL;
  457. format = pmu_find_format(formats, term->config);
  458. if (!format)
  459. return -EINVAL;
  460. switch (format->value) {
  461. case PERF_PMU_FORMAT_VALUE_CONFIG:
  462. vp = &attr->config;
  463. break;
  464. case PERF_PMU_FORMAT_VALUE_CONFIG1:
  465. vp = &attr->config1;
  466. break;
  467. case PERF_PMU_FORMAT_VALUE_CONFIG2:
  468. vp = &attr->config2;
  469. break;
  470. default:
  471. return -EINVAL;
  472. }
  473. /*
  474. * XXX If we ever decide to go with string values for
  475. * non-hardcoded terms, here's the place to translate
  476. * them into value.
  477. */
  478. pmu_format_value(format->bits, term->val.num, vp, zero);
  479. return 0;
  480. }
  481. int perf_pmu__config_terms(struct list_head *formats,
  482. struct perf_event_attr *attr,
  483. struct list_head *head_terms,
  484. bool zero)
  485. {
  486. struct parse_events_term *term;
  487. list_for_each_entry(term, head_terms, list)
  488. if (pmu_config_term(formats, attr, term, zero))
  489. return -EINVAL;
  490. return 0;
  491. }
  492. /*
  493. * Configures event's 'attr' parameter based on the:
  494. * 1) users input - specified in terms parameter
  495. * 2) pmu format definitions - specified by pmu parameter
  496. */
  497. int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr,
  498. struct list_head *head_terms)
  499. {
  500. bool zero = !!pmu->default_config;
  501. attr->type = pmu->type;
  502. return perf_pmu__config_terms(&pmu->format, attr, head_terms, zero);
  503. }
  504. static struct perf_pmu_alias *pmu_find_alias(struct perf_pmu *pmu,
  505. struct parse_events_term *term)
  506. {
  507. struct perf_pmu_alias *alias;
  508. char *name;
  509. if (parse_events__is_hardcoded_term(term))
  510. return NULL;
  511. if (term->type_val == PARSE_EVENTS__TERM_TYPE_NUM) {
  512. if (term->val.num != 1)
  513. return NULL;
  514. if (pmu_find_format(&pmu->format, term->config))
  515. return NULL;
  516. name = term->config;
  517. } else if (term->type_val == PARSE_EVENTS__TERM_TYPE_STR) {
  518. if (strcasecmp(term->config, "event"))
  519. return NULL;
  520. name = term->val.str;
  521. } else {
  522. return NULL;
  523. }
  524. list_for_each_entry(alias, &pmu->aliases, list) {
  525. if (!strcasecmp(alias->name, name))
  526. return alias;
  527. }
  528. return NULL;
  529. }
  530. static int check_info_data(struct perf_pmu_alias *alias,
  531. struct perf_pmu_info *info)
  532. {
  533. /*
  534. * Only one term in event definition can
  535. * define unit, scale and snapshot, fail
  536. * if there's more than one.
  537. */
  538. if ((info->unit && alias->unit) ||
  539. (info->scale && alias->scale) ||
  540. (info->snapshot && alias->snapshot))
  541. return -EINVAL;
  542. if (alias->unit)
  543. info->unit = alias->unit;
  544. if (alias->scale)
  545. info->scale = alias->scale;
  546. if (alias->snapshot)
  547. info->snapshot = alias->snapshot;
  548. return 0;
  549. }
  550. /*
  551. * Find alias in the terms list and replace it with the terms
  552. * defined for the alias
  553. */
  554. int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms,
  555. struct perf_pmu_info *info)
  556. {
  557. struct parse_events_term *term, *h;
  558. struct perf_pmu_alias *alias;
  559. int ret;
  560. info->per_pkg = false;
  561. /*
  562. * Mark unit and scale as not set
  563. * (different from default values, see below)
  564. */
  565. info->unit = NULL;
  566. info->scale = 0.0;
  567. info->snapshot = false;
  568. list_for_each_entry_safe(term, h, head_terms, list) {
  569. alias = pmu_find_alias(pmu, term);
  570. if (!alias)
  571. continue;
  572. ret = pmu_alias_terms(alias, &term->list);
  573. if (ret)
  574. return ret;
  575. ret = check_info_data(alias, info);
  576. if (ret)
  577. return ret;
  578. if (alias->per_pkg)
  579. info->per_pkg = true;
  580. list_del(&term->list);
  581. free(term);
  582. }
  583. /*
  584. * if no unit or scale foundin aliases, then
  585. * set defaults as for evsel
  586. * unit cannot left to NULL
  587. */
  588. if (info->unit == NULL)
  589. info->unit = "";
  590. if (info->scale == 0.0)
  591. info->scale = 1.0;
  592. return 0;
  593. }
  594. int perf_pmu__new_format(struct list_head *list, char *name,
  595. int config, unsigned long *bits)
  596. {
  597. struct perf_pmu_format *format;
  598. format = zalloc(sizeof(*format));
  599. if (!format)
  600. return -ENOMEM;
  601. format->name = strdup(name);
  602. format->value = config;
  603. memcpy(format->bits, bits, sizeof(format->bits));
  604. list_add_tail(&format->list, list);
  605. return 0;
  606. }
  607. void perf_pmu__set_format(unsigned long *bits, long from, long to)
  608. {
  609. long b;
  610. if (!to)
  611. to = from;
  612. memset(bits, 0, BITS_TO_BYTES(PERF_PMU_FORMAT_BITS));
  613. for (b = from; b <= to; b++)
  614. set_bit(b, bits);
  615. }
  616. static char *format_alias(char *buf, int len, struct perf_pmu *pmu,
  617. struct perf_pmu_alias *alias)
  618. {
  619. snprintf(buf, len, "%s/%s/", pmu->name, alias->name);
  620. return buf;
  621. }
  622. static char *format_alias_or(char *buf, int len, struct perf_pmu *pmu,
  623. struct perf_pmu_alias *alias)
  624. {
  625. snprintf(buf, len, "%s OR %s/%s/", alias->name, pmu->name, alias->name);
  626. return buf;
  627. }
  628. static int cmp_string(const void *a, const void *b)
  629. {
  630. const char * const *as = a;
  631. const char * const *bs = b;
  632. return strcmp(*as, *bs);
  633. }
  634. void print_pmu_events(const char *event_glob, bool name_only)
  635. {
  636. struct perf_pmu *pmu;
  637. struct perf_pmu_alias *alias;
  638. char buf[1024];
  639. int printed = 0;
  640. int len, j;
  641. char **aliases;
  642. pmu = NULL;
  643. len = 0;
  644. while ((pmu = perf_pmu__scan(pmu)) != NULL) {
  645. list_for_each_entry(alias, &pmu->aliases, list)
  646. len++;
  647. if (pmu->selectable)
  648. len++;
  649. }
  650. aliases = zalloc(sizeof(char *) * len);
  651. if (!aliases)
  652. goto out_enomem;
  653. pmu = NULL;
  654. j = 0;
  655. while ((pmu = perf_pmu__scan(pmu)) != NULL) {
  656. list_for_each_entry(alias, &pmu->aliases, list) {
  657. char *name = format_alias(buf, sizeof(buf), pmu, alias);
  658. bool is_cpu = !strcmp(pmu->name, "cpu");
  659. if (event_glob != NULL &&
  660. !(strglobmatch(name, event_glob) ||
  661. (!is_cpu && strglobmatch(alias->name,
  662. event_glob))))
  663. continue;
  664. if (is_cpu && !name_only)
  665. name = format_alias_or(buf, sizeof(buf), pmu, alias);
  666. aliases[j] = strdup(name);
  667. if (aliases[j] == NULL)
  668. goto out_enomem;
  669. j++;
  670. }
  671. if (pmu->selectable) {
  672. char *s;
  673. if (asprintf(&s, "%s//", pmu->name) < 0)
  674. goto out_enomem;
  675. aliases[j] = s;
  676. j++;
  677. }
  678. }
  679. len = j;
  680. qsort(aliases, len, sizeof(char *), cmp_string);
  681. for (j = 0; j < len; j++) {
  682. if (name_only) {
  683. printf("%s ", aliases[j]);
  684. continue;
  685. }
  686. printf(" %-50s [Kernel PMU event]\n", aliases[j]);
  687. printed++;
  688. }
  689. if (printed)
  690. printf("\n");
  691. out_free:
  692. for (j = 0; j < len; j++)
  693. zfree(&aliases[j]);
  694. zfree(&aliases);
  695. return;
  696. out_enomem:
  697. printf("FATAL: not enough memory to print PMU events\n");
  698. if (aliases)
  699. goto out_free;
  700. }
  701. bool pmu_have_event(const char *pname, const char *name)
  702. {
  703. struct perf_pmu *pmu;
  704. struct perf_pmu_alias *alias;
  705. pmu = NULL;
  706. while ((pmu = perf_pmu__scan(pmu)) != NULL) {
  707. if (strcmp(pname, pmu->name))
  708. continue;
  709. list_for_each_entry(alias, &pmu->aliases, list)
  710. if (!strcmp(alias->name, name))
  711. return true;
  712. }
  713. return false;
  714. }
  715. static FILE *perf_pmu__open_file(struct perf_pmu *pmu, const char *name)
  716. {
  717. struct stat st;
  718. char path[PATH_MAX];
  719. const char *sysfs;
  720. sysfs = sysfs__mountpoint();
  721. if (!sysfs)
  722. return NULL;
  723. snprintf(path, PATH_MAX,
  724. "%s" EVENT_SOURCE_DEVICE_PATH "%s/%s", sysfs, pmu->name, name);
  725. if (stat(path, &st) < 0)
  726. return NULL;
  727. return fopen(path, "r");
  728. }
  729. int perf_pmu__scan_file(struct perf_pmu *pmu, const char *name, const char *fmt,
  730. ...)
  731. {
  732. va_list args;
  733. FILE *file;
  734. int ret = EOF;
  735. va_start(args, fmt);
  736. file = perf_pmu__open_file(pmu, name);
  737. if (file) {
  738. ret = vfscanf(file, fmt, args);
  739. fclose(file);
  740. }
  741. va_end(args);
  742. return ret;
  743. }