pmu.c 33 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543
  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. scnprintf(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. scnprintf(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. scnprintf(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. scnprintf(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. const char *name = pmu->name;
  626. map = perf_pmu__find_map(pmu);
  627. if (!map)
  628. return;
  629. /*
  630. * Found a matching PMU events table. Create aliases
  631. */
  632. i = 0;
  633. while (1) {
  634. const char *cpu_name = is_arm_pmu_core(name) ? name : "cpu";
  635. struct pmu_event *pe = &map->table[i++];
  636. const char *pname = pe->pmu ? pe->pmu : cpu_name;
  637. if (!pe->name) {
  638. if (pe->metric_group || pe->metric_name)
  639. continue;
  640. break;
  641. }
  642. /*
  643. * uncore alias may be from different PMU
  644. * with common prefix
  645. */
  646. if (pmu_is_uncore(name) &&
  647. !strncmp(pname, name, strlen(pname)))
  648. goto new_alias;
  649. if (strcmp(pname, name))
  650. continue;
  651. new_alias:
  652. /* need type casts to override 'const' */
  653. __perf_pmu__new_alias(head, NULL, (char *)pe->name,
  654. (char *)pe->desc, (char *)pe->event,
  655. (char *)pe->long_desc, (char *)pe->topic,
  656. (char *)pe->unit, (char *)pe->perpkg,
  657. (char *)pe->metric_expr,
  658. (char *)pe->metric_name);
  659. }
  660. }
  661. struct perf_event_attr * __weak
  662. perf_pmu__get_default_config(struct perf_pmu *pmu __maybe_unused)
  663. {
  664. return NULL;
  665. }
  666. static struct perf_pmu *pmu_lookup(const char *name)
  667. {
  668. struct perf_pmu *pmu;
  669. LIST_HEAD(format);
  670. LIST_HEAD(aliases);
  671. __u32 type;
  672. /*
  673. * The pmu data we store & need consists of the pmu
  674. * type value and format definitions. Load both right
  675. * now.
  676. */
  677. if (pmu_format(name, &format))
  678. return NULL;
  679. /*
  680. * Check the type first to avoid unnecessary work.
  681. */
  682. if (pmu_type(name, &type))
  683. return NULL;
  684. if (pmu_aliases(name, &aliases))
  685. return NULL;
  686. pmu = zalloc(sizeof(*pmu));
  687. if (!pmu)
  688. return NULL;
  689. pmu->cpus = pmu_cpumask(name);
  690. pmu->name = strdup(name);
  691. pmu->type = type;
  692. pmu->is_uncore = pmu_is_uncore(name);
  693. pmu_add_cpu_aliases(&aliases, pmu);
  694. INIT_LIST_HEAD(&pmu->format);
  695. INIT_LIST_HEAD(&pmu->aliases);
  696. list_splice(&format, &pmu->format);
  697. list_splice(&aliases, &pmu->aliases);
  698. list_add_tail(&pmu->list, &pmus);
  699. pmu->default_config = perf_pmu__get_default_config(pmu);
  700. return pmu;
  701. }
  702. static struct perf_pmu *pmu_find(const char *name)
  703. {
  704. struct perf_pmu *pmu;
  705. list_for_each_entry(pmu, &pmus, list)
  706. if (!strcmp(pmu->name, name))
  707. return pmu;
  708. return NULL;
  709. }
  710. struct perf_pmu *perf_pmu__scan(struct perf_pmu *pmu)
  711. {
  712. /*
  713. * pmu iterator: If pmu is NULL, we start at the begin,
  714. * otherwise return the next pmu. Returns NULL on end.
  715. */
  716. if (!pmu) {
  717. pmu_read_sysfs();
  718. pmu = list_prepare_entry(pmu, &pmus, list);
  719. }
  720. list_for_each_entry_continue(pmu, &pmus, list)
  721. return pmu;
  722. return NULL;
  723. }
  724. struct perf_pmu *perf_pmu__find(const char *name)
  725. {
  726. struct perf_pmu *pmu;
  727. /*
  728. * Once PMU is loaded it stays in the list,
  729. * so we keep us from multiple reading/parsing
  730. * the pmu format definitions.
  731. */
  732. pmu = pmu_find(name);
  733. if (pmu)
  734. return pmu;
  735. return pmu_lookup(name);
  736. }
  737. static struct perf_pmu_format *
  738. pmu_find_format(struct list_head *formats, const char *name)
  739. {
  740. struct perf_pmu_format *format;
  741. list_for_each_entry(format, formats, list)
  742. if (!strcmp(format->name, name))
  743. return format;
  744. return NULL;
  745. }
  746. __u64 perf_pmu__format_bits(struct list_head *formats, const char *name)
  747. {
  748. struct perf_pmu_format *format = pmu_find_format(formats, name);
  749. __u64 bits = 0;
  750. int fbit;
  751. if (!format)
  752. return 0;
  753. for_each_set_bit(fbit, format->bits, PERF_PMU_FORMAT_BITS)
  754. bits |= 1ULL << fbit;
  755. return bits;
  756. }
  757. /*
  758. * Sets value based on the format definition (format parameter)
  759. * and unformated value (value parameter).
  760. */
  761. static void pmu_format_value(unsigned long *format, __u64 value, __u64 *v,
  762. bool zero)
  763. {
  764. unsigned long fbit, vbit;
  765. for (fbit = 0, vbit = 0; fbit < PERF_PMU_FORMAT_BITS; fbit++) {
  766. if (!test_bit(fbit, format))
  767. continue;
  768. if (value & (1llu << vbit++))
  769. *v |= (1llu << fbit);
  770. else if (zero)
  771. *v &= ~(1llu << fbit);
  772. }
  773. }
  774. static __u64 pmu_format_max_value(const unsigned long *format)
  775. {
  776. int w;
  777. w = bitmap_weight(format, PERF_PMU_FORMAT_BITS);
  778. if (!w)
  779. return 0;
  780. if (w < 64)
  781. return (1ULL << w) - 1;
  782. return -1;
  783. }
  784. /*
  785. * Term is a string term, and might be a param-term. Try to look up it's value
  786. * in the remaining terms.
  787. * - We have a term like "base-or-format-term=param-term",
  788. * - We need to find the value supplied for "param-term" (with param-term named
  789. * in a config string) later on in the term list.
  790. */
  791. static int pmu_resolve_param_term(struct parse_events_term *term,
  792. struct list_head *head_terms,
  793. __u64 *value)
  794. {
  795. struct parse_events_term *t;
  796. list_for_each_entry(t, head_terms, list) {
  797. if (t->type_val == PARSE_EVENTS__TERM_TYPE_NUM) {
  798. if (!strcmp(t->config, term->config)) {
  799. t->used = true;
  800. *value = t->val.num;
  801. return 0;
  802. }
  803. }
  804. }
  805. if (verbose > 0)
  806. printf("Required parameter '%s' not specified\n", term->config);
  807. return -1;
  808. }
  809. static char *pmu_formats_string(struct list_head *formats)
  810. {
  811. struct perf_pmu_format *format;
  812. char *str = NULL;
  813. struct strbuf buf = STRBUF_INIT;
  814. unsigned i = 0;
  815. if (!formats)
  816. return NULL;
  817. /* sysfs exported terms */
  818. list_for_each_entry(format, formats, list)
  819. if (strbuf_addf(&buf, i++ ? ",%s" : "%s", format->name) < 0)
  820. goto error;
  821. str = strbuf_detach(&buf, NULL);
  822. error:
  823. strbuf_release(&buf);
  824. return str;
  825. }
  826. /*
  827. * Setup one of config[12] attr members based on the
  828. * user input data - term parameter.
  829. */
  830. static int pmu_config_term(struct list_head *formats,
  831. struct perf_event_attr *attr,
  832. struct parse_events_term *term,
  833. struct list_head *head_terms,
  834. bool zero, struct parse_events_error *err)
  835. {
  836. struct perf_pmu_format *format;
  837. __u64 *vp;
  838. __u64 val, max_val;
  839. /*
  840. * If this is a parameter we've already used for parameterized-eval,
  841. * skip it in normal eval.
  842. */
  843. if (term->used)
  844. return 0;
  845. /*
  846. * Hardcoded terms should be already in, so nothing
  847. * to be done for them.
  848. */
  849. if (parse_events__is_hardcoded_term(term))
  850. return 0;
  851. format = pmu_find_format(formats, term->config);
  852. if (!format) {
  853. if (verbose > 0)
  854. printf("Invalid event/parameter '%s'\n", term->config);
  855. if (err) {
  856. char *pmu_term = pmu_formats_string(formats);
  857. err->idx = term->err_term;
  858. err->str = strdup("unknown term");
  859. err->help = parse_events_formats_error_string(pmu_term);
  860. free(pmu_term);
  861. }
  862. return -EINVAL;
  863. }
  864. switch (format->value) {
  865. case PERF_PMU_FORMAT_VALUE_CONFIG:
  866. vp = &attr->config;
  867. break;
  868. case PERF_PMU_FORMAT_VALUE_CONFIG1:
  869. vp = &attr->config1;
  870. break;
  871. case PERF_PMU_FORMAT_VALUE_CONFIG2:
  872. vp = &attr->config2;
  873. break;
  874. default:
  875. return -EINVAL;
  876. }
  877. /*
  878. * Either directly use a numeric term, or try to translate string terms
  879. * using event parameters.
  880. */
  881. if (term->type_val == PARSE_EVENTS__TERM_TYPE_NUM) {
  882. if (term->no_value &&
  883. bitmap_weight(format->bits, PERF_PMU_FORMAT_BITS) > 1) {
  884. if (err) {
  885. err->idx = term->err_val;
  886. err->str = strdup("no value assigned for term");
  887. }
  888. return -EINVAL;
  889. }
  890. val = term->val.num;
  891. } else if (term->type_val == PARSE_EVENTS__TERM_TYPE_STR) {
  892. if (strcmp(term->val.str, "?")) {
  893. if (verbose > 0) {
  894. pr_info("Invalid sysfs entry %s=%s\n",
  895. term->config, term->val.str);
  896. }
  897. if (err) {
  898. err->idx = term->err_val;
  899. err->str = strdup("expected numeric value");
  900. }
  901. return -EINVAL;
  902. }
  903. if (pmu_resolve_param_term(term, head_terms, &val))
  904. return -EINVAL;
  905. } else
  906. return -EINVAL;
  907. max_val = pmu_format_max_value(format->bits);
  908. if (val > max_val) {
  909. if (err) {
  910. err->idx = term->err_val;
  911. if (asprintf(&err->str,
  912. "value too big for format, maximum is %llu",
  913. (unsigned long long)max_val) < 0)
  914. err->str = strdup("value too big for format");
  915. return -EINVAL;
  916. }
  917. /*
  918. * Assume we don't care if !err, in which case the value will be
  919. * silently truncated.
  920. */
  921. }
  922. pmu_format_value(format->bits, val, vp, zero);
  923. return 0;
  924. }
  925. int perf_pmu__config_terms(struct list_head *formats,
  926. struct perf_event_attr *attr,
  927. struct list_head *head_terms,
  928. bool zero, struct parse_events_error *err)
  929. {
  930. struct parse_events_term *term;
  931. list_for_each_entry(term, head_terms, list) {
  932. if (pmu_config_term(formats, attr, term, head_terms,
  933. zero, err))
  934. return -EINVAL;
  935. }
  936. return 0;
  937. }
  938. /*
  939. * Configures event's 'attr' parameter based on the:
  940. * 1) users input - specified in terms parameter
  941. * 2) pmu format definitions - specified by pmu parameter
  942. */
  943. int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr,
  944. struct list_head *head_terms,
  945. struct parse_events_error *err)
  946. {
  947. bool zero = !!pmu->default_config;
  948. attr->type = pmu->type;
  949. return perf_pmu__config_terms(&pmu->format, attr, head_terms,
  950. zero, err);
  951. }
  952. static struct perf_pmu_alias *pmu_find_alias(struct perf_pmu *pmu,
  953. struct parse_events_term *term)
  954. {
  955. struct perf_pmu_alias *alias;
  956. char *name;
  957. if (parse_events__is_hardcoded_term(term))
  958. return NULL;
  959. if (term->type_val == PARSE_EVENTS__TERM_TYPE_NUM) {
  960. if (term->val.num != 1)
  961. return NULL;
  962. if (pmu_find_format(&pmu->format, term->config))
  963. return NULL;
  964. name = term->config;
  965. } else if (term->type_val == PARSE_EVENTS__TERM_TYPE_STR) {
  966. if (strcasecmp(term->config, "event"))
  967. return NULL;
  968. name = term->val.str;
  969. } else {
  970. return NULL;
  971. }
  972. list_for_each_entry(alias, &pmu->aliases, list) {
  973. if (!strcasecmp(alias->name, name))
  974. return alias;
  975. }
  976. return NULL;
  977. }
  978. static int check_info_data(struct perf_pmu_alias *alias,
  979. struct perf_pmu_info *info)
  980. {
  981. /*
  982. * Only one term in event definition can
  983. * define unit, scale and snapshot, fail
  984. * if there's more than one.
  985. */
  986. if ((info->unit && alias->unit[0]) ||
  987. (info->scale && alias->scale) ||
  988. (info->snapshot && alias->snapshot))
  989. return -EINVAL;
  990. if (alias->unit[0])
  991. info->unit = alias->unit;
  992. if (alias->scale)
  993. info->scale = alias->scale;
  994. if (alias->snapshot)
  995. info->snapshot = alias->snapshot;
  996. return 0;
  997. }
  998. /*
  999. * Find alias in the terms list and replace it with the terms
  1000. * defined for the alias
  1001. */
  1002. int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms,
  1003. struct perf_pmu_info *info)
  1004. {
  1005. struct parse_events_term *term, *h;
  1006. struct perf_pmu_alias *alias;
  1007. int ret;
  1008. info->per_pkg = false;
  1009. /*
  1010. * Mark unit and scale as not set
  1011. * (different from default values, see below)
  1012. */
  1013. info->unit = NULL;
  1014. info->scale = 0.0;
  1015. info->snapshot = false;
  1016. info->metric_expr = NULL;
  1017. info->metric_name = NULL;
  1018. list_for_each_entry_safe(term, h, head_terms, list) {
  1019. alias = pmu_find_alias(pmu, term);
  1020. if (!alias)
  1021. continue;
  1022. ret = pmu_alias_terms(alias, &term->list);
  1023. if (ret)
  1024. return ret;
  1025. ret = check_info_data(alias, info);
  1026. if (ret)
  1027. return ret;
  1028. if (alias->per_pkg)
  1029. info->per_pkg = true;
  1030. info->metric_expr = alias->metric_expr;
  1031. info->metric_name = alias->metric_name;
  1032. list_del(&term->list);
  1033. free(term);
  1034. }
  1035. /*
  1036. * if no unit or scale foundin aliases, then
  1037. * set defaults as for evsel
  1038. * unit cannot left to NULL
  1039. */
  1040. if (info->unit == NULL)
  1041. info->unit = "";
  1042. if (info->scale == 0.0)
  1043. info->scale = 1.0;
  1044. return 0;
  1045. }
  1046. int perf_pmu__new_format(struct list_head *list, char *name,
  1047. int config, unsigned long *bits)
  1048. {
  1049. struct perf_pmu_format *format;
  1050. format = zalloc(sizeof(*format));
  1051. if (!format)
  1052. return -ENOMEM;
  1053. format->name = strdup(name);
  1054. format->value = config;
  1055. memcpy(format->bits, bits, sizeof(format->bits));
  1056. list_add_tail(&format->list, list);
  1057. return 0;
  1058. }
  1059. void perf_pmu__set_format(unsigned long *bits, long from, long to)
  1060. {
  1061. long b;
  1062. if (!to)
  1063. to = from;
  1064. memset(bits, 0, BITS_TO_BYTES(PERF_PMU_FORMAT_BITS));
  1065. for (b = from; b <= to; b++)
  1066. set_bit(b, bits);
  1067. }
  1068. static int sub_non_neg(int a, int b)
  1069. {
  1070. if (b > a)
  1071. return 0;
  1072. return a - b;
  1073. }
  1074. static char *format_alias(char *buf, int len, struct perf_pmu *pmu,
  1075. struct perf_pmu_alias *alias)
  1076. {
  1077. struct parse_events_term *term;
  1078. int used = snprintf(buf, len, "%s/%s", pmu->name, alias->name);
  1079. list_for_each_entry(term, &alias->terms, list) {
  1080. if (term->type_val == PARSE_EVENTS__TERM_TYPE_STR)
  1081. used += snprintf(buf + used, sub_non_neg(len, used),
  1082. ",%s=%s", term->config,
  1083. term->val.str);
  1084. }
  1085. if (sub_non_neg(len, used) > 0) {
  1086. buf[used] = '/';
  1087. used++;
  1088. }
  1089. if (sub_non_neg(len, used) > 0) {
  1090. buf[used] = '\0';
  1091. used++;
  1092. } else
  1093. buf[len - 1] = '\0';
  1094. return buf;
  1095. }
  1096. static char *format_alias_or(char *buf, int len, struct perf_pmu *pmu,
  1097. struct perf_pmu_alias *alias)
  1098. {
  1099. snprintf(buf, len, "%s OR %s/%s/", alias->name, pmu->name, alias->name);
  1100. return buf;
  1101. }
  1102. struct sevent {
  1103. char *name;
  1104. char *desc;
  1105. char *topic;
  1106. char *str;
  1107. char *pmu;
  1108. char *metric_expr;
  1109. char *metric_name;
  1110. };
  1111. static int cmp_sevent(const void *a, const void *b)
  1112. {
  1113. const struct sevent *as = a;
  1114. const struct sevent *bs = b;
  1115. /* Put extra events last */
  1116. if (!!as->desc != !!bs->desc)
  1117. return !!as->desc - !!bs->desc;
  1118. if (as->topic && bs->topic) {
  1119. int n = strcmp(as->topic, bs->topic);
  1120. if (n)
  1121. return n;
  1122. }
  1123. return strcmp(as->name, bs->name);
  1124. }
  1125. static void wordwrap(char *s, int start, int max, int corr)
  1126. {
  1127. int column = start;
  1128. int n;
  1129. while (*s) {
  1130. int wlen = strcspn(s, " \t");
  1131. if (column + wlen >= max && column > start) {
  1132. printf("\n%*s", start, "");
  1133. column = start + corr;
  1134. }
  1135. n = printf("%s%.*s", column > start ? " " : "", wlen, s);
  1136. if (n <= 0)
  1137. break;
  1138. s += wlen;
  1139. column += n;
  1140. s = ltrim(s);
  1141. }
  1142. }
  1143. void print_pmu_events(const char *event_glob, bool name_only, bool quiet_flag,
  1144. bool long_desc, bool details_flag)
  1145. {
  1146. struct perf_pmu *pmu;
  1147. struct perf_pmu_alias *alias;
  1148. char buf[1024];
  1149. int printed = 0;
  1150. int len, j;
  1151. struct sevent *aliases;
  1152. int numdesc = 0;
  1153. int columns = pager_get_columns();
  1154. char *topic = NULL;
  1155. pmu = NULL;
  1156. len = 0;
  1157. while ((pmu = perf_pmu__scan(pmu)) != NULL) {
  1158. list_for_each_entry(alias, &pmu->aliases, list)
  1159. len++;
  1160. if (pmu->selectable)
  1161. len++;
  1162. }
  1163. aliases = zalloc(sizeof(struct sevent) * len);
  1164. if (!aliases)
  1165. goto out_enomem;
  1166. pmu = NULL;
  1167. j = 0;
  1168. while ((pmu = perf_pmu__scan(pmu)) != NULL) {
  1169. list_for_each_entry(alias, &pmu->aliases, list) {
  1170. char *name = alias->desc ? alias->name :
  1171. format_alias(buf, sizeof(buf), pmu, alias);
  1172. bool is_cpu = !strcmp(pmu->name, "cpu");
  1173. if (event_glob != NULL &&
  1174. !(strglobmatch_nocase(name, event_glob) ||
  1175. (!is_cpu && strglobmatch_nocase(alias->name,
  1176. event_glob)) ||
  1177. (alias->topic &&
  1178. strglobmatch_nocase(alias->topic, event_glob))))
  1179. continue;
  1180. if (is_cpu && !name_only && !alias->desc)
  1181. name = format_alias_or(buf, sizeof(buf), pmu, alias);
  1182. aliases[j].name = name;
  1183. if (is_cpu && !name_only && !alias->desc)
  1184. aliases[j].name = format_alias_or(buf,
  1185. sizeof(buf),
  1186. pmu, alias);
  1187. aliases[j].name = strdup(aliases[j].name);
  1188. if (!aliases[j].name)
  1189. goto out_enomem;
  1190. aliases[j].desc = long_desc ? alias->long_desc :
  1191. alias->desc;
  1192. aliases[j].topic = alias->topic;
  1193. aliases[j].str = alias->str;
  1194. aliases[j].pmu = pmu->name;
  1195. aliases[j].metric_expr = alias->metric_expr;
  1196. aliases[j].metric_name = alias->metric_name;
  1197. j++;
  1198. }
  1199. if (pmu->selectable &&
  1200. (event_glob == NULL || strglobmatch(pmu->name, event_glob))) {
  1201. char *s;
  1202. if (asprintf(&s, "%s//", pmu->name) < 0)
  1203. goto out_enomem;
  1204. aliases[j].name = s;
  1205. j++;
  1206. }
  1207. }
  1208. len = j;
  1209. qsort(aliases, len, sizeof(struct sevent), cmp_sevent);
  1210. for (j = 0; j < len; j++) {
  1211. /* Skip duplicates */
  1212. if (j > 0 && !strcmp(aliases[j].name, aliases[j - 1].name))
  1213. continue;
  1214. if (name_only) {
  1215. printf("%s ", aliases[j].name);
  1216. continue;
  1217. }
  1218. if (aliases[j].desc && !quiet_flag) {
  1219. if (numdesc++ == 0)
  1220. printf("\n");
  1221. if (aliases[j].topic && (!topic ||
  1222. strcmp(topic, aliases[j].topic))) {
  1223. printf("%s%s:\n", topic ? "\n" : "",
  1224. aliases[j].topic);
  1225. topic = aliases[j].topic;
  1226. }
  1227. printf(" %-50s\n", aliases[j].name);
  1228. printf("%*s", 8, "[");
  1229. wordwrap(aliases[j].desc, 8, columns, 0);
  1230. printf("]\n");
  1231. if (details_flag) {
  1232. printf("%*s%s/%s/ ", 8, "", aliases[j].pmu, aliases[j].str);
  1233. if (aliases[j].metric_name)
  1234. printf(" MetricName: %s", aliases[j].metric_name);
  1235. if (aliases[j].metric_expr)
  1236. printf(" MetricExpr: %s", aliases[j].metric_expr);
  1237. putchar('\n');
  1238. }
  1239. } else
  1240. printf(" %-50s [Kernel PMU event]\n", aliases[j].name);
  1241. printed++;
  1242. }
  1243. if (printed && pager_in_use())
  1244. printf("\n");
  1245. out_free:
  1246. for (j = 0; j < len; j++)
  1247. zfree(&aliases[j].name);
  1248. zfree(&aliases);
  1249. return;
  1250. out_enomem:
  1251. printf("FATAL: not enough memory to print PMU events\n");
  1252. if (aliases)
  1253. goto out_free;
  1254. }
  1255. bool pmu_have_event(const char *pname, const char *name)
  1256. {
  1257. struct perf_pmu *pmu;
  1258. struct perf_pmu_alias *alias;
  1259. pmu = NULL;
  1260. while ((pmu = perf_pmu__scan(pmu)) != NULL) {
  1261. if (strcmp(pname, pmu->name))
  1262. continue;
  1263. list_for_each_entry(alias, &pmu->aliases, list)
  1264. if (!strcmp(alias->name, name))
  1265. return true;
  1266. }
  1267. return false;
  1268. }
  1269. static FILE *perf_pmu__open_file(struct perf_pmu *pmu, const char *name)
  1270. {
  1271. struct stat st;
  1272. char path[PATH_MAX];
  1273. const char *sysfs;
  1274. sysfs = sysfs__mountpoint();
  1275. if (!sysfs)
  1276. return NULL;
  1277. snprintf(path, PATH_MAX,
  1278. "%s" EVENT_SOURCE_DEVICE_PATH "%s/%s", sysfs, pmu->name, name);
  1279. if (stat(path, &st) < 0)
  1280. return NULL;
  1281. return fopen(path, "r");
  1282. }
  1283. int perf_pmu__scan_file(struct perf_pmu *pmu, const char *name, const char *fmt,
  1284. ...)
  1285. {
  1286. va_list args;
  1287. FILE *file;
  1288. int ret = EOF;
  1289. va_start(args, fmt);
  1290. file = perf_pmu__open_file(pmu, name);
  1291. if (file) {
  1292. ret = vfscanf(file, fmt, args);
  1293. fclose(file);
  1294. }
  1295. va_end(args);
  1296. return ret;
  1297. }