intel-bts.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466
  1. /*
  2. * intel-bts.c: Intel Processor Trace support
  3. * Copyright (c) 2013-2015, Intel Corporation.
  4. *
  5. * This program is free software; you can redistribute it and/or modify it
  6. * under the terms and conditions of the GNU General Public License,
  7. * version 2, as published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope it will be useful, but WITHOUT
  10. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  12. * more details.
  13. *
  14. */
  15. #include <linux/kernel.h>
  16. #include <linux/types.h>
  17. #include <linux/bitops.h>
  18. #include <linux/log2.h>
  19. #include "../../util/cpumap.h"
  20. #include "../../util/evsel.h"
  21. #include "../../util/evlist.h"
  22. #include "../../util/session.h"
  23. #include "../../util/util.h"
  24. #include "../../util/pmu.h"
  25. #include "../../util/debug.h"
  26. #include "../../util/tsc.h"
  27. #include "../../util/auxtrace.h"
  28. #include "../../util/intel-bts.h"
  29. #define KiB(x) ((x) * 1024)
  30. #define MiB(x) ((x) * 1024 * 1024)
  31. #define KiB_MASK(x) (KiB(x) - 1)
  32. #define MiB_MASK(x) (MiB(x) - 1)
  33. #define INTEL_BTS_DFLT_SAMPLE_SIZE KiB(4)
  34. #define INTEL_BTS_MAX_SAMPLE_SIZE KiB(60)
  35. struct intel_bts_snapshot_ref {
  36. void *ref_buf;
  37. size_t ref_offset;
  38. bool wrapped;
  39. };
  40. struct intel_bts_recording {
  41. struct auxtrace_record itr;
  42. struct perf_pmu *intel_bts_pmu;
  43. struct perf_evlist *evlist;
  44. bool snapshot_mode;
  45. size_t snapshot_size;
  46. int snapshot_ref_cnt;
  47. struct intel_bts_snapshot_ref *snapshot_refs;
  48. };
  49. struct branch {
  50. u64 from;
  51. u64 to;
  52. u64 misc;
  53. };
  54. static size_t
  55. intel_bts_info_priv_size(struct auxtrace_record *itr __maybe_unused,
  56. struct perf_evlist *evlist __maybe_unused)
  57. {
  58. return INTEL_BTS_AUXTRACE_PRIV_SIZE;
  59. }
  60. static int intel_bts_info_fill(struct auxtrace_record *itr,
  61. struct perf_session *session,
  62. struct auxtrace_info_event *auxtrace_info,
  63. size_t priv_size)
  64. {
  65. struct intel_bts_recording *btsr =
  66. container_of(itr, struct intel_bts_recording, itr);
  67. struct perf_pmu *intel_bts_pmu = btsr->intel_bts_pmu;
  68. struct perf_event_mmap_page *pc;
  69. struct perf_tsc_conversion tc = { .time_mult = 0, };
  70. bool cap_user_time_zero = false;
  71. int err;
  72. if (priv_size != INTEL_BTS_AUXTRACE_PRIV_SIZE)
  73. return -EINVAL;
  74. if (!session->evlist->nr_mmaps)
  75. return -EINVAL;
  76. pc = session->evlist->mmap[0].base;
  77. if (pc) {
  78. err = perf_read_tsc_conversion(pc, &tc);
  79. if (err) {
  80. if (err != -EOPNOTSUPP)
  81. return err;
  82. } else {
  83. cap_user_time_zero = tc.time_mult != 0;
  84. }
  85. if (!cap_user_time_zero)
  86. ui__warning("Intel BTS: TSC not available\n");
  87. }
  88. auxtrace_info->type = PERF_AUXTRACE_INTEL_BTS;
  89. auxtrace_info->priv[INTEL_BTS_PMU_TYPE] = intel_bts_pmu->type;
  90. auxtrace_info->priv[INTEL_BTS_TIME_SHIFT] = tc.time_shift;
  91. auxtrace_info->priv[INTEL_BTS_TIME_MULT] = tc.time_mult;
  92. auxtrace_info->priv[INTEL_BTS_TIME_ZERO] = tc.time_zero;
  93. auxtrace_info->priv[INTEL_BTS_CAP_USER_TIME_ZERO] = cap_user_time_zero;
  94. auxtrace_info->priv[INTEL_BTS_SNAPSHOT_MODE] = btsr->snapshot_mode;
  95. return 0;
  96. }
  97. static int intel_bts_recording_options(struct auxtrace_record *itr,
  98. struct perf_evlist *evlist,
  99. struct record_opts *opts)
  100. {
  101. struct intel_bts_recording *btsr =
  102. container_of(itr, struct intel_bts_recording, itr);
  103. struct perf_pmu *intel_bts_pmu = btsr->intel_bts_pmu;
  104. struct perf_evsel *evsel, *intel_bts_evsel = NULL;
  105. const struct cpu_map *cpus = evlist->cpus;
  106. bool privileged = geteuid() == 0 || perf_event_paranoid() < 0;
  107. btsr->evlist = evlist;
  108. btsr->snapshot_mode = opts->auxtrace_snapshot_mode;
  109. evlist__for_each_entry(evlist, evsel) {
  110. if (evsel->attr.type == intel_bts_pmu->type) {
  111. if (intel_bts_evsel) {
  112. pr_err("There may be only one " INTEL_BTS_PMU_NAME " event\n");
  113. return -EINVAL;
  114. }
  115. evsel->attr.freq = 0;
  116. evsel->attr.sample_period = 1;
  117. intel_bts_evsel = evsel;
  118. opts->full_auxtrace = true;
  119. }
  120. }
  121. if (opts->auxtrace_snapshot_mode && !opts->full_auxtrace) {
  122. pr_err("Snapshot mode (-S option) requires " INTEL_BTS_PMU_NAME " PMU event (-e " INTEL_BTS_PMU_NAME ")\n");
  123. return -EINVAL;
  124. }
  125. if (!opts->full_auxtrace)
  126. return 0;
  127. if (opts->full_auxtrace && !cpu_map__empty(cpus)) {
  128. pr_err(INTEL_BTS_PMU_NAME " does not support per-cpu recording\n");
  129. return -EINVAL;
  130. }
  131. /* Set default sizes for snapshot mode */
  132. if (opts->auxtrace_snapshot_mode) {
  133. if (!opts->auxtrace_snapshot_size && !opts->auxtrace_mmap_pages) {
  134. if (privileged) {
  135. opts->auxtrace_mmap_pages = MiB(4) / page_size;
  136. } else {
  137. opts->auxtrace_mmap_pages = KiB(128) / page_size;
  138. if (opts->mmap_pages == UINT_MAX)
  139. opts->mmap_pages = KiB(256) / page_size;
  140. }
  141. } else if (!opts->auxtrace_mmap_pages && !privileged &&
  142. opts->mmap_pages == UINT_MAX) {
  143. opts->mmap_pages = KiB(256) / page_size;
  144. }
  145. if (!opts->auxtrace_snapshot_size)
  146. opts->auxtrace_snapshot_size =
  147. opts->auxtrace_mmap_pages * (size_t)page_size;
  148. if (!opts->auxtrace_mmap_pages) {
  149. size_t sz = opts->auxtrace_snapshot_size;
  150. sz = round_up(sz, page_size) / page_size;
  151. opts->auxtrace_mmap_pages = roundup_pow_of_two(sz);
  152. }
  153. if (opts->auxtrace_snapshot_size >
  154. opts->auxtrace_mmap_pages * (size_t)page_size) {
  155. pr_err("Snapshot size %zu must not be greater than AUX area tracing mmap size %zu\n",
  156. opts->auxtrace_snapshot_size,
  157. opts->auxtrace_mmap_pages * (size_t)page_size);
  158. return -EINVAL;
  159. }
  160. if (!opts->auxtrace_snapshot_size || !opts->auxtrace_mmap_pages) {
  161. pr_err("Failed to calculate default snapshot size and/or AUX area tracing mmap pages\n");
  162. return -EINVAL;
  163. }
  164. pr_debug2("Intel BTS snapshot size: %zu\n",
  165. opts->auxtrace_snapshot_size);
  166. }
  167. /* Set default sizes for full trace mode */
  168. if (opts->full_auxtrace && !opts->auxtrace_mmap_pages) {
  169. if (privileged) {
  170. opts->auxtrace_mmap_pages = MiB(4) / page_size;
  171. } else {
  172. opts->auxtrace_mmap_pages = KiB(128) / page_size;
  173. if (opts->mmap_pages == UINT_MAX)
  174. opts->mmap_pages = KiB(256) / page_size;
  175. }
  176. }
  177. /* Validate auxtrace_mmap_pages */
  178. if (opts->auxtrace_mmap_pages) {
  179. size_t sz = opts->auxtrace_mmap_pages * (size_t)page_size;
  180. size_t min_sz;
  181. if (opts->auxtrace_snapshot_mode)
  182. min_sz = KiB(4);
  183. else
  184. min_sz = KiB(8);
  185. if (sz < min_sz || !is_power_of_2(sz)) {
  186. pr_err("Invalid mmap size for Intel BTS: must be at least %zuKiB and a power of 2\n",
  187. min_sz / 1024);
  188. return -EINVAL;
  189. }
  190. }
  191. if (intel_bts_evsel) {
  192. /*
  193. * To obtain the auxtrace buffer file descriptor, the auxtrace event
  194. * must come first.
  195. */
  196. perf_evlist__to_front(evlist, intel_bts_evsel);
  197. /*
  198. * In the case of per-cpu mmaps, we need the CPU on the
  199. * AUX event.
  200. */
  201. if (!cpu_map__empty(cpus))
  202. perf_evsel__set_sample_bit(intel_bts_evsel, CPU);
  203. }
  204. /* Add dummy event to keep tracking */
  205. if (opts->full_auxtrace) {
  206. struct perf_evsel *tracking_evsel;
  207. int err;
  208. err = parse_events(evlist, "dummy:u", NULL);
  209. if (err)
  210. return err;
  211. tracking_evsel = perf_evlist__last(evlist);
  212. perf_evlist__set_tracking_event(evlist, tracking_evsel);
  213. tracking_evsel->attr.freq = 0;
  214. tracking_evsel->attr.sample_period = 1;
  215. }
  216. return 0;
  217. }
  218. static int intel_bts_parse_snapshot_options(struct auxtrace_record *itr,
  219. struct record_opts *opts,
  220. const char *str)
  221. {
  222. struct intel_bts_recording *btsr =
  223. container_of(itr, struct intel_bts_recording, itr);
  224. unsigned long long snapshot_size = 0;
  225. char *endptr;
  226. if (str) {
  227. snapshot_size = strtoull(str, &endptr, 0);
  228. if (*endptr || snapshot_size > SIZE_MAX)
  229. return -1;
  230. }
  231. opts->auxtrace_snapshot_mode = true;
  232. opts->auxtrace_snapshot_size = snapshot_size;
  233. btsr->snapshot_size = snapshot_size;
  234. return 0;
  235. }
  236. static u64 intel_bts_reference(struct auxtrace_record *itr __maybe_unused)
  237. {
  238. return rdtsc();
  239. }
  240. static int intel_bts_alloc_snapshot_refs(struct intel_bts_recording *btsr,
  241. int idx)
  242. {
  243. const size_t sz = sizeof(struct intel_bts_snapshot_ref);
  244. int cnt = btsr->snapshot_ref_cnt, new_cnt = cnt * 2;
  245. struct intel_bts_snapshot_ref *refs;
  246. if (!new_cnt)
  247. new_cnt = 16;
  248. while (new_cnt <= idx)
  249. new_cnt *= 2;
  250. refs = calloc(new_cnt, sz);
  251. if (!refs)
  252. return -ENOMEM;
  253. memcpy(refs, btsr->snapshot_refs, cnt * sz);
  254. btsr->snapshot_refs = refs;
  255. btsr->snapshot_ref_cnt = new_cnt;
  256. return 0;
  257. }
  258. static void intel_bts_free_snapshot_refs(struct intel_bts_recording *btsr)
  259. {
  260. int i;
  261. for (i = 0; i < btsr->snapshot_ref_cnt; i++)
  262. zfree(&btsr->snapshot_refs[i].ref_buf);
  263. zfree(&btsr->snapshot_refs);
  264. }
  265. static void intel_bts_recording_free(struct auxtrace_record *itr)
  266. {
  267. struct intel_bts_recording *btsr =
  268. container_of(itr, struct intel_bts_recording, itr);
  269. intel_bts_free_snapshot_refs(btsr);
  270. free(btsr);
  271. }
  272. static int intel_bts_snapshot_start(struct auxtrace_record *itr)
  273. {
  274. struct intel_bts_recording *btsr =
  275. container_of(itr, struct intel_bts_recording, itr);
  276. struct perf_evsel *evsel;
  277. evlist__for_each_entry(btsr->evlist, evsel) {
  278. if (evsel->attr.type == btsr->intel_bts_pmu->type)
  279. return perf_evsel__disable(evsel);
  280. }
  281. return -EINVAL;
  282. }
  283. static int intel_bts_snapshot_finish(struct auxtrace_record *itr)
  284. {
  285. struct intel_bts_recording *btsr =
  286. container_of(itr, struct intel_bts_recording, itr);
  287. struct perf_evsel *evsel;
  288. evlist__for_each_entry(btsr->evlist, evsel) {
  289. if (evsel->attr.type == btsr->intel_bts_pmu->type)
  290. return perf_evsel__enable(evsel);
  291. }
  292. return -EINVAL;
  293. }
  294. static bool intel_bts_first_wrap(u64 *data, size_t buf_size)
  295. {
  296. int i, a, b;
  297. b = buf_size >> 3;
  298. a = b - 512;
  299. if (a < 0)
  300. a = 0;
  301. for (i = a; i < b; i++) {
  302. if (data[i])
  303. return true;
  304. }
  305. return false;
  306. }
  307. static int intel_bts_find_snapshot(struct auxtrace_record *itr, int idx,
  308. struct auxtrace_mmap *mm, unsigned char *data,
  309. u64 *head, u64 *old)
  310. {
  311. struct intel_bts_recording *btsr =
  312. container_of(itr, struct intel_bts_recording, itr);
  313. bool wrapped;
  314. int err;
  315. pr_debug3("%s: mmap index %d old head %zu new head %zu\n",
  316. __func__, idx, (size_t)*old, (size_t)*head);
  317. if (idx >= btsr->snapshot_ref_cnt) {
  318. err = intel_bts_alloc_snapshot_refs(btsr, idx);
  319. if (err)
  320. goto out_err;
  321. }
  322. wrapped = btsr->snapshot_refs[idx].wrapped;
  323. if (!wrapped && intel_bts_first_wrap((u64 *)data, mm->len)) {
  324. btsr->snapshot_refs[idx].wrapped = true;
  325. wrapped = true;
  326. }
  327. /*
  328. * In full trace mode 'head' continually increases. However in snapshot
  329. * mode 'head' is an offset within the buffer. Here 'old' and 'head'
  330. * are adjusted to match the full trace case which expects that 'old' is
  331. * always less than 'head'.
  332. */
  333. if (wrapped) {
  334. *old = *head;
  335. *head += mm->len;
  336. } else {
  337. if (mm->mask)
  338. *old &= mm->mask;
  339. else
  340. *old %= mm->len;
  341. if (*old > *head)
  342. *head += mm->len;
  343. }
  344. pr_debug3("%s: wrap-around %sdetected, adjusted old head %zu adjusted new head %zu\n",
  345. __func__, wrapped ? "" : "not ", (size_t)*old, (size_t)*head);
  346. return 0;
  347. out_err:
  348. pr_err("%s: failed, error %d\n", __func__, err);
  349. return err;
  350. }
  351. static int intel_bts_read_finish(struct auxtrace_record *itr, int idx)
  352. {
  353. struct intel_bts_recording *btsr =
  354. container_of(itr, struct intel_bts_recording, itr);
  355. struct perf_evsel *evsel;
  356. evlist__for_each_entry(btsr->evlist, evsel) {
  357. if (evsel->attr.type == btsr->intel_bts_pmu->type)
  358. return perf_evlist__enable_event_idx(btsr->evlist,
  359. evsel, idx);
  360. }
  361. return -EINVAL;
  362. }
  363. struct auxtrace_record *intel_bts_recording_init(int *err)
  364. {
  365. struct perf_pmu *intel_bts_pmu = perf_pmu__find(INTEL_BTS_PMU_NAME);
  366. struct intel_bts_recording *btsr;
  367. if (!intel_bts_pmu)
  368. return NULL;
  369. if (setenv("JITDUMP_USE_ARCH_TIMESTAMP", "1", 1)) {
  370. *err = -errno;
  371. return NULL;
  372. }
  373. btsr = zalloc(sizeof(struct intel_bts_recording));
  374. if (!btsr) {
  375. *err = -ENOMEM;
  376. return NULL;
  377. }
  378. btsr->intel_bts_pmu = intel_bts_pmu;
  379. btsr->itr.recording_options = intel_bts_recording_options;
  380. btsr->itr.info_priv_size = intel_bts_info_priv_size;
  381. btsr->itr.info_fill = intel_bts_info_fill;
  382. btsr->itr.free = intel_bts_recording_free;
  383. btsr->itr.snapshot_start = intel_bts_snapshot_start;
  384. btsr->itr.snapshot_finish = intel_bts_snapshot_finish;
  385. btsr->itr.find_snapshot = intel_bts_find_snapshot;
  386. btsr->itr.parse_snapshot_options = intel_bts_parse_snapshot_options;
  387. btsr->itr.reference = intel_bts_reference;
  388. btsr->itr.read_finish = intel_bts_read_finish;
  389. btsr->itr.alignment = sizeof(struct branch);
  390. return &btsr->itr;
  391. }