pmu.c 33 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553
  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. void perf_pmu__del_formats(struct list_head *formats)
  1069. {
  1070. struct perf_pmu_format *fmt, *tmp;
  1071. list_for_each_entry_safe(fmt, tmp, formats, list) {
  1072. list_del(&fmt->list);
  1073. free(fmt->name);
  1074. free(fmt);
  1075. }
  1076. }
  1077. static int sub_non_neg(int a, int b)
  1078. {
  1079. if (b > a)
  1080. return 0;
  1081. return a - b;
  1082. }
  1083. static char *format_alias(char *buf, int len, struct perf_pmu *pmu,
  1084. struct perf_pmu_alias *alias)
  1085. {
  1086. struct parse_events_term *term;
  1087. int used = snprintf(buf, len, "%s/%s", pmu->name, alias->name);
  1088. list_for_each_entry(term, &alias->terms, list) {
  1089. if (term->type_val == PARSE_EVENTS__TERM_TYPE_STR)
  1090. used += snprintf(buf + used, sub_non_neg(len, used),
  1091. ",%s=%s", term->config,
  1092. term->val.str);
  1093. }
  1094. if (sub_non_neg(len, used) > 0) {
  1095. buf[used] = '/';
  1096. used++;
  1097. }
  1098. if (sub_non_neg(len, used) > 0) {
  1099. buf[used] = '\0';
  1100. used++;
  1101. } else
  1102. buf[len - 1] = '\0';
  1103. return buf;
  1104. }
  1105. static char *format_alias_or(char *buf, int len, struct perf_pmu *pmu,
  1106. struct perf_pmu_alias *alias)
  1107. {
  1108. snprintf(buf, len, "%s OR %s/%s/", alias->name, pmu->name, alias->name);
  1109. return buf;
  1110. }
  1111. struct sevent {
  1112. char *name;
  1113. char *desc;
  1114. char *topic;
  1115. char *str;
  1116. char *pmu;
  1117. char *metric_expr;
  1118. char *metric_name;
  1119. };
  1120. static int cmp_sevent(const void *a, const void *b)
  1121. {
  1122. const struct sevent *as = a;
  1123. const struct sevent *bs = b;
  1124. /* Put extra events last */
  1125. if (!!as->desc != !!bs->desc)
  1126. return !!as->desc - !!bs->desc;
  1127. if (as->topic && bs->topic) {
  1128. int n = strcmp(as->topic, bs->topic);
  1129. if (n)
  1130. return n;
  1131. }
  1132. return strcmp(as->name, bs->name);
  1133. }
  1134. static void wordwrap(char *s, int start, int max, int corr)
  1135. {
  1136. int column = start;
  1137. int n;
  1138. while (*s) {
  1139. int wlen = strcspn(s, " \t");
  1140. if (column + wlen >= max && column > start) {
  1141. printf("\n%*s", start, "");
  1142. column = start + corr;
  1143. }
  1144. n = printf("%s%.*s", column > start ? " " : "", wlen, s);
  1145. if (n <= 0)
  1146. break;
  1147. s += wlen;
  1148. column += n;
  1149. s = ltrim(s);
  1150. }
  1151. }
  1152. void print_pmu_events(const char *event_glob, bool name_only, bool quiet_flag,
  1153. bool long_desc, bool details_flag)
  1154. {
  1155. struct perf_pmu *pmu;
  1156. struct perf_pmu_alias *alias;
  1157. char buf[1024];
  1158. int printed = 0;
  1159. int len, j;
  1160. struct sevent *aliases;
  1161. int numdesc = 0;
  1162. int columns = pager_get_columns();
  1163. char *topic = NULL;
  1164. pmu = NULL;
  1165. len = 0;
  1166. while ((pmu = perf_pmu__scan(pmu)) != NULL) {
  1167. list_for_each_entry(alias, &pmu->aliases, list)
  1168. len++;
  1169. if (pmu->selectable)
  1170. len++;
  1171. }
  1172. aliases = zalloc(sizeof(struct sevent) * len);
  1173. if (!aliases)
  1174. goto out_enomem;
  1175. pmu = NULL;
  1176. j = 0;
  1177. while ((pmu = perf_pmu__scan(pmu)) != NULL) {
  1178. list_for_each_entry(alias, &pmu->aliases, list) {
  1179. char *name = alias->desc ? alias->name :
  1180. format_alias(buf, sizeof(buf), pmu, alias);
  1181. bool is_cpu = !strcmp(pmu->name, "cpu");
  1182. if (event_glob != NULL &&
  1183. !(strglobmatch_nocase(name, event_glob) ||
  1184. (!is_cpu && strglobmatch_nocase(alias->name,
  1185. event_glob)) ||
  1186. (alias->topic &&
  1187. strglobmatch_nocase(alias->topic, event_glob))))
  1188. continue;
  1189. if (is_cpu && !name_only && !alias->desc)
  1190. name = format_alias_or(buf, sizeof(buf), pmu, alias);
  1191. aliases[j].name = name;
  1192. if (is_cpu && !name_only && !alias->desc)
  1193. aliases[j].name = format_alias_or(buf,
  1194. sizeof(buf),
  1195. pmu, alias);
  1196. aliases[j].name = strdup(aliases[j].name);
  1197. if (!aliases[j].name)
  1198. goto out_enomem;
  1199. aliases[j].desc = long_desc ? alias->long_desc :
  1200. alias->desc;
  1201. aliases[j].topic = alias->topic;
  1202. aliases[j].str = alias->str;
  1203. aliases[j].pmu = pmu->name;
  1204. aliases[j].metric_expr = alias->metric_expr;
  1205. aliases[j].metric_name = alias->metric_name;
  1206. j++;
  1207. }
  1208. if (pmu->selectable &&
  1209. (event_glob == NULL || strglobmatch(pmu->name, event_glob))) {
  1210. char *s;
  1211. if (asprintf(&s, "%s//", pmu->name) < 0)
  1212. goto out_enomem;
  1213. aliases[j].name = s;
  1214. j++;
  1215. }
  1216. }
  1217. len = j;
  1218. qsort(aliases, len, sizeof(struct sevent), cmp_sevent);
  1219. for (j = 0; j < len; j++) {
  1220. /* Skip duplicates */
  1221. if (j > 0 && !strcmp(aliases[j].name, aliases[j - 1].name))
  1222. continue;
  1223. if (name_only) {
  1224. printf("%s ", aliases[j].name);
  1225. continue;
  1226. }
  1227. if (aliases[j].desc && !quiet_flag) {
  1228. if (numdesc++ == 0)
  1229. printf("\n");
  1230. if (aliases[j].topic && (!topic ||
  1231. strcmp(topic, aliases[j].topic))) {
  1232. printf("%s%s:\n", topic ? "\n" : "",
  1233. aliases[j].topic);
  1234. topic = aliases[j].topic;
  1235. }
  1236. printf(" %-50s\n", aliases[j].name);
  1237. printf("%*s", 8, "[");
  1238. wordwrap(aliases[j].desc, 8, columns, 0);
  1239. printf("]\n");
  1240. if (details_flag) {
  1241. printf("%*s%s/%s/ ", 8, "", aliases[j].pmu, aliases[j].str);
  1242. if (aliases[j].metric_name)
  1243. printf(" MetricName: %s", aliases[j].metric_name);
  1244. if (aliases[j].metric_expr)
  1245. printf(" MetricExpr: %s", aliases[j].metric_expr);
  1246. putchar('\n');
  1247. }
  1248. } else
  1249. printf(" %-50s [Kernel PMU event]\n", aliases[j].name);
  1250. printed++;
  1251. }
  1252. if (printed && pager_in_use())
  1253. printf("\n");
  1254. out_free:
  1255. for (j = 0; j < len; j++)
  1256. zfree(&aliases[j].name);
  1257. zfree(&aliases);
  1258. return;
  1259. out_enomem:
  1260. printf("FATAL: not enough memory to print PMU events\n");
  1261. if (aliases)
  1262. goto out_free;
  1263. }
  1264. bool pmu_have_event(const char *pname, const char *name)
  1265. {
  1266. struct perf_pmu *pmu;
  1267. struct perf_pmu_alias *alias;
  1268. pmu = NULL;
  1269. while ((pmu = perf_pmu__scan(pmu)) != NULL) {
  1270. if (strcmp(pname, pmu->name))
  1271. continue;
  1272. list_for_each_entry(alias, &pmu->aliases, list)
  1273. if (!strcmp(alias->name, name))
  1274. return true;
  1275. }
  1276. return false;
  1277. }
  1278. static FILE *perf_pmu__open_file(struct perf_pmu *pmu, const char *name)
  1279. {
  1280. struct stat st;
  1281. char path[PATH_MAX];
  1282. const char *sysfs;
  1283. sysfs = sysfs__mountpoint();
  1284. if (!sysfs)
  1285. return NULL;
  1286. snprintf(path, PATH_MAX,
  1287. "%s" EVENT_SOURCE_DEVICE_PATH "%s/%s", sysfs, pmu->name, name);
  1288. if (stat(path, &st) < 0)
  1289. return NULL;
  1290. return fopen(path, "r");
  1291. }
  1292. int perf_pmu__scan_file(struct perf_pmu *pmu, const char *name, const char *fmt,
  1293. ...)
  1294. {
  1295. va_list args;
  1296. FILE *file;
  1297. int ret = EOF;
  1298. va_start(args, fmt);
  1299. file = perf_pmu__open_file(pmu, name);
  1300. if (file) {
  1301. ret = vfscanf(file, fmt, args);
  1302. fclose(file);
  1303. }
  1304. va_end(args);
  1305. return ret;
  1306. }