arm-spe.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Arm Statistical Profiling Extensions (SPE) support
  4. * Copyright (c) 2017-2018, Arm Ltd.
  5. */
  6. #include <byteswap.h>
  7. #include <endian.h>
  8. #include <errno.h>
  9. #include <inttypes.h>
  10. #include <linux/bitops.h>
  11. #include <linux/kernel.h>
  12. #include <linux/log2.h>
  13. #include <linux/types.h>
  14. #include <linux/zalloc.h>
  15. #include <stdlib.h>
  16. #include <unistd.h>
  17. #include "auxtrace.h"
  18. #include "color.h"
  19. #include "debug.h"
  20. #include "evlist.h"
  21. #include "evsel.h"
  22. #include "machine.h"
  23. #include "session.h"
  24. #include "symbol.h"
  25. #include "thread.h"
  26. #include "thread-stack.h"
  27. #include "tool.h"
  28. #include "util/synthetic-events.h"
  29. #include "arm-spe.h"
  30. #include "arm-spe-decoder/arm-spe-decoder.h"
  31. #include "arm-spe-decoder/arm-spe-pkt-decoder.h"
  32. #define MAX_TIMESTAMP (~0ULL)
  33. struct arm_spe {
  34. struct auxtrace auxtrace;
  35. struct auxtrace_queues queues;
  36. struct auxtrace_heap heap;
  37. struct itrace_synth_opts synth_opts;
  38. u32 auxtrace_type;
  39. struct perf_session *session;
  40. struct machine *machine;
  41. u32 pmu_type;
  42. u8 timeless_decoding;
  43. u8 data_queued;
  44. u64 sample_type;
  45. u8 sample_flc;
  46. u8 sample_llc;
  47. u8 sample_tlb;
  48. u8 sample_branch;
  49. u8 sample_remote_access;
  50. u64 l1d_miss_id;
  51. u64 l1d_access_id;
  52. u64 llc_miss_id;
  53. u64 llc_access_id;
  54. u64 tlb_miss_id;
  55. u64 tlb_access_id;
  56. u64 branch_miss_id;
  57. u64 remote_access_id;
  58. u64 kernel_start;
  59. unsigned long num_events;
  60. };
  61. struct arm_spe_queue {
  62. struct arm_spe *spe;
  63. unsigned int queue_nr;
  64. struct auxtrace_buffer *buffer;
  65. struct auxtrace_buffer *old_buffer;
  66. union perf_event *event_buf;
  67. bool on_heap;
  68. bool done;
  69. pid_t pid;
  70. pid_t tid;
  71. int cpu;
  72. struct arm_spe_decoder *decoder;
  73. u64 time;
  74. u64 timestamp;
  75. struct thread *thread;
  76. };
  77. static void arm_spe_dump(struct arm_spe *spe __maybe_unused,
  78. unsigned char *buf, size_t len)
  79. {
  80. struct arm_spe_pkt packet;
  81. size_t pos = 0;
  82. int ret, pkt_len, i;
  83. char desc[ARM_SPE_PKT_DESC_MAX];
  84. const char *color = PERF_COLOR_BLUE;
  85. color_fprintf(stdout, color,
  86. ". ... ARM SPE data: size %zu bytes\n",
  87. len);
  88. while (len) {
  89. ret = arm_spe_get_packet(buf, len, &packet);
  90. if (ret > 0)
  91. pkt_len = ret;
  92. else
  93. pkt_len = 1;
  94. printf(".");
  95. color_fprintf(stdout, color, " %08x: ", pos);
  96. for (i = 0; i < pkt_len; i++)
  97. color_fprintf(stdout, color, " %02x", buf[i]);
  98. for (; i < 16; i++)
  99. color_fprintf(stdout, color, " ");
  100. if (ret > 0) {
  101. ret = arm_spe_pkt_desc(&packet, desc,
  102. ARM_SPE_PKT_DESC_MAX);
  103. if (ret > 0)
  104. color_fprintf(stdout, color, " %s\n", desc);
  105. } else {
  106. color_fprintf(stdout, color, " Bad packet!\n");
  107. }
  108. pos += pkt_len;
  109. buf += pkt_len;
  110. len -= pkt_len;
  111. }
  112. }
  113. static void arm_spe_dump_event(struct arm_spe *spe, unsigned char *buf,
  114. size_t len)
  115. {
  116. printf(".\n");
  117. arm_spe_dump(spe, buf, len);
  118. }
  119. static int arm_spe_get_trace(struct arm_spe_buffer *b, void *data)
  120. {
  121. struct arm_spe_queue *speq = data;
  122. struct auxtrace_buffer *buffer = speq->buffer;
  123. struct auxtrace_buffer *old_buffer = speq->old_buffer;
  124. struct auxtrace_queue *queue;
  125. queue = &speq->spe->queues.queue_array[speq->queue_nr];
  126. buffer = auxtrace_buffer__next(queue, buffer);
  127. /* If no more data, drop the previous auxtrace_buffer and return */
  128. if (!buffer) {
  129. if (old_buffer)
  130. auxtrace_buffer__drop_data(old_buffer);
  131. b->len = 0;
  132. return 0;
  133. }
  134. speq->buffer = buffer;
  135. /* If the aux_buffer doesn't have data associated, try to load it */
  136. if (!buffer->data) {
  137. /* get the file desc associated with the perf data file */
  138. int fd = perf_data__fd(speq->spe->session->data);
  139. buffer->data = auxtrace_buffer__get_data(buffer, fd);
  140. if (!buffer->data)
  141. return -ENOMEM;
  142. }
  143. b->len = buffer->size;
  144. b->buf = buffer->data;
  145. if (b->len) {
  146. if (old_buffer)
  147. auxtrace_buffer__drop_data(old_buffer);
  148. speq->old_buffer = buffer;
  149. } else {
  150. auxtrace_buffer__drop_data(buffer);
  151. return arm_spe_get_trace(b, data);
  152. }
  153. return 0;
  154. }
  155. static struct arm_spe_queue *arm_spe__alloc_queue(struct arm_spe *spe,
  156. unsigned int queue_nr)
  157. {
  158. struct arm_spe_params params = { .get_trace = 0, };
  159. struct arm_spe_queue *speq;
  160. speq = zalloc(sizeof(*speq));
  161. if (!speq)
  162. return NULL;
  163. speq->event_buf = malloc(PERF_SAMPLE_MAX_SIZE);
  164. if (!speq->event_buf)
  165. goto out_free;
  166. speq->spe = spe;
  167. speq->queue_nr = queue_nr;
  168. speq->pid = -1;
  169. speq->tid = -1;
  170. speq->cpu = -1;
  171. /* params set */
  172. params.get_trace = arm_spe_get_trace;
  173. params.data = speq;
  174. /* create new decoder */
  175. speq->decoder = arm_spe_decoder_new(&params);
  176. if (!speq->decoder)
  177. goto out_free;
  178. return speq;
  179. out_free:
  180. zfree(&speq->event_buf);
  181. free(speq);
  182. return NULL;
  183. }
  184. static inline u8 arm_spe_cpumode(struct arm_spe *spe, u64 ip)
  185. {
  186. return ip >= spe->kernel_start ?
  187. PERF_RECORD_MISC_KERNEL :
  188. PERF_RECORD_MISC_USER;
  189. }
  190. static void arm_spe_prep_sample(struct arm_spe *spe,
  191. struct arm_spe_queue *speq,
  192. union perf_event *event,
  193. struct perf_sample *sample)
  194. {
  195. struct arm_spe_record *record = &speq->decoder->record;
  196. if (!spe->timeless_decoding)
  197. sample->time = speq->timestamp;
  198. sample->ip = record->from_ip;
  199. sample->cpumode = arm_spe_cpumode(spe, sample->ip);
  200. sample->pid = speq->pid;
  201. sample->tid = speq->tid;
  202. sample->addr = record->to_ip;
  203. sample->period = 1;
  204. sample->cpu = speq->cpu;
  205. event->sample.header.type = PERF_RECORD_SAMPLE;
  206. event->sample.header.misc = sample->cpumode;
  207. event->sample.header.size = sizeof(struct perf_event_header);
  208. }
  209. static int arm_spe__inject_event(union perf_event *event, struct perf_sample *sample, u64 type)
  210. {
  211. event->header.size = perf_event__sample_event_size(sample, type, 0);
  212. return perf_event__synthesize_sample(event, type, 0, sample);
  213. }
  214. static inline int
  215. arm_spe_deliver_synth_event(struct arm_spe *spe,
  216. struct arm_spe_queue *speq __maybe_unused,
  217. union perf_event *event,
  218. struct perf_sample *sample)
  219. {
  220. int ret;
  221. if (spe->synth_opts.inject) {
  222. ret = arm_spe__inject_event(event, sample, spe->sample_type);
  223. if (ret)
  224. return ret;
  225. }
  226. ret = perf_session__deliver_synth_event(spe->session, event, sample);
  227. if (ret)
  228. pr_err("ARM SPE: failed to deliver event, error %d\n", ret);
  229. return ret;
  230. }
  231. static int
  232. arm_spe_synth_spe_events_sample(struct arm_spe_queue *speq,
  233. u64 spe_events_id)
  234. {
  235. struct arm_spe *spe = speq->spe;
  236. union perf_event *event = speq->event_buf;
  237. struct perf_sample sample = { .ip = 0, };
  238. arm_spe_prep_sample(spe, speq, event, &sample);
  239. sample.id = spe_events_id;
  240. sample.stream_id = spe_events_id;
  241. return arm_spe_deliver_synth_event(spe, speq, event, &sample);
  242. }
  243. static int arm_spe_sample(struct arm_spe_queue *speq)
  244. {
  245. const struct arm_spe_record *record = &speq->decoder->record;
  246. struct arm_spe *spe = speq->spe;
  247. int err;
  248. if (spe->sample_flc) {
  249. if (record->type & ARM_SPE_L1D_MISS) {
  250. err = arm_spe_synth_spe_events_sample(
  251. speq, spe->l1d_miss_id);
  252. if (err)
  253. return err;
  254. }
  255. if (record->type & ARM_SPE_L1D_ACCESS) {
  256. err = arm_spe_synth_spe_events_sample(
  257. speq, spe->l1d_access_id);
  258. if (err)
  259. return err;
  260. }
  261. }
  262. if (spe->sample_llc) {
  263. if (record->type & ARM_SPE_LLC_MISS) {
  264. err = arm_spe_synth_spe_events_sample(
  265. speq, spe->llc_miss_id);
  266. if (err)
  267. return err;
  268. }
  269. if (record->type & ARM_SPE_LLC_ACCESS) {
  270. err = arm_spe_synth_spe_events_sample(
  271. speq, spe->llc_access_id);
  272. if (err)
  273. return err;
  274. }
  275. }
  276. if (spe->sample_tlb) {
  277. if (record->type & ARM_SPE_TLB_MISS) {
  278. err = arm_spe_synth_spe_events_sample(
  279. speq, spe->tlb_miss_id);
  280. if (err)
  281. return err;
  282. }
  283. if (record->type & ARM_SPE_TLB_ACCESS) {
  284. err = arm_spe_synth_spe_events_sample(
  285. speq, spe->tlb_access_id);
  286. if (err)
  287. return err;
  288. }
  289. }
  290. if (spe->sample_branch && (record->type & ARM_SPE_BRANCH_MISS)) {
  291. err = arm_spe_synth_spe_events_sample(speq,
  292. spe->branch_miss_id);
  293. if (err)
  294. return err;
  295. }
  296. if (spe->sample_remote_access &&
  297. (record->type & ARM_SPE_REMOTE_ACCESS)) {
  298. err = arm_spe_synth_spe_events_sample(speq,
  299. spe->remote_access_id);
  300. if (err)
  301. return err;
  302. }
  303. return 0;
  304. }
  305. static int arm_spe_run_decoder(struct arm_spe_queue *speq, u64 *timestamp)
  306. {
  307. struct arm_spe *spe = speq->spe;
  308. int ret;
  309. if (!spe->kernel_start)
  310. spe->kernel_start = machine__kernel_start(spe->machine);
  311. while (1) {
  312. ret = arm_spe_decode(speq->decoder);
  313. if (!ret) {
  314. pr_debug("No data or all data has been processed.\n");
  315. return 1;
  316. }
  317. /*
  318. * Error is detected when decode SPE trace data, continue to
  319. * the next trace data and find out more records.
  320. */
  321. if (ret < 0)
  322. continue;
  323. ret = arm_spe_sample(speq);
  324. if (ret)
  325. return ret;
  326. if (!spe->timeless_decoding && speq->timestamp >= *timestamp) {
  327. *timestamp = speq->timestamp;
  328. return 0;
  329. }
  330. }
  331. return 0;
  332. }
  333. static int arm_spe__setup_queue(struct arm_spe *spe,
  334. struct auxtrace_queue *queue,
  335. unsigned int queue_nr)
  336. {
  337. struct arm_spe_queue *speq = queue->priv;
  338. struct arm_spe_record *record;
  339. if (list_empty(&queue->head) || speq)
  340. return 0;
  341. speq = arm_spe__alloc_queue(spe, queue_nr);
  342. if (!speq)
  343. return -ENOMEM;
  344. queue->priv = speq;
  345. if (queue->cpu != -1)
  346. speq->cpu = queue->cpu;
  347. if (!speq->on_heap) {
  348. int ret;
  349. if (spe->timeless_decoding)
  350. return 0;
  351. retry:
  352. ret = arm_spe_decode(speq->decoder);
  353. if (!ret)
  354. return 0;
  355. if (ret < 0)
  356. goto retry;
  357. record = &speq->decoder->record;
  358. speq->timestamp = record->timestamp;
  359. ret = auxtrace_heap__add(&spe->heap, queue_nr, speq->timestamp);
  360. if (ret)
  361. return ret;
  362. speq->on_heap = true;
  363. }
  364. return 0;
  365. }
  366. static int arm_spe__setup_queues(struct arm_spe *spe)
  367. {
  368. unsigned int i;
  369. int ret;
  370. for (i = 0; i < spe->queues.nr_queues; i++) {
  371. ret = arm_spe__setup_queue(spe, &spe->queues.queue_array[i], i);
  372. if (ret)
  373. return ret;
  374. }
  375. return 0;
  376. }
  377. static int arm_spe__update_queues(struct arm_spe *spe)
  378. {
  379. if (spe->queues.new_data) {
  380. spe->queues.new_data = false;
  381. return arm_spe__setup_queues(spe);
  382. }
  383. return 0;
  384. }
  385. static bool arm_spe__is_timeless_decoding(struct arm_spe *spe)
  386. {
  387. struct evsel *evsel;
  388. struct evlist *evlist = spe->session->evlist;
  389. bool timeless_decoding = true;
  390. /*
  391. * Circle through the list of event and complain if we find one
  392. * with the time bit set.
  393. */
  394. evlist__for_each_entry(evlist, evsel) {
  395. if ((evsel->core.attr.sample_type & PERF_SAMPLE_TIME))
  396. timeless_decoding = false;
  397. }
  398. return timeless_decoding;
  399. }
  400. static void arm_spe_set_pid_tid_cpu(struct arm_spe *spe,
  401. struct auxtrace_queue *queue)
  402. {
  403. struct arm_spe_queue *speq = queue->priv;
  404. pid_t tid;
  405. tid = machine__get_current_tid(spe->machine, speq->cpu);
  406. if (tid != -1) {
  407. speq->tid = tid;
  408. thread__zput(speq->thread);
  409. } else
  410. speq->tid = queue->tid;
  411. if ((!speq->thread) && (speq->tid != -1)) {
  412. speq->thread = machine__find_thread(spe->machine, -1,
  413. speq->tid);
  414. }
  415. if (speq->thread) {
  416. speq->pid = speq->thread->pid_;
  417. if (queue->cpu == -1)
  418. speq->cpu = speq->thread->cpu;
  419. }
  420. }
  421. static int arm_spe_process_queues(struct arm_spe *spe, u64 timestamp)
  422. {
  423. unsigned int queue_nr;
  424. u64 ts;
  425. int ret;
  426. while (1) {
  427. struct auxtrace_queue *queue;
  428. struct arm_spe_queue *speq;
  429. if (!spe->heap.heap_cnt)
  430. return 0;
  431. if (spe->heap.heap_array[0].ordinal >= timestamp)
  432. return 0;
  433. queue_nr = spe->heap.heap_array[0].queue_nr;
  434. queue = &spe->queues.queue_array[queue_nr];
  435. speq = queue->priv;
  436. auxtrace_heap__pop(&spe->heap);
  437. if (spe->heap.heap_cnt) {
  438. ts = spe->heap.heap_array[0].ordinal + 1;
  439. if (ts > timestamp)
  440. ts = timestamp;
  441. } else {
  442. ts = timestamp;
  443. }
  444. arm_spe_set_pid_tid_cpu(spe, queue);
  445. ret = arm_spe_run_decoder(speq, &ts);
  446. if (ret < 0) {
  447. auxtrace_heap__add(&spe->heap, queue_nr, ts);
  448. return ret;
  449. }
  450. if (!ret) {
  451. ret = auxtrace_heap__add(&spe->heap, queue_nr, ts);
  452. if (ret < 0)
  453. return ret;
  454. } else {
  455. speq->on_heap = false;
  456. }
  457. }
  458. return 0;
  459. }
  460. static int arm_spe_process_timeless_queues(struct arm_spe *spe, pid_t tid,
  461. u64 time_)
  462. {
  463. struct auxtrace_queues *queues = &spe->queues;
  464. unsigned int i;
  465. u64 ts = 0;
  466. for (i = 0; i < queues->nr_queues; i++) {
  467. struct auxtrace_queue *queue = &spe->queues.queue_array[i];
  468. struct arm_spe_queue *speq = queue->priv;
  469. if (speq && (tid == -1 || speq->tid == tid)) {
  470. speq->time = time_;
  471. arm_spe_set_pid_tid_cpu(spe, queue);
  472. arm_spe_run_decoder(speq, &ts);
  473. }
  474. }
  475. return 0;
  476. }
  477. static int arm_spe_process_event(struct perf_session *session,
  478. union perf_event *event,
  479. struct perf_sample *sample,
  480. struct perf_tool *tool)
  481. {
  482. int err = 0;
  483. u64 timestamp;
  484. struct arm_spe *spe = container_of(session->auxtrace,
  485. struct arm_spe, auxtrace);
  486. if (dump_trace)
  487. return 0;
  488. if (!tool->ordered_events) {
  489. pr_err("SPE trace requires ordered events\n");
  490. return -EINVAL;
  491. }
  492. if (sample->time && (sample->time != (u64) -1))
  493. timestamp = sample->time;
  494. else
  495. timestamp = 0;
  496. if (timestamp || spe->timeless_decoding) {
  497. err = arm_spe__update_queues(spe);
  498. if (err)
  499. return err;
  500. }
  501. if (spe->timeless_decoding) {
  502. if (event->header.type == PERF_RECORD_EXIT) {
  503. err = arm_spe_process_timeless_queues(spe,
  504. event->fork.tid,
  505. sample->time);
  506. }
  507. } else if (timestamp) {
  508. if (event->header.type == PERF_RECORD_EXIT) {
  509. err = arm_spe_process_queues(spe, timestamp);
  510. if (err)
  511. return err;
  512. }
  513. }
  514. return err;
  515. }
  516. static int arm_spe_process_auxtrace_event(struct perf_session *session,
  517. union perf_event *event,
  518. struct perf_tool *tool __maybe_unused)
  519. {
  520. struct arm_spe *spe = container_of(session->auxtrace, struct arm_spe,
  521. auxtrace);
  522. if (!spe->data_queued) {
  523. struct auxtrace_buffer *buffer;
  524. off_t data_offset;
  525. int fd = perf_data__fd(session->data);
  526. int err;
  527. if (perf_data__is_pipe(session->data)) {
  528. data_offset = 0;
  529. } else {
  530. data_offset = lseek(fd, 0, SEEK_CUR);
  531. if (data_offset == -1)
  532. return -errno;
  533. }
  534. err = auxtrace_queues__add_event(&spe->queues, session, event,
  535. data_offset, &buffer);
  536. if (err)
  537. return err;
  538. /* Dump here now we have copied a piped trace out of the pipe */
  539. if (dump_trace) {
  540. if (auxtrace_buffer__get_data(buffer, fd)) {
  541. arm_spe_dump_event(spe, buffer->data,
  542. buffer->size);
  543. auxtrace_buffer__put_data(buffer);
  544. }
  545. }
  546. }
  547. return 0;
  548. }
  549. static int arm_spe_flush(struct perf_session *session __maybe_unused,
  550. struct perf_tool *tool __maybe_unused)
  551. {
  552. struct arm_spe *spe = container_of(session->auxtrace, struct arm_spe,
  553. auxtrace);
  554. int ret;
  555. if (dump_trace)
  556. return 0;
  557. if (!tool->ordered_events)
  558. return -EINVAL;
  559. ret = arm_spe__update_queues(spe);
  560. if (ret < 0)
  561. return ret;
  562. if (spe->timeless_decoding)
  563. return arm_spe_process_timeless_queues(spe, -1,
  564. MAX_TIMESTAMP - 1);
  565. return arm_spe_process_queues(spe, MAX_TIMESTAMP);
  566. }
  567. static void arm_spe_free_queue(void *priv)
  568. {
  569. struct arm_spe_queue *speq = priv;
  570. if (!speq)
  571. return;
  572. thread__zput(speq->thread);
  573. arm_spe_decoder_free(speq->decoder);
  574. zfree(&speq->event_buf);
  575. free(speq);
  576. }
  577. static void arm_spe_free_events(struct perf_session *session)
  578. {
  579. struct arm_spe *spe = container_of(session->auxtrace, struct arm_spe,
  580. auxtrace);
  581. struct auxtrace_queues *queues = &spe->queues;
  582. unsigned int i;
  583. for (i = 0; i < queues->nr_queues; i++) {
  584. arm_spe_free_queue(queues->queue_array[i].priv);
  585. queues->queue_array[i].priv = NULL;
  586. }
  587. auxtrace_queues__free(queues);
  588. }
  589. static void arm_spe_free(struct perf_session *session)
  590. {
  591. struct arm_spe *spe = container_of(session->auxtrace, struct arm_spe,
  592. auxtrace);
  593. auxtrace_heap__free(&spe->heap);
  594. arm_spe_free_events(session);
  595. session->auxtrace = NULL;
  596. free(spe);
  597. }
  598. static bool arm_spe_evsel_is_auxtrace(struct perf_session *session,
  599. struct evsel *evsel)
  600. {
  601. struct arm_spe *spe = container_of(session->auxtrace, struct arm_spe, auxtrace);
  602. return evsel->core.attr.type == spe->pmu_type;
  603. }
  604. static const char * const arm_spe_info_fmts[] = {
  605. [ARM_SPE_PMU_TYPE] = " PMU Type %"PRId64"\n",
  606. };
  607. static void arm_spe_print_info(__u64 *arr)
  608. {
  609. if (!dump_trace)
  610. return;
  611. fprintf(stdout, arm_spe_info_fmts[ARM_SPE_PMU_TYPE], arr[ARM_SPE_PMU_TYPE]);
  612. }
  613. struct arm_spe_synth {
  614. struct perf_tool dummy_tool;
  615. struct perf_session *session;
  616. };
  617. static int arm_spe_event_synth(struct perf_tool *tool,
  618. union perf_event *event,
  619. struct perf_sample *sample __maybe_unused,
  620. struct machine *machine __maybe_unused)
  621. {
  622. struct arm_spe_synth *arm_spe_synth =
  623. container_of(tool, struct arm_spe_synth, dummy_tool);
  624. return perf_session__deliver_synth_event(arm_spe_synth->session,
  625. event, NULL);
  626. }
  627. static int arm_spe_synth_event(struct perf_session *session,
  628. struct perf_event_attr *attr, u64 id)
  629. {
  630. struct arm_spe_synth arm_spe_synth;
  631. memset(&arm_spe_synth, 0, sizeof(struct arm_spe_synth));
  632. arm_spe_synth.session = session;
  633. return perf_event__synthesize_attr(&arm_spe_synth.dummy_tool, attr, 1,
  634. &id, arm_spe_event_synth);
  635. }
  636. static void arm_spe_set_event_name(struct evlist *evlist, u64 id,
  637. const char *name)
  638. {
  639. struct evsel *evsel;
  640. evlist__for_each_entry(evlist, evsel) {
  641. if (evsel->core.id && evsel->core.id[0] == id) {
  642. if (evsel->name)
  643. zfree(&evsel->name);
  644. evsel->name = strdup(name);
  645. break;
  646. }
  647. }
  648. }
  649. static int
  650. arm_spe_synth_events(struct arm_spe *spe, struct perf_session *session)
  651. {
  652. struct evlist *evlist = session->evlist;
  653. struct evsel *evsel;
  654. struct perf_event_attr attr;
  655. bool found = false;
  656. u64 id;
  657. int err;
  658. evlist__for_each_entry(evlist, evsel) {
  659. if (evsel->core.attr.type == spe->pmu_type) {
  660. found = true;
  661. break;
  662. }
  663. }
  664. if (!found) {
  665. pr_debug("No selected events with SPE trace data\n");
  666. return 0;
  667. }
  668. memset(&attr, 0, sizeof(struct perf_event_attr));
  669. attr.size = sizeof(struct perf_event_attr);
  670. attr.type = PERF_TYPE_HARDWARE;
  671. attr.sample_type = evsel->core.attr.sample_type & PERF_SAMPLE_MASK;
  672. attr.sample_type |= PERF_SAMPLE_IP | PERF_SAMPLE_TID |
  673. PERF_SAMPLE_PERIOD;
  674. if (spe->timeless_decoding)
  675. attr.sample_type &= ~(u64)PERF_SAMPLE_TIME;
  676. else
  677. attr.sample_type |= PERF_SAMPLE_TIME;
  678. spe->sample_type = attr.sample_type;
  679. attr.exclude_user = evsel->core.attr.exclude_user;
  680. attr.exclude_kernel = evsel->core.attr.exclude_kernel;
  681. attr.exclude_hv = evsel->core.attr.exclude_hv;
  682. attr.exclude_host = evsel->core.attr.exclude_host;
  683. attr.exclude_guest = evsel->core.attr.exclude_guest;
  684. attr.sample_id_all = evsel->core.attr.sample_id_all;
  685. attr.read_format = evsel->core.attr.read_format;
  686. /* create new id val to be a fixed offset from evsel id */
  687. id = evsel->core.id[0] + 1000000000;
  688. if (!id)
  689. id = 1;
  690. if (spe->synth_opts.flc) {
  691. spe->sample_flc = true;
  692. /* Level 1 data cache miss */
  693. err = arm_spe_synth_event(session, &attr, id);
  694. if (err)
  695. return err;
  696. spe->l1d_miss_id = id;
  697. arm_spe_set_event_name(evlist, id, "l1d-miss");
  698. id += 1;
  699. /* Level 1 data cache access */
  700. err = arm_spe_synth_event(session, &attr, id);
  701. if (err)
  702. return err;
  703. spe->l1d_access_id = id;
  704. arm_spe_set_event_name(evlist, id, "l1d-access");
  705. id += 1;
  706. }
  707. if (spe->synth_opts.llc) {
  708. spe->sample_llc = true;
  709. /* Last level cache miss */
  710. err = arm_spe_synth_event(session, &attr, id);
  711. if (err)
  712. return err;
  713. spe->llc_miss_id = id;
  714. arm_spe_set_event_name(evlist, id, "llc-miss");
  715. id += 1;
  716. /* Last level cache access */
  717. err = arm_spe_synth_event(session, &attr, id);
  718. if (err)
  719. return err;
  720. spe->llc_access_id = id;
  721. arm_spe_set_event_name(evlist, id, "llc-access");
  722. id += 1;
  723. }
  724. if (spe->synth_opts.tlb) {
  725. spe->sample_tlb = true;
  726. /* TLB miss */
  727. err = arm_spe_synth_event(session, &attr, id);
  728. if (err)
  729. return err;
  730. spe->tlb_miss_id = id;
  731. arm_spe_set_event_name(evlist, id, "tlb-miss");
  732. id += 1;
  733. /* TLB access */
  734. err = arm_spe_synth_event(session, &attr, id);
  735. if (err)
  736. return err;
  737. spe->tlb_access_id = id;
  738. arm_spe_set_event_name(evlist, id, "tlb-access");
  739. id += 1;
  740. }
  741. if (spe->synth_opts.branches) {
  742. spe->sample_branch = true;
  743. /* Branch miss */
  744. err = arm_spe_synth_event(session, &attr, id);
  745. if (err)
  746. return err;
  747. spe->branch_miss_id = id;
  748. arm_spe_set_event_name(evlist, id, "branch-miss");
  749. id += 1;
  750. }
  751. if (spe->synth_opts.remote_access) {
  752. spe->sample_remote_access = true;
  753. /* Remote access */
  754. err = arm_spe_synth_event(session, &attr, id);
  755. if (err)
  756. return err;
  757. spe->remote_access_id = id;
  758. arm_spe_set_event_name(evlist, id, "remote-access");
  759. id += 1;
  760. }
  761. return 0;
  762. }
  763. int arm_spe_process_auxtrace_info(union perf_event *event,
  764. struct perf_session *session)
  765. {
  766. struct perf_record_auxtrace_info *auxtrace_info = &event->auxtrace_info;
  767. size_t min_sz = sizeof(u64) * ARM_SPE_AUXTRACE_PRIV_MAX;
  768. struct arm_spe *spe;
  769. int err;
  770. if (auxtrace_info->header.size < sizeof(struct perf_record_auxtrace_info) +
  771. min_sz)
  772. return -EINVAL;
  773. spe = zalloc(sizeof(struct arm_spe));
  774. if (!spe)
  775. return -ENOMEM;
  776. err = auxtrace_queues__init(&spe->queues);
  777. if (err)
  778. goto err_free;
  779. spe->session = session;
  780. spe->machine = &session->machines.host; /* No kvm support */
  781. spe->auxtrace_type = auxtrace_info->type;
  782. spe->pmu_type = auxtrace_info->priv[ARM_SPE_PMU_TYPE];
  783. spe->timeless_decoding = arm_spe__is_timeless_decoding(spe);
  784. spe->auxtrace.process_event = arm_spe_process_event;
  785. spe->auxtrace.process_auxtrace_event = arm_spe_process_auxtrace_event;
  786. spe->auxtrace.flush_events = arm_spe_flush;
  787. spe->auxtrace.free_events = arm_spe_free_events;
  788. spe->auxtrace.free = arm_spe_free;
  789. spe->auxtrace.evsel_is_auxtrace = arm_spe_evsel_is_auxtrace;
  790. session->auxtrace = &spe->auxtrace;
  791. arm_spe_print_info(&auxtrace_info->priv[0]);
  792. if (dump_trace)
  793. return 0;
  794. if (session->itrace_synth_opts && session->itrace_synth_opts->set)
  795. spe->synth_opts = *session->itrace_synth_opts;
  796. else
  797. itrace_synth_opts__set_default(&spe->synth_opts, false);
  798. err = arm_spe_synth_events(spe, session);
  799. if (err)
  800. goto err_free_queues;
  801. err = auxtrace_queues__process_index(&spe->queues, session);
  802. if (err)
  803. goto err_free_queues;
  804. if (spe->queues.populated)
  805. spe->data_queued = true;
  806. return 0;
  807. err_free_queues:
  808. auxtrace_queues__free(&spe->queues);
  809. session->auxtrace = NULL;
  810. err_free:
  811. free(spe);
  812. return err;
  813. }