pmu.c 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536
  1. // SPDX-License-Identifier: GPL-2.0
  2. #include <linux/list.h>
  3. #include <linux/compiler.h>
  4. #include <sys/types.h>
  5. #include <errno.h>
  6. #include <fcntl.h>
  7. #include <sys/stat.h>
  8. #include <unistd.h>
  9. #include <stdio.h>
  10. #include <stdbool.h>
  11. #include <stdarg.h>
  12. #include <dirent.h>
  13. #include <api/fs/fs.h>
  14. #include <locale.h>
  15. #include <regex.h>
  16. #include "util.h"
  17. #include "pmu.h"
  18. #include "parse-events.h"
  19. #include "cpumap.h"
  20. #include "header.h"
  21. #include "pmu-events/pmu-events.h"
  22. #include "cache.h"
  23. #include "string2.h"
  24. struct perf_pmu_format {
  25. char *name;
  26. int value;
  27. DECLARE_BITMAP(bits, PERF_PMU_FORMAT_BITS);
  28. struct list_head list;
  29. };
  30. #define EVENT_SOURCE_DEVICE_PATH "/bus/event_source/devices/"
  31. int perf_pmu_parse(struct list_head *list, char *name);
  32. extern FILE *perf_pmu_in;
  33. static LIST_HEAD(pmus);
  34. /*
  35. * Parse & process all the sysfs attributes located under
  36. * the directory specified in 'dir' parameter.
  37. */
  38. int perf_pmu__format_parse(char *dir, struct list_head *head)
  39. {
  40. struct dirent *evt_ent;
  41. DIR *format_dir;
  42. int ret = 0;
  43. format_dir = opendir(dir);
  44. if (!format_dir)
  45. return -EINVAL;
  46. while (!ret && (evt_ent = readdir(format_dir))) {
  47. char path[PATH_MAX];
  48. char *name = evt_ent->d_name;
  49. FILE *file;
  50. if (!strcmp(name, ".") || !strcmp(name, ".."))
  51. continue;
  52. snprintf(path, PATH_MAX, "%s/%s", dir, name);
  53. ret = -EINVAL;
  54. file = fopen(path, "r");
  55. if (!file)
  56. break;
  57. perf_pmu_in = file;
  58. ret = perf_pmu_parse(head, name);
  59. fclose(file);
  60. }
  61. closedir(format_dir);
  62. return ret;
  63. }
  64. /*
  65. * Reading/parsing the default pmu format definition, which should be
  66. * located at:
  67. * /sys/bus/event_source/devices/<dev>/format as sysfs group attributes.
  68. */
  69. static int pmu_format(const char *name, struct list_head *format)
  70. {
  71. struct stat st;
  72. char path[PATH_MAX];
  73. const char *sysfs = sysfs__mountpoint();
  74. if (!sysfs)
  75. return -1;
  76. snprintf(path, PATH_MAX,
  77. "%s" EVENT_SOURCE_DEVICE_PATH "%s/format", sysfs, name);
  78. if (stat(path, &st) < 0)
  79. return 0; /* no error if format does not exist */
  80. if (perf_pmu__format_parse(path, format))
  81. return -1;
  82. return 0;
  83. }
  84. static int convert_scale(const char *scale, char **end, double *sval)
  85. {
  86. char *lc;
  87. int ret = 0;
  88. /*
  89. * save current locale
  90. */
  91. lc = setlocale(LC_NUMERIC, NULL);
  92. /*
  93. * The lc string may be allocated in static storage,
  94. * so get a dynamic copy to make it survive setlocale
  95. * call below.
  96. */
  97. lc = strdup(lc);
  98. if (!lc) {
  99. ret = -ENOMEM;
  100. goto out;
  101. }
  102. /*
  103. * force to C locale to ensure kernel
  104. * scale string is converted correctly.
  105. * kernel uses default C locale.
  106. */
  107. setlocale(LC_NUMERIC, "C");
  108. *sval = strtod(scale, end);
  109. out:
  110. /* restore locale */
  111. setlocale(LC_NUMERIC, lc);
  112. free(lc);
  113. return ret;
  114. }
  115. static int perf_pmu__parse_scale(struct perf_pmu_alias *alias, char *dir, char *name)
  116. {
  117. struct stat st;
  118. ssize_t sret;
  119. char scale[128];
  120. int fd, ret = -1;
  121. char path[PATH_MAX];
  122. snprintf(path, PATH_MAX, "%s/%s.scale", dir, name);
  123. fd = open(path, O_RDONLY);
  124. if (fd == -1)
  125. return -1;
  126. if (fstat(fd, &st) < 0)
  127. goto error;
  128. sret = read(fd, scale, sizeof(scale)-1);
  129. if (sret < 0)
  130. goto error;
  131. if (scale[sret - 1] == '\n')
  132. scale[sret - 1] = '\0';
  133. else
  134. scale[sret] = '\0';
  135. ret = convert_scale(scale, NULL, &alias->scale);
  136. error:
  137. close(fd);
  138. return ret;
  139. }
  140. static int perf_pmu__parse_unit(struct perf_pmu_alias *alias, char *dir, char *name)
  141. {
  142. char path[PATH_MAX];
  143. ssize_t sret;
  144. int fd;
  145. snprintf(path, PATH_MAX, "%s/%s.unit", dir, name);
  146. fd = open(path, O_RDONLY);
  147. if (fd == -1)
  148. return -1;
  149. sret = read(fd, alias->unit, UNIT_MAX_LEN);
  150. if (sret < 0)
  151. goto error;
  152. close(fd);
  153. if (alias->unit[sret - 1] == '\n')
  154. alias->unit[sret - 1] = '\0';
  155. else
  156. alias->unit[sret] = '\0';
  157. return 0;
  158. error:
  159. close(fd);
  160. alias->unit[0] = '\0';
  161. return -1;
  162. }
  163. static int
  164. perf_pmu__parse_per_pkg(struct perf_pmu_alias *alias, char *dir, char *name)
  165. {
  166. char path[PATH_MAX];
  167. int fd;
  168. snprintf(path, PATH_MAX, "%s/%s.per-pkg", dir, name);
  169. fd = open(path, O_RDONLY);
  170. if (fd == -1)
  171. return -1;
  172. close(fd);
  173. alias->per_pkg = true;
  174. return 0;
  175. }
  176. static int perf_pmu__parse_snapshot(struct perf_pmu_alias *alias,
  177. char *dir, char *name)
  178. {
  179. char path[PATH_MAX];
  180. int fd;
  181. snprintf(path, PATH_MAX, "%s/%s.snapshot", dir, name);
  182. fd = open(path, O_RDONLY);
  183. if (fd == -1)
  184. return -1;
  185. alias->snapshot = true;
  186. close(fd);
  187. return 0;
  188. }
  189. static void perf_pmu_assign_str(char *name, const char *field, char **old_str,
  190. char **new_str)
  191. {
  192. if (!*old_str)
  193. goto set_new;
  194. if (*new_str) { /* Have new string, check with old */
  195. if (strcasecmp(*old_str, *new_str))
  196. pr_debug("alias %s differs in field '%s'\n",
  197. name, field);
  198. zfree(old_str);
  199. } else /* Nothing new --> keep old string */
  200. return;
  201. set_new:
  202. *old_str = *new_str;
  203. *new_str = NULL;
  204. }
  205. static void perf_pmu_update_alias(struct perf_pmu_alias *old,
  206. struct perf_pmu_alias *newalias)
  207. {
  208. perf_pmu_assign_str(old->name, "desc", &old->desc, &newalias->desc);
  209. perf_pmu_assign_str(old->name, "long_desc", &old->long_desc,
  210. &newalias->long_desc);
  211. perf_pmu_assign_str(old->name, "topic", &old->topic, &newalias->topic);
  212. perf_pmu_assign_str(old->name, "metric_expr", &old->metric_expr,
  213. &newalias->metric_expr);
  214. perf_pmu_assign_str(old->name, "metric_name", &old->metric_name,
  215. &newalias->metric_name);
  216. perf_pmu_assign_str(old->name, "value", &old->str, &newalias->str);
  217. old->scale = newalias->scale;
  218. old->per_pkg = newalias->per_pkg;
  219. old->snapshot = newalias->snapshot;
  220. memcpy(old->unit, newalias->unit, sizeof(old->unit));
  221. }
  222. /* Delete an alias entry. */
  223. static void perf_pmu_free_alias(struct perf_pmu_alias *newalias)
  224. {
  225. zfree(&newalias->name);
  226. zfree(&newalias->desc);
  227. zfree(&newalias->long_desc);
  228. zfree(&newalias->topic);
  229. zfree(&newalias->str);
  230. zfree(&newalias->metric_expr);
  231. zfree(&newalias->metric_name);
  232. parse_events_terms__purge(&newalias->terms);
  233. free(newalias);
  234. }
  235. /* Merge an alias, search in alias list. If this name is already
  236. * present merge both of them to combine all information.
  237. */
  238. static bool perf_pmu_merge_alias(struct perf_pmu_alias *newalias,
  239. struct list_head *alist)
  240. {
  241. struct perf_pmu_alias *a;
  242. list_for_each_entry(a, alist, list) {
  243. if (!strcasecmp(newalias->name, a->name)) {
  244. perf_pmu_update_alias(a, newalias);
  245. perf_pmu_free_alias(newalias);
  246. return true;
  247. }
  248. }
  249. return false;
  250. }
  251. static int __perf_pmu__new_alias(struct list_head *list, char *dir, char *name,
  252. char *desc, char *val,
  253. char *long_desc, char *topic,
  254. char *unit, char *perpkg,
  255. char *metric_expr,
  256. char *metric_name)
  257. {
  258. struct parse_events_term *term;
  259. struct perf_pmu_alias *alias;
  260. int ret;
  261. int num;
  262. char newval[256];
  263. alias = malloc(sizeof(*alias));
  264. if (!alias)
  265. return -ENOMEM;
  266. INIT_LIST_HEAD(&alias->terms);
  267. alias->scale = 1.0;
  268. alias->unit[0] = '\0';
  269. alias->per_pkg = false;
  270. alias->snapshot = false;
  271. ret = parse_events_terms(&alias->terms, val);
  272. if (ret) {
  273. pr_err("Cannot parse alias %s: %d\n", val, ret);
  274. free(alias);
  275. return ret;
  276. }
  277. /* Scan event and remove leading zeroes, spaces, newlines, some
  278. * platforms have terms specified as
  279. * event=0x0091 (read from files ../<PMU>/events/<FILE>
  280. * and terms specified as event=0x91 (read from JSON files).
  281. *
  282. * Rebuild string to make alias->str member comparable.
  283. */
  284. memset(newval, 0, sizeof(newval));
  285. ret = 0;
  286. list_for_each_entry(term, &alias->terms, list) {
  287. if (ret)
  288. ret += scnprintf(newval + ret, sizeof(newval) - ret,
  289. ",");
  290. if (term->type_val == PARSE_EVENTS__TERM_TYPE_NUM)
  291. ret += scnprintf(newval + ret, sizeof(newval) - ret,
  292. "%s=%#x", term->config, term->val.num);
  293. else if (term->type_val == PARSE_EVENTS__TERM_TYPE_STR)
  294. ret += scnprintf(newval + ret, sizeof(newval) - ret,
  295. "%s=%s", term->config, term->val.str);
  296. }
  297. alias->name = strdup(name);
  298. if (dir) {
  299. /*
  300. * load unit name and scale if available
  301. */
  302. perf_pmu__parse_unit(alias, dir, name);
  303. perf_pmu__parse_scale(alias, dir, name);
  304. perf_pmu__parse_per_pkg(alias, dir, name);
  305. perf_pmu__parse_snapshot(alias, dir, name);
  306. }
  307. alias->metric_expr = metric_expr ? strdup(metric_expr) : NULL;
  308. alias->metric_name = metric_name ? strdup(metric_name): NULL;
  309. alias->desc = desc ? strdup(desc) : NULL;
  310. alias->long_desc = long_desc ? strdup(long_desc) :
  311. desc ? strdup(desc) : NULL;
  312. alias->topic = topic ? strdup(topic) : NULL;
  313. if (unit) {
  314. if (convert_scale(unit, &unit, &alias->scale) < 0)
  315. return -1;
  316. snprintf(alias->unit, sizeof(alias->unit), "%s", unit);
  317. }
  318. alias->per_pkg = perpkg && sscanf(perpkg, "%d", &num) == 1 && num == 1;
  319. alias->str = strdup(newval);
  320. if (!perf_pmu_merge_alias(alias, list))
  321. list_add_tail(&alias->list, list);
  322. return 0;
  323. }
  324. static int perf_pmu__new_alias(struct list_head *list, char *dir, char *name, FILE *file)
  325. {
  326. char buf[256];
  327. int ret;
  328. ret = fread(buf, 1, sizeof(buf), file);
  329. if (ret == 0)
  330. return -EINVAL;
  331. buf[ret] = 0;
  332. /* Remove trailing newline from sysfs file */
  333. rtrim(buf);
  334. return __perf_pmu__new_alias(list, dir, name, NULL, buf, NULL, NULL, NULL,
  335. NULL, NULL, NULL);
  336. }
  337. static inline bool pmu_alias_info_file(char *name)
  338. {
  339. size_t len;
  340. len = strlen(name);
  341. if (len > 5 && !strcmp(name + len - 5, ".unit"))
  342. return true;
  343. if (len > 6 && !strcmp(name + len - 6, ".scale"))
  344. return true;
  345. if (len > 8 && !strcmp(name + len - 8, ".per-pkg"))
  346. return true;
  347. if (len > 9 && !strcmp(name + len - 9, ".snapshot"))
  348. return true;
  349. return false;
  350. }
  351. /*
  352. * Process all the sysfs attributes located under the directory
  353. * specified in 'dir' parameter.
  354. */
  355. static int pmu_aliases_parse(char *dir, struct list_head *head)
  356. {
  357. struct dirent *evt_ent;
  358. DIR *event_dir;
  359. event_dir = opendir(dir);
  360. if (!event_dir)
  361. return -EINVAL;
  362. while ((evt_ent = readdir(event_dir))) {
  363. char path[PATH_MAX];
  364. char *name = evt_ent->d_name;
  365. FILE *file;
  366. if (!strcmp(name, ".") || !strcmp(name, ".."))
  367. continue;
  368. /*
  369. * skip info files parsed in perf_pmu__new_alias()
  370. */
  371. if (pmu_alias_info_file(name))
  372. continue;
  373. scnprintf(path, PATH_MAX, "%s/%s", dir, name);
  374. file = fopen(path, "r");
  375. if (!file) {
  376. pr_debug("Cannot open %s\n", path);
  377. continue;
  378. }
  379. if (perf_pmu__new_alias(head, dir, name, file) < 0)
  380. pr_debug("Cannot set up %s\n", name);
  381. fclose(file);
  382. }
  383. closedir(event_dir);
  384. return 0;
  385. }
  386. /*
  387. * Reading the pmu event aliases definition, which should be located at:
  388. * /sys/bus/event_source/devices/<dev>/events as sysfs group attributes.
  389. */
  390. static int pmu_aliases(const char *name, struct list_head *head)
  391. {
  392. struct stat st;
  393. char path[PATH_MAX];
  394. const char *sysfs = sysfs__mountpoint();
  395. if (!sysfs)
  396. return -1;
  397. snprintf(path, PATH_MAX,
  398. "%s/bus/event_source/devices/%s/events", sysfs, name);
  399. if (stat(path, &st) < 0)
  400. return 0; /* no error if 'events' does not exist */
  401. if (pmu_aliases_parse(path, head))
  402. return -1;
  403. return 0;
  404. }
  405. static int pmu_alias_terms(struct perf_pmu_alias *alias,
  406. struct list_head *terms)
  407. {
  408. struct parse_events_term *term, *cloned;
  409. LIST_HEAD(list);
  410. int ret;
  411. list_for_each_entry(term, &alias->terms, list) {
  412. ret = parse_events_term__clone(&cloned, term);
  413. if (ret) {
  414. parse_events_terms__purge(&list);
  415. return ret;
  416. }
  417. /*
  418. * Weak terms don't override command line options,
  419. * which we don't want for implicit terms in aliases.
  420. */
  421. cloned->weak = true;
  422. list_add_tail(&cloned->list, &list);
  423. }
  424. list_splice(&list, terms);
  425. return 0;
  426. }
  427. /*
  428. * Reading/parsing the default pmu type value, which should be
  429. * located at:
  430. * /sys/bus/event_source/devices/<dev>/type as sysfs attribute.
  431. */
  432. static int pmu_type(const char *name, __u32 *type)
  433. {
  434. struct stat st;
  435. char path[PATH_MAX];
  436. FILE *file;
  437. int ret = 0;
  438. const char *sysfs = sysfs__mountpoint();
  439. if (!sysfs)
  440. return -1;
  441. snprintf(path, PATH_MAX,
  442. "%s" EVENT_SOURCE_DEVICE_PATH "%s/type", sysfs, name);
  443. if (stat(path, &st) < 0)
  444. return -1;
  445. file = fopen(path, "r");
  446. if (!file)
  447. return -EINVAL;
  448. if (1 != fscanf(file, "%u", type))
  449. ret = -1;
  450. fclose(file);
  451. return ret;
  452. }
  453. /* Add all pmus in sysfs to pmu list: */
  454. static void pmu_read_sysfs(void)
  455. {
  456. char path[PATH_MAX];
  457. DIR *dir;
  458. struct dirent *dent;
  459. const char *sysfs = sysfs__mountpoint();
  460. if (!sysfs)
  461. return;
  462. snprintf(path, PATH_MAX,
  463. "%s" EVENT_SOURCE_DEVICE_PATH, sysfs);
  464. dir = opendir(path);
  465. if (!dir)
  466. return;
  467. while ((dent = readdir(dir))) {
  468. if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, ".."))
  469. continue;
  470. /* add to static LIST_HEAD(pmus): */
  471. perf_pmu__find(dent->d_name);
  472. }
  473. closedir(dir);
  474. }
  475. static struct cpu_map *__pmu_cpumask(const char *path)
  476. {
  477. FILE *file;
  478. struct cpu_map *cpus;
  479. file = fopen(path, "r");
  480. if (!file)
  481. return NULL;
  482. cpus = cpu_map__read(file);
  483. fclose(file);
  484. return cpus;
  485. }
  486. /*
  487. * Uncore PMUs have a "cpumask" file under sysfs. CPU PMUs (e.g. on arm/arm64)
  488. * may have a "cpus" file.
  489. */
  490. #define CPUS_TEMPLATE_UNCORE "%s/bus/event_source/devices/%s/cpumask"
  491. #define CPUS_TEMPLATE_CPU "%s/bus/event_source/devices/%s/cpus"
  492. static struct cpu_map *pmu_cpumask(const char *name)
  493. {
  494. char path[PATH_MAX];
  495. struct cpu_map *cpus;
  496. const char *sysfs = sysfs__mountpoint();
  497. const char *templates[] = {
  498. CPUS_TEMPLATE_UNCORE,
  499. CPUS_TEMPLATE_CPU,
  500. NULL
  501. };
  502. const char **template;
  503. if (!sysfs)
  504. return NULL;
  505. for (template = templates; *template; template++) {
  506. snprintf(path, PATH_MAX, *template, sysfs, name);
  507. cpus = __pmu_cpumask(path);
  508. if (cpus)
  509. return cpus;
  510. }
  511. return NULL;
  512. }
  513. static bool pmu_is_uncore(const char *name)
  514. {
  515. char path[PATH_MAX];
  516. struct cpu_map *cpus;
  517. const char *sysfs = sysfs__mountpoint();
  518. snprintf(path, PATH_MAX, CPUS_TEMPLATE_UNCORE, sysfs, name);
  519. cpus = __pmu_cpumask(path);
  520. cpu_map__put(cpus);
  521. return !!cpus;
  522. }
  523. /*
  524. * PMU CORE devices have different name other than cpu in sysfs on some
  525. * platforms.
  526. * Looking for possible sysfs files to identify the arm core device.
  527. */
  528. static int is_arm_pmu_core(const char *name)
  529. {
  530. struct stat st;
  531. char path[PATH_MAX];
  532. const char *sysfs = sysfs__mountpoint();
  533. if (!sysfs)
  534. return 0;
  535. /* Look for cpu sysfs (specific to arm) */
  536. scnprintf(path, PATH_MAX, "%s/bus/event_source/devices/%s/cpus",
  537. sysfs, name);
  538. if (stat(path, &st) == 0)
  539. return 1;
  540. return 0;
  541. }
  542. /*
  543. * Return the CPU id as a raw string.
  544. *
  545. * Each architecture should provide a more precise id string that
  546. * can be use to match the architecture's "mapfile".
  547. */
  548. char * __weak get_cpuid_str(struct perf_pmu *pmu __maybe_unused)
  549. {
  550. return NULL;
  551. }
  552. /* Return zero when the cpuid from the mapfile.csv matches the
  553. * cpuid string generated on this platform.
  554. * Otherwise return non-zero.
  555. */
  556. int strcmp_cpuid_str(const char *mapcpuid, const char *cpuid)
  557. {
  558. regex_t re;
  559. regmatch_t pmatch[1];
  560. int match;
  561. if (regcomp(&re, mapcpuid, REG_EXTENDED) != 0) {
  562. /* Warn unable to generate match particular string. */
  563. pr_info("Invalid regular expression %s\n", mapcpuid);
  564. return 1;
  565. }
  566. match = !regexec(&re, cpuid, 1, pmatch, 0);
  567. regfree(&re);
  568. if (match) {
  569. size_t match_len = (pmatch[0].rm_eo - pmatch[0].rm_so);
  570. /* Verify the entire string matched. */
  571. if (match_len == strlen(cpuid))
  572. return 0;
  573. }
  574. return 1;
  575. }
  576. static char *perf_pmu__getcpuid(struct perf_pmu *pmu)
  577. {
  578. char *cpuid;
  579. static bool printed;
  580. cpuid = getenv("PERF_CPUID");
  581. if (cpuid)
  582. cpuid = strdup(cpuid);
  583. if (!cpuid)
  584. cpuid = get_cpuid_str(pmu);
  585. if (!cpuid)
  586. return NULL;
  587. if (!printed) {
  588. pr_debug("Using CPUID %s\n", cpuid);
  589. printed = true;
  590. }
  591. return cpuid;
  592. }
  593. struct pmu_events_map *perf_pmu__find_map(struct perf_pmu *pmu)
  594. {
  595. struct pmu_events_map *map;
  596. char *cpuid = perf_pmu__getcpuid(pmu);
  597. int i;
  598. /* on some platforms which uses cpus map, cpuid can be NULL for
  599. * PMUs other than CORE PMUs.
  600. */
  601. if (!cpuid)
  602. return NULL;
  603. i = 0;
  604. for (;;) {
  605. map = &pmu_events_map[i++];
  606. if (!map->table) {
  607. map = NULL;
  608. break;
  609. }
  610. if (!strcmp_cpuid_str(map->cpuid, cpuid))
  611. break;
  612. }
  613. free(cpuid);
  614. return map;
  615. }
  616. /*
  617. * From the pmu_events_map, find the table of PMU events that corresponds
  618. * to the current running CPU. Then, add all PMU events from that table
  619. * as aliases.
  620. */
  621. static void pmu_add_cpu_aliases(struct list_head *head, struct perf_pmu *pmu)
  622. {
  623. int i;
  624. struct pmu_events_map *map;
  625. struct pmu_event *pe;
  626. const char *name = pmu->name;
  627. const char *pname;
  628. map = perf_pmu__find_map(pmu);
  629. if (!map)
  630. return;
  631. /*
  632. * Found a matching PMU events table. Create aliases
  633. */
  634. i = 0;
  635. while (1) {
  636. pe = &map->table[i++];
  637. if (!pe->name) {
  638. if (pe->metric_group || pe->metric_name)
  639. continue;
  640. break;
  641. }
  642. if (!is_arm_pmu_core(name)) {
  643. pname = pe->pmu ? pe->pmu : "cpu";
  644. if (strcmp(pname, name))
  645. continue;
  646. }
  647. /* need type casts to override 'const' */
  648. __perf_pmu__new_alias(head, NULL, (char *)pe->name,
  649. (char *)pe->desc, (char *)pe->event,
  650. (char *)pe->long_desc, (char *)pe->topic,
  651. (char *)pe->unit, (char *)pe->perpkg,
  652. (char *)pe->metric_expr,
  653. (char *)pe->metric_name);
  654. }
  655. }
  656. struct perf_event_attr * __weak
  657. perf_pmu__get_default_config(struct perf_pmu *pmu __maybe_unused)
  658. {
  659. return NULL;
  660. }
  661. static struct perf_pmu *pmu_lookup(const char *name)
  662. {
  663. struct perf_pmu *pmu;
  664. LIST_HEAD(format);
  665. LIST_HEAD(aliases);
  666. __u32 type;
  667. /*
  668. * The pmu data we store & need consists of the pmu
  669. * type value and format definitions. Load both right
  670. * now.
  671. */
  672. if (pmu_format(name, &format))
  673. return NULL;
  674. /*
  675. * Check the type first to avoid unnecessary work.
  676. */
  677. if (pmu_type(name, &type))
  678. return NULL;
  679. if (pmu_aliases(name, &aliases))
  680. return NULL;
  681. pmu = zalloc(sizeof(*pmu));
  682. if (!pmu)
  683. return NULL;
  684. pmu->cpus = pmu_cpumask(name);
  685. pmu->name = strdup(name);
  686. pmu->type = type;
  687. pmu->is_uncore = pmu_is_uncore(name);
  688. pmu_add_cpu_aliases(&aliases, pmu);
  689. INIT_LIST_HEAD(&pmu->format);
  690. INIT_LIST_HEAD(&pmu->aliases);
  691. list_splice(&format, &pmu->format);
  692. list_splice(&aliases, &pmu->aliases);
  693. list_add_tail(&pmu->list, &pmus);
  694. pmu->default_config = perf_pmu__get_default_config(pmu);
  695. return pmu;
  696. }
  697. static struct perf_pmu *pmu_find(const char *name)
  698. {
  699. struct perf_pmu *pmu;
  700. list_for_each_entry(pmu, &pmus, list)
  701. if (!strcmp(pmu->name, name))
  702. return pmu;
  703. return NULL;
  704. }
  705. struct perf_pmu *perf_pmu__scan(struct perf_pmu *pmu)
  706. {
  707. /*
  708. * pmu iterator: If pmu is NULL, we start at the begin,
  709. * otherwise return the next pmu. Returns NULL on end.
  710. */
  711. if (!pmu) {
  712. pmu_read_sysfs();
  713. pmu = list_prepare_entry(pmu, &pmus, list);
  714. }
  715. list_for_each_entry_continue(pmu, &pmus, list)
  716. return pmu;
  717. return NULL;
  718. }
  719. struct perf_pmu *perf_pmu__find(const char *name)
  720. {
  721. struct perf_pmu *pmu;
  722. /*
  723. * Once PMU is loaded it stays in the list,
  724. * so we keep us from multiple reading/parsing
  725. * the pmu format definitions.
  726. */
  727. pmu = pmu_find(name);
  728. if (pmu)
  729. return pmu;
  730. return pmu_lookup(name);
  731. }
  732. static struct perf_pmu_format *
  733. pmu_find_format(struct list_head *formats, const char *name)
  734. {
  735. struct perf_pmu_format *format;
  736. list_for_each_entry(format, formats, list)
  737. if (!strcmp(format->name, name))
  738. return format;
  739. return NULL;
  740. }
  741. __u64 perf_pmu__format_bits(struct list_head *formats, const char *name)
  742. {
  743. struct perf_pmu_format *format = pmu_find_format(formats, name);
  744. __u64 bits = 0;
  745. int fbit;
  746. if (!format)
  747. return 0;
  748. for_each_set_bit(fbit, format->bits, PERF_PMU_FORMAT_BITS)
  749. bits |= 1ULL << fbit;
  750. return bits;
  751. }
  752. /*
  753. * Sets value based on the format definition (format parameter)
  754. * and unformated value (value parameter).
  755. */
  756. static void pmu_format_value(unsigned long *format, __u64 value, __u64 *v,
  757. bool zero)
  758. {
  759. unsigned long fbit, vbit;
  760. for (fbit = 0, vbit = 0; fbit < PERF_PMU_FORMAT_BITS; fbit++) {
  761. if (!test_bit(fbit, format))
  762. continue;
  763. if (value & (1llu << vbit++))
  764. *v |= (1llu << fbit);
  765. else if (zero)
  766. *v &= ~(1llu << fbit);
  767. }
  768. }
  769. static __u64 pmu_format_max_value(const unsigned long *format)
  770. {
  771. int w;
  772. w = bitmap_weight(format, PERF_PMU_FORMAT_BITS);
  773. if (!w)
  774. return 0;
  775. if (w < 64)
  776. return (1ULL << w) - 1;
  777. return -1;
  778. }
  779. /*
  780. * Term is a string term, and might be a param-term. Try to look up it's value
  781. * in the remaining terms.
  782. * - We have a term like "base-or-format-term=param-term",
  783. * - We need to find the value supplied for "param-term" (with param-term named
  784. * in a config string) later on in the term list.
  785. */
  786. static int pmu_resolve_param_term(struct parse_events_term *term,
  787. struct list_head *head_terms,
  788. __u64 *value)
  789. {
  790. struct parse_events_term *t;
  791. list_for_each_entry(t, head_terms, list) {
  792. if (t->type_val == PARSE_EVENTS__TERM_TYPE_NUM) {
  793. if (!strcmp(t->config, term->config)) {
  794. t->used = true;
  795. *value = t->val.num;
  796. return 0;
  797. }
  798. }
  799. }
  800. if (verbose > 0)
  801. printf("Required parameter '%s' not specified\n", term->config);
  802. return -1;
  803. }
  804. static char *pmu_formats_string(struct list_head *formats)
  805. {
  806. struct perf_pmu_format *format;
  807. char *str = NULL;
  808. struct strbuf buf = STRBUF_INIT;
  809. unsigned i = 0;
  810. if (!formats)
  811. return NULL;
  812. /* sysfs exported terms */
  813. list_for_each_entry(format, formats, list)
  814. if (strbuf_addf(&buf, i++ ? ",%s" : "%s", format->name) < 0)
  815. goto error;
  816. str = strbuf_detach(&buf, NULL);
  817. error:
  818. strbuf_release(&buf);
  819. return str;
  820. }
  821. /*
  822. * Setup one of config[12] attr members based on the
  823. * user input data - term parameter.
  824. */
  825. static int pmu_config_term(struct list_head *formats,
  826. struct perf_event_attr *attr,
  827. struct parse_events_term *term,
  828. struct list_head *head_terms,
  829. bool zero, struct parse_events_error *err)
  830. {
  831. struct perf_pmu_format *format;
  832. __u64 *vp;
  833. __u64 val, max_val;
  834. /*
  835. * If this is a parameter we've already used for parameterized-eval,
  836. * skip it in normal eval.
  837. */
  838. if (term->used)
  839. return 0;
  840. /*
  841. * Hardcoded terms should be already in, so nothing
  842. * to be done for them.
  843. */
  844. if (parse_events__is_hardcoded_term(term))
  845. return 0;
  846. format = pmu_find_format(formats, term->config);
  847. if (!format) {
  848. if (verbose > 0)
  849. printf("Invalid event/parameter '%s'\n", term->config);
  850. if (err) {
  851. char *pmu_term = pmu_formats_string(formats);
  852. err->idx = term->err_term;
  853. err->str = strdup("unknown term");
  854. err->help = parse_events_formats_error_string(pmu_term);
  855. free(pmu_term);
  856. }
  857. return -EINVAL;
  858. }
  859. switch (format->value) {
  860. case PERF_PMU_FORMAT_VALUE_CONFIG:
  861. vp = &attr->config;
  862. break;
  863. case PERF_PMU_FORMAT_VALUE_CONFIG1:
  864. vp = &attr->config1;
  865. break;
  866. case PERF_PMU_FORMAT_VALUE_CONFIG2:
  867. vp = &attr->config2;
  868. break;
  869. default:
  870. return -EINVAL;
  871. }
  872. /*
  873. * Either directly use a numeric term, or try to translate string terms
  874. * using event parameters.
  875. */
  876. if (term->type_val == PARSE_EVENTS__TERM_TYPE_NUM) {
  877. if (term->no_value &&
  878. bitmap_weight(format->bits, PERF_PMU_FORMAT_BITS) > 1) {
  879. if (err) {
  880. err->idx = term->err_val;
  881. err->str = strdup("no value assigned for term");
  882. }
  883. return -EINVAL;
  884. }
  885. val = term->val.num;
  886. } else if (term->type_val == PARSE_EVENTS__TERM_TYPE_STR) {
  887. if (strcmp(term->val.str, "?")) {
  888. if (verbose > 0) {
  889. pr_info("Invalid sysfs entry %s=%s\n",
  890. term->config, term->val.str);
  891. }
  892. if (err) {
  893. err->idx = term->err_val;
  894. err->str = strdup("expected numeric value");
  895. }
  896. return -EINVAL;
  897. }
  898. if (pmu_resolve_param_term(term, head_terms, &val))
  899. return -EINVAL;
  900. } else
  901. return -EINVAL;
  902. max_val = pmu_format_max_value(format->bits);
  903. if (val > max_val) {
  904. if (err) {
  905. err->idx = term->err_val;
  906. if (asprintf(&err->str,
  907. "value too big for format, maximum is %llu",
  908. (unsigned long long)max_val) < 0)
  909. err->str = strdup("value too big for format");
  910. return -EINVAL;
  911. }
  912. /*
  913. * Assume we don't care if !err, in which case the value will be
  914. * silently truncated.
  915. */
  916. }
  917. pmu_format_value(format->bits, val, vp, zero);
  918. return 0;
  919. }
  920. int perf_pmu__config_terms(struct list_head *formats,
  921. struct perf_event_attr *attr,
  922. struct list_head *head_terms,
  923. bool zero, struct parse_events_error *err)
  924. {
  925. struct parse_events_term *term;
  926. list_for_each_entry(term, head_terms, list) {
  927. if (pmu_config_term(formats, attr, term, head_terms,
  928. zero, err))
  929. return -EINVAL;
  930. }
  931. return 0;
  932. }
  933. /*
  934. * Configures event's 'attr' parameter based on the:
  935. * 1) users input - specified in terms parameter
  936. * 2) pmu format definitions - specified by pmu parameter
  937. */
  938. int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr,
  939. struct list_head *head_terms,
  940. struct parse_events_error *err)
  941. {
  942. bool zero = !!pmu->default_config;
  943. attr->type = pmu->type;
  944. return perf_pmu__config_terms(&pmu->format, attr, head_terms,
  945. zero, err);
  946. }
  947. static struct perf_pmu_alias *pmu_find_alias(struct perf_pmu *pmu,
  948. struct parse_events_term *term)
  949. {
  950. struct perf_pmu_alias *alias;
  951. char *name;
  952. if (parse_events__is_hardcoded_term(term))
  953. return NULL;
  954. if (term->type_val == PARSE_EVENTS__TERM_TYPE_NUM) {
  955. if (term->val.num != 1)
  956. return NULL;
  957. if (pmu_find_format(&pmu->format, term->config))
  958. return NULL;
  959. name = term->config;
  960. } else if (term->type_val == PARSE_EVENTS__TERM_TYPE_STR) {
  961. if (strcasecmp(term->config, "event"))
  962. return NULL;
  963. name = term->val.str;
  964. } else {
  965. return NULL;
  966. }
  967. list_for_each_entry(alias, &pmu->aliases, list) {
  968. if (!strcasecmp(alias->name, name))
  969. return alias;
  970. }
  971. return NULL;
  972. }
  973. static int check_info_data(struct perf_pmu_alias *alias,
  974. struct perf_pmu_info *info)
  975. {
  976. /*
  977. * Only one term in event definition can
  978. * define unit, scale and snapshot, fail
  979. * if there's more than one.
  980. */
  981. if ((info->unit && alias->unit[0]) ||
  982. (info->scale && alias->scale) ||
  983. (info->snapshot && alias->snapshot))
  984. return -EINVAL;
  985. if (alias->unit[0])
  986. info->unit = alias->unit;
  987. if (alias->scale)
  988. info->scale = alias->scale;
  989. if (alias->snapshot)
  990. info->snapshot = alias->snapshot;
  991. return 0;
  992. }
  993. /*
  994. * Find alias in the terms list and replace it with the terms
  995. * defined for the alias
  996. */
  997. int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms,
  998. struct perf_pmu_info *info)
  999. {
  1000. struct parse_events_term *term, *h;
  1001. struct perf_pmu_alias *alias;
  1002. int ret;
  1003. info->per_pkg = false;
  1004. /*
  1005. * Mark unit and scale as not set
  1006. * (different from default values, see below)
  1007. */
  1008. info->unit = NULL;
  1009. info->scale = 0.0;
  1010. info->snapshot = false;
  1011. info->metric_expr = NULL;
  1012. info->metric_name = NULL;
  1013. list_for_each_entry_safe(term, h, head_terms, list) {
  1014. alias = pmu_find_alias(pmu, term);
  1015. if (!alias)
  1016. continue;
  1017. ret = pmu_alias_terms(alias, &term->list);
  1018. if (ret)
  1019. return ret;
  1020. ret = check_info_data(alias, info);
  1021. if (ret)
  1022. return ret;
  1023. if (alias->per_pkg)
  1024. info->per_pkg = true;
  1025. info->metric_expr = alias->metric_expr;
  1026. info->metric_name = alias->metric_name;
  1027. list_del(&term->list);
  1028. free(term);
  1029. }
  1030. /*
  1031. * if no unit or scale foundin aliases, then
  1032. * set defaults as for evsel
  1033. * unit cannot left to NULL
  1034. */
  1035. if (info->unit == NULL)
  1036. info->unit = "";
  1037. if (info->scale == 0.0)
  1038. info->scale = 1.0;
  1039. return 0;
  1040. }
  1041. int perf_pmu__new_format(struct list_head *list, char *name,
  1042. int config, unsigned long *bits)
  1043. {
  1044. struct perf_pmu_format *format;
  1045. format = zalloc(sizeof(*format));
  1046. if (!format)
  1047. return -ENOMEM;
  1048. format->name = strdup(name);
  1049. format->value = config;
  1050. memcpy(format->bits, bits, sizeof(format->bits));
  1051. list_add_tail(&format->list, list);
  1052. return 0;
  1053. }
  1054. void perf_pmu__set_format(unsigned long *bits, long from, long to)
  1055. {
  1056. long b;
  1057. if (!to)
  1058. to = from;
  1059. memset(bits, 0, BITS_TO_BYTES(PERF_PMU_FORMAT_BITS));
  1060. for (b = from; b <= to; b++)
  1061. set_bit(b, bits);
  1062. }
  1063. static int sub_non_neg(int a, int b)
  1064. {
  1065. if (b > a)
  1066. return 0;
  1067. return a - b;
  1068. }
  1069. static char *format_alias(char *buf, int len, struct perf_pmu *pmu,
  1070. struct perf_pmu_alias *alias)
  1071. {
  1072. struct parse_events_term *term;
  1073. int used = snprintf(buf, len, "%s/%s", pmu->name, alias->name);
  1074. list_for_each_entry(term, &alias->terms, list) {
  1075. if (term->type_val == PARSE_EVENTS__TERM_TYPE_STR)
  1076. used += snprintf(buf + used, sub_non_neg(len, used),
  1077. ",%s=%s", term->config,
  1078. term->val.str);
  1079. }
  1080. if (sub_non_neg(len, used) > 0) {
  1081. buf[used] = '/';
  1082. used++;
  1083. }
  1084. if (sub_non_neg(len, used) > 0) {
  1085. buf[used] = '\0';
  1086. used++;
  1087. } else
  1088. buf[len - 1] = '\0';
  1089. return buf;
  1090. }
  1091. static char *format_alias_or(char *buf, int len, struct perf_pmu *pmu,
  1092. struct perf_pmu_alias *alias)
  1093. {
  1094. snprintf(buf, len, "%s OR %s/%s/", alias->name, pmu->name, alias->name);
  1095. return buf;
  1096. }
  1097. struct sevent {
  1098. char *name;
  1099. char *desc;
  1100. char *topic;
  1101. char *str;
  1102. char *pmu;
  1103. char *metric_expr;
  1104. char *metric_name;
  1105. };
  1106. static int cmp_sevent(const void *a, const void *b)
  1107. {
  1108. const struct sevent *as = a;
  1109. const struct sevent *bs = b;
  1110. /* Put extra events last */
  1111. if (!!as->desc != !!bs->desc)
  1112. return !!as->desc - !!bs->desc;
  1113. if (as->topic && bs->topic) {
  1114. int n = strcmp(as->topic, bs->topic);
  1115. if (n)
  1116. return n;
  1117. }
  1118. return strcmp(as->name, bs->name);
  1119. }
  1120. static void wordwrap(char *s, int start, int max, int corr)
  1121. {
  1122. int column = start;
  1123. int n;
  1124. while (*s) {
  1125. int wlen = strcspn(s, " \t");
  1126. if (column + wlen >= max && column > start) {
  1127. printf("\n%*s", start, "");
  1128. column = start + corr;
  1129. }
  1130. n = printf("%s%.*s", column > start ? " " : "", wlen, s);
  1131. if (n <= 0)
  1132. break;
  1133. s += wlen;
  1134. column += n;
  1135. s = ltrim(s);
  1136. }
  1137. }
  1138. void print_pmu_events(const char *event_glob, bool name_only, bool quiet_flag,
  1139. bool long_desc, bool details_flag)
  1140. {
  1141. struct perf_pmu *pmu;
  1142. struct perf_pmu_alias *alias;
  1143. char buf[1024];
  1144. int printed = 0;
  1145. int len, j;
  1146. struct sevent *aliases;
  1147. int numdesc = 0;
  1148. int columns = pager_get_columns();
  1149. char *topic = NULL;
  1150. pmu = NULL;
  1151. len = 0;
  1152. while ((pmu = perf_pmu__scan(pmu)) != NULL) {
  1153. list_for_each_entry(alias, &pmu->aliases, list)
  1154. len++;
  1155. if (pmu->selectable)
  1156. len++;
  1157. }
  1158. aliases = zalloc(sizeof(struct sevent) * len);
  1159. if (!aliases)
  1160. goto out_enomem;
  1161. pmu = NULL;
  1162. j = 0;
  1163. while ((pmu = perf_pmu__scan(pmu)) != NULL) {
  1164. list_for_each_entry(alias, &pmu->aliases, list) {
  1165. char *name = alias->desc ? alias->name :
  1166. format_alias(buf, sizeof(buf), pmu, alias);
  1167. bool is_cpu = !strcmp(pmu->name, "cpu");
  1168. if (event_glob != NULL &&
  1169. !(strglobmatch_nocase(name, event_glob) ||
  1170. (!is_cpu && strglobmatch_nocase(alias->name,
  1171. event_glob)) ||
  1172. (alias->topic &&
  1173. strglobmatch_nocase(alias->topic, event_glob))))
  1174. continue;
  1175. if (is_cpu && !name_only && !alias->desc)
  1176. name = format_alias_or(buf, sizeof(buf), pmu, alias);
  1177. aliases[j].name = name;
  1178. if (is_cpu && !name_only && !alias->desc)
  1179. aliases[j].name = format_alias_or(buf,
  1180. sizeof(buf),
  1181. pmu, alias);
  1182. aliases[j].name = strdup(aliases[j].name);
  1183. if (!aliases[j].name)
  1184. goto out_enomem;
  1185. aliases[j].desc = long_desc ? alias->long_desc :
  1186. alias->desc;
  1187. aliases[j].topic = alias->topic;
  1188. aliases[j].str = alias->str;
  1189. aliases[j].pmu = pmu->name;
  1190. aliases[j].metric_expr = alias->metric_expr;
  1191. aliases[j].metric_name = alias->metric_name;
  1192. j++;
  1193. }
  1194. if (pmu->selectable &&
  1195. (event_glob == NULL || strglobmatch(pmu->name, event_glob))) {
  1196. char *s;
  1197. if (asprintf(&s, "%s//", pmu->name) < 0)
  1198. goto out_enomem;
  1199. aliases[j].name = s;
  1200. j++;
  1201. }
  1202. }
  1203. len = j;
  1204. qsort(aliases, len, sizeof(struct sevent), cmp_sevent);
  1205. for (j = 0; j < len; j++) {
  1206. /* Skip duplicates */
  1207. if (j > 0 && !strcmp(aliases[j].name, aliases[j - 1].name))
  1208. continue;
  1209. if (name_only) {
  1210. printf("%s ", aliases[j].name);
  1211. continue;
  1212. }
  1213. if (aliases[j].desc && !quiet_flag) {
  1214. if (numdesc++ == 0)
  1215. printf("\n");
  1216. if (aliases[j].topic && (!topic ||
  1217. strcmp(topic, aliases[j].topic))) {
  1218. printf("%s%s:\n", topic ? "\n" : "",
  1219. aliases[j].topic);
  1220. topic = aliases[j].topic;
  1221. }
  1222. printf(" %-50s\n", aliases[j].name);
  1223. printf("%*s", 8, "[");
  1224. wordwrap(aliases[j].desc, 8, columns, 0);
  1225. printf("]\n");
  1226. if (details_flag) {
  1227. printf("%*s%s/%s/ ", 8, "", aliases[j].pmu, aliases[j].str);
  1228. if (aliases[j].metric_name)
  1229. printf(" MetricName: %s", aliases[j].metric_name);
  1230. if (aliases[j].metric_expr)
  1231. printf(" MetricExpr: %s", aliases[j].metric_expr);
  1232. putchar('\n');
  1233. }
  1234. } else
  1235. printf(" %-50s [Kernel PMU event]\n", aliases[j].name);
  1236. printed++;
  1237. }
  1238. if (printed && pager_in_use())
  1239. printf("\n");
  1240. out_free:
  1241. for (j = 0; j < len; j++)
  1242. zfree(&aliases[j].name);
  1243. zfree(&aliases);
  1244. return;
  1245. out_enomem:
  1246. printf("FATAL: not enough memory to print PMU events\n");
  1247. if (aliases)
  1248. goto out_free;
  1249. }
  1250. bool pmu_have_event(const char *pname, const char *name)
  1251. {
  1252. struct perf_pmu *pmu;
  1253. struct perf_pmu_alias *alias;
  1254. pmu = NULL;
  1255. while ((pmu = perf_pmu__scan(pmu)) != NULL) {
  1256. if (strcmp(pname, pmu->name))
  1257. continue;
  1258. list_for_each_entry(alias, &pmu->aliases, list)
  1259. if (!strcmp(alias->name, name))
  1260. return true;
  1261. }
  1262. return false;
  1263. }
  1264. static FILE *perf_pmu__open_file(struct perf_pmu *pmu, const char *name)
  1265. {
  1266. struct stat st;
  1267. char path[PATH_MAX];
  1268. const char *sysfs;
  1269. sysfs = sysfs__mountpoint();
  1270. if (!sysfs)
  1271. return NULL;
  1272. snprintf(path, PATH_MAX,
  1273. "%s" EVENT_SOURCE_DEVICE_PATH "%s/%s", sysfs, pmu->name, name);
  1274. if (stat(path, &st) < 0)
  1275. return NULL;
  1276. return fopen(path, "r");
  1277. }
  1278. int perf_pmu__scan_file(struct perf_pmu *pmu, const char *name, const char *fmt,
  1279. ...)
  1280. {
  1281. va_list args;
  1282. FILE *file;
  1283. int ret = EOF;
  1284. va_start(args, fmt);
  1285. file = perf_pmu__open_file(pmu, name);
  1286. if (file) {
  1287. ret = vfscanf(file, fmt, args);
  1288. fclose(file);
  1289. }
  1290. va_end(args);
  1291. return ret;
  1292. }