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

perf inject: Add Instruction Tracing support

Add support for decoding an AUX area assuming it contains instruction
tracing data. The AUX area tracing events are stripped and replaced by
synthesized events.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.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/1428594864-29309-21-git-send-email-adrian.hunter@intel.com
[ Do not use -Z as an alternative to --itrace ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Adrian Hunter and committed by
Arnaldo Carvalho de Melo
0f0aa5e0 cd17a9b5

+95 -2
+26
tools/perf/Documentation/perf-inject.txt
··· 44 44 --kallsyms=<file>:: 45 45 kallsyms pathname 46 46 47 + --itrace:: 48 + Decode Instruction Tracing data, replacing it with synthesized events. 49 + Options are: 50 + 51 + i synthesize instructions events 52 + b synthesize branches events 53 + c synthesize branches events (calls only) 54 + r synthesize branches events (returns only) 55 + e synthesize error events 56 + d create a debug log 57 + g synthesize a call chain for instructions events 58 + 59 + The default is all events i.e. the same as --itrace=ibe 60 + 61 + In addition, the period (default 100000) for instructions events 62 + can be specified in units of: 63 + 64 + i instructions 65 + t ticks 66 + ms milliseconds 67 + us microseconds 68 + ns nanoseconds (default) 69 + 70 + Also the call chain size (default 16, max. 1024) for instructions 71 + events can be specified. 72 + 47 73 SEE ALSO 48 74 -------- 49 75 linkperf:perf-record[1], linkperf:perf-report[1], linkperf:perf-archive[1]
+69 -2
tools/perf/builtin-inject.c
··· 16 16 #include "util/debug.h" 17 17 #include "util/build-id.h" 18 18 #include "util/data.h" 19 + #include "util/auxtrace.h" 19 20 20 21 #include "util/parse-options.h" 21 22 ··· 31 30 struct perf_data_file output; 32 31 u64 bytes_written; 33 32 struct list_head samples; 33 + struct itrace_synth_opts itrace_synth_opts; 34 34 }; 35 35 36 36 struct event_entry { ··· 207 205 return err; 208 206 } 209 207 208 + static int perf_event__repipe_comm(struct perf_tool *tool, 209 + union perf_event *event, 210 + struct perf_sample *sample, 211 + struct machine *machine) 212 + { 213 + int err; 214 + 215 + err = perf_event__process_comm(tool, event, sample, machine); 216 + perf_event__repipe(tool, event, sample, machine); 217 + 218 + return err; 219 + } 220 + 221 + static int perf_event__repipe_exit(struct perf_tool *tool, 222 + union perf_event *event, 223 + struct perf_sample *sample, 224 + struct machine *machine) 225 + { 226 + int err; 227 + 228 + err = perf_event__process_exit(tool, event, sample, machine); 229 + perf_event__repipe(tool, event, sample, machine); 230 + 231 + return err; 232 + } 233 + 210 234 static int perf_event__repipe_tracing_data(struct perf_tool *tool, 211 235 union perf_event *event, 212 236 struct perf_session *session) ··· 241 213 242 214 perf_event__repipe_synth(tool, event); 243 215 err = perf_event__process_tracing_data(tool, event, session); 216 + 217 + return err; 218 + } 219 + 220 + static int perf_event__repipe_id_index(struct perf_tool *tool, 221 + union perf_event *event, 222 + struct perf_session *session) 223 + { 224 + int err; 225 + 226 + perf_event__repipe_synth(tool, event); 227 + err = perf_event__process_id_index(tool, event, session); 244 228 245 229 return err; 246 230 } ··· 441 401 struct perf_session *session = inject->session; 442 402 struct perf_data_file *file_out = &inject->output; 443 403 int fd = perf_data_file__fd(file_out); 404 + u64 output_data_offset; 444 405 445 406 signal(SIGINT, sig_handler); 446 407 447 - if (inject->build_ids || inject->sched_stat) { 408 + if (inject->build_ids || inject->sched_stat || 409 + inject->itrace_synth_opts.set) { 448 410 inject->tool.mmap = perf_event__repipe_mmap; 449 411 inject->tool.mmap2 = perf_event__repipe_mmap2; 450 412 inject->tool.fork = perf_event__repipe_fork; 451 413 inject->tool.tracing_data = perf_event__repipe_tracing_data; 452 414 } 415 + 416 + output_data_offset = session->header.data_offset; 453 417 454 418 if (inject->build_ids) { 455 419 inject->tool.sample = perf_event__inject_buildid; ··· 473 429 else if (!strncmp(name, "sched:sched_stat_", 17)) 474 430 evsel->handler = perf_inject__sched_stat; 475 431 } 432 + } else if (inject->itrace_synth_opts.set) { 433 + session->itrace_synth_opts = &inject->itrace_synth_opts; 434 + inject->itrace_synth_opts.inject = true; 435 + inject->tool.comm = perf_event__repipe_comm; 436 + inject->tool.exit = perf_event__repipe_exit; 437 + inject->tool.id_index = perf_event__repipe_id_index; 438 + inject->tool.auxtrace_info = perf_event__process_auxtrace_info; 439 + inject->tool.auxtrace = perf_event__process_auxtrace; 440 + inject->tool.ordered_events = true; 441 + inject->tool.ordering_requires_timestamps = true; 442 + /* Allow space in the header for new attributes */ 443 + output_data_offset = 4096; 476 444 } 477 445 478 446 if (!file_out->is_pipe) 479 - lseek(fd, session->header.data_offset, SEEK_SET); 447 + lseek(fd, output_data_offset, SEEK_SET); 480 448 481 449 ret = perf_session__process_events(session); 482 450 ··· 496 440 if (inject->build_ids) 497 441 perf_header__set_feat(&session->header, 498 442 HEADER_BUILD_ID); 443 + /* 444 + * The AUX areas have been removed and replaced with 445 + * synthesized hardware events, so clear the feature flag. 446 + */ 447 + if (inject->itrace_synth_opts.set) 448 + perf_header__clear_feat(&session->header, 449 + HEADER_AUXTRACE); 450 + session->header.data_offset = output_data_offset; 499 451 session->header.data_size = inject->bytes_written; 500 452 perf_session__write_header(session, session->evlist, fd, true); 501 453 } ··· 561 497 OPT_STRING(0, "kallsyms", &symbol_conf.kallsyms_name, "file", 562 498 "kallsyms pathname"), 563 499 OPT_BOOLEAN('f', "force", &file.force, "don't complain, do it"), 500 + OPT_CALLBACK_OPTARG(0, "itrace", &inject.itrace_synth_opts, 501 + NULL, "opts", "Instruction Tracing options", 502 + itrace_parse_synth_opts), 564 503 OPT_END() 565 504 }; 566 505 const char * const inject_usage[] = {