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

perf tools: Allow controlling synthesizing PERF_RECORD_ metadata events during record

Depending on the use case, it might require some kind of synthesizing
and some not. Make it controllable to turn off heavy operations like
MMAP for all tasks.

Currently all users are converted to enable all the synthesis by
default. It'll be updated in the later patch.

Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Acked-by: Jiri Olsa <jolsa@redhat.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Ian Rogers <irogers@google.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jin Yao <yao.jin@linux.intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: https //lore.kernel.org/r/20210811044658.1313391-1-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Namhyung Kim and committed by
Arnaldo Carvalho de Melo
84111b9c 8228e936

+44 -34
+2 -2
tools/perf/bench/synthesize.c
··· 80 80 NULL, 81 81 target, threads, 82 82 process_synthesized_event, 83 - data_mmap, 83 + true, data_mmap, 84 84 nr_threads_synthesize); 85 85 if (err) 86 86 return err; ··· 171 171 NULL, 172 172 target, NULL, 173 173 process_synthesized_event, 174 - false, 174 + true, false, 175 175 nr_threads_synthesize); 176 176 if (err) { 177 177 perf_session__delete(session);
+1 -1
tools/perf/builtin-kvm.c
··· 1456 1456 perf_session__set_id_hdr_size(kvm->session); 1457 1457 ordered_events__set_copy_on_queue(&kvm->session->ordered_events, true); 1458 1458 machine__synthesize_threads(&kvm->session->machines.host, &kvm->opts.target, 1459 - kvm->evlist->core.threads, false, 1); 1459 + kvm->evlist->core.threads, true, false, 1); 1460 1460 err = kvm_live_open_events(kvm); 1461 1461 if (err) 1462 1462 goto out;
+4 -2
tools/perf/builtin-record.c
··· 1266 1266 err = perf_event__synthesize_thread_map(&rec->tool, thread_map, 1267 1267 process_synthesized_event, 1268 1268 &rec->session->machines.host, 1269 + true, 1269 1270 rec->opts.sample_address); 1270 1271 perf_thread_map__put(thread_map); 1271 1272 return err; ··· 1481 1480 f = process_locked_synthesized_event; 1482 1481 } 1483 1482 1484 - err = __machine__synthesize_threads(machine, tool, &opts->target, rec->evlist->core.threads, 1485 - f, opts->sample_address, 1483 + err = __machine__synthesize_threads(machine, tool, &opts->target, 1484 + rec->evlist->core.threads, 1485 + f, true, opts->sample_address, 1486 1486 rec->opts.nr_threads_synthesize); 1487 1487 1488 1488 if (rec->opts.nr_threads_synthesize > 1)
+1 -1
tools/perf/builtin-top.c
··· 1271 1271 pr_debug("Couldn't synthesize cgroup events.\n"); 1272 1272 1273 1273 machine__synthesize_threads(&top->session->machines.host, &opts->target, 1274 - top->evlist->core.threads, false, 1274 + top->evlist->core.threads, true, false, 1275 1275 top->nr_threads_synthesize); 1276 1276 1277 1277 if (top->nr_threads_synthesize > 1)
+2 -2
tools/perf/builtin-trace.c
··· 1628 1628 goto out; 1629 1629 1630 1630 err = __machine__synthesize_threads(trace->host, &trace->tool, &trace->opts.target, 1631 - evlist->core.threads, trace__tool_process, false, 1632 - 1); 1631 + evlist->core.threads, trace__tool_process, 1632 + true, false, 1); 1633 1633 out: 1634 1634 if (err) 1635 1635 symbol__exit();
+2 -1
tools/perf/tests/code-reading.c
··· 606 606 } 607 607 608 608 ret = perf_event__synthesize_thread_map(NULL, threads, 609 - perf_event__process, machine, false); 609 + perf_event__process, machine, 610 + true, false); 610 611 if (ret < 0) { 611 612 pr_debug("perf_event__synthesize_thread_map failed\n"); 612 613 goto out_err;
+2 -2
tools/perf/tests/mmap-thread-lookup.c
··· 135 135 { 136 136 return perf_event__synthesize_threads(NULL, 137 137 perf_event__process, 138 - machine, 0, 1); 138 + machine, 1, 0, 1); 139 139 } 140 140 141 141 static int synth_process(struct machine *machine) ··· 147 147 148 148 err = perf_event__synthesize_thread_map(NULL, map, 149 149 perf_event__process, 150 - machine, 0); 150 + machine, 1, 0); 151 151 152 152 perf_thread_map__put(map); 153 153 return err;
+26 -19
tools/perf/util/synthetic-events.c
··· 715 715 union perf_event *fork_event, 716 716 union perf_event *namespaces_event, 717 717 pid_t pid, int full, perf_event__handler_t process, 718 - struct perf_tool *tool, struct machine *machine, bool mmap_data) 718 + struct perf_tool *tool, struct machine *machine, 719 + bool needs_mmap, bool mmap_data) 719 720 { 720 721 char filename[PATH_MAX]; 721 722 struct dirent **dirent; ··· 740 739 * send mmap only for thread group leader 741 740 * see thread__init_maps() 742 741 */ 743 - if (pid == tgid && 742 + if (pid == tgid && needs_mmap && 744 743 perf_event__synthesize_mmap_events(tool, mmap_event, pid, tgid, 745 744 process, machine, mmap_data)) 746 745 return -1; ··· 787 786 break; 788 787 789 788 rc = 0; 790 - if (_pid == pid && !kernel_thread) { 789 + if (_pid == pid && !kernel_thread && needs_mmap) { 791 790 /* process the parent's maps too */ 792 791 rc = perf_event__synthesize_mmap_events(tool, mmap_event, pid, tgid, 793 792 process, machine, mmap_data); ··· 807 806 struct perf_thread_map *threads, 808 807 perf_event__handler_t process, 809 808 struct machine *machine, 810 - bool mmap_data) 809 + bool needs_mmap, bool mmap_data) 811 810 { 812 811 union perf_event *comm_event, *mmap_event, *fork_event; 813 812 union perf_event *namespaces_event; ··· 837 836 fork_event, namespaces_event, 838 837 perf_thread_map__pid(threads, thread), 0, 839 838 process, tool, machine, 840 - mmap_data)) { 839 + needs_mmap, mmap_data)) { 841 840 err = -1; 842 841 break; 843 842 } ··· 863 862 fork_event, namespaces_event, 864 863 comm_event->comm.pid, 0, 865 864 process, tool, machine, 866 - mmap_data)) { 865 + needs_mmap, mmap_data)) { 867 866 err = -1; 868 867 break; 869 868 } ··· 883 882 static int __perf_event__synthesize_threads(struct perf_tool *tool, 884 883 perf_event__handler_t process, 885 884 struct machine *machine, 885 + bool needs_mmap, 886 886 bool mmap_data, 887 887 struct dirent **dirent, 888 888 int start, ··· 928 926 */ 929 927 __event__synthesize_thread(comm_event, mmap_event, fork_event, 930 928 namespaces_event, pid, 1, process, 931 - tool, machine, mmap_data); 929 + tool, machine, needs_mmap, mmap_data); 932 930 } 933 931 err = 0; 934 932 ··· 947 945 struct perf_tool *tool; 948 946 perf_event__handler_t process; 949 947 struct machine *machine; 948 + bool needs_mmap; 950 949 bool mmap_data; 951 950 struct dirent **dirent; 952 951 int num; ··· 959 956 struct synthesize_threads_arg *args = arg; 960 957 961 958 __perf_event__synthesize_threads(args->tool, args->process, 962 - args->machine, args->mmap_data, 959 + args->machine, 960 + args->needs_mmap, args->mmap_data, 963 961 args->dirent, 964 962 args->start, args->num); 965 963 return NULL; ··· 969 965 int perf_event__synthesize_threads(struct perf_tool *tool, 970 966 perf_event__handler_t process, 971 967 struct machine *machine, 972 - bool mmap_data, 968 + bool needs_mmap, bool mmap_data, 973 969 unsigned int nr_threads_synthesize) 974 970 { 975 971 struct synthesize_threads_arg *args = NULL; ··· 998 994 999 995 if (thread_nr <= 1) { 1000 996 err = __perf_event__synthesize_threads(tool, process, 1001 - machine, mmap_data, 997 + machine, 998 + needs_mmap, mmap_data, 1002 999 dirent, base, n); 1003 1000 goto free_dirent; 1004 1001 } ··· 1020 1015 args[i].tool = tool; 1021 1016 args[i].process = process; 1022 1017 args[i].machine = machine; 1018 + args[i].needs_mmap = needs_mmap; 1023 1019 args[i].mmap_data = mmap_data; 1024 1020 args[i].dirent = dirent; 1025 1021 } ··· 1781 1775 1782 1776 int __machine__synthesize_threads(struct machine *machine, struct perf_tool *tool, 1783 1777 struct target *target, struct perf_thread_map *threads, 1784 - perf_event__handler_t process, bool data_mmap, 1785 - unsigned int nr_threads_synthesize) 1778 + perf_event__handler_t process, bool needs_mmap, 1779 + bool data_mmap, unsigned int nr_threads_synthesize) 1786 1780 { 1787 1781 if (target__has_task(target)) 1788 - return perf_event__synthesize_thread_map(tool, threads, process, machine, data_mmap); 1782 + return perf_event__synthesize_thread_map(tool, threads, process, machine, 1783 + needs_mmap, data_mmap); 1789 1784 else if (target__has_cpu(target)) 1790 - return perf_event__synthesize_threads(tool, process, 1791 - machine, data_mmap, 1785 + return perf_event__synthesize_threads(tool, process, machine, 1786 + needs_mmap, data_mmap, 1792 1787 nr_threads_synthesize); 1793 1788 /* command specified */ 1794 1789 return 0; 1795 1790 } 1796 1791 1797 1792 int machine__synthesize_threads(struct machine *machine, struct target *target, 1798 - struct perf_thread_map *threads, bool data_mmap, 1799 - unsigned int nr_threads_synthesize) 1793 + struct perf_thread_map *threads, bool needs_mmap, 1794 + bool data_mmap, unsigned int nr_threads_synthesize) 1800 1795 { 1801 1796 return __machine__synthesize_threads(machine, NULL, target, threads, 1802 - perf_event__process, data_mmap, 1803 - nr_threads_synthesize); 1797 + perf_event__process, needs_mmap, 1798 + data_mmap, nr_threads_synthesize); 1804 1799 } 1805 1800 1806 1801 static struct perf_record_event_update *event_update_event__new(size_t size, u64 type, u64 id)
+4 -4
tools/perf/util/synthetic-events.h
··· 53 53 int perf_event__synthesize_stat_round(struct perf_tool *tool, u64 time, u64 type, perf_event__handler_t process, struct machine *machine); 54 54 int perf_event__synthesize_stat(struct perf_tool *tool, u32 cpu, u32 thread, u64 id, struct perf_counts_values *count, perf_event__handler_t process, struct machine *machine); 55 55 int perf_event__synthesize_thread_map2(struct perf_tool *tool, struct perf_thread_map *threads, perf_event__handler_t process, struct machine *machine); 56 - int perf_event__synthesize_thread_map(struct perf_tool *tool, struct perf_thread_map *threads, perf_event__handler_t process, struct machine *machine, bool mmap_data); 57 - int perf_event__synthesize_threads(struct perf_tool *tool, perf_event__handler_t process, struct machine *machine, bool mmap_data, unsigned int nr_threads_synthesize); 56 + int perf_event__synthesize_thread_map(struct perf_tool *tool, struct perf_thread_map *threads, perf_event__handler_t process, struct machine *machine, bool needs_mmap, bool mmap_data); 57 + int perf_event__synthesize_threads(struct perf_tool *tool, perf_event__handler_t process, struct machine *machine, bool needs_mmap, bool mmap_data, unsigned int nr_threads_synthesize); 58 58 int perf_event__synthesize_tracing_data(struct perf_tool *tool, int fd, struct evlist *evlist, perf_event__handler_t process); 59 59 int perf_event__synth_time_conv(const struct perf_event_mmap_page *pc, struct perf_tool *tool, perf_event__handler_t process, struct machine *machine); 60 60 pid_t perf_event__synthesize_comm(struct perf_tool *tool, union perf_event *event, pid_t pid, perf_event__handler_t process, struct machine *machine); ··· 65 65 66 66 int __machine__synthesize_threads(struct machine *machine, struct perf_tool *tool, 67 67 struct target *target, struct perf_thread_map *threads, 68 - perf_event__handler_t process, bool data_mmap, 68 + perf_event__handler_t process, bool needs_mmap, bool data_mmap, 69 69 unsigned int nr_threads_synthesize); 70 70 int machine__synthesize_threads(struct machine *machine, struct target *target, 71 - struct perf_thread_map *threads, bool data_mmap, 71 + struct perf_thread_map *threads, bool needs_mmap, bool data_mmap, 72 72 unsigned int nr_threads_synthesize); 73 73 74 74 #ifdef HAVE_AUXTRACE_SUPPORT