Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

perf tools: Add support for PERF_RECORD_ITRACE_START

Add support for the PERF_RECORD_ITRACE_START event type. This event can
be used to determine the pid and tid that are running when Instruction
Tracing starts. Generally that information would come from a
sched_switch event but, at the start, no sched_switch events may yet
have been recorded.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1430404667-10593-8-git-send-email-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Adrian Hunter and committed by
Arnaldo Carvalho de Melo
0ad21f68 4a96f7a0

+59
+1
tools/perf/builtin-inject.c
··· 559 559 .exit = perf_event__repipe, 560 560 .lost = perf_event__repipe, 561 561 .aux = perf_event__repipe, 562 + .itrace_start = perf_event__repipe, 562 563 .read = perf_event__repipe_sample, 563 564 .throttle = perf_event__repipe, 564 565 .unthrottle = perf_event__repipe,
+18
tools/perf/util/event.c
··· 24 24 [PERF_RECORD_READ] = "READ", 25 25 [PERF_RECORD_SAMPLE] = "SAMPLE", 26 26 [PERF_RECORD_AUX] = "AUX", 27 + [PERF_RECORD_ITRACE_START] = "ITRACE_START", 27 28 [PERF_RECORD_HEADER_ATTR] = "ATTR", 28 29 [PERF_RECORD_HEADER_EVENT_TYPE] = "EVENT_TYPE", 29 30 [PERF_RECORD_HEADER_TRACING_DATA] = "TRACING_DATA", ··· 705 704 return machine__process_aux_event(machine, event); 706 705 } 707 706 707 + int perf_event__process_itrace_start(struct perf_tool *tool __maybe_unused, 708 + union perf_event *event, 709 + struct perf_sample *sample __maybe_unused, 710 + struct machine *machine) 711 + { 712 + return machine__process_itrace_start_event(machine, event); 713 + } 714 + 708 715 size_t perf_event__fprintf_mmap(union perf_event *event, FILE *fp) 709 716 { 710 717 return fprintf(fp, " %d/%d: [%#" PRIx64 "(%#" PRIx64 ") @ %#" PRIx64 "]: %c %s\n", ··· 785 776 event->aux.flags & PERF_AUX_FLAG_OVERWRITE ? "O" : ""); 786 777 } 787 778 779 + size_t perf_event__fprintf_itrace_start(union perf_event *event, FILE *fp) 780 + { 781 + return fprintf(fp, " pid: %u tid: %u\n", 782 + event->itrace_start.pid, event->itrace_start.tid); 783 + } 784 + 788 785 size_t perf_event__fprintf(union perf_event *event, FILE *fp) 789 786 { 790 787 size_t ret = fprintf(fp, "PERF_RECORD_%s", ··· 812 797 break; 813 798 case PERF_RECORD_AUX: 814 799 ret += perf_event__fprintf_aux(event, fp); 800 + break; 801 + case PERF_RECORD_ITRACE_START: 802 + ret += perf_event__fprintf_itrace_start(event, fp); 815 803 break; 816 804 default: 817 805 ret += fprintf(fp, "\n");
+11
tools/perf/util/event.h
··· 330 330 u64 flags; 331 331 }; 332 332 333 + struct itrace_start_event { 334 + struct perf_event_header header; 335 + u32 pid, tid; 336 + }; 337 + 333 338 union perf_event { 334 339 struct perf_event_header header; 335 340 struct mmap_event mmap; ··· 354 349 struct auxtrace_event auxtrace; 355 350 struct auxtrace_error_event auxtrace_error; 356 351 struct aux_event aux; 352 + struct itrace_start_event itrace_start; 357 353 }; 358 354 359 355 void perf_event__print_totals(void); ··· 394 388 union perf_event *event, 395 389 struct perf_sample *sample, 396 390 struct machine *machine); 391 + int perf_event__process_itrace_start(struct perf_tool *tool, 392 + union perf_event *event, 393 + struct perf_sample *sample, 394 + struct machine *machine); 397 395 int perf_event__process_mmap(struct perf_tool *tool, 398 396 union perf_event *event, 399 397 struct perf_sample *sample, ··· 456 446 size_t perf_event__fprintf_mmap2(union perf_event *event, FILE *fp); 457 447 size_t perf_event__fprintf_task(union perf_event *event, FILE *fp); 458 448 size_t perf_event__fprintf_aux(union perf_event *event, FILE *fp); 449 + size_t perf_event__fprintf_itrace_start(union perf_event *event, FILE *fp); 459 450 size_t perf_event__fprintf(union perf_event *event, FILE *fp); 460 451 461 452 u64 kallsyms__get_function_start(const char *kallsyms_filename,
+11
tools/perf/util/machine.c
··· 494 494 return 0; 495 495 } 496 496 497 + int machine__process_itrace_start_event(struct machine *machine __maybe_unused, 498 + union perf_event *event) 499 + { 500 + if (dump_trace) 501 + perf_event__fprintf_itrace_start(event, stdout); 502 + return 0; 503 + } 504 + 497 505 struct map *machine__new_module(struct machine *machine, u64 start, 498 506 const char *filename) 499 507 { ··· 1349 1341 ret = machine__process_lost_event(machine, event, sample); break; 1350 1342 case PERF_RECORD_AUX: 1351 1343 ret = machine__process_aux_event(machine, event); break; 1344 + case PERF_RECORD_ITRACE_START: 1345 + ret = machine__process_itrace_start_event(machine, event); 1346 + break; 1352 1347 default: 1353 1348 ret = -1; 1354 1349 break;
+2
tools/perf/util/machine.h
··· 83 83 struct perf_sample *sample); 84 84 int machine__process_aux_event(struct machine *machine, 85 85 union perf_event *event); 86 + int machine__process_itrace_start_event(struct machine *machine, 87 + union perf_event *event); 86 88 int machine__process_mmap_event(struct machine *machine, union perf_event *event, 87 89 struct perf_sample *sample); 88 90 int machine__process_mmap2_event(struct machine *machine, union perf_event *event,
+15
tools/perf/util/session.c
··· 327 327 tool->lost = perf_event__process_lost; 328 328 if (tool->aux == NULL) 329 329 tool->aux = perf_event__process_aux; 330 + if (tool->itrace_start == NULL) 331 + tool->itrace_start = perf_event__process_itrace_start; 330 332 if (tool->read == NULL) 331 333 tool->read = process_event_sample_stub; 332 334 if (tool->throttle == NULL) ··· 455 453 456 454 if (sample_id_all) 457 455 swap_sample_id_all(event, &event->aux + 1); 456 + } 457 + 458 + static void perf_event__itrace_start_swap(union perf_event *event, 459 + bool sample_id_all) 460 + { 461 + event->itrace_start.pid = bswap_32(event->itrace_start.pid); 462 + event->itrace_start.tid = bswap_32(event->itrace_start.tid); 463 + 464 + if (sample_id_all) 465 + swap_sample_id_all(event, &event->itrace_start + 1); 458 466 } 459 467 460 468 static void perf_event__throttle_swap(union perf_event *event, ··· 605 593 [PERF_RECORD_UNTHROTTLE] = perf_event__throttle_swap, 606 594 [PERF_RECORD_SAMPLE] = perf_event__all64_swap, 607 595 [PERF_RECORD_AUX] = perf_event__aux_swap, 596 + [PERF_RECORD_ITRACE_START] = perf_event__itrace_start_swap, 608 597 [PERF_RECORD_HEADER_ATTR] = perf_event__hdr_attr_swap, 609 598 [PERF_RECORD_HEADER_EVENT_TYPE] = perf_event__event_type_swap, 610 599 [PERF_RECORD_HEADER_TRACING_DATA] = perf_event__tracing_data_swap, ··· 1057 1044 return tool->unthrottle(tool, event, sample, machine); 1058 1045 case PERF_RECORD_AUX: 1059 1046 return tool->aux(tool, event, sample, machine); 1047 + case PERF_RECORD_ITRACE_START: 1048 + return tool->itrace_start(tool, event, sample, machine); 1060 1049 default: 1061 1050 ++evlist->stats.nr_unknown_events; 1062 1051 return -1;
+1
tools/perf/util/tool.h
··· 44 44 exit, 45 45 lost, 46 46 aux, 47 + itrace_start, 47 48 throttle, 48 49 unthrottle; 49 50 event_attr_op attr;