diff options
Diffstat (limited to 'tools/perf/builtin-trace.c')
-rw-r--r-- | tools/perf/builtin-trace.c | 105 |
1 files changed, 95 insertions, 10 deletions
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 3d54316639a4..6c7025370ec0 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -3117,7 +3117,27 @@ static int trace__init_syscalls_bpf_prog_array_maps(struct trace *trace) return err; } -#else + +static void trace__delete_augmented_syscalls(struct trace *trace) +{ + struct evsel *evsel, *tmp; + + evlist__remove(trace->evlist, trace->syscalls.events.augmented); + evsel__delete(trace->syscalls.events.augmented); + trace->syscalls.events.augmented = NULL; + + evlist__for_each_entry_safe(trace->evlist, tmp, evsel) { + if (evsel->bpf_obj == trace->bpf_obj) { + evlist__remove(trace->evlist, evsel); + evsel__delete(evsel); + } + + } + + bpf_object__close(trace->bpf_obj); + trace->bpf_obj = NULL; +} +#else // HAVE_LIBBPF_SUPPORT static int trace__set_ev_qualifier_bpf_filter(struct trace *trace __maybe_unused) { return 0; @@ -3138,8 +3158,27 @@ static int trace__init_syscalls_bpf_prog_array_maps(struct trace *trace __maybe_ { return 0; } + +static void trace__delete_augmented_syscalls(struct trace *trace __maybe_unused) +{ +} #endif // HAVE_LIBBPF_SUPPORT +static bool trace__only_augmented_syscalls_evsels(struct trace *trace) +{ + struct evsel *evsel; + + evlist__for_each_entry(trace->evlist, evsel) { + if (evsel == trace->syscalls.events.augmented || + evsel->bpf_obj == trace->bpf_obj) + continue; + + return false; + } + + return true; +} + static int trace__set_ev_qualifier_filter(struct trace *trace) { if (trace->syscalls.map) @@ -3316,7 +3355,6 @@ static int trace__run(struct trace *trace, int argc, const char **argv) perf_evlist__add_newtp(evlist, "sched", "sched_stat_runtime", trace__sched_stat_runtime)) goto out_error_sched_stat_runtime; - /* * If a global cgroup was set, apply it to all the events without an * explicit cgroup. I.e.: @@ -4221,6 +4259,22 @@ int cmd_trace(int argc, const char **argv) argc = parse_options_subcommand(argc, argv, trace_options, trace_subcommands, trace_usage, PARSE_OPT_STOP_AT_NON_OPTION); + + /* + * Here we already passed thru trace__parse_events_option() and it has + * already figured out if -e syscall_name, if not but if --event + * foo:bar was used, the user is interested _just_ in those, say, + * tracepoint events, not in the strace-like syscall-name-based mode. + * + * This is important because we need to check if strace-like mode is + * needed to decided if we should filter out the eBPF + * __augmented_syscalls__ code, if it is in the mix, say, via + * .perfconfig trace.add_events, and filter those out. + */ + if (!trace.trace_syscalls && !trace.trace_pgfaults && + trace.evlist->core.nr_entries == 0 /* Was --events used? */) { + trace.trace_syscalls = true; + } /* * Now that we have --verbose figured out, lets see if we need to parse * events from .perfconfig, so that if those events fail parsing, say some @@ -4265,9 +4319,45 @@ int cmd_trace(int argc, const char **argv) trace.bpf_obj = evsel->bpf_obj; - trace__set_bpf_map_filtered_pids(&trace); - trace__set_bpf_map_syscalls(&trace); - trace.syscalls.unaugmented_prog = trace__find_bpf_program_by_title(&trace, "!raw_syscalls:unaugmented"); + /* + * If we have _just_ the augmenter event but don't have a + * explicit --syscalls, then assume we want all strace-like + * syscalls: + */ + if (!trace.trace_syscalls && trace__only_augmented_syscalls_evsels(&trace)) + trace.trace_syscalls = true; + /* + * So, if we have a syscall augmenter, but trace_syscalls, aka + * strace-like syscall tracing is not set, then we need to trow + * away the augmenter, i.e. all the events that were created + * from that BPF object file. + * + * This is more to fix the current .perfconfig trace.add_events + * style of setting up the strace-like eBPF based syscall point + * payload augmenter. + * + * All this complexity will be avoided by adding an alternative + * to trace.add_events in the form of + * trace.bpf_augmented_syscalls, that will be only parsed if we + * need it. + * + * .perfconfig trace.add_events is still useful if we want, for + * instance, have msr_write.msr in some .perfconfig profile based + * 'perf trace --config determinism.profile' mode, where for some + * particular goal/workload type we want a set of events and + * output mode (with timings, etc) instead of having to add + * all via the command line. + * + * Also --config to specify an alternate .perfconfig file needs + * to be implemented. + */ + if (!trace.trace_syscalls) { + trace__delete_augmented_syscalls(&trace); + } else { + trace__set_bpf_map_filtered_pids(&trace); + trace__set_bpf_map_syscalls(&trace); + trace.syscalls.unaugmented_prog = trace__find_bpf_program_by_title(&trace, "!raw_syscalls:unaugmented"); + } } err = bpf__setup_stdout(trace.evlist); @@ -4410,11 +4500,6 @@ init_augmented_syscall_tp: if (trace.summary_only) trace.summary = trace.summary_only; - if (!trace.trace_syscalls && !trace.trace_pgfaults && - trace.evlist->core.nr_entries == 0 /* Was --events used? */) { - trace.trace_syscalls = true; - } - if (output_name != NULL) { err = trace__open_output(&trace, output_name); if (err < 0) { |