pmus.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887
  1. // SPDX-License-Identifier: GPL-2.0
  2. #include <linux/list.h>
  3. #include <linux/list_sort.h>
  4. #include <linux/string.h>
  5. #include <linux/zalloc.h>
  6. #include <api/io_dir.h>
  7. #include <subcmd/pager.h>
  8. #include <sys/types.h>
  9. #include <ctype.h>
  10. #include <pthread.h>
  11. #include <string.h>
  12. #include <unistd.h>
  13. #include "cpumap.h"
  14. #include "debug.h"
  15. #include "drm_pmu.h"
  16. #include "evsel.h"
  17. #include "pmus.h"
  18. #include "pmu.h"
  19. #include "hwmon_pmu.h"
  20. #include "tool_pmu.h"
  21. #include "print-events.h"
  22. #include "strbuf.h"
  23. #include "string2.h"
  24. /*
  25. * core_pmus: A PMU belongs to core_pmus if it's name is "cpu" or it's sysfs
  26. * directory contains "cpus" file. All PMUs belonging to core_pmus
  27. * must have pmu->is_core=1. If there are more than one PMU in
  28. * this list, perf interprets it as a heterogeneous platform.
  29. * (FWIW, certain ARM platforms having heterogeneous cores uses
  30. * homogeneous PMU, and thus they are treated as homogeneous
  31. * platform by perf because core_pmus will have only one entry)
  32. * other_pmus: All other PMUs which are not part of core_pmus list. It doesn't
  33. * matter whether PMU is present per SMT-thread or outside of the
  34. * core in the hw. For e.g., an instance of AMD ibs_fetch// and
  35. * ibs_op// PMUs is present in each hw SMT thread, however they
  36. * are captured under other_pmus. PMUs belonging to other_pmus
  37. * must have pmu->is_core=0 but pmu->is_uncore could be 0 or 1.
  38. */
  39. static LIST_HEAD(core_pmus);
  40. static LIST_HEAD(other_pmus);
  41. enum perf_tool_pmu_type {
  42. PERF_TOOL_PMU_TYPE_PE_CORE,
  43. PERF_TOOL_PMU_TYPE_PE_OTHER,
  44. PERF_TOOL_PMU_TYPE_TOOL,
  45. PERF_TOOL_PMU_TYPE_HWMON,
  46. PERF_TOOL_PMU_TYPE_DRM,
  47. #define PERF_TOOL_PMU_TYPE_PE_CORE_MASK (1 << PERF_TOOL_PMU_TYPE_PE_CORE)
  48. #define PERF_TOOL_PMU_TYPE_PE_OTHER_MASK (1 << PERF_TOOL_PMU_TYPE_PE_OTHER)
  49. #define PERF_TOOL_PMU_TYPE_TOOL_MASK (1 << PERF_TOOL_PMU_TYPE_TOOL)
  50. #define PERF_TOOL_PMU_TYPE_HWMON_MASK (1 << PERF_TOOL_PMU_TYPE_HWMON)
  51. #define PERF_TOOL_PMU_TYPE_DRM_MASK (1 << PERF_TOOL_PMU_TYPE_DRM)
  52. #define PERF_TOOL_PMU_TYPE_ALL_MASK (PERF_TOOL_PMU_TYPE_PE_CORE_MASK | \
  53. PERF_TOOL_PMU_TYPE_PE_OTHER_MASK | \
  54. PERF_TOOL_PMU_TYPE_TOOL_MASK | \
  55. PERF_TOOL_PMU_TYPE_HWMON_MASK | \
  56. PERF_TOOL_PMU_TYPE_DRM_MASK)
  57. };
  58. static unsigned int read_pmu_types;
  59. static void pmu_read_sysfs(unsigned int to_read_pmus);
  60. size_t pmu_name_len_no_suffix(const char *str)
  61. {
  62. int orig_len, len;
  63. bool has_hex_digits = false;
  64. orig_len = len = strlen(str);
  65. /* Count trailing digits. */
  66. while (len > 0 && isxdigit(str[len - 1])) {
  67. if (!isdigit(str[len - 1]))
  68. has_hex_digits = true;
  69. len--;
  70. }
  71. if (len > 0 && len != orig_len && str[len - 1] == '_') {
  72. /*
  73. * There is a '_{num}' suffix. For decimal suffixes any length
  74. * will do, for hexadecimal ensure more than 2 hex digits so
  75. * that S390's cpum_cf PMU doesn't match.
  76. */
  77. if (!has_hex_digits || (orig_len - len) > 2)
  78. return len - 1;
  79. }
  80. /* Use the full length. */
  81. return orig_len;
  82. }
  83. int pmu_name_cmp(const char *lhs_pmu_name, const char *rhs_pmu_name)
  84. {
  85. unsigned long long lhs_num = 0, rhs_num = 0;
  86. size_t lhs_pmu_name_len = pmu_name_len_no_suffix(lhs_pmu_name);
  87. size_t rhs_pmu_name_len = pmu_name_len_no_suffix(rhs_pmu_name);
  88. int ret = strncmp(lhs_pmu_name, rhs_pmu_name,
  89. lhs_pmu_name_len < rhs_pmu_name_len ? lhs_pmu_name_len : rhs_pmu_name_len);
  90. if (lhs_pmu_name_len != rhs_pmu_name_len || ret != 0 || lhs_pmu_name_len == 0)
  91. return ret;
  92. if (lhs_pmu_name_len + 1 < strlen(lhs_pmu_name))
  93. lhs_num = strtoull(&lhs_pmu_name[lhs_pmu_name_len + 1], NULL, 16);
  94. if (rhs_pmu_name_len + 1 < strlen(rhs_pmu_name))
  95. rhs_num = strtoull(&rhs_pmu_name[rhs_pmu_name_len + 1], NULL, 16);
  96. return lhs_num < rhs_num ? -1 : (lhs_num > rhs_num ? 1 : 0);
  97. }
  98. void perf_pmus__destroy(void)
  99. {
  100. struct perf_pmu *pmu, *tmp;
  101. list_for_each_entry_safe(pmu, tmp, &core_pmus, list) {
  102. list_del(&pmu->list);
  103. perf_pmu__delete(pmu);
  104. }
  105. list_for_each_entry_safe(pmu, tmp, &other_pmus, list) {
  106. list_del(&pmu->list);
  107. perf_pmu__delete(pmu);
  108. }
  109. read_pmu_types = 0;
  110. }
  111. static struct perf_pmu *pmu_find(const char *name)
  112. {
  113. struct perf_pmu *pmu;
  114. list_for_each_entry(pmu, &core_pmus, list) {
  115. if (!strcmp(pmu->name, name) ||
  116. (pmu->alias_name && !strcmp(pmu->alias_name, name)))
  117. return pmu;
  118. }
  119. list_for_each_entry(pmu, &other_pmus, list) {
  120. if (!strcmp(pmu->name, name) ||
  121. (pmu->alias_name && !strcmp(pmu->alias_name, name)))
  122. return pmu;
  123. }
  124. return NULL;
  125. }
  126. struct perf_pmu *perf_pmus__find(const char *name)
  127. {
  128. struct perf_pmu *pmu;
  129. int dirfd;
  130. bool core_pmu;
  131. unsigned int to_read_pmus = 0;
  132. /*
  133. * Once PMU is loaded it stays in the list,
  134. * so we keep us from multiple reading/parsing
  135. * the pmu format definitions.
  136. */
  137. pmu = pmu_find(name);
  138. if (pmu)
  139. return pmu;
  140. if (read_pmu_types == PERF_TOOL_PMU_TYPE_ALL_MASK)
  141. return NULL;
  142. core_pmu = is_pmu_core(name);
  143. if (core_pmu && (read_pmu_types & PERF_TOOL_PMU_TYPE_PE_CORE_MASK))
  144. return NULL;
  145. dirfd = perf_pmu__event_source_devices_fd();
  146. pmu = perf_pmu__lookup(core_pmu ? &core_pmus : &other_pmus, dirfd, name,
  147. /*eager_load=*/false);
  148. close(dirfd);
  149. if (pmu)
  150. return pmu;
  151. /* Looking up an individual perf event PMU failed, check if a tool PMU should be read. */
  152. if (!strncmp(name, "hwmon_", 6))
  153. to_read_pmus |= PERF_TOOL_PMU_TYPE_HWMON_MASK;
  154. else if (!strncmp(name, "drm_", 4))
  155. to_read_pmus |= PERF_TOOL_PMU_TYPE_DRM_MASK;
  156. else if (!strcmp(name, "tool"))
  157. to_read_pmus |= PERF_TOOL_PMU_TYPE_TOOL_MASK;
  158. if (to_read_pmus) {
  159. pmu_read_sysfs(to_read_pmus);
  160. pmu = pmu_find(name);
  161. if (pmu)
  162. return pmu;
  163. }
  164. /* Read all necessary PMUs from sysfs and see if the PMU is found. */
  165. to_read_pmus = PERF_TOOL_PMU_TYPE_PE_CORE_MASK;
  166. if (!core_pmu)
  167. to_read_pmus |= PERF_TOOL_PMU_TYPE_PE_OTHER_MASK;
  168. pmu_read_sysfs(to_read_pmus);
  169. return pmu_find(name);
  170. }
  171. static struct perf_pmu *perf_pmu__find2(int dirfd, const char *name)
  172. {
  173. struct perf_pmu *pmu;
  174. bool core_pmu;
  175. /*
  176. * Once PMU is loaded it stays in the list,
  177. * so we keep us from multiple reading/parsing
  178. * the pmu format definitions.
  179. */
  180. pmu = pmu_find(name);
  181. if (pmu)
  182. return pmu;
  183. if (read_pmu_types == PERF_TOOL_PMU_TYPE_ALL_MASK)
  184. return NULL;
  185. core_pmu = is_pmu_core(name);
  186. if (core_pmu && (read_pmu_types & PERF_TOOL_PMU_TYPE_PE_CORE_MASK))
  187. return NULL;
  188. return perf_pmu__lookup(core_pmu ? &core_pmus : &other_pmus, dirfd, name,
  189. /*eager_load=*/false);
  190. }
  191. static int pmus_cmp(void *priv __maybe_unused,
  192. const struct list_head *lhs, const struct list_head *rhs)
  193. {
  194. struct perf_pmu *lhs_pmu = container_of(lhs, struct perf_pmu, list);
  195. struct perf_pmu *rhs_pmu = container_of(rhs, struct perf_pmu, list);
  196. return pmu_name_cmp(lhs_pmu->name ?: "", rhs_pmu->name ?: "");
  197. }
  198. /* Add all pmus in sysfs to pmu list: */
  199. static void pmu_read_sysfs(unsigned int to_read_types)
  200. {
  201. struct perf_pmu *tool_pmu;
  202. if ((read_pmu_types & to_read_types) == to_read_types) {
  203. /* All requested PMU types have been read. */
  204. return;
  205. }
  206. if (to_read_types & (PERF_TOOL_PMU_TYPE_PE_CORE_MASK | PERF_TOOL_PMU_TYPE_PE_OTHER_MASK)) {
  207. int fd = perf_pmu__event_source_devices_fd();
  208. struct io_dir dir;
  209. struct io_dirent64 *dent;
  210. bool core_only = (to_read_types & PERF_TOOL_PMU_TYPE_PE_OTHER_MASK) == 0;
  211. if (fd < 0)
  212. goto skip_pe_pmus;
  213. io_dir__init(&dir, fd);
  214. while ((dent = io_dir__readdir(&dir)) != NULL) {
  215. if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, ".."))
  216. continue;
  217. if (core_only && !is_pmu_core(dent->d_name))
  218. continue;
  219. /* add to static LIST_HEAD(core_pmus) or LIST_HEAD(other_pmus): */
  220. perf_pmu__find2(fd, dent->d_name);
  221. }
  222. close(fd);
  223. }
  224. skip_pe_pmus:
  225. if ((to_read_types & PERF_TOOL_PMU_TYPE_PE_CORE_MASK) && list_empty(&core_pmus)) {
  226. if (!perf_pmu__create_placeholder_core_pmu(&core_pmus))
  227. pr_err("Failure to set up any core PMUs\n");
  228. }
  229. list_sort(NULL, &core_pmus, pmus_cmp);
  230. if ((to_read_types & PERF_TOOL_PMU_TYPE_TOOL_MASK) != 0 &&
  231. (read_pmu_types & PERF_TOOL_PMU_TYPE_TOOL_MASK) == 0) {
  232. tool_pmu = tool_pmu__new();
  233. if (tool_pmu)
  234. list_add_tail(&tool_pmu->list, &other_pmus);
  235. }
  236. if ((to_read_types & PERF_TOOL_PMU_TYPE_HWMON_MASK) != 0 &&
  237. (read_pmu_types & PERF_TOOL_PMU_TYPE_HWMON_MASK) == 0)
  238. perf_pmus__read_hwmon_pmus(&other_pmus);
  239. if ((to_read_types & PERF_TOOL_PMU_TYPE_DRM_MASK) != 0 &&
  240. (read_pmu_types & PERF_TOOL_PMU_TYPE_DRM_MASK) == 0)
  241. perf_pmus__read_drm_pmus(&other_pmus);
  242. list_sort(NULL, &other_pmus, pmus_cmp);
  243. read_pmu_types |= to_read_types;
  244. }
  245. static struct perf_pmu *__perf_pmus__find_by_type(unsigned int type)
  246. {
  247. struct perf_pmu *pmu;
  248. list_for_each_entry(pmu, &core_pmus, list) {
  249. if (pmu->type == type)
  250. return pmu;
  251. }
  252. list_for_each_entry(pmu, &other_pmus, list) {
  253. if (pmu->type == type)
  254. return pmu;
  255. }
  256. return NULL;
  257. }
  258. struct perf_pmu *perf_pmus__find_by_type(unsigned int type)
  259. {
  260. unsigned int to_read_pmus;
  261. struct perf_pmu *pmu = __perf_pmus__find_by_type(type);
  262. if (pmu || (read_pmu_types == PERF_TOOL_PMU_TYPE_ALL_MASK))
  263. return pmu;
  264. if (type >= PERF_PMU_TYPE_PE_START && type <= PERF_PMU_TYPE_PE_END) {
  265. to_read_pmus = PERF_TOOL_PMU_TYPE_PE_CORE_MASK |
  266. PERF_TOOL_PMU_TYPE_PE_OTHER_MASK;
  267. } else if (type >= PERF_PMU_TYPE_DRM_START && type <= PERF_PMU_TYPE_DRM_END) {
  268. to_read_pmus = PERF_TOOL_PMU_TYPE_DRM_MASK;
  269. } else if (type >= PERF_PMU_TYPE_HWMON_START && type <= PERF_PMU_TYPE_HWMON_END) {
  270. to_read_pmus = PERF_TOOL_PMU_TYPE_HWMON_MASK;
  271. } else {
  272. to_read_pmus = PERF_TOOL_PMU_TYPE_TOOL_MASK;
  273. }
  274. pmu_read_sysfs(to_read_pmus);
  275. pmu = __perf_pmus__find_by_type(type);
  276. return pmu;
  277. }
  278. /*
  279. * pmu iterator: If pmu is NULL, we start at the begin, otherwise return the
  280. * next pmu. Returns NULL on end.
  281. */
  282. struct perf_pmu *perf_pmus__scan(struct perf_pmu *pmu)
  283. {
  284. bool use_core_pmus = !pmu || pmu->is_core;
  285. if (!pmu) {
  286. pmu_read_sysfs(PERF_TOOL_PMU_TYPE_ALL_MASK);
  287. pmu = list_prepare_entry(pmu, &core_pmus, list);
  288. }
  289. if (use_core_pmus) {
  290. list_for_each_entry_continue(pmu, &core_pmus, list)
  291. return pmu;
  292. pmu = NULL;
  293. pmu = list_prepare_entry(pmu, &other_pmus, list);
  294. }
  295. list_for_each_entry_continue(pmu, &other_pmus, list)
  296. return pmu;
  297. return NULL;
  298. }
  299. struct perf_pmu *perf_pmus__scan_core(struct perf_pmu *pmu)
  300. {
  301. if (!pmu) {
  302. pmu_read_sysfs(PERF_TOOL_PMU_TYPE_PE_CORE_MASK);
  303. return list_first_entry_or_null(&core_pmus, typeof(*pmu), list);
  304. }
  305. list_for_each_entry_continue(pmu, &core_pmus, list)
  306. return pmu;
  307. return NULL;
  308. }
  309. struct perf_pmu *perf_pmus__scan_for_event(struct perf_pmu *pmu, const char *event)
  310. {
  311. bool use_core_pmus = !pmu || pmu->is_core;
  312. if (!pmu) {
  313. /* Hwmon filename values that aren't used. */
  314. enum hwmon_type type;
  315. int number;
  316. /*
  317. * Core PMUs, other sysfs PMUs and tool PMU can take all event
  318. * types or aren't wother optimizing for.
  319. */
  320. unsigned int to_read_pmus = PERF_TOOL_PMU_TYPE_PE_CORE_MASK |
  321. PERF_TOOL_PMU_TYPE_PE_OTHER_MASK |
  322. PERF_TOOL_PMU_TYPE_TOOL_MASK;
  323. /* Could the event be a hwmon event? */
  324. if (parse_hwmon_filename(event, &type, &number, /*item=*/NULL, /*alarm=*/NULL))
  325. to_read_pmus |= PERF_TOOL_PMU_TYPE_HWMON_MASK;
  326. /* Could the event be a DRM event? */
  327. if (strlen(event) > 4 && strncmp("drm-", event, 4) == 0)
  328. to_read_pmus |= PERF_TOOL_PMU_TYPE_DRM_MASK;
  329. pmu_read_sysfs(to_read_pmus);
  330. pmu = list_prepare_entry(pmu, &core_pmus, list);
  331. }
  332. if (use_core_pmus) {
  333. list_for_each_entry_continue(pmu, &core_pmus, list)
  334. return pmu;
  335. pmu = NULL;
  336. pmu = list_prepare_entry(pmu, &other_pmus, list);
  337. }
  338. list_for_each_entry_continue(pmu, &other_pmus, list)
  339. return pmu;
  340. return NULL;
  341. }
  342. struct perf_pmu *perf_pmus__scan_matching_wildcard(struct perf_pmu *pmu, const char *wildcard)
  343. {
  344. bool use_core_pmus = !pmu || pmu->is_core;
  345. if (!pmu) {
  346. /*
  347. * Core PMUs, other sysfs PMUs and tool PMU can have any name or
  348. * aren't wother optimizing for.
  349. */
  350. unsigned int to_read_pmus = PERF_TOOL_PMU_TYPE_PE_CORE_MASK |
  351. PERF_TOOL_PMU_TYPE_PE_OTHER_MASK |
  352. PERF_TOOL_PMU_TYPE_TOOL_MASK;
  353. /*
  354. * Hwmon PMUs have an alias from a sysfs name like hwmon0,
  355. * hwmon1, etc. or have a name of hwmon_<name>. They therefore
  356. * can only have a wildcard match if the wildcard begins with
  357. * "hwmon". Similarly drm PMUs must start "drm_", avoid reading
  358. * such events unless the PMU could match.
  359. */
  360. if (strisglob(wildcard)) {
  361. to_read_pmus |= PERF_TOOL_PMU_TYPE_HWMON_MASK |
  362. PERF_TOOL_PMU_TYPE_DRM_MASK;
  363. } else if (strlen(wildcard) >= 4 && strncmp("drm_", wildcard, 4) == 0) {
  364. to_read_pmus |= PERF_TOOL_PMU_TYPE_DRM_MASK;
  365. } else if (strlen(wildcard) >= 5 && strncmp("hwmon", wildcard, 5) == 0) {
  366. to_read_pmus |= PERF_TOOL_PMU_TYPE_HWMON_MASK;
  367. }
  368. pmu_read_sysfs(to_read_pmus);
  369. pmu = list_prepare_entry(pmu, &core_pmus, list);
  370. }
  371. if (use_core_pmus) {
  372. list_for_each_entry_continue(pmu, &core_pmus, list) {
  373. if (perf_pmu__wildcard_match(pmu, wildcard))
  374. return pmu;
  375. }
  376. pmu = NULL;
  377. pmu = list_prepare_entry(pmu, &other_pmus, list);
  378. }
  379. list_for_each_entry_continue(pmu, &other_pmus, list) {
  380. if (perf_pmu__wildcard_match(pmu, wildcard))
  381. return pmu;
  382. }
  383. return NULL;
  384. }
  385. static struct perf_pmu *perf_pmus__scan_skip_duplicates(struct perf_pmu *pmu)
  386. {
  387. bool use_core_pmus = !pmu || pmu->is_core;
  388. int last_pmu_name_len = 0;
  389. const char *last_pmu_name = (pmu && pmu->name) ? pmu->name : "";
  390. if (!pmu) {
  391. pmu_read_sysfs(PERF_TOOL_PMU_TYPE_ALL_MASK);
  392. pmu = list_prepare_entry(pmu, &core_pmus, list);
  393. } else
  394. last_pmu_name_len = pmu_name_len_no_suffix(pmu->name ?: "");
  395. if (use_core_pmus) {
  396. list_for_each_entry_continue(pmu, &core_pmus, list) {
  397. int pmu_name_len = pmu_name_len_no_suffix(pmu->name ?: "");
  398. if (last_pmu_name_len == pmu_name_len &&
  399. !strncmp(last_pmu_name, pmu->name ?: "", pmu_name_len))
  400. continue;
  401. return pmu;
  402. }
  403. pmu = NULL;
  404. pmu = list_prepare_entry(pmu, &other_pmus, list);
  405. }
  406. list_for_each_entry_continue(pmu, &other_pmus, list) {
  407. int pmu_name_len = pmu_name_len_no_suffix(pmu->name ?: "");
  408. if (last_pmu_name_len == pmu_name_len &&
  409. !strncmp(last_pmu_name, pmu->name ?: "", pmu_name_len))
  410. continue;
  411. return pmu;
  412. }
  413. return NULL;
  414. }
  415. const struct perf_pmu *perf_pmus__pmu_for_pmu_filter(const char *str)
  416. {
  417. struct perf_pmu *pmu = NULL;
  418. while ((pmu = perf_pmus__scan(pmu)) != NULL) {
  419. if (!strcmp(pmu->name, str))
  420. return pmu;
  421. /* Ignore "uncore_" prefix. */
  422. if (!strncmp(pmu->name, "uncore_", 7)) {
  423. if (!strcmp(pmu->name + 7, str))
  424. return pmu;
  425. }
  426. /* Ignore "cpu_" prefix on Intel hybrid PMUs. */
  427. if (!strncmp(pmu->name, "cpu_", 4)) {
  428. if (!strcmp(pmu->name + 4, str))
  429. return pmu;
  430. }
  431. }
  432. return NULL;
  433. }
  434. /** Struct for ordering events as output in perf list. */
  435. struct sevent {
  436. /** PMU for event. */
  437. const struct perf_pmu *pmu;
  438. const char *name;
  439. const char* alias;
  440. const char *scale_unit;
  441. const char *desc;
  442. const char *long_desc;
  443. const char *encoding_desc;
  444. const char *topic;
  445. const char *pmu_name;
  446. const char *event_type_desc;
  447. bool deprecated;
  448. };
  449. static int cmp_sevent(const void *a, const void *b)
  450. {
  451. const struct sevent *as = a;
  452. const struct sevent *bs = b;
  453. bool a_iscpu, b_iscpu;
  454. int ret;
  455. /* Put extra events last. */
  456. if (!!as->desc != !!bs->desc)
  457. return !!as->desc - !!bs->desc;
  458. /* Order by topics. */
  459. ret = strcmp(as->topic ?: "", bs->topic ?: "");
  460. if (ret)
  461. return ret;
  462. /* Order CPU core events to be first */
  463. a_iscpu = as->pmu ? as->pmu->is_core : true;
  464. b_iscpu = bs->pmu ? bs->pmu->is_core : true;
  465. if (a_iscpu != b_iscpu)
  466. return a_iscpu ? -1 : 1;
  467. /* Order by PMU name. */
  468. if (as->pmu != bs->pmu) {
  469. ret = strcmp(as->pmu_name ?: "", bs->pmu_name ?: "");
  470. if (ret)
  471. return ret;
  472. }
  473. /* Order by event name. */
  474. return strcmp(as->name, bs->name);
  475. }
  476. static bool pmu_alias_is_duplicate(struct sevent *a, struct sevent *b)
  477. {
  478. /* Different names -> never duplicates */
  479. if (strcmp(a->name ?: "//", b->name ?: "//"))
  480. return false;
  481. /* Don't remove duplicates for different PMUs */
  482. return strcmp(a->pmu_name, b->pmu_name) == 0;
  483. }
  484. struct events_callback_state {
  485. struct sevent *aliases;
  486. size_t aliases_len;
  487. size_t index;
  488. };
  489. static int perf_pmus__print_pmu_events__callback(void *vstate,
  490. struct pmu_event_info *info)
  491. {
  492. struct events_callback_state *state = vstate;
  493. struct sevent *s;
  494. if (state->index >= state->aliases_len) {
  495. pr_err("Unexpected event %s/%s/\n", info->pmu->name, info->name);
  496. return 1;
  497. }
  498. assert(info->pmu != NULL || info->name != NULL);
  499. s = &state->aliases[state->index];
  500. s->pmu = info->pmu;
  501. #define COPY_STR(str) s->str = info->str ? strdup(info->str) : NULL
  502. COPY_STR(name);
  503. COPY_STR(alias);
  504. COPY_STR(scale_unit);
  505. COPY_STR(desc);
  506. COPY_STR(long_desc);
  507. COPY_STR(encoding_desc);
  508. COPY_STR(topic);
  509. COPY_STR(pmu_name);
  510. COPY_STR(event_type_desc);
  511. #undef COPY_STR
  512. s->deprecated = info->deprecated;
  513. state->index++;
  514. return 0;
  515. }
  516. void perf_pmus__print_pmu_events(const struct print_callbacks *print_cb, void *print_state)
  517. {
  518. struct perf_pmu *pmu;
  519. int printed = 0;
  520. int len;
  521. struct sevent *aliases;
  522. struct events_callback_state state;
  523. bool skip_duplicate_pmus = print_cb->skip_duplicate_pmus(print_state);
  524. struct perf_pmu *(*scan_fn)(struct perf_pmu *);
  525. if (skip_duplicate_pmus)
  526. scan_fn = perf_pmus__scan_skip_duplicates;
  527. else
  528. scan_fn = perf_pmus__scan;
  529. pmu = NULL;
  530. len = 0;
  531. while ((pmu = scan_fn(pmu)) != NULL)
  532. len += perf_pmu__num_events(pmu);
  533. aliases = zalloc(sizeof(struct sevent) * len);
  534. if (!aliases) {
  535. pr_err("FATAL: not enough memory to print PMU events\n");
  536. return;
  537. }
  538. pmu = NULL;
  539. state = (struct events_callback_state) {
  540. .aliases = aliases,
  541. .aliases_len = len,
  542. .index = 0,
  543. };
  544. while ((pmu = scan_fn(pmu)) != NULL) {
  545. perf_pmu__for_each_event(pmu, skip_duplicate_pmus, &state,
  546. perf_pmus__print_pmu_events__callback);
  547. }
  548. qsort(aliases, len, sizeof(struct sevent), cmp_sevent);
  549. for (int j = 0; j < len; j++) {
  550. /* Skip duplicates */
  551. if (j < len - 1 && pmu_alias_is_duplicate(&aliases[j], &aliases[j + 1]))
  552. goto free;
  553. print_cb->print_event(print_state,
  554. aliases[j].topic,
  555. aliases[j].pmu_name,
  556. aliases[j].pmu->type,
  557. aliases[j].name,
  558. aliases[j].alias,
  559. aliases[j].scale_unit,
  560. aliases[j].deprecated,
  561. aliases[j].event_type_desc,
  562. aliases[j].desc,
  563. aliases[j].long_desc,
  564. aliases[j].encoding_desc);
  565. free:
  566. zfree(&aliases[j].name);
  567. zfree(&aliases[j].alias);
  568. zfree(&aliases[j].scale_unit);
  569. zfree(&aliases[j].desc);
  570. zfree(&aliases[j].long_desc);
  571. zfree(&aliases[j].encoding_desc);
  572. zfree(&aliases[j].topic);
  573. zfree(&aliases[j].pmu_name);
  574. zfree(&aliases[j].event_type_desc);
  575. }
  576. if (printed && pager_in_use())
  577. printf("\n");
  578. zfree(&aliases);
  579. }
  580. struct build_format_string_args {
  581. struct strbuf short_string;
  582. struct strbuf long_string;
  583. int num_formats;
  584. };
  585. static int build_format_string(void *state, const char *name, int config,
  586. const unsigned long *bits)
  587. {
  588. struct build_format_string_args *args = state;
  589. unsigned int num_bits;
  590. int ret1, ret2 = 0;
  591. (void)config;
  592. args->num_formats++;
  593. if (args->num_formats > 1) {
  594. strbuf_addch(&args->long_string, ',');
  595. if (args->num_formats < 4)
  596. strbuf_addch(&args->short_string, ',');
  597. }
  598. num_bits = bits ? bitmap_weight(bits, PERF_PMU_FORMAT_BITS) : 0;
  599. if (num_bits <= 1) {
  600. ret1 = strbuf_addf(&args->long_string, "%s", name);
  601. if (args->num_formats < 4)
  602. ret2 = strbuf_addf(&args->short_string, "%s", name);
  603. } else if (num_bits > 8) {
  604. ret1 = strbuf_addf(&args->long_string, "%s=0..0x%llx", name,
  605. ULLONG_MAX >> (64 - num_bits));
  606. if (args->num_formats < 4) {
  607. ret2 = strbuf_addf(&args->short_string, "%s=0..0x%llx", name,
  608. ULLONG_MAX >> (64 - num_bits));
  609. }
  610. } else {
  611. ret1 = strbuf_addf(&args->long_string, "%s=0..%llu", name,
  612. ULLONG_MAX >> (64 - num_bits));
  613. if (args->num_formats < 4) {
  614. ret2 = strbuf_addf(&args->short_string, "%s=0..%llu", name,
  615. ULLONG_MAX >> (64 - num_bits));
  616. }
  617. }
  618. return ret1 < 0 ? ret1 : (ret2 < 0 ? ret2 : 0);
  619. }
  620. void perf_pmus__print_raw_pmu_events(const struct print_callbacks *print_cb, void *print_state)
  621. {
  622. bool skip_duplicate_pmus = print_cb->skip_duplicate_pmus(print_state);
  623. struct perf_pmu *(*scan_fn)(struct perf_pmu *);
  624. struct perf_pmu *pmu = NULL;
  625. if (skip_duplicate_pmus)
  626. scan_fn = perf_pmus__scan_skip_duplicates;
  627. else
  628. scan_fn = perf_pmus__scan;
  629. while ((pmu = scan_fn(pmu)) != NULL) {
  630. struct build_format_string_args format_args = {
  631. .short_string = STRBUF_INIT,
  632. .long_string = STRBUF_INIT,
  633. .num_formats = 0,
  634. };
  635. int len = pmu_name_len_no_suffix(pmu->name);
  636. const char *desc = "(see 'man perf-list' or 'man perf-record' on how to encode it)";
  637. if (!pmu->is_core)
  638. desc = NULL;
  639. strbuf_addf(&format_args.short_string, "%.*s/", len, pmu->name);
  640. strbuf_addf(&format_args.long_string, "%.*s/", len, pmu->name);
  641. perf_pmu__for_each_format(pmu, &format_args, build_format_string);
  642. if (format_args.num_formats > 3)
  643. strbuf_addf(&format_args.short_string, ",.../modifier");
  644. else
  645. strbuf_addf(&format_args.short_string, "/modifier");
  646. strbuf_addf(&format_args.long_string, "/modifier");
  647. print_cb->print_event(print_state,
  648. /*topic=*/NULL,
  649. /*pmu_name=*/NULL,
  650. pmu->type,
  651. format_args.short_string.buf,
  652. /*event_alias=*/NULL,
  653. /*scale_unit=*/NULL,
  654. /*deprecated=*/false,
  655. "Raw event descriptor",
  656. desc,
  657. /*long_desc=*/NULL,
  658. format_args.long_string.buf);
  659. strbuf_release(&format_args.short_string);
  660. strbuf_release(&format_args.long_string);
  661. }
  662. }
  663. bool perf_pmus__have_event(const char *pname, const char *name)
  664. {
  665. struct perf_pmu *pmu = perf_pmus__find(pname);
  666. return pmu && perf_pmu__have_event(pmu, name);
  667. }
  668. int perf_pmus__num_core_pmus(void)
  669. {
  670. static int count;
  671. if (!count) {
  672. struct perf_pmu *pmu = NULL;
  673. while ((pmu = perf_pmus__scan_core(pmu)) != NULL)
  674. count++;
  675. }
  676. return count;
  677. }
  678. static bool __perf_pmus__supports_extended_type(void)
  679. {
  680. struct perf_pmu *pmu = NULL;
  681. if (perf_pmus__num_core_pmus() <= 1)
  682. return false;
  683. while ((pmu = perf_pmus__scan_core(pmu)) != NULL) {
  684. if (!is_event_supported(PERF_TYPE_HARDWARE, PERF_COUNT_HW_CPU_CYCLES | ((__u64)pmu->type << PERF_PMU_TYPE_SHIFT)))
  685. return false;
  686. }
  687. return true;
  688. }
  689. static bool perf_pmus__do_support_extended_type;
  690. static void perf_pmus__init_supports_extended_type(void)
  691. {
  692. perf_pmus__do_support_extended_type = __perf_pmus__supports_extended_type();
  693. }
  694. bool perf_pmus__supports_extended_type(void)
  695. {
  696. static pthread_once_t extended_type_once = PTHREAD_ONCE_INIT;
  697. pthread_once(&extended_type_once, perf_pmus__init_supports_extended_type);
  698. return perf_pmus__do_support_extended_type;
  699. }
  700. struct perf_pmu *perf_pmus__find_by_attr(const struct perf_event_attr *attr)
  701. {
  702. struct perf_pmu *pmu = perf_pmus__find_by_type(attr->type);
  703. u32 type = attr->type;
  704. bool legacy_core_type = type == PERF_TYPE_HARDWARE || type == PERF_TYPE_HW_CACHE;
  705. if (!pmu && legacy_core_type && perf_pmus__supports_extended_type()) {
  706. type = attr->config >> PERF_PMU_TYPE_SHIFT;
  707. pmu = perf_pmus__find_by_type(type);
  708. }
  709. if (!pmu && (legacy_core_type || type == PERF_TYPE_RAW)) {
  710. /*
  711. * For legacy events, if there was no extended type info then
  712. * assume the PMU is the first core PMU.
  713. *
  714. * On architectures like ARM there is no sysfs PMU with type
  715. * PERF_TYPE_RAW, assume the RAW events are going to be handled
  716. * by the first core PMU.
  717. */
  718. pmu = perf_pmus__find_core_pmu();
  719. }
  720. return pmu;
  721. }
  722. struct perf_pmu *evsel__find_pmu(const struct evsel *evsel)
  723. {
  724. struct perf_pmu *pmu = evsel->pmu;
  725. if (pmu)
  726. return pmu;
  727. pmu = perf_pmus__find_by_attr(&evsel->core.attr);
  728. ((struct evsel *)evsel)->pmu = pmu;
  729. return pmu;
  730. }
  731. struct perf_pmu *perf_pmus__find_core_pmu(void)
  732. {
  733. return perf_pmus__scan_core(NULL);
  734. }
  735. struct perf_pmu *perf_pmus__add_test_pmu(int test_sysfs_dirfd, const char *name)
  736. {
  737. /*
  738. * Some PMU functions read from the sysfs mount point, so care is
  739. * needed, hence passing the eager_load flag to load things like the
  740. * format files.
  741. */
  742. return perf_pmu__lookup(&other_pmus, test_sysfs_dirfd, name, /*eager_load=*/true);
  743. }
  744. struct perf_pmu *perf_pmus__add_test_hwmon_pmu(const char *hwmon_dir,
  745. const char *sysfs_name,
  746. const char *name)
  747. {
  748. return hwmon_pmu__new(&other_pmus, hwmon_dir, sysfs_name, name);
  749. }
  750. struct perf_pmu *perf_pmus__fake_pmu(void)
  751. {
  752. static struct perf_pmu fake = {
  753. .name = "fake",
  754. .type = PERF_PMU_TYPE_FAKE,
  755. .format = LIST_HEAD_INIT(fake.format),
  756. };
  757. return &fake;
  758. }