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