evlist.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840
  1. // SPDX-License-Identifier: GPL-2.0
  2. #include <perf/evlist.h>
  3. #include <perf/evsel.h>
  4. #include <linux/bitops.h>
  5. #include <linux/list.h>
  6. #include <linux/hash.h>
  7. #include <sys/ioctl.h>
  8. #include <internal/evlist.h>
  9. #include <internal/evsel.h>
  10. #include <internal/xyarray.h>
  11. #include <internal/mmap.h>
  12. #include <internal/cpumap.h>
  13. #include <internal/threadmap.h>
  14. #include <internal/lib.h>
  15. #include <linux/zalloc.h>
  16. #include <stdlib.h>
  17. #include <errno.h>
  18. #include <unistd.h>
  19. #include <fcntl.h>
  20. #include <signal.h>
  21. #include <poll.h>
  22. #include <sys/mman.h>
  23. #include <perf/cpumap.h>
  24. #include <perf/threadmap.h>
  25. #include <api/fd/array.h>
  26. #include "internal.h"
  27. void perf_evlist__init(struct perf_evlist *evlist)
  28. {
  29. INIT_LIST_HEAD(&evlist->entries);
  30. evlist->nr_entries = 0;
  31. fdarray__init(&evlist->pollfd, 64);
  32. perf_evlist__reset_id_hash(evlist);
  33. }
  34. static void __perf_evlist__propagate_maps(struct perf_evlist *evlist,
  35. struct perf_evsel *evsel)
  36. {
  37. if (perf_cpu_map__is_empty(evsel->cpus)) {
  38. if (perf_cpu_map__is_empty(evsel->pmu_cpus)) {
  39. /*
  40. * Assume the unset PMU cpus were for a system-wide
  41. * event, like a software or tracepoint.
  42. */
  43. evsel->pmu_cpus = perf_cpu_map__new_online_cpus();
  44. }
  45. if (evlist->has_user_cpus && !evsel->system_wide) {
  46. /*
  47. * Use the user CPUs unless the evsel is set to be
  48. * system wide, such as the dummy event.
  49. */
  50. evsel->cpus = perf_cpu_map__get(evlist->user_requested_cpus);
  51. } else {
  52. /*
  53. * System wide and other modes, assume the cpu map
  54. * should be set to all PMU CPUs.
  55. */
  56. evsel->cpus = perf_cpu_map__get(evsel->pmu_cpus);
  57. }
  58. }
  59. /*
  60. * Avoid "any CPU"(-1) for uncore and PMUs that require a CPU, even if
  61. * requested.
  62. */
  63. if (evsel->requires_cpu && perf_cpu_map__has_any_cpu(evsel->cpus)) {
  64. perf_cpu_map__put(evsel->cpus);
  65. evsel->cpus = perf_cpu_map__get(evsel->pmu_cpus);
  66. }
  67. /*
  68. * Globally requested CPUs replace user requested unless the evsel is
  69. * set to be system wide.
  70. */
  71. if (evlist->has_user_cpus && !evsel->system_wide) {
  72. assert(!perf_cpu_map__has_any_cpu(evlist->user_requested_cpus));
  73. if (!perf_cpu_map__equal(evsel->cpus, evlist->user_requested_cpus)) {
  74. perf_cpu_map__put(evsel->cpus);
  75. evsel->cpus = perf_cpu_map__get(evlist->user_requested_cpus);
  76. }
  77. }
  78. /* Ensure cpus only references valid PMU CPUs. */
  79. if (!perf_cpu_map__has_any_cpu(evsel->cpus) &&
  80. !perf_cpu_map__is_subset(evsel->pmu_cpus, evsel->cpus)) {
  81. struct perf_cpu_map *tmp = perf_cpu_map__intersect(evsel->pmu_cpus, evsel->cpus);
  82. perf_cpu_map__put(evsel->cpus);
  83. evsel->cpus = tmp;
  84. }
  85. /*
  86. * Was event requested on all the PMU's CPUs but the user requested is
  87. * any CPU (-1)? If so switch to using any CPU (-1) to reduce the number
  88. * of events.
  89. */
  90. if (!evsel->system_wide &&
  91. !evsel->requires_cpu &&
  92. perf_cpu_map__equal(evsel->cpus, evsel->pmu_cpus) &&
  93. perf_cpu_map__has_any_cpu(evlist->user_requested_cpus)) {
  94. perf_cpu_map__put(evsel->cpus);
  95. evsel->cpus = perf_cpu_map__get(evlist->user_requested_cpus);
  96. }
  97. /*
  98. * Tool events may only read on the first CPU index to avoid double
  99. * counting things like duration_time. Make the evsel->cpus contain just
  100. * that single entry otherwise we may spend time changing affinity to
  101. * CPUs that just have tool events, etc.
  102. */
  103. if (evsel->reads_only_on_cpu_idx0 && perf_cpu_map__nr(evsel->cpus) > 0) {
  104. struct perf_cpu_map *srcs[3] = {
  105. evlist->all_cpus,
  106. evlist->user_requested_cpus,
  107. evsel->pmu_cpus,
  108. };
  109. for (size_t i = 0; i < ARRAY_SIZE(srcs); i++) {
  110. if (!srcs[i])
  111. continue;
  112. perf_cpu_map__put(evsel->cpus);
  113. evsel->cpus = perf_cpu_map__new_int(perf_cpu_map__cpu(srcs[i], 0).cpu);
  114. break;
  115. }
  116. }
  117. /* Sanity check assert before the evsel is potentially removed. */
  118. assert(!evsel->requires_cpu || !perf_cpu_map__has_any_cpu(evsel->cpus));
  119. /*
  120. * Empty cpu lists would eventually get opened as "any" so remove
  121. * genuinely empty ones before they're opened in the wrong place.
  122. */
  123. if (perf_cpu_map__is_empty(evsel->cpus)) {
  124. struct perf_evsel *next = perf_evlist__next(evlist, evsel);
  125. perf_evlist__remove(evlist, evsel);
  126. /* Keep idx contiguous */
  127. if (next)
  128. list_for_each_entry_from(next, &evlist->entries, node)
  129. next->idx--;
  130. return;
  131. }
  132. if (evsel->system_wide) {
  133. perf_thread_map__put(evsel->threads);
  134. evsel->threads = perf_thread_map__new_dummy();
  135. } else {
  136. perf_thread_map__put(evsel->threads);
  137. evsel->threads = perf_thread_map__get(evlist->threads);
  138. }
  139. perf_cpu_map__merge(&evlist->all_cpus, evsel->cpus);
  140. }
  141. static void perf_evlist__propagate_maps(struct perf_evlist *evlist)
  142. {
  143. evlist->needs_map_propagation = true;
  144. /* Clear the all_cpus set which will be merged into during propagation. */
  145. perf_cpu_map__put(evlist->all_cpus);
  146. evlist->all_cpus = NULL;
  147. /* 2 rounds so that reads_only_on_cpu_idx0 benefit from knowing the other CPU maps. */
  148. for (int round = 0; round < 2; round++) {
  149. struct perf_evsel *evsel, *n;
  150. list_for_each_entry_safe(evsel, n, &evlist->entries, node) {
  151. if ((!evsel->reads_only_on_cpu_idx0 && round == 0) ||
  152. (evsel->reads_only_on_cpu_idx0 && round == 1))
  153. __perf_evlist__propagate_maps(evlist, evsel);
  154. }
  155. }
  156. }
  157. void perf_evlist__add(struct perf_evlist *evlist,
  158. struct perf_evsel *evsel)
  159. {
  160. evsel->idx = evlist->nr_entries;
  161. list_add_tail(&evsel->node, &evlist->entries);
  162. evlist->nr_entries += 1;
  163. if (evlist->needs_map_propagation)
  164. __perf_evlist__propagate_maps(evlist, evsel);
  165. }
  166. void perf_evlist__remove(struct perf_evlist *evlist,
  167. struct perf_evsel *evsel)
  168. {
  169. list_del_init(&evsel->node);
  170. evlist->nr_entries -= 1;
  171. }
  172. struct perf_evlist *perf_evlist__new(void)
  173. {
  174. struct perf_evlist *evlist = zalloc(sizeof(*evlist));
  175. if (evlist != NULL)
  176. perf_evlist__init(evlist);
  177. return evlist;
  178. }
  179. struct perf_evsel *
  180. perf_evlist__next(struct perf_evlist *evlist, struct perf_evsel *prev)
  181. {
  182. struct perf_evsel *next;
  183. if (!prev) {
  184. next = list_first_entry(&evlist->entries,
  185. struct perf_evsel,
  186. node);
  187. } else {
  188. next = list_next_entry(prev, node);
  189. }
  190. /* Empty list is noticed here so don't need checking on entry. */
  191. if (&next->node == &evlist->entries)
  192. return NULL;
  193. return next;
  194. }
  195. static void perf_evlist__purge(struct perf_evlist *evlist)
  196. {
  197. struct perf_evsel *pos, *n;
  198. perf_evlist__for_each_entry_safe(evlist, n, pos) {
  199. list_del_init(&pos->node);
  200. perf_evsel__delete(pos);
  201. }
  202. evlist->nr_entries = 0;
  203. }
  204. void perf_evlist__exit(struct perf_evlist *evlist)
  205. {
  206. perf_cpu_map__put(evlist->user_requested_cpus);
  207. perf_cpu_map__put(evlist->all_cpus);
  208. perf_thread_map__put(evlist->threads);
  209. evlist->user_requested_cpus = NULL;
  210. evlist->all_cpus = NULL;
  211. evlist->threads = NULL;
  212. fdarray__exit(&evlist->pollfd);
  213. }
  214. void perf_evlist__delete(struct perf_evlist *evlist)
  215. {
  216. if (evlist == NULL)
  217. return;
  218. perf_evlist__munmap(evlist);
  219. perf_evlist__close(evlist);
  220. perf_evlist__purge(evlist);
  221. perf_evlist__exit(evlist);
  222. free(evlist);
  223. }
  224. void perf_evlist__set_maps(struct perf_evlist *evlist,
  225. struct perf_cpu_map *cpus,
  226. struct perf_thread_map *threads)
  227. {
  228. /*
  229. * Allow for the possibility that one or another of the maps isn't being
  230. * changed i.e. don't put it. Note we are assuming the maps that are
  231. * being applied are brand new and evlist is taking ownership of the
  232. * original reference count of 1. If that is not the case it is up to
  233. * the caller to increase the reference count.
  234. */
  235. if (cpus != evlist->user_requested_cpus) {
  236. perf_cpu_map__put(evlist->user_requested_cpus);
  237. evlist->user_requested_cpus = perf_cpu_map__get(cpus);
  238. }
  239. if (threads != evlist->threads) {
  240. perf_thread_map__put(evlist->threads);
  241. evlist->threads = perf_thread_map__get(threads);
  242. }
  243. perf_evlist__propagate_maps(evlist);
  244. }
  245. int perf_evlist__open(struct perf_evlist *evlist)
  246. {
  247. struct perf_evsel *evsel;
  248. int err;
  249. perf_evlist__for_each_entry(evlist, evsel) {
  250. err = perf_evsel__open(evsel, evsel->cpus, evsel->threads);
  251. if (err < 0)
  252. goto out_err;
  253. }
  254. return 0;
  255. out_err:
  256. perf_evlist__close(evlist);
  257. return err;
  258. }
  259. void perf_evlist__close(struct perf_evlist *evlist)
  260. {
  261. struct perf_evsel *evsel;
  262. perf_evlist__for_each_entry_reverse(evlist, evsel)
  263. perf_evsel__close(evsel);
  264. }
  265. void perf_evlist__enable(struct perf_evlist *evlist)
  266. {
  267. struct perf_evsel *evsel;
  268. perf_evlist__for_each_entry(evlist, evsel)
  269. perf_evsel__enable(evsel);
  270. }
  271. void perf_evlist__disable(struct perf_evlist *evlist)
  272. {
  273. struct perf_evsel *evsel;
  274. perf_evlist__for_each_entry(evlist, evsel)
  275. perf_evsel__disable(evsel);
  276. }
  277. u64 perf_evlist__read_format(struct perf_evlist *evlist)
  278. {
  279. struct perf_evsel *first = perf_evlist__first(evlist);
  280. return first->attr.read_format;
  281. }
  282. #define SID(e, x, y) xyarray__entry(e->sample_id, x, y)
  283. static void perf_evlist__id_hash(struct perf_evlist *evlist,
  284. struct perf_evsel *evsel,
  285. int cpu_map_idx, int thread, u64 id)
  286. {
  287. int hash;
  288. struct perf_sample_id *sid = SID(evsel, cpu_map_idx, thread);
  289. sid->id = id;
  290. sid->evsel = evsel;
  291. hash = hash_64(sid->id, PERF_EVLIST__HLIST_BITS);
  292. hlist_add_head(&sid->node, &evlist->heads[hash]);
  293. }
  294. void perf_evlist__reset_id_hash(struct perf_evlist *evlist)
  295. {
  296. int i;
  297. for (i = 0; i < PERF_EVLIST__HLIST_SIZE; ++i)
  298. INIT_HLIST_HEAD(&evlist->heads[i]);
  299. }
  300. void perf_evlist__id_add(struct perf_evlist *evlist,
  301. struct perf_evsel *evsel,
  302. int cpu_map_idx, int thread, u64 id)
  303. {
  304. if (!SID(evsel, cpu_map_idx, thread))
  305. return;
  306. perf_evlist__id_hash(evlist, evsel, cpu_map_idx, thread, id);
  307. evsel->id[evsel->ids++] = id;
  308. }
  309. int perf_evlist__id_add_fd(struct perf_evlist *evlist,
  310. struct perf_evsel *evsel,
  311. int cpu_map_idx, int thread, int fd)
  312. {
  313. u64 read_data[4] = { 0, };
  314. int id_idx = 1; /* The first entry is the counter value */
  315. u64 id;
  316. int ret;
  317. if (!SID(evsel, cpu_map_idx, thread))
  318. return -1;
  319. ret = ioctl(fd, PERF_EVENT_IOC_ID, &id);
  320. if (!ret)
  321. goto add;
  322. if (errno != ENOTTY)
  323. return -1;
  324. /* Legacy way to get event id.. All hail to old kernels! */
  325. /*
  326. * This way does not work with group format read, so bail
  327. * out in that case.
  328. */
  329. if (perf_evlist__read_format(evlist) & PERF_FORMAT_GROUP)
  330. return -1;
  331. if (!(evsel->attr.read_format & PERF_FORMAT_ID) ||
  332. read(fd, &read_data, sizeof(read_data)) == -1)
  333. return -1;
  334. if (evsel->attr.read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
  335. ++id_idx;
  336. if (evsel->attr.read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
  337. ++id_idx;
  338. id = read_data[id_idx];
  339. add:
  340. perf_evlist__id_add(evlist, evsel, cpu_map_idx, thread, id);
  341. return 0;
  342. }
  343. int perf_evlist__alloc_pollfd(struct perf_evlist *evlist)
  344. {
  345. int nr_cpus = perf_cpu_map__nr(evlist->all_cpus);
  346. int nr_threads = perf_thread_map__nr(evlist->threads);
  347. int nfds = 0;
  348. struct perf_evsel *evsel;
  349. perf_evlist__for_each_entry(evlist, evsel) {
  350. if (evsel->system_wide)
  351. nfds += nr_cpus;
  352. else
  353. nfds += nr_cpus * nr_threads;
  354. }
  355. if (fdarray__available_entries(&evlist->pollfd) < nfds &&
  356. fdarray__grow(&evlist->pollfd, nfds) < 0)
  357. return -ENOMEM;
  358. return 0;
  359. }
  360. int perf_evlist__add_pollfd(struct perf_evlist *evlist, int fd,
  361. void *ptr, short revent, enum fdarray_flags flags)
  362. {
  363. int pos = fdarray__add(&evlist->pollfd, fd, revent | POLLERR | POLLHUP, flags);
  364. if (pos >= 0) {
  365. evlist->pollfd.priv[pos].ptr = ptr;
  366. fcntl(fd, F_SETFL, O_NONBLOCK);
  367. }
  368. return pos;
  369. }
  370. static void perf_evlist__munmap_filtered(struct fdarray *fda, int fd,
  371. void *arg __maybe_unused)
  372. {
  373. struct perf_mmap *map = fda->priv[fd].ptr;
  374. if (map)
  375. perf_mmap__put(map);
  376. }
  377. int perf_evlist__filter_pollfd(struct perf_evlist *evlist, short revents_and_mask)
  378. {
  379. return fdarray__filter(&evlist->pollfd, revents_and_mask,
  380. perf_evlist__munmap_filtered, NULL);
  381. }
  382. int perf_evlist__poll(struct perf_evlist *evlist, int timeout)
  383. {
  384. return fdarray__poll(&evlist->pollfd, timeout);
  385. }
  386. static struct perf_mmap* perf_evlist__alloc_mmap(struct perf_evlist *evlist, bool overwrite)
  387. {
  388. int i;
  389. struct perf_mmap *map;
  390. map = zalloc(evlist->nr_mmaps * sizeof(struct perf_mmap));
  391. if (!map)
  392. return NULL;
  393. for (i = 0; i < evlist->nr_mmaps; i++) {
  394. struct perf_mmap *prev = i ? &map[i - 1] : NULL;
  395. /*
  396. * When the perf_mmap() call is made we grab one refcount, plus
  397. * one extra to let perf_mmap__consume() get the last
  398. * events after all real references (perf_mmap__get()) are
  399. * dropped.
  400. *
  401. * Each PERF_EVENT_IOC_SET_OUTPUT points to this mmap and
  402. * thus does perf_mmap__get() on it.
  403. */
  404. perf_mmap__init(&map[i], prev, overwrite, NULL);
  405. }
  406. return map;
  407. }
  408. static void perf_evsel__set_sid_idx(struct perf_evsel *evsel, int idx, int cpu, int thread)
  409. {
  410. struct perf_sample_id *sid = SID(evsel, cpu, thread);
  411. sid->idx = idx;
  412. sid->cpu = perf_cpu_map__cpu(evsel->cpus, cpu);
  413. sid->tid = perf_thread_map__pid(evsel->threads, thread);
  414. }
  415. static struct perf_mmap*
  416. perf_evlist__mmap_cb_get(struct perf_evlist *evlist, bool overwrite, int idx)
  417. {
  418. struct perf_mmap *maps;
  419. maps = overwrite ? evlist->mmap_ovw : evlist->mmap;
  420. if (!maps) {
  421. maps = perf_evlist__alloc_mmap(evlist, overwrite);
  422. if (!maps)
  423. return NULL;
  424. if (overwrite)
  425. evlist->mmap_ovw = maps;
  426. else
  427. evlist->mmap = maps;
  428. }
  429. return &maps[idx];
  430. }
  431. #define FD(e, x, y) (*(int *) xyarray__entry(e->fd, x, y))
  432. static int
  433. perf_evlist__mmap_cb_mmap(struct perf_mmap *map, struct perf_mmap_param *mp,
  434. int output, struct perf_cpu cpu)
  435. {
  436. return perf_mmap__mmap(map, mp, output, cpu);
  437. }
  438. static void perf_evlist__set_mmap_first(struct perf_evlist *evlist, struct perf_mmap *map,
  439. bool overwrite)
  440. {
  441. if (overwrite)
  442. evlist->mmap_ovw_first = map;
  443. else
  444. evlist->mmap_first = map;
  445. }
  446. static int
  447. mmap_per_evsel(struct perf_evlist *evlist, struct perf_evlist_mmap_ops *ops,
  448. int idx, struct perf_mmap_param *mp, int cpu_idx,
  449. int thread, int *_output, int *_output_overwrite, int *nr_mmaps)
  450. {
  451. struct perf_cpu evlist_cpu = perf_cpu_map__cpu(evlist->all_cpus, cpu_idx);
  452. struct perf_evsel *evsel;
  453. int revent;
  454. perf_evlist__for_each_entry(evlist, evsel) {
  455. bool overwrite = evsel->attr.write_backward;
  456. enum fdarray_flags flgs;
  457. struct perf_mmap *map;
  458. int *output, fd, cpu;
  459. if (evsel->system_wide && thread)
  460. continue;
  461. cpu = perf_cpu_map__idx(evsel->cpus, evlist_cpu);
  462. if (cpu == -1)
  463. continue;
  464. map = ops->get(evlist, overwrite, idx);
  465. if (map == NULL)
  466. return -ENOMEM;
  467. if (overwrite) {
  468. mp->prot = PROT_READ;
  469. output = _output_overwrite;
  470. } else {
  471. mp->prot = PROT_READ | PROT_WRITE;
  472. output = _output;
  473. }
  474. fd = FD(evsel, cpu, thread);
  475. if (*output == -1) {
  476. *output = fd;
  477. /*
  478. * The last one will be done at perf_mmap__consume(), so that we
  479. * make sure we don't prevent tools from consuming every last event in
  480. * the ring buffer.
  481. *
  482. * I.e. we can get the POLLHUP meaning that the fd doesn't exist
  483. * anymore, but the last events for it are still in the ring buffer,
  484. * waiting to be consumed.
  485. *
  486. * Tools can chose to ignore this at their own discretion, but the
  487. * evlist layer can't just drop it when filtering events in
  488. * perf_evlist__filter_pollfd().
  489. */
  490. refcount_set(&map->refcnt, 2);
  491. if (ops->idx)
  492. ops->idx(evlist, evsel, mp, idx);
  493. /* Debug message used by test scripts */
  494. pr_debug("idx %d: mmapping fd %d\n", idx, *output);
  495. if (ops->mmap(map, mp, *output, evlist_cpu) < 0)
  496. return -1;
  497. *nr_mmaps += 1;
  498. if (!idx)
  499. perf_evlist__set_mmap_first(evlist, map, overwrite);
  500. } else {
  501. /* Debug message used by test scripts */
  502. pr_debug("idx %d: set output fd %d -> %d\n", idx, fd, *output);
  503. if (ioctl(fd, PERF_EVENT_IOC_SET_OUTPUT, *output) != 0)
  504. return -1;
  505. perf_mmap__get(map);
  506. }
  507. revent = !overwrite ? POLLIN : 0;
  508. flgs = evsel->system_wide ? fdarray_flag__nonfilterable : fdarray_flag__default;
  509. if (perf_evlist__add_pollfd(evlist, fd, map, revent, flgs) < 0) {
  510. perf_mmap__put(map);
  511. return -1;
  512. }
  513. if (evsel->attr.read_format & PERF_FORMAT_ID) {
  514. if (perf_evlist__id_add_fd(evlist, evsel, cpu, thread,
  515. fd) < 0)
  516. return -1;
  517. perf_evsel__set_sid_idx(evsel, idx, cpu, thread);
  518. }
  519. }
  520. return 0;
  521. }
  522. static int
  523. mmap_per_thread(struct perf_evlist *evlist, struct perf_evlist_mmap_ops *ops,
  524. struct perf_mmap_param *mp)
  525. {
  526. int nr_threads = perf_thread_map__nr(evlist->threads);
  527. int nr_cpus = perf_cpu_map__nr(evlist->all_cpus);
  528. int cpu, thread, idx = 0;
  529. int nr_mmaps = 0;
  530. pr_debug("%s: nr cpu values (may include -1) %d nr threads %d\n",
  531. __func__, nr_cpus, nr_threads);
  532. /* per-thread mmaps */
  533. for (thread = 0; thread < nr_threads; thread++, idx++) {
  534. int output = -1;
  535. int output_overwrite = -1;
  536. if (mmap_per_evsel(evlist, ops, idx, mp, 0, thread, &output,
  537. &output_overwrite, &nr_mmaps))
  538. goto out_unmap;
  539. }
  540. /* system-wide mmaps i.e. per-cpu */
  541. for (cpu = 1; cpu < nr_cpus; cpu++, idx++) {
  542. int output = -1;
  543. int output_overwrite = -1;
  544. if (mmap_per_evsel(evlist, ops, idx, mp, cpu, 0, &output,
  545. &output_overwrite, &nr_mmaps))
  546. goto out_unmap;
  547. }
  548. if (nr_mmaps != evlist->nr_mmaps)
  549. pr_err("Miscounted nr_mmaps %d vs %d\n", nr_mmaps, evlist->nr_mmaps);
  550. return 0;
  551. out_unmap:
  552. perf_evlist__munmap(evlist);
  553. return -1;
  554. }
  555. static int
  556. mmap_per_cpu(struct perf_evlist *evlist, struct perf_evlist_mmap_ops *ops,
  557. struct perf_mmap_param *mp)
  558. {
  559. int nr_threads = perf_thread_map__nr(evlist->threads);
  560. int nr_cpus = perf_cpu_map__nr(evlist->all_cpus);
  561. int nr_mmaps = 0;
  562. int cpu, thread;
  563. pr_debug("%s: nr cpu values %d nr threads %d\n", __func__, nr_cpus, nr_threads);
  564. for (cpu = 0; cpu < nr_cpus; cpu++) {
  565. int output = -1;
  566. int output_overwrite = -1;
  567. for (thread = 0; thread < nr_threads; thread++) {
  568. if (mmap_per_evsel(evlist, ops, cpu, mp, cpu,
  569. thread, &output, &output_overwrite, &nr_mmaps))
  570. goto out_unmap;
  571. }
  572. }
  573. if (nr_mmaps != evlist->nr_mmaps)
  574. pr_err("Miscounted nr_mmaps %d vs %d\n", nr_mmaps, evlist->nr_mmaps);
  575. return 0;
  576. out_unmap:
  577. perf_evlist__munmap(evlist);
  578. return -1;
  579. }
  580. static int perf_evlist__nr_mmaps(struct perf_evlist *evlist)
  581. {
  582. int nr_mmaps;
  583. /* One for each CPU */
  584. nr_mmaps = perf_cpu_map__nr(evlist->all_cpus);
  585. if (perf_cpu_map__has_any_cpu_or_is_empty(evlist->all_cpus)) {
  586. /* Plus one for each thread */
  587. nr_mmaps += perf_thread_map__nr(evlist->threads);
  588. /* Minus the per-thread CPU (-1) */
  589. nr_mmaps -= 1;
  590. }
  591. return nr_mmaps;
  592. }
  593. int perf_evlist__mmap_ops(struct perf_evlist *evlist,
  594. struct perf_evlist_mmap_ops *ops,
  595. struct perf_mmap_param *mp)
  596. {
  597. const struct perf_cpu_map *cpus = evlist->all_cpus;
  598. struct perf_evsel *evsel;
  599. if (!ops || !ops->get || !ops->mmap)
  600. return -EINVAL;
  601. mp->mask = evlist->mmap_len - page_size - 1;
  602. evlist->nr_mmaps = perf_evlist__nr_mmaps(evlist);
  603. perf_evlist__for_each_entry(evlist, evsel) {
  604. if ((evsel->attr.read_format & PERF_FORMAT_ID) &&
  605. evsel->sample_id == NULL &&
  606. perf_evsel__alloc_id(evsel, evsel->fd->max_x, evsel->fd->max_y) < 0)
  607. return -ENOMEM;
  608. }
  609. if (evlist->pollfd.entries == NULL && perf_evlist__alloc_pollfd(evlist) < 0)
  610. return -ENOMEM;
  611. if (perf_cpu_map__has_any_cpu_or_is_empty(cpus))
  612. return mmap_per_thread(evlist, ops, mp);
  613. return mmap_per_cpu(evlist, ops, mp);
  614. }
  615. int perf_evlist__mmap(struct perf_evlist *evlist, int pages)
  616. {
  617. struct perf_mmap_param mp;
  618. struct perf_evlist_mmap_ops ops = {
  619. .get = perf_evlist__mmap_cb_get,
  620. .mmap = perf_evlist__mmap_cb_mmap,
  621. };
  622. evlist->mmap_len = (pages + 1) * page_size;
  623. return perf_evlist__mmap_ops(evlist, &ops, &mp);
  624. }
  625. void perf_evlist__munmap(struct perf_evlist *evlist)
  626. {
  627. int i;
  628. if (evlist->mmap) {
  629. for (i = 0; i < evlist->nr_mmaps; i++)
  630. perf_mmap__munmap(&evlist->mmap[i]);
  631. }
  632. if (evlist->mmap_ovw) {
  633. for (i = 0; i < evlist->nr_mmaps; i++)
  634. perf_mmap__munmap(&evlist->mmap_ovw[i]);
  635. }
  636. zfree(&evlist->mmap);
  637. zfree(&evlist->mmap_ovw);
  638. }
  639. struct perf_mmap*
  640. perf_evlist__next_mmap(struct perf_evlist *evlist, struct perf_mmap *map,
  641. bool overwrite)
  642. {
  643. if (map)
  644. return map->next;
  645. return overwrite ? evlist->mmap_ovw_first : evlist->mmap_first;
  646. }
  647. void __perf_evlist__set_leader(struct list_head *list, struct perf_evsel *leader)
  648. {
  649. struct perf_evsel *evsel;
  650. int n = 0;
  651. __perf_evlist__for_each_entry(list, evsel) {
  652. evsel->leader = leader;
  653. n++;
  654. }
  655. leader->nr_members = n;
  656. }
  657. void perf_evlist__set_leader(struct perf_evlist *evlist)
  658. {
  659. if (evlist->nr_entries) {
  660. struct perf_evsel *first = list_entry(evlist->entries.next,
  661. struct perf_evsel, node);
  662. __perf_evlist__set_leader(&evlist->entries, first);
  663. }
  664. }
  665. int perf_evlist__nr_groups(struct perf_evlist *evlist)
  666. {
  667. struct perf_evsel *evsel;
  668. int nr_groups = 0;
  669. perf_evlist__for_each_evsel(evlist, evsel) {
  670. /*
  671. * evsels by default have a nr_members of 1, and they are their
  672. * own leader. If the nr_members is >1 then this is an
  673. * indication of a group.
  674. */
  675. if (evsel->leader == evsel && evsel->nr_members > 1)
  676. nr_groups++;
  677. }
  678. return nr_groups;
  679. }
  680. void perf_evlist__go_system_wide(struct perf_evlist *evlist, struct perf_evsel *evsel)
  681. {
  682. if (!evsel->system_wide) {
  683. evsel->system_wide = true;
  684. if (evlist->needs_map_propagation)
  685. __perf_evlist__propagate_maps(evlist, evsel);
  686. }
  687. }