aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-inject.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/builtin-inject.c')
-rw-r--r--tools/perf/builtin-inject.c105
1 files changed, 99 insertions, 6 deletions
diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c
index 0022e02ed31a..7fa68663ed72 100644
--- a/tools/perf/builtin-inject.c
+++ b/tools/perf/builtin-inject.c
@@ -17,6 +17,7 @@
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#include "util/auxtrace.h"
20#include "util/jit.h"
20 21
21#include <subcmd/parse-options.h> 22#include <subcmd/parse-options.h>
22 23
@@ -29,6 +30,7 @@ struct perf_inject {
29 bool sched_stat; 30 bool sched_stat;
30 bool have_auxtrace; 31 bool have_auxtrace;
31 bool strip; 32 bool strip;
33 bool jit_mode;
32 const char *input_name; 34 const char *input_name;
33 struct perf_data_file output; 35 struct perf_data_file output;
34 u64 bytes_written; 36 u64 bytes_written;
@@ -71,6 +73,15 @@ static int perf_event__repipe_oe_synth(struct perf_tool *tool,
71 return perf_event__repipe_synth(tool, event); 73 return perf_event__repipe_synth(tool, event);
72} 74}
73 75
76#ifdef HAVE_JITDUMP
77static int perf_event__drop_oe(struct perf_tool *tool __maybe_unused,
78 union perf_event *event __maybe_unused,
79 struct ordered_events *oe __maybe_unused)
80{
81 return 0;
82}
83#endif
84
74static int perf_event__repipe_op2_synth(struct perf_tool *tool, 85static int perf_event__repipe_op2_synth(struct perf_tool *tool,
75 union perf_event *event, 86 union perf_event *event,
76 struct perf_session *session 87 struct perf_session *session
@@ -234,6 +245,31 @@ static int perf_event__repipe_mmap(struct perf_tool *tool,
234 return err; 245 return err;
235} 246}
236 247
248#ifdef HAVE_JITDUMP
249static int perf_event__jit_repipe_mmap(struct perf_tool *tool,
250 union perf_event *event,
251 struct perf_sample *sample,
252 struct machine *machine)
253{
254 struct perf_inject *inject = container_of(tool, struct perf_inject, tool);
255 u64 n = 0;
256 int ret;
257
258 /*
259 * if jit marker, then inject jit mmaps and generate ELF images
260 */
261 ret = jit_process(inject->session, &inject->output, machine,
262 event->mmap.filename, sample->pid, &n);
263 if (ret < 0)
264 return ret;
265 if (ret) {
266 inject->bytes_written += n;
267 return 0;
268 }
269 return perf_event__repipe_mmap(tool, event, sample, machine);
270}
271#endif
272
237static int perf_event__repipe_mmap2(struct perf_tool *tool, 273static int perf_event__repipe_mmap2(struct perf_tool *tool,
238 union perf_event *event, 274 union perf_event *event,
239 struct perf_sample *sample, 275 struct perf_sample *sample,
@@ -247,6 +283,31 @@ static int perf_event__repipe_mmap2(struct perf_tool *tool,
247 return err; 283 return err;
248} 284}
249 285
286#ifdef HAVE_JITDUMP
287static int perf_event__jit_repipe_mmap2(struct perf_tool *tool,
288 union perf_event *event,
289 struct perf_sample *sample,
290 struct machine *machine)
291{
292 struct perf_inject *inject = container_of(tool, struct perf_inject, tool);
293 u64 n = 0;
294 int ret;
295
296 /*
297 * if jit marker, then inject jit mmaps and generate ELF images
298 */
299 ret = jit_process(inject->session, &inject->output, machine,
300 event->mmap2.filename, sample->pid, &n);
301 if (ret < 0)
302 return ret;
303 if (ret) {
304 inject->bytes_written += n;
305 return 0;
306 }
307 return perf_event__repipe_mmap2(tool, event, sample, machine);
308}
309#endif
310
250static int perf_event__repipe_fork(struct perf_tool *tool, 311static int perf_event__repipe_fork(struct perf_tool *tool,
251 union perf_event *event, 312 union perf_event *event,
252 struct perf_sample *sample, 313 struct perf_sample *sample,
@@ -626,12 +687,16 @@ static int __cmd_inject(struct perf_inject *inject)
626 ret = perf_session__process_events(session); 687 ret = perf_session__process_events(session);
627 688
628 if (!file_out->is_pipe) { 689 if (!file_out->is_pipe) {
629 if (inject->build_ids) { 690 if (inject->build_ids)
630 perf_header__set_feat(&session->header, 691 perf_header__set_feat(&session->header,
631 HEADER_BUILD_ID); 692 HEADER_BUILD_ID);
632 if (inject->have_auxtrace) 693 /*
633 dsos__hit_all(session); 694 * Keep all buildids when there is unprocessed AUX data because
634 } 695 * it is not known which ones the AUX trace hits.
696 */
697 if (perf_header__has_feat(&session->header, HEADER_BUILD_ID) &&
698 inject->have_auxtrace && !inject->itrace_synth_opts.set)
699 dsos__hit_all(session);
635 /* 700 /*
636 * The AUX areas have been removed and replaced with 701 * The AUX areas have been removed and replaced with
637 * synthesized hardware events, so clear the feature flag and 702 * synthesized hardware events, so clear the feature flag and
@@ -703,7 +768,7 @@ int cmd_inject(int argc, const char **argv, const char *prefix __maybe_unused)
703 }; 768 };
704 int ret; 769 int ret;
705 770
706 const struct option options[] = { 771 struct option options[] = {
707 OPT_BOOLEAN('b', "build-ids", &inject.build_ids, 772 OPT_BOOLEAN('b', "build-ids", &inject.build_ids,
708 "Inject build-ids into the output stream"), 773 "Inject build-ids into the output stream"),
709 OPT_STRING('i', "input", &inject.input_name, "file", 774 OPT_STRING('i', "input", &inject.input_name, "file",
@@ -713,6 +778,9 @@ int cmd_inject(int argc, const char **argv, const char *prefix __maybe_unused)
713 OPT_BOOLEAN('s', "sched-stat", &inject.sched_stat, 778 OPT_BOOLEAN('s', "sched-stat", &inject.sched_stat,
714 "Merge sched-stat and sched-switch for getting events " 779 "Merge sched-stat and sched-switch for getting events "
715 "where and how long tasks slept"), 780 "where and how long tasks slept"),
781#ifdef HAVE_JITDUMP
782 OPT_BOOLEAN('j', "jit", &inject.jit_mode, "merge jitdump files into perf.data file"),
783#endif
716 OPT_INCR('v', "verbose", &verbose, 784 OPT_INCR('v', "verbose", &verbose,
717 "be more verbose (show build ids, etc)"), 785 "be more verbose (show build ids, etc)"),
718 OPT_STRING(0, "kallsyms", &symbol_conf.kallsyms_name, "file", 786 OPT_STRING(0, "kallsyms", &symbol_conf.kallsyms_name, "file",
@@ -729,7 +797,9 @@ int cmd_inject(int argc, const char **argv, const char *prefix __maybe_unused)
729 "perf inject [<options>]", 797 "perf inject [<options>]",
730 NULL 798 NULL
731 }; 799 };
732 800#ifndef HAVE_JITDUMP
801 set_option_nobuild(options, 'j', "jit", "NO_LIBELF=1", true);
802#endif
733 argc = parse_options(argc, argv, options, inject_usage, 0); 803 argc = parse_options(argc, argv, options, inject_usage, 0);
734 804
735 /* 805 /*
@@ -755,6 +825,29 @@ int cmd_inject(int argc, const char **argv, const char *prefix __maybe_unused)
755 if (inject.session == NULL) 825 if (inject.session == NULL)
756 return -1; 826 return -1;
757 827
828 if (inject.build_ids) {
829 /*
830 * to make sure the mmap records are ordered correctly
831 * and so that the correct especially due to jitted code
832 * mmaps. We cannot generate the buildid hit list and
833 * inject the jit mmaps at the same time for now.
834 */
835 inject.tool.ordered_events = true;
836 inject.tool.ordering_requires_timestamps = true;
837 }
838#ifdef HAVE_JITDUMP
839 if (inject.jit_mode) {
840 inject.tool.mmap2 = perf_event__jit_repipe_mmap2;
841 inject.tool.mmap = perf_event__jit_repipe_mmap;
842 inject.tool.ordered_events = true;
843 inject.tool.ordering_requires_timestamps = true;
844 /*
845 * JIT MMAP injection injects all MMAP events in one go, so it
846 * does not obey finished_round semantics.
847 */
848 inject.tool.finished_round = perf_event__drop_oe;
849 }
850#endif
758 ret = symbol__init(&inject.session->header.env); 851 ret = symbol__init(&inject.session->header.env);
759 if (ret < 0) 852 if (ret < 0)
760 goto out_delete; 853 goto out_delete;