aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-inject.c
diff options
context:
space:
mode:
authorAdrian Hunter <adrian.hunter@intel.com>2015-04-09 11:54:00 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2015-04-29 09:37:57 -0400
commit0f0aa5e0693ce4000a7657cc47ce4f32b86b91ba (patch)
tree306c85337ffc7a4f75f41040ecc16bc84cff3344 /tools/perf/builtin-inject.c
parentcd17a9b54463970a47fec33d94f220950c9990c4 (diff)
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>
Diffstat (limited to 'tools/perf/builtin-inject.c')
-rw-r--r--tools/perf/builtin-inject.c71
1 files changed, 69 insertions, 2 deletions
diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c
index 8f4cad7e9fe7..c5f6515f0723 100644
--- a/tools/perf/builtin-inject.c
+++ b/tools/perf/builtin-inject.c
@@ -16,6 +16,7 @@
16#include "util/debug.h" 16#include "util/debug.h"
17#include "util/build-id.h" 17#include "util/build-id.h"
18#include "util/data.h" 18#include "util/data.h"
19#include "util/auxtrace.h"
19 20
20#include "util/parse-options.h" 21#include "util/parse-options.h"
21 22
@@ -30,6 +31,7 @@ struct perf_inject {
30 struct perf_data_file output; 31 struct perf_data_file output;
31 u64 bytes_written; 32 u64 bytes_written;
32 struct list_head samples; 33 struct list_head samples;
34 struct itrace_synth_opts itrace_synth_opts;
33}; 35};
34 36
35struct event_entry { 37struct event_entry {
@@ -205,6 +207,32 @@ static int perf_event__repipe_fork(struct perf_tool *tool,
205 return err; 207 return err;
206} 208}
207 209
210static int perf_event__repipe_comm(struct perf_tool *tool,
211 union perf_event *event,
212 struct perf_sample *sample,
213 struct machine *machine)
214{
215 int err;
216
217 err = perf_event__process_comm(tool, event, sample, machine);
218 perf_event__repipe(tool, event, sample, machine);
219
220 return err;
221}
222
223static int perf_event__repipe_exit(struct perf_tool *tool,
224 union perf_event *event,
225 struct perf_sample *sample,
226 struct machine *machine)
227{
228 int err;
229
230 err = perf_event__process_exit(tool, event, sample, machine);
231 perf_event__repipe(tool, event, sample, machine);
232
233 return err;
234}
235
208static int perf_event__repipe_tracing_data(struct perf_tool *tool, 236static int perf_event__repipe_tracing_data(struct perf_tool *tool,
209 union perf_event *event, 237 union perf_event *event,
210 struct perf_session *session) 238 struct perf_session *session)
@@ -217,6 +245,18 @@ static int perf_event__repipe_tracing_data(struct perf_tool *tool,
217 return err; 245 return err;
218} 246}
219 247
248static int perf_event__repipe_id_index(struct perf_tool *tool,
249 union perf_event *event,
250 struct perf_session *session)
251{
252 int err;
253
254 perf_event__repipe_synth(tool, event);
255 err = perf_event__process_id_index(tool, event, session);
256
257 return err;
258}
259
220static int dso__read_build_id(struct dso *dso) 260static int dso__read_build_id(struct dso *dso)
221{ 261{
222 if (dso->has_build_id) 262 if (dso->has_build_id)
@@ -401,16 +441,20 @@ static int __cmd_inject(struct perf_inject *inject)
401 struct perf_session *session = inject->session; 441 struct perf_session *session = inject->session;
402 struct perf_data_file *file_out = &inject->output; 442 struct perf_data_file *file_out = &inject->output;
403 int fd = perf_data_file__fd(file_out); 443 int fd = perf_data_file__fd(file_out);
444 u64 output_data_offset;
404 445
405 signal(SIGINT, sig_handler); 446 signal(SIGINT, sig_handler);
406 447
407 if (inject->build_ids || inject->sched_stat) { 448 if (inject->build_ids || inject->sched_stat ||
449 inject->itrace_synth_opts.set) {
408 inject->tool.mmap = perf_event__repipe_mmap; 450 inject->tool.mmap = perf_event__repipe_mmap;
409 inject->tool.mmap2 = perf_event__repipe_mmap2; 451 inject->tool.mmap2 = perf_event__repipe_mmap2;
410 inject->tool.fork = perf_event__repipe_fork; 452 inject->tool.fork = perf_event__repipe_fork;
411 inject->tool.tracing_data = perf_event__repipe_tracing_data; 453 inject->tool.tracing_data = perf_event__repipe_tracing_data;
412 } 454 }
413 455
456 output_data_offset = session->header.data_offset;
457
414 if (inject->build_ids) { 458 if (inject->build_ids) {
415 inject->tool.sample = perf_event__inject_buildid; 459 inject->tool.sample = perf_event__inject_buildid;
416 } else if (inject->sched_stat) { 460 } else if (inject->sched_stat) {
@@ -429,10 +473,22 @@ static int __cmd_inject(struct perf_inject *inject)
429 else if (!strncmp(name, "sched:sched_stat_", 17)) 473 else if (!strncmp(name, "sched:sched_stat_", 17))
430 evsel->handler = perf_inject__sched_stat; 474 evsel->handler = perf_inject__sched_stat;
431 } 475 }
476 } else if (inject->itrace_synth_opts.set) {
477 session->itrace_synth_opts = &inject->itrace_synth_opts;
478 inject->itrace_synth_opts.inject = true;
479 inject->tool.comm = perf_event__repipe_comm;
480 inject->tool.exit = perf_event__repipe_exit;
481 inject->tool.id_index = perf_event__repipe_id_index;
482 inject->tool.auxtrace_info = perf_event__process_auxtrace_info;
483 inject->tool.auxtrace = perf_event__process_auxtrace;
484 inject->tool.ordered_events = true;
485 inject->tool.ordering_requires_timestamps = true;
486 /* Allow space in the header for new attributes */
487 output_data_offset = 4096;
432 } 488 }
433 489
434 if (!file_out->is_pipe) 490 if (!file_out->is_pipe)
435 lseek(fd, session->header.data_offset, SEEK_SET); 491 lseek(fd, output_data_offset, SEEK_SET);
436 492
437 ret = perf_session__process_events(session); 493 ret = perf_session__process_events(session);
438 494
@@ -440,6 +496,14 @@ static int __cmd_inject(struct perf_inject *inject)
440 if (inject->build_ids) 496 if (inject->build_ids)
441 perf_header__set_feat(&session->header, 497 perf_header__set_feat(&session->header,
442 HEADER_BUILD_ID); 498 HEADER_BUILD_ID);
499 /*
500 * The AUX areas have been removed and replaced with
501 * synthesized hardware events, so clear the feature flag.
502 */
503 if (inject->itrace_synth_opts.set)
504 perf_header__clear_feat(&session->header,
505 HEADER_AUXTRACE);
506 session->header.data_offset = output_data_offset;
443 session->header.data_size = inject->bytes_written; 507 session->header.data_size = inject->bytes_written;
444 perf_session__write_header(session, session->evlist, fd, true); 508 perf_session__write_header(session, session->evlist, fd, true);
445 } 509 }
@@ -497,6 +561,9 @@ int cmd_inject(int argc, const char **argv, const char *prefix __maybe_unused)
497 OPT_STRING(0, "kallsyms", &symbol_conf.kallsyms_name, "file", 561 OPT_STRING(0, "kallsyms", &symbol_conf.kallsyms_name, "file",
498 "kallsyms pathname"), 562 "kallsyms pathname"),
499 OPT_BOOLEAN('f', "force", &file.force, "don't complain, do it"), 563 OPT_BOOLEAN('f', "force", &file.force, "don't complain, do it"),
564 OPT_CALLBACK_OPTARG(0, "itrace", &inject.itrace_synth_opts,
565 NULL, "opts", "Instruction Tracing options",
566 itrace_parse_synth_opts),
500 OPT_END() 567 OPT_END()
501 }; 568 };
502 const char * const inject_usage[] = { 569 const char * const inject_usage[] = {