aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/lib/traceevent/Documentation/libtraceevent-func_apis.txt10
-rw-r--r--tools/lib/traceevent/event-parse.c18
-rw-r--r--tools/perf/Makefile.perf2
-rw-r--r--tools/perf/arch/arm/util/cs-etm.c2
-rw-r--r--tools/perf/arch/arm64/util/arm-spe.c2
-rw-r--r--tools/perf/arch/arm64/util/dwarf-regs.c1
-rw-r--r--tools/perf/arch/arm64/util/header.c4
-rw-r--r--tools/perf/arch/arm64/util/unwind-libunwind.c2
-rw-r--r--tools/perf/arch/powerpc/util/dwarf-regs.c1
-rw-r--r--tools/perf/arch/powerpc/util/header.c1
-rw-r--r--tools/perf/arch/powerpc/util/kvm-stat.c45
-rw-r--r--tools/perf/arch/powerpc/util/skip-callchain-idx.c1
-rw-r--r--tools/perf/arch/powerpc/util/sym-handling.c1
-rw-r--r--tools/perf/arch/s390/util/machine.c2
-rw-r--r--tools/perf/arch/x86/tests/intel-cqm.c1
-rw-r--r--tools/perf/arch/x86/tests/perf-time-to-tsc.c1
-rw-r--r--tools/perf/arch/x86/tests/rdpmc.c2
-rw-r--r--tools/perf/arch/x86/util/archinsn.c1
-rw-r--r--tools/perf/arch/x86/util/event.c2
-rw-r--r--tools/perf/arch/x86/util/intel-bts.c2
-rw-r--r--tools/perf/arch/x86/util/intel-pt.c2
-rw-r--r--tools/perf/arch/x86/util/machine.c3
-rw-r--r--tools/perf/arch/x86/util/tsc.c2
-rw-r--r--tools/perf/bench/epoll-ctl.c2
-rw-r--r--tools/perf/bench/epoll-wait.c2
-rw-r--r--tools/perf/bench/futex-hash.c2
-rw-r--r--tools/perf/bench/futex-lock-pi.c2
-rw-r--r--tools/perf/bench/futex-requeue.c2
-rw-r--r--tools/perf/bench/futex-wake-parallel.c3
-rw-r--r--tools/perf/bench/futex-wake.c2
-rw-r--r--tools/perf/bench/numa.c1
-rw-r--r--tools/perf/bench/sched-messaging.c2
-rw-r--r--tools/perf/bench/sched-pipe.c2
-rw-r--r--tools/perf/builtin-annotate.c1
-rw-r--r--tools/perf/builtin-c2c.c1
-rw-r--r--tools/perf/builtin-config.c1
-rw-r--r--tools/perf/builtin-evlist.c2
-rw-r--r--tools/perf/builtin-inject.c1
-rw-r--r--tools/perf/builtin-kvm.c15
-rw-r--r--tools/perf/builtin-record.c10
-rw-r--r--tools/perf/builtin-report.c2
-rw-r--r--tools/perf/builtin-sched.c3
-rw-r--r--tools/perf/builtin-stat.c24
-rw-r--r--tools/perf/builtin-top.c1
-rw-r--r--tools/perf/builtin-trace.c1
-rw-r--r--tools/perf/jvmti/Build9
-rw-r--r--tools/perf/lib/Makefile1
-rw-r--r--tools/perf/lib/cpumap.c12
-rw-r--r--tools/perf/lib/include/perf/cpumap.h1
-rw-r--r--tools/perf/lib/libperf.map1
-rw-r--r--tools/perf/perf.c2
-rw-r--r--tools/perf/pmu-events/arch/arm64/arm/cortex-a76-n1/branch.json14
-rw-r--r--tools/perf/pmu-events/arch/arm64/arm/cortex-a76-n1/bus.json24
-rw-r--r--tools/perf/pmu-events/arch/arm64/arm/cortex-a76-n1/cache.json207
-rw-r--r--tools/perf/pmu-events/arch/arm64/arm/cortex-a76-n1/exception.json52
-rw-r--r--tools/perf/pmu-events/arch/arm64/arm/cortex-a76-n1/instruction.json108
-rw-r--r--tools/perf/pmu-events/arch/arm64/arm/cortex-a76-n1/memory.json23
-rw-r--r--tools/perf/pmu-events/arch/arm64/arm/cortex-a76-n1/other.json7
-rw-r--r--tools/perf/pmu-events/arch/arm64/arm/cortex-a76-n1/pipeline.json14
-rw-r--r--tools/perf/pmu-events/arch/arm64/mapfile.csv2
-rw-r--r--tools/perf/tests/bitmap.c2
-rw-r--r--tools/perf/tests/clang.c2
-rw-r--r--tools/perf/tests/code-reading.c2
-rw-r--r--tools/perf/tests/cpumap.c1
-rw-r--r--tools/perf/tests/dso-data.c1
-rw-r--r--tools/perf/tests/dwarf-unwind.c1
-rw-r--r--tools/perf/tests/event-times.c1
-rw-r--r--tools/perf/tests/event_update.c4
-rw-r--r--tools/perf/tests/hists_common.c2
-rw-r--r--tools/perf/tests/keep-tracking.c3
-rw-r--r--tools/perf/tests/llvm.c1
-rw-r--r--tools/perf/tests/make6
-rw-r--r--tools/perf/tests/mem2node.c2
-rw-r--r--tools/perf/tests/mmap-basic.c3
-rw-r--r--tools/perf/tests/mmap-thread-lookup.c4
-rw-r--r--tools/perf/tests/openat-syscall-all-cpus.c5
-rw-r--r--tools/perf/tests/parse-events.c1
-rw-r--r--tools/perf/tests/parse-no-sample-id-all.c2
-rw-r--r--tools/perf/tests/perf-hooks.c1
-rw-r--r--tools/perf/tests/pmu.c1
-rw-r--r--tools/perf/tests/sample-parsing.c2
-rw-r--r--tools/perf/tests/stat.c1
-rw-r--r--tools/perf/tests/switch-tracking.c1
-rw-r--r--tools/perf/tests/task-exit.c2
-rw-r--r--tools/perf/tests/thread-map.c1
-rw-r--r--tools/perf/tests/topology.c2
-rw-r--r--tools/perf/tests/vmlinux-kallsyms.c2
-rw-r--r--tools/perf/ui/browser.c1
-rw-r--r--tools/perf/ui/browsers/annotate.c1
-rw-r--r--tools/perf/ui/browsers/header.c1
-rw-r--r--tools/perf/ui/browsers/map.c1
-rw-r--r--tools/perf/ui/browsers/res_sample.c2
-rw-r--r--tools/perf/ui/browsers/scripts.c3
-rw-r--r--tools/perf/ui/gtk/helpline.c1
-rw-r--r--tools/perf/ui/gtk/progress.c1
-rw-r--r--tools/perf/ui/gtk/setup.c3
-rw-r--r--tools/perf/ui/gtk/util.c1
-rw-r--r--tools/perf/ui/helpline.c2
-rw-r--r--tools/perf/ui/hist.c1
-rw-r--r--tools/perf/ui/setup.c2
-rw-r--r--tools/perf/ui/stdio/hist.c1
-rw-r--r--tools/perf/ui/tui/helpline.c1
-rw-r--r--tools/perf/ui/tui/setup.c2
-rw-r--r--tools/perf/ui/tui/util.c1
-rw-r--r--tools/perf/util/Build1
-rw-r--r--tools/perf/util/annotate.c2
-rw-r--r--tools/perf/util/arm-spe.c1
-rw-r--r--tools/perf/util/auxtrace.c6
-rw-r--r--tools/perf/util/auxtrace.h18
-rw-r--r--tools/perf/util/bpf-event.c1
-rw-r--r--tools/perf/util/bpf-event.h15
-rw-r--r--tools/perf/util/branch.c2
-rw-r--r--tools/perf/util/branch.h9
-rw-r--r--tools/perf/util/build-id.c2
-rw-r--r--tools/perf/util/callchain.c1
-rw-r--r--tools/perf/util/callchain.h5
-rw-r--r--tools/perf/util/cloexec.c2
-rw-r--r--tools/perf/util/cs-etm-decoder/cs-etm-decoder.c1
-rw-r--r--tools/perf/util/cs-etm.c2
-rw-r--r--tools/perf/util/data.c3
-rw-r--r--tools/perf/util/debug.c1
-rw-r--r--tools/perf/util/debug.h2
-rw-r--r--tools/perf/util/demangle-java.c1
-rw-r--r--tools/perf/util/demangle-rust.c1
-rw-r--r--tools/perf/util/dwarf-regs.c1
-rw-r--r--tools/perf/util/env.h3
-rw-r--r--tools/perf/util/event.c1109
-rw-r--r--tools/perf/util/event.h77
-rw-r--r--tools/perf/util/evlist.c2
-rw-r--r--tools/perf/util/evsel.c280
-rw-r--r--tools/perf/util/evsel.h5
-rw-r--r--tools/perf/util/evsel_fprintf.c1
-rw-r--r--tools/perf/util/header.c395
-rw-r--r--tools/perf/util/header.h60
-rw-r--r--tools/perf/util/hist.h1
-rw-r--r--tools/perf/util/intel-bts.c2
-rw-r--r--tools/perf/util/intel-pt.c1
-rw-r--r--tools/perf/util/jitdump.c2
-rw-r--r--tools/perf/util/kvm-stat.h4
-rw-r--r--tools/perf/util/libunwind/arm64.c1
-rw-r--r--tools/perf/util/libunwind/x86_32.c1
-rw-r--r--tools/perf/util/llvm-utils.c1
-rw-r--r--tools/perf/util/lzma.c2
-rw-r--r--tools/perf/util/machine.c15
-rw-r--r--tools/perf/util/machine.h15
-rw-r--r--tools/perf/util/memswap.h7
-rw-r--r--tools/perf/util/namespaces.c18
-rw-r--r--tools/perf/util/namespaces.h2
-rw-r--r--tools/perf/util/parse-events.c1
-rw-r--r--tools/perf/util/perf-hooks.c1
-rw-r--r--tools/perf/util/pmu.c1
-rw-r--r--tools/perf/util/probe-file.c1
-rw-r--r--tools/perf/util/python.c4
-rw-r--r--tools/perf/util/record.c2
-rw-r--r--tools/perf/util/rwsem.c1
-rw-r--r--tools/perf/util/s390-cpumsf.c1
-rw-r--r--tools/perf/util/s390-sample-raw.c1
-rw-r--r--tools/perf/util/scripting-engines/trace-event-python.c2
-rw-r--r--tools/perf/util/session.c72
-rw-r--r--tools/perf/util/session.h5
-rw-r--r--tools/perf/util/srccode.c2
-rw-r--r--tools/perf/util/stat.c60
-rw-r--r--tools/perf/util/stat.h9
-rw-r--r--tools/perf/util/svghelper.c2
-rw-r--r--tools/perf/util/symbol-elf.c3
-rw-r--r--tools/perf/util/symbol-minimal.c3
-rw-r--r--tools/perf/util/symbol.c2
-rw-r--r--tools/perf/util/synthetic-events.c1884
-rw-r--r--tools/perf/util/synthetic-events.h103
-rw-r--r--tools/perf/util/target.c2
-rw-r--r--tools/perf/util/top.c1
-rw-r--r--tools/perf/util/trace-event-info.c2
-rw-r--r--tools/perf/util/trace-event-read.c1
-rw-r--r--tools/perf/util/trace-event.c1
-rw-r--r--tools/perf/util/tsc.h14
-rw-r--r--tools/perf/util/unwind-libdw.c1
-rw-r--r--tools/perf/util/unwind-libunwind-local.c1
-rw-r--r--tools/perf/util/usage.c1
-rw-r--r--tools/perf/util/vdso.c2
-rw-r--r--tools/perf/util/zlib.c4
180 files changed, 2763 insertions, 2256 deletions
diff --git a/tools/lib/traceevent/Documentation/libtraceevent-func_apis.txt b/tools/lib/traceevent/Documentation/libtraceevent-func_apis.txt
index 38bfea30a5f6..f6aca0df2151 100644
--- a/tools/lib/traceevent/Documentation/libtraceevent-func_apis.txt
+++ b/tools/lib/traceevent/Documentation/libtraceevent-func_apis.txt
@@ -59,12 +59,12 @@ parser context.
59 59
60The _tep_register_function()_ function registers a function name mapped to an 60The _tep_register_function()_ function registers a function name mapped to an
61address and (optional) module. This mapping is used in case the function tracer 61address and (optional) module. This mapping is used in case the function tracer
62or events have "%pF" or "%pS" parameter in its format string. It is common to 62or events have "%pS" parameter in its format string. It is common to pass in
63pass in the kallsyms function names with their corresponding addresses with this 63the kallsyms function names with their corresponding addresses with this
64function. The _tep_ argument is the trace event parser context. The _name_ is 64function. The _tep_ argument is the trace event parser context. The _name_ is
65the name of the function, the string is copied internally. The _addr_ is 65the name of the function, the string is copied internally. The _addr_ is the
66the start address of the function. The _mod_ is the kernel module 66start address of the function. The _mod_ is the kernel module the function may
67the function may be in (NULL for none). 67be in (NULL for none).
68 68
69The _tep_register_print_string()_ function registers a string by the address 69The _tep_register_print_string()_ function registers a string by the address
70it was stored in the kernel. Some strings internal to the kernel with static 70it was stored in the kernel. Some strings internal to the kernel with static
diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c
index bb22238debfe..6f842af4550b 100644
--- a/tools/lib/traceevent/event-parse.c
+++ b/tools/lib/traceevent/event-parse.c
@@ -4367,10 +4367,20 @@ static struct tep_print_arg *make_bprint_args(char *fmt, void *data, int size, s
4367 switch (*ptr) { 4367 switch (*ptr) {
4368 case 's': 4368 case 's':
4369 case 'S': 4369 case 'S':
4370 case 'f':
4371 case 'F':
4372 case 'x': 4370 case 'x':
4373 break; 4371 break;
4372 case 'f':
4373 case 'F':
4374 /*
4375 * Pre-5.5 kernels use %pf and
4376 * %pF for printing symbols
4377 * while kernels since 5.5 use
4378 * %pfw for fwnodes. So check
4379 * %p[fF] isn't followed by 'w'.
4380 */
4381 if (ptr[1] != 'w')
4382 break;
4383 /* fall through */
4374 default: 4384 default:
4375 /* 4385 /*
4376 * Older kernels do not process 4386 * Older kernels do not process
@@ -4487,12 +4497,12 @@ get_bprint_format(void *data, int size __maybe_unused,
4487 4497
4488 printk = find_printk(tep, addr); 4498 printk = find_printk(tep, addr);
4489 if (!printk) { 4499 if (!printk) {
4490 if (asprintf(&format, "%%pf: (NO FORMAT FOUND at %llx)\n", addr) < 0) 4500 if (asprintf(&format, "%%ps: (NO FORMAT FOUND at %llx)\n", addr) < 0)
4491 return NULL; 4501 return NULL;
4492 return format; 4502 return format;
4493 } 4503 }
4494 4504
4495 if (asprintf(&format, "%s: %s", "%pf", printk->printk) < 0) 4505 if (asprintf(&format, "%s: %s", "%ps", printk->printk) < 0)
4496 return NULL; 4506 return NULL;
4497 4507
4498 return format; 4508 return format;
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index f9807d8c005b..2ccc12f3730b 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -567,7 +567,7 @@ all: shell_compatibility_test $(ALL_PROGRAMS) $(LANG_BINDINGS) $(OTHER_PROGRAMS)
567# Create python binding output directory if not already present 567# Create python binding output directory if not already present
568_dummy := $(shell [ -d '$(OUTPUT)python' ] || mkdir -p '$(OUTPUT)python') 568_dummy := $(shell [ -d '$(OUTPUT)python' ] || mkdir -p '$(OUTPUT)python')
569 569
570$(OUTPUT)python/perf.so: $(PYTHON_EXT_SRCS) $(PYTHON_EXT_DEPS) $(LIBTRACEEVENT_DYNAMIC_LIST) 570$(OUTPUT)python/perf.so: $(PYTHON_EXT_SRCS) $(PYTHON_EXT_DEPS) $(LIBTRACEEVENT_DYNAMIC_LIST) $(LIBPERF)
571 $(QUIET_GEN)LDSHARED="$(CC) -pthread -shared" \ 571 $(QUIET_GEN)LDSHARED="$(CC) -pthread -shared" \
572 CFLAGS='$(CFLAGS)' LDFLAGS='$(LDFLAGS) $(LIBTRACEEVENT_DYNAMIC_LIST_LDFLAGS)' \ 572 CFLAGS='$(CFLAGS)' LDFLAGS='$(LDFLAGS) $(LIBTRACEEVENT_DYNAMIC_LIST_LDFLAGS)' \
573 $(PYTHON_WORD) util/setup.py \ 573 $(PYTHON_WORD) util/setup.py \
diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/cs-etm.c
index c32db09baf0d..5d120b1e35ed 100644
--- a/tools/perf/arch/arm/util/cs-etm.c
+++ b/tools/perf/arch/arm/util/cs-etm.c
@@ -25,7 +25,7 @@
25#include "../../util/evsel.h" 25#include "../../util/evsel.h"
26#include "../../util/pmu.h" 26#include "../../util/pmu.h"
27#include "../../util/cs-etm.h" 27#include "../../util/cs-etm.h"
28#include "../../util/util.h" 28#include "../../util/util.h" // page_size
29#include "../../util/session.h" 29#include "../../util/session.h"
30 30
31#include <errno.h> 31#include <errno.h>
diff --git a/tools/perf/arch/arm64/util/arm-spe.c b/tools/perf/arch/arm64/util/arm-spe.c
index 4b364692da67..eebbf31f995c 100644
--- a/tools/perf/arch/arm64/util/arm-spe.c
+++ b/tools/perf/arch/arm64/util/arm-spe.c
@@ -16,7 +16,7 @@
16#include "../../util/evsel.h" 16#include "../../util/evsel.h"
17#include "../../util/evlist.h" 17#include "../../util/evlist.h"
18#include "../../util/session.h" 18#include "../../util/session.h"
19#include "../../util/util.h" 19#include "../../util/util.h" // page_size
20#include "../../util/pmu.h" 20#include "../../util/pmu.h"
21#include "../../util/debug.h" 21#include "../../util/debug.h"
22#include "../../util/auxtrace.h" 22#include "../../util/auxtrace.h"
diff --git a/tools/perf/arch/arm64/util/dwarf-regs.c b/tools/perf/arch/arm64/util/dwarf-regs.c
index b047b882c5b1..917b97d7c5d3 100644
--- a/tools/perf/arch/arm64/util/dwarf-regs.c
+++ b/tools/perf/arch/arm64/util/dwarf-regs.c
@@ -11,7 +11,6 @@
11#include <dwarf-regs.h> 11#include <dwarf-regs.h>
12#include <linux/ptrace.h> /* for struct user_pt_regs */ 12#include <linux/ptrace.h> /* for struct user_pt_regs */
13#include <linux/stringify.h> 13#include <linux/stringify.h>
14#include "util.h"
15 14
16struct pt_regs_dwarfnum { 15struct pt_regs_dwarfnum {
17 const char *name; 16 const char *name;
diff --git a/tools/perf/arch/arm64/util/header.c b/tools/perf/arch/arm64/util/header.c
index e41defaaa2e6..a32e4b72a98f 100644
--- a/tools/perf/arch/arm64/util/header.c
+++ b/tools/perf/arch/arm64/util/header.c
@@ -1,5 +1,7 @@
1#include <stdio.h> 1#include <stdio.h>
2#include <stdlib.h> 2#include <stdlib.h>
3#include <perf/cpumap.h>
4#include <internal/cpumap.h>
3#include <api/fs/fs.h> 5#include <api/fs/fs.h>
4#include "debug.h" 6#include "debug.h"
5#include "header.h" 7#include "header.h"
@@ -29,7 +31,7 @@ char *get_cpuid_str(struct perf_pmu *pmu)
29 31
30 /* read midr from list of cpus mapped to this pmu */ 32 /* read midr from list of cpus mapped to this pmu */
31 cpus = perf_cpu_map__get(pmu->cpus); 33 cpus = perf_cpu_map__get(pmu->cpus);
32 for (cpu = 0; cpu < cpus->nr; cpu++) { 34 for (cpu = 0; cpu < perf_cpu_map__nr(cpus); cpu++) {
33 scnprintf(path, PATH_MAX, "%s/devices/system/cpu/cpu%d"MIDR, 35 scnprintf(path, PATH_MAX, "%s/devices/system/cpu/cpu%d"MIDR,
34 sysfs, cpus->map[cpu]); 36 sysfs, cpus->map[cpu]);
35 37
diff --git a/tools/perf/arch/arm64/util/unwind-libunwind.c b/tools/perf/arch/arm64/util/unwind-libunwind.c
index 002520d4036b..1495a9523a23 100644
--- a/tools/perf/arch/arm64/util/unwind-libunwind.c
+++ b/tools/perf/arch/arm64/util/unwind-libunwind.c
@@ -5,8 +5,8 @@
5#include <libunwind.h> 5#include <libunwind.h>
6#include "perf_regs.h" 6#include "perf_regs.h"
7#include "../../util/unwind.h" 7#include "../../util/unwind.h"
8#include "../../util/debug.h"
9#endif 8#endif
9#include "../../util/debug.h"
10 10
11int LIBUNWIND__ARCH_REG_ID(int regnum) 11int LIBUNWIND__ARCH_REG_ID(int regnum)
12{ 12{
diff --git a/tools/perf/arch/powerpc/util/dwarf-regs.c b/tools/perf/arch/powerpc/util/dwarf-regs.c
index 4952890b9428..0c4f4caf53ac 100644
--- a/tools/perf/arch/powerpc/util/dwarf-regs.c
+++ b/tools/perf/arch/powerpc/util/dwarf-regs.c
@@ -12,7 +12,6 @@
12#include <linux/ptrace.h> 12#include <linux/ptrace.h>
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/stringify.h> 14#include <linux/stringify.h>
15#include "util.h"
16 15
17struct pt_regs_dwarfnum { 16struct pt_regs_dwarfnum {
18 const char *name; 17 const char *name;
diff --git a/tools/perf/arch/powerpc/util/header.c b/tools/perf/arch/powerpc/util/header.c
index 0b242664f5ea..b6b7bc7e31a1 100644
--- a/tools/perf/arch/powerpc/util/header.c
+++ b/tools/perf/arch/powerpc/util/header.c
@@ -6,7 +6,6 @@
6#include <string.h> 6#include <string.h>
7#include <linux/stringify.h> 7#include <linux/stringify.h>
8#include "header.h" 8#include "header.h"
9#include "util.h"
10 9
11#define mfspr(rn) ({unsigned long rval; \ 10#define mfspr(rn) ({unsigned long rval; \
12 asm volatile("mfspr %0," __stringify(rn) \ 11 asm volatile("mfspr %0," __stringify(rn) \
diff --git a/tools/perf/arch/powerpc/util/kvm-stat.c b/tools/perf/arch/powerpc/util/kvm-stat.c
index f0dbf7b075c8..9cc1c4a9dec4 100644
--- a/tools/perf/arch/powerpc/util/kvm-stat.c
+++ b/tools/perf/arch/powerpc/util/kvm-stat.c
@@ -5,9 +5,11 @@
5#include "util/debug.h" 5#include "util/debug.h"
6#include "util/evsel.h" 6#include "util/evsel.h"
7#include "util/evlist.h" 7#include "util/evlist.h"
8#include "util/pmu.h"
8 9
9#include "book3s_hv_exits.h" 10#include "book3s_hv_exits.h"
10#include "book3s_hcalls.h" 11#include "book3s_hcalls.h"
12#include <subcmd/parse-options.h>
11 13
12#define NR_TPS 4 14#define NR_TPS 4
13 15
@@ -172,3 +174,46 @@ int cpu_isa_init(struct perf_kvm_stat *kvm, const char *cpuid __maybe_unused)
172 174
173 return ret; 175 return ret;
174} 176}
177
178/*
179 * Incase of powerpc architecture, pmu registers are programmable
180 * by guest kernel. So monitoring guest via host may not provide
181 * valid samples with default 'cycles' event. It is better to use
182 * 'trace_imc/trace_cycles' event for guest profiling, since it
183 * can track the guest instruction pointer in the trace-record.
184 *
185 * Function to parse the arguments and return appropriate values.
186 */
187int kvm_add_default_arch_event(int *argc, const char **argv)
188{
189 const char **tmp;
190 bool event = false;
191 int i, j = *argc;
192
193 const struct option event_options[] = {
194 OPT_BOOLEAN('e', "event", &event, NULL),
195 OPT_END()
196 };
197
198 tmp = calloc(j + 1, sizeof(char *));
199 if (!tmp)
200 return -EINVAL;
201
202 for (i = 0; i < j; i++)
203 tmp[i] = argv[i];
204
205 parse_options(j, tmp, event_options, NULL, PARSE_OPT_KEEP_UNKNOWN);
206 if (!event) {
207 if (pmu_have_event("trace_imc", "trace_cycles")) {
208 argv[j++] = strdup("-e");
209 argv[j++] = strdup("trace_imc/trace_cycles/");
210 *argc += 2;
211 } else {
212 free(tmp);
213 return -EINVAL;
214 }
215 }
216
217 free(tmp);
218 return 0;
219}
diff --git a/tools/perf/arch/powerpc/util/skip-callchain-idx.c b/tools/perf/arch/powerpc/util/skip-callchain-idx.c
index fc9c2f5fcd52..3018a054526a 100644
--- a/tools/perf/arch/powerpc/util/skip-callchain-idx.c
+++ b/tools/perf/arch/powerpc/util/skip-callchain-idx.c
@@ -13,6 +13,7 @@
13#include "util/callchain.h" 13#include "util/callchain.h"
14#include "util/debug.h" 14#include "util/debug.h"
15#include "util/dso.h" 15#include "util/dso.h"
16#include "util/event.h" // struct ip_callchain
16#include "util/map.h" 17#include "util/map.h"
17#include "util/symbol.h" 18#include "util/symbol.h"
18 19
diff --git a/tools/perf/arch/powerpc/util/sym-handling.c b/tools/perf/arch/powerpc/util/sym-handling.c
index 8a4b717e0a53..abb7a12d8f93 100644
--- a/tools/perf/arch/powerpc/util/sym-handling.c
+++ b/tools/perf/arch/powerpc/util/sym-handling.c
@@ -4,7 +4,6 @@
4 * Copyright (C) 2015 Naveen N. Rao, IBM Corporation 4 * Copyright (C) 2015 Naveen N. Rao, IBM Corporation
5 */ 5 */
6 6
7#include "debug.h"
8#include "dso.h" 7#include "dso.h"
9#include "symbol.h" 8#include "symbol.h"
10#include "map.h" 9#include "map.h"
diff --git a/tools/perf/arch/s390/util/machine.c b/tools/perf/arch/s390/util/machine.c
index c8c86a0c9b79..df099d6cc3f5 100644
--- a/tools/perf/arch/s390/util/machine.c
+++ b/tools/perf/arch/s390/util/machine.c
@@ -2,7 +2,7 @@
2#include <unistd.h> 2#include <unistd.h>
3#include <stdio.h> 3#include <stdio.h>
4#include <string.h> 4#include <string.h>
5#include "util.h" 5#include "util.h" // page_size
6#include "machine.h" 6#include "machine.h"
7#include "api/fs/fs.h" 7#include "api/fs/fs.h"
8#include "debug.h" 8#include "debug.h"
diff --git a/tools/perf/arch/x86/tests/intel-cqm.c b/tools/perf/arch/x86/tests/intel-cqm.c
index 3b5cc3373821..111c0ab2e7b5 100644
--- a/tools/perf/arch/x86/tests/intel-cqm.c
+++ b/tools/perf/arch/x86/tests/intel-cqm.c
@@ -5,7 +5,6 @@
5#include "evlist.h" 5#include "evlist.h"
6#include "evsel.h" 6#include "evsel.h"
7#include "arch-tests.h" 7#include "arch-tests.h"
8#include "util.h"
9 8
10#include <signal.h> 9#include <signal.h>
11#include <sys/mman.h> 10#include <sys/mman.h>
diff --git a/tools/perf/arch/x86/tests/perf-time-to-tsc.c b/tools/perf/arch/x86/tests/perf-time-to-tsc.c
index eb3635941c2b..0a4570b340fa 100644
--- a/tools/perf/arch/x86/tests/perf-time-to-tsc.c
+++ b/tools/perf/arch/x86/tests/perf-time-to-tsc.c
@@ -15,7 +15,6 @@
15#include "evlist.h" 15#include "evlist.h"
16#include "evsel.h" 16#include "evsel.h"
17#include "thread_map.h" 17#include "thread_map.h"
18#include "cpumap.h"
19#include "record.h" 18#include "record.h"
20#include "tsc.h" 19#include "tsc.h"
21#include "tests/tests.h" 20#include "tests/tests.h"
diff --git a/tools/perf/arch/x86/tests/rdpmc.c b/tools/perf/arch/x86/tests/rdpmc.c
index 6e67cee792b1..e7640fb047de 100644
--- a/tools/perf/arch/x86/tests/rdpmc.c
+++ b/tools/perf/arch/x86/tests/rdpmc.c
@@ -13,7 +13,7 @@
13#include "tests/tests.h" 13#include "tests/tests.h"
14#include "cloexec.h" 14#include "cloexec.h"
15#include "event.h" 15#include "event.h"
16#include "util.h" 16#include "util.h" // page_size
17#include "arch-tests.h" 17#include "arch-tests.h"
18 18
19static u64 rdpmc(unsigned int counter) 19static u64 rdpmc(unsigned int counter)
diff --git a/tools/perf/arch/x86/util/archinsn.c b/tools/perf/arch/x86/util/archinsn.c
index 9876c7a7ed7c..3e6791531ca5 100644
--- a/tools/perf/arch/x86/util/archinsn.c
+++ b/tools/perf/arch/x86/util/archinsn.c
@@ -1,6 +1,7 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2#include "../../../../arch/x86/include/asm/insn.h" 2#include "../../../../arch/x86/include/asm/insn.h"
3#include "archinsn.h" 3#include "archinsn.h"
4#include "event.h"
4#include "machine.h" 5#include "machine.h"
5#include "thread.h" 6#include "thread.h"
6#include "symbol.h" 7#include "symbol.h"
diff --git a/tools/perf/arch/x86/util/event.c b/tools/perf/arch/x86/util/event.c
index a3a0b6884779..d357c625c09f 100644
--- a/tools/perf/arch/x86/util/event.c
+++ b/tools/perf/arch/x86/util/event.c
@@ -3,6 +3,8 @@
3#include <linux/string.h> 3#include <linux/string.h>
4#include <linux/zalloc.h> 4#include <linux/zalloc.h>
5 5
6#include "../../util/event.h"
7#include "../../util/synthetic-events.h"
6#include "../../util/machine.h" 8#include "../../util/machine.h"
7#include "../../util/tool.h" 9#include "../../util/tool.h"
8#include "../../util/map.h" 10#include "../../util/map.h"
diff --git a/tools/perf/arch/x86/util/intel-bts.c b/tools/perf/arch/x86/util/intel-bts.c
index d263430c045f..090d90e093df 100644
--- a/tools/perf/arch/x86/util/intel-bts.c
+++ b/tools/perf/arch/x86/util/intel-bts.c
@@ -22,7 +22,7 @@
22#include "../../util/tsc.h" 22#include "../../util/tsc.h"
23#include "../../util/auxtrace.h" 23#include "../../util/auxtrace.h"
24#include "../../util/intel-bts.h" 24#include "../../util/intel-bts.h"
25#include "../../util/util.h" 25#include "../../util/util.h" // page_size
26 26
27#define KiB(x) ((x) * 1024) 27#define KiB(x) ((x) * 1024)
28#define MiB(x) ((x) * 1024 * 1024) 28#define MiB(x) ((x) * 1024 * 1024)
diff --git a/tools/perf/arch/x86/util/intel-pt.c b/tools/perf/arch/x86/util/intel-pt.c
index cb7cf16af79c..3d041b89f018 100644
--- a/tools/perf/arch/x86/util/intel-pt.c
+++ b/tools/perf/arch/x86/util/intel-pt.c
@@ -26,7 +26,7 @@
26#include "../../util/record.h" 26#include "../../util/record.h"
27#include "../../util/target.h" 27#include "../../util/target.h"
28#include "../../util/tsc.h" 28#include "../../util/tsc.h"
29#include "../../util/util.h" 29#include "../../util/util.h" // page_size
30#include "../../util/intel-pt.h" 30#include "../../util/intel-pt.h"
31 31
32#define KiB(x) ((x) * 1024) 32#define KiB(x) ((x) * 1024)
diff --git a/tools/perf/arch/x86/util/machine.c b/tools/perf/arch/x86/util/machine.c
index 1e9ec783b9a1..f0c289862f9f 100644
--- a/tools/perf/arch/x86/util/machine.c
+++ b/tools/perf/arch/x86/util/machine.c
@@ -1,9 +1,10 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2#include <linux/types.h> 2#include <linux/types.h>
3#include <linux/string.h> 3#include <linux/string.h>
4#include <limits.h>
4#include <stdlib.h> 5#include <stdlib.h>
5 6
6#include "../../util/util.h" 7#include "../../util/util.h" // page_size
7#include "../../util/machine.h" 8#include "../../util/machine.h"
8#include "../../util/map.h" 9#include "../../util/map.h"
9#include "../../util/symbol.h" 10#include "../../util/symbol.h"
diff --git a/tools/perf/arch/x86/util/tsc.c b/tools/perf/arch/x86/util/tsc.c
index c5197a15119b..2f55afb14e1f 100644
--- a/tools/perf/arch/x86/util/tsc.c
+++ b/tools/perf/arch/x86/util/tsc.c
@@ -8,6 +8,8 @@
8#include <linux/types.h> 8#include <linux/types.h>
9#include <asm/barrier.h> 9#include <asm/barrier.h>
10#include "../../../util/debug.h" 10#include "../../../util/debug.h"
11#include "../../../util/event.h"
12#include "../../../util/synthetic-events.h"
11#include "../../../util/tsc.h" 13#include "../../../util/tsc.h"
12 14
13int perf_read_tsc_conversion(const struct perf_event_mmap_page *pc, 15int perf_read_tsc_conversion(const struct perf_event_mmap_page *pc,
diff --git a/tools/perf/bench/epoll-ctl.c b/tools/perf/bench/epoll-ctl.c
index d1caa4a0a12a..bb617e568841 100644
--- a/tools/perf/bench/epoll-ctl.c
+++ b/tools/perf/bench/epoll-ctl.c
@@ -21,12 +21,12 @@
21#include <sys/resource.h> 21#include <sys/resource.h>
22#include <sys/epoll.h> 22#include <sys/epoll.h>
23#include <sys/eventfd.h> 23#include <sys/eventfd.h>
24#include <internal/cpumap.h>
24#include <perf/cpumap.h> 25#include <perf/cpumap.h>
25 26
26#include "../util/stat.h" 27#include "../util/stat.h"
27#include <subcmd/parse-options.h> 28#include <subcmd/parse-options.h>
28#include "bench.h" 29#include "bench.h"
29#include "cpumap.h"
30 30
31#include <err.h> 31#include <err.h>
32 32
diff --git a/tools/perf/bench/epoll-wait.c b/tools/perf/bench/epoll-wait.c
index f6b4472847d2..7af694437f4e 100644
--- a/tools/perf/bench/epoll-wait.c
+++ b/tools/perf/bench/epoll-wait.c
@@ -76,12 +76,12 @@
76#include <sys/epoll.h> 76#include <sys/epoll.h>
77#include <sys/eventfd.h> 77#include <sys/eventfd.h>
78#include <sys/types.h> 78#include <sys/types.h>
79#include <internal/cpumap.h>
79#include <perf/cpumap.h> 80#include <perf/cpumap.h>
80 81
81#include "../util/stat.h" 82#include "../util/stat.h"
82#include <subcmd/parse-options.h> 83#include <subcmd/parse-options.h>
83#include "bench.h" 84#include "bench.h"
84#include "cpumap.h"
85 85
86#include <err.h> 86#include <err.h>
87 87
diff --git a/tools/perf/bench/futex-hash.c b/tools/perf/bench/futex-hash.c
index 80e138904c66..8ba0c3330a9a 100644
--- a/tools/perf/bench/futex-hash.c
+++ b/tools/perf/bench/futex-hash.c
@@ -20,13 +20,13 @@
20#include <linux/kernel.h> 20#include <linux/kernel.h>
21#include <linux/zalloc.h> 21#include <linux/zalloc.h>
22#include <sys/time.h> 22#include <sys/time.h>
23#include <internal/cpumap.h>
23#include <perf/cpumap.h> 24#include <perf/cpumap.h>
24 25
25#include "../util/stat.h" 26#include "../util/stat.h"
26#include <subcmd/parse-options.h> 27#include <subcmd/parse-options.h>
27#include "bench.h" 28#include "bench.h"
28#include "futex.h" 29#include "futex.h"
29#include "cpumap.h"
30 30
31#include <err.h> 31#include <err.h>
32 32
diff --git a/tools/perf/bench/futex-lock-pi.c b/tools/perf/bench/futex-lock-pi.c
index c5d6d0abbaa9..d0cae8125423 100644
--- a/tools/perf/bench/futex-lock-pi.c
+++ b/tools/perf/bench/futex-lock-pi.c
@@ -14,10 +14,10 @@
14#include <linux/kernel.h> 14#include <linux/kernel.h>
15#include <linux/zalloc.h> 15#include <linux/zalloc.h>
16#include <errno.h> 16#include <errno.h>
17#include <internal/cpumap.h>
17#include <perf/cpumap.h> 18#include <perf/cpumap.h>
18#include "bench.h" 19#include "bench.h"
19#include "futex.h" 20#include "futex.h"
20#include "cpumap.h"
21 21
22#include <err.h> 22#include <err.h>
23#include <stdlib.h> 23#include <stdlib.h>
diff --git a/tools/perf/bench/futex-requeue.c b/tools/perf/bench/futex-requeue.c
index 75d3418c1a88..a00a6891447a 100644
--- a/tools/perf/bench/futex-requeue.c
+++ b/tools/perf/bench/futex-requeue.c
@@ -20,10 +20,10 @@
20#include <linux/kernel.h> 20#include <linux/kernel.h>
21#include <linux/time64.h> 21#include <linux/time64.h>
22#include <errno.h> 22#include <errno.h>
23#include <internal/cpumap.h>
23#include <perf/cpumap.h> 24#include <perf/cpumap.h>
24#include "bench.h" 25#include "bench.h"
25#include "futex.h" 26#include "futex.h"
26#include "cpumap.h"
27 27
28#include <err.h> 28#include <err.h>
29#include <stdlib.h> 29#include <stdlib.h>
diff --git a/tools/perf/bench/futex-wake-parallel.c b/tools/perf/bench/futex-wake-parallel.c
index 163fe16c275a..a053cf2b7039 100644
--- a/tools/perf/bench/futex-wake-parallel.c
+++ b/tools/perf/bench/futex-wake-parallel.c
@@ -29,7 +29,8 @@ int bench_futex_wake_parallel(int argc __maybe_unused, const char **argv __maybe
29#include <linux/time64.h> 29#include <linux/time64.h>
30#include <errno.h> 30#include <errno.h>
31#include "futex.h" 31#include "futex.h"
32#include "cpumap.h" 32#include <internal/cpumap.h>
33#include <perf/cpumap.h>
33 34
34#include <err.h> 35#include <err.h>
35#include <stdlib.h> 36#include <stdlib.h>
diff --git a/tools/perf/bench/futex-wake.c b/tools/perf/bench/futex-wake.c
index 77dcdc13618a..df810096abfe 100644
--- a/tools/perf/bench/futex-wake.c
+++ b/tools/perf/bench/futex-wake.c
@@ -20,10 +20,10 @@
20#include <linux/kernel.h> 20#include <linux/kernel.h>
21#include <linux/time64.h> 21#include <linux/time64.h>
22#include <errno.h> 22#include <errno.h>
23#include <internal/cpumap.h>
23#include <perf/cpumap.h> 24#include <perf/cpumap.h>
24#include "bench.h" 25#include "bench.h"
25#include "futex.h" 26#include "futex.h"
26#include "cpumap.h"
27 27
28#include <err.h> 28#include <err.h>
29#include <stdlib.h> 29#include <stdlib.h>
diff --git a/tools/perf/bench/numa.c b/tools/perf/bench/numa.c
index 62b8ef4bcb1f..5797253b9700 100644
--- a/tools/perf/bench/numa.c
+++ b/tools/perf/bench/numa.c
@@ -9,7 +9,6 @@
9/* For the CLR_() macros */ 9/* For the CLR_() macros */
10#include <pthread.h> 10#include <pthread.h>
11 11
12#include "../builtin.h"
13#include <subcmd/parse-options.h> 12#include <subcmd/parse-options.h>
14#include "../util/cloexec.h" 13#include "../util/cloexec.h"
15 14
diff --git a/tools/perf/bench/sched-messaging.c b/tools/perf/bench/sched-messaging.c
index c63eb9a46346..97e4a4fb3362 100644
--- a/tools/perf/bench/sched-messaging.c
+++ b/tools/perf/bench/sched-messaging.c
@@ -10,9 +10,7 @@
10 * 10 *
11 */ 11 */
12 12
13#include "../util/util.h"
14#include <subcmd/parse-options.h> 13#include <subcmd/parse-options.h>
15#include "../builtin.h"
16#include "bench.h" 14#include "bench.h"
17 15
18/* Test groups of 20 processes spraying to 20 receivers */ 16/* Test groups of 20 processes spraying to 20 receivers */
diff --git a/tools/perf/bench/sched-pipe.c b/tools/perf/bench/sched-pipe.c
index 35b07f197d48..3c88d1f201f1 100644
--- a/tools/perf/bench/sched-pipe.c
+++ b/tools/perf/bench/sched-pipe.c
@@ -9,9 +9,7 @@
9 * http://people.redhat.com/mingo/cfs-scheduler/tools/pipe-test-1m.c 9 * http://people.redhat.com/mingo/cfs-scheduler/tools/pipe-test-1m.c
10 * Ported to perf by Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp> 10 * Ported to perf by Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp>
11 */ 11 */
12#include "../util/util.h"
13#include <subcmd/parse-options.h> 12#include <subcmd/parse-options.h>
14#include "../builtin.h"
15#include "bench.h" 13#include "bench.h"
16 14
17#include <unistd.h> 15#include <unistd.h>
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 4e4d2e76232e..553c651fa0a2 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -27,6 +27,7 @@
27#include "util/sort.h" 27#include "util/sort.h"
28#include "util/hist.h" 28#include "util/hist.h"
29#include "util/dso.h" 29#include "util/dso.h"
30#include "util/machine.h"
30#include "util/map.h" 31#include "util/map.h"
31#include "util/session.h" 32#include "util/session.h"
32#include "util/tool.h" 33#include "util/tool.h"
diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c
index b09b12e0976b..61aaacc2aedd 100644
--- a/tools/perf/builtin-c2c.c
+++ b/tools/perf/builtin-c2c.c
@@ -20,6 +20,7 @@
20#include <sys/param.h> 20#include <sys/param.h>
21#include "debug.h" 21#include "debug.h"
22#include "builtin.h" 22#include "builtin.h"
23#include <perf/cpumap.h>
23#include <subcmd/pager.h> 24#include <subcmd/pager.h>
24#include <subcmd/parse-options.h> 25#include <subcmd/parse-options.h>
25#include "map_symbol.h" 26#include "map_symbol.h"
diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c
index 42d8157e047a..2603015f98be 100644
--- a/tools/perf/builtin-config.c
+++ b/tools/perf/builtin-config.c
@@ -9,7 +9,6 @@
9 9
10#include "util/cache.h" 10#include "util/cache.h"
11#include <subcmd/parse-options.h> 11#include <subcmd/parse-options.h>
12#include "util/util.h"
13#include "util/debug.h" 12#include "util/debug.h"
14#include "util/config.h" 13#include "util/config.h"
15#include <linux/string.h> 14#include <linux/string.h>
diff --git a/tools/perf/builtin-evlist.c b/tools/perf/builtin-evlist.c
index 238fa3876805..294494e60e48 100644
--- a/tools/perf/builtin-evlist.c
+++ b/tools/perf/builtin-evlist.c
@@ -5,8 +5,6 @@
5 */ 5 */
6#include "builtin.h" 6#include "builtin.h"
7 7
8#include "util/util.h"
9
10#include <linux/list.h> 8#include <linux/list.h>
11 9
12#include "perf.h" 10#include "perf.h"
diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c
index c14f40b858bc..23a76cf3846f 100644
--- a/tools/perf/builtin-inject.c
+++ b/tools/perf/builtin-inject.c
@@ -21,6 +21,7 @@
21#include "util/auxtrace.h" 21#include "util/auxtrace.h"
22#include "util/jit.h" 22#include "util/jit.h"
23#include "util/symbol.h" 23#include "util/symbol.h"
24#include "util/synthetic-events.h"
24#include "util/thread.h" 25#include "util/thread.h"
25 26
26#include <subcmd/parse-options.h> 27#include <subcmd/parse-options.h>
diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
index 0a4fcbe32bf6..6e3e36658900 100644
--- a/tools/perf/builtin-kvm.c
+++ b/tools/perf/builtin-kvm.c
@@ -17,9 +17,11 @@
17#include "util/debug.h" 17#include "util/debug.h"
18#include "util/tool.h" 18#include "util/tool.h"
19#include "util/stat.h" 19#include "util/stat.h"
20#include "util/synthetic-events.h"
20#include "util/top.h" 21#include "util/top.h"
21#include "util/data.h" 22#include "util/data.h"
22#include "util/ordered-events.h" 23#include "util/ordered-events.h"
24#include "util/kvm-stat.h"
23#include "ui/ui.h" 25#include "ui/ui.h"
24 26
25#include <sys/prctl.h> 27#include <sys/prctl.h>
@@ -58,7 +60,6 @@ static const char *get_filename_for_perf_kvm(void)
58} 60}
59 61
60#ifdef HAVE_KVM_STAT_SUPPORT 62#ifdef HAVE_KVM_STAT_SUPPORT
61#include "util/kvm-stat.h"
62 63
63void exit_event_get_key(struct evsel *evsel, 64void exit_event_get_key(struct evsel *evsel,
64 struct perf_sample *sample, 65 struct perf_sample *sample,
@@ -1513,11 +1514,21 @@ perf_stat:
1513} 1514}
1514#endif /* HAVE_KVM_STAT_SUPPORT */ 1515#endif /* HAVE_KVM_STAT_SUPPORT */
1515 1516
1517int __weak kvm_add_default_arch_event(int *argc __maybe_unused,
1518 const char **argv __maybe_unused)
1519{
1520 return 0;
1521}
1522
1516static int __cmd_record(const char *file_name, int argc, const char **argv) 1523static int __cmd_record(const char *file_name, int argc, const char **argv)
1517{ 1524{
1518 int rec_argc, i = 0, j; 1525 int rec_argc, i = 0, j, ret;
1519 const char **rec_argv; 1526 const char **rec_argv;
1520 1527
1528 ret = kvm_add_default_arch_event(&argc, argv);
1529 if (ret)
1530 return -EINVAL;
1531
1521 rec_argc = argc + 2; 1532 rec_argc = argc + 2;
1522 rec_argv = calloc(rec_argc + 1, sizeof(char *)); 1533 rec_argv = calloc(rec_argc + 1, sizeof(char *));
1523 rec_argv[i++] = strdup("record"); 1534 rec_argv[i++] = strdup("record");
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 1447004eee8a..4bd11c918e73 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -38,6 +38,7 @@
38#include "util/trigger.h" 38#include "util/trigger.h"
39#include "util/perf-hooks.h" 39#include "util/perf-hooks.h"
40#include "util/cpu-set-sched.h" 40#include "util/cpu-set-sched.h"
41#include "util/synthetic-events.h"
41#include "util/time-utils.h" 42#include "util/time-utils.h"
42#include "util/units.h" 43#include "util/units.h"
43#include "util/bpf-event.h" 44#include "util/bpf-event.h"
@@ -1180,15 +1181,6 @@ static void workload_exec_failed_signal(int signo __maybe_unused,
1180static void snapshot_sig_handler(int sig); 1181static void snapshot_sig_handler(int sig);
1181static void alarm_sig_handler(int sig); 1182static void alarm_sig_handler(int sig);
1182 1183
1183int __weak
1184perf_event__synth_time_conv(const struct perf_event_mmap_page *pc __maybe_unused,
1185 struct perf_tool *tool __maybe_unused,
1186 perf_event__handler_t process __maybe_unused,
1187 struct machine *machine __maybe_unused)
1188{
1189 return 0;
1190}
1191
1192static const struct perf_event_mmap_page * 1184static const struct perf_event_mmap_page *
1193perf_evlist__pick_pc(struct evlist *evlist) 1185perf_evlist__pick_pc(struct evlist *evlist)
1194{ 1186{
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index b18fab94d38d..3047e5169d9d 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -48,7 +48,7 @@
48#include "util/auxtrace.h" 48#include "util/auxtrace.h"
49#include "util/units.h" 49#include "util/units.h"
50#include "util/branch.h" 50#include "util/branch.h"
51#include "util/util.h" 51#include "util/util.h" // perf_tip()
52#include "ui/ui.h" 52#include "ui/ui.h"
53#include "ui/progress.h" 53#include "ui/progress.h"
54 54
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index ec96d64aec69..f0b828c201cc 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -3,6 +3,7 @@
3#include "perf.h" 3#include "perf.h"
4#include "perf-sys.h" 4#include "perf-sys.h"
5 5
6#include "util/cpumap.h"
6#include "util/evlist.h" 7#include "util/evlist.h"
7#include "util/evsel.h" 8#include "util/evsel.h"
8#include "util/symbol.h" 9#include "util/symbol.h"
@@ -23,6 +24,7 @@
23#include "util/trace-event.h" 24#include "util/trace-event.h"
24 25
25#include "util/debug.h" 26#include "util/debug.h"
27#include "util/event.h"
26 28
27#include <linux/kernel.h> 29#include <linux/kernel.h>
28#include <linux/log2.h> 30#include <linux/log2.h>
@@ -36,6 +38,7 @@
36#include <pthread.h> 38#include <pthread.h>
37#include <math.h> 39#include <math.h>
38#include <api/fs/fs.h> 40#include <api/fs/fs.h>
41#include <perf/cpumap.h>
39#include <linux/time64.h> 42#include <linux/time64.h>
40 43
41#include <linux/ctype.h> 44#include <linux/ctype.h>
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 7e17bf9f700a..60cdd383af81 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -61,6 +61,7 @@
61#include "util/tool.h" 61#include "util/tool.h"
62#include "util/string2.h" 62#include "util/string2.h"
63#include "util/metricgroup.h" 63#include "util/metricgroup.h"
64#include "util/synthetic-events.h"
64#include "util/target.h" 65#include "util/target.h"
65#include "util/time-utils.h" 66#include "util/time-utils.h"
66#include "util/top.h" 67#include "util/top.h"
@@ -540,8 +541,8 @@ try_again:
540 if (err < 0) 541 if (err < 0)
541 return err; 542 return err;
542 543
543 err = perf_stat_synthesize_config(&stat_config, NULL, evsel_list, 544 err = perf_event__synthesize_stat_events(&stat_config, NULL, evsel_list,
544 process_synthesized_event, is_pipe); 545 process_synthesized_event, is_pipe);
545 if (err < 0) 546 if (err < 0)
546 return err; 547 return err;
547 } 548 }
@@ -822,18 +823,6 @@ static int perf_stat__get_core(struct perf_stat_config *config __maybe_unused,
822 return cpu_map__get_core(map, cpu, NULL); 823 return cpu_map__get_core(map, cpu, NULL);
823} 824}
824 825
825static int cpu_map__get_max(struct perf_cpu_map *map)
826{
827 int i, max = -1;
828
829 for (i = 0; i < map->nr; i++) {
830 if (map->map[i] > max)
831 max = map->map[i];
832 }
833
834 return max;
835}
836
837static int perf_stat__get_aggr(struct perf_stat_config *config, 826static int perf_stat__get_aggr(struct perf_stat_config *config,
838 aggr_get_id_t get_id, struct perf_cpu_map *map, int idx) 827 aggr_get_id_t get_id, struct perf_cpu_map *map, int idx)
839{ 828{
@@ -928,7 +917,7 @@ static int perf_stat_init_aggr_mode(void)
928 * taking the highest cpu number to be the size of 917 * taking the highest cpu number to be the size of
929 * the aggregation translate cpumap. 918 * the aggregation translate cpumap.
930 */ 919 */
931 nr = cpu_map__get_max(evsel_list->core.cpus); 920 nr = perf_cpu_map__max(evsel_list->core.cpus);
932 stat_config.cpus_aggr_map = perf_cpu_map__empty_new(nr + 1); 921 stat_config.cpus_aggr_map = perf_cpu_map__empty_new(nr + 1);
933 return stat_config.cpus_aggr_map ? 0 : -ENOMEM; 922 return stat_config.cpus_aggr_map ? 0 : -ENOMEM;
934} 923}
@@ -1963,8 +1952,11 @@ int cmd_stat(int argc, const char **argv)
1963 fprintf(output, "[ perf stat: executing run #%d ... ]\n", 1952 fprintf(output, "[ perf stat: executing run #%d ... ]\n",
1964 run_idx + 1); 1953 run_idx + 1);
1965 1954
1955 if (run_idx != 0)
1956 perf_evlist__reset_prev_raw_counts(evsel_list);
1957
1966 status = run_perf_stat(argc, argv, run_idx); 1958 status = run_perf_stat(argc, argv, run_idx);
1967 if (forever && status != -1) { 1959 if (forever && status != -1 && !interval) {
1968 print_counters(NULL, argc, argv); 1960 print_counters(NULL, argc, argv);
1969 perf_stat__reset_stats(); 1961 perf_stat__reset_stats();
1970 } 1962 }
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 726e3f2dd8c7..b052470f89b4 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -32,6 +32,7 @@
32#include "util/map.h" 32#include "util/map.h"
33#include "util/session.h" 33#include "util/session.h"
34#include "util/symbol.h" 34#include "util/symbol.h"
35#include "util/synthetic-events.h"
35#include "util/top.h" 36#include "util/top.h"
36#include "util/util.h" 37#include "util/util.h"
37#include <linux/rbtree.h> 38#include <linux/rbtree.h>
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 0f633f0d6be8..f0f735093e21 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -28,6 +28,7 @@
28#include "util/dso.h" 28#include "util/dso.h"
29#include "util/env.h" 29#include "util/env.h"
30#include "util/event.h" 30#include "util/event.h"
31#include "util/synthetic-events.h"
31#include "util/evlist.h" 32#include "util/evlist.h"
32#include "util/evswitch.h" 33#include "util/evswitch.h"
33#include <subcmd/pager.h> 34#include <subcmd/pager.h>
diff --git a/tools/perf/jvmti/Build b/tools/perf/jvmti/Build
index eaeb8cb5379b..1e148bbdf820 100644
--- a/tools/perf/jvmti/Build
+++ b/tools/perf/jvmti/Build
@@ -1,8 +1,17 @@
1jvmti-y += libjvmti.o 1jvmti-y += libjvmti.o
2jvmti-y += jvmti_agent.o 2jvmti-y += jvmti_agent.o
3 3
4# For strlcpy
5jvmti-y += libstring.o
6
4CFLAGS_jvmti = -fPIC -DPIC -I$(JDIR)/include -I$(JDIR)/include/linux 7CFLAGS_jvmti = -fPIC -DPIC -I$(JDIR)/include -I$(JDIR)/include/linux
5CFLAGS_REMOVE_jvmti = -Wmissing-declarations 8CFLAGS_REMOVE_jvmti = -Wmissing-declarations
6CFLAGS_REMOVE_jvmti += -Wstrict-prototypes 9CFLAGS_REMOVE_jvmti += -Wstrict-prototypes
7CFLAGS_REMOVE_jvmti += -Wextra 10CFLAGS_REMOVE_jvmti += -Wextra
8CFLAGS_REMOVE_jvmti += -Wwrite-strings 11CFLAGS_REMOVE_jvmti += -Wwrite-strings
12
13CFLAGS_libstring.o += -Wno-unused-parameter -DETC_PERFCONFIG="BUILD_STR($(ETC_PERFCONFIG_SQ))"
14
15$(OUTPUT)jvmti/libstring.o: ../lib/string.c FORCE
16 $(call rule_mkdir)
17 $(call if_changed_dep,cc_o_c)
diff --git a/tools/perf/lib/Makefile b/tools/perf/lib/Makefile
index a67efb8d9d39..e325c0503dc6 100644
--- a/tools/perf/lib/Makefile
+++ b/tools/perf/lib/Makefile
@@ -146,6 +146,7 @@ install_headers:
146 $(call do_install,include/perf/threadmap.h,$(prefix)/include/perf,644); \ 146 $(call do_install,include/perf/threadmap.h,$(prefix)/include/perf,644); \
147 $(call do_install,include/perf/evlist.h,$(prefix)/include/perf,644); \ 147 $(call do_install,include/perf/evlist.h,$(prefix)/include/perf,644); \
148 $(call do_install,include/perf/evsel.h,$(prefix)/include/perf,644); 148 $(call do_install,include/perf/evsel.h,$(prefix)/include/perf,644);
149 $(call do_install,include/perf/event.h,$(prefix)/include/perf,644);
149 150
150install_pkgconfig: $(LIBPERF_PC) 151install_pkgconfig: $(LIBPERF_PC)
151 $(call QUIET_INSTALL, $(LIBPERF_PC)) \ 152 $(call QUIET_INSTALL, $(LIBPERF_PC)) \
diff --git a/tools/perf/lib/cpumap.c b/tools/perf/lib/cpumap.c
index 1f0e6f334237..2ca1fafa620d 100644
--- a/tools/perf/lib/cpumap.c
+++ b/tools/perf/lib/cpumap.c
@@ -260,3 +260,15 @@ int perf_cpu_map__idx(struct perf_cpu_map *cpus, int cpu)
260 260
261 return -1; 261 return -1;
262} 262}
263
264int perf_cpu_map__max(struct perf_cpu_map *map)
265{
266 int i, max = -1;
267
268 for (i = 0; i < map->nr; i++) {
269 if (map->map[i] > max)
270 max = map->map[i];
271 }
272
273 return max;
274}
diff --git a/tools/perf/lib/include/perf/cpumap.h b/tools/perf/lib/include/perf/cpumap.h
index 8aa995c59498..ac9aa497f84a 100644
--- a/tools/perf/lib/include/perf/cpumap.h
+++ b/tools/perf/lib/include/perf/cpumap.h
@@ -16,6 +16,7 @@ LIBPERF_API void perf_cpu_map__put(struct perf_cpu_map *map);
16LIBPERF_API int perf_cpu_map__cpu(const struct perf_cpu_map *cpus, int idx); 16LIBPERF_API int perf_cpu_map__cpu(const struct perf_cpu_map *cpus, int idx);
17LIBPERF_API int perf_cpu_map__nr(const struct perf_cpu_map *cpus); 17LIBPERF_API int perf_cpu_map__nr(const struct perf_cpu_map *cpus);
18LIBPERF_API bool perf_cpu_map__empty(const struct perf_cpu_map *map); 18LIBPERF_API bool perf_cpu_map__empty(const struct perf_cpu_map *map);
19LIBPERF_API int perf_cpu_map__max(struct perf_cpu_map *map);
19 20
20#define perf_cpu_map__for_each_cpu(cpu, idx, cpus) \ 21#define perf_cpu_map__for_each_cpu(cpu, idx, cpus) \
21 for ((idx) = 0, (cpu) = perf_cpu_map__cpu(cpus, idx); \ 22 for ((idx) = 0, (cpu) = perf_cpu_map__cpu(cpus, idx); \
diff --git a/tools/perf/lib/libperf.map b/tools/perf/lib/libperf.map
index dc4d66363bc4..cd0d17b996c8 100644
--- a/tools/perf/lib/libperf.map
+++ b/tools/perf/lib/libperf.map
@@ -9,6 +9,7 @@ LIBPERF_0.0.1 {
9 perf_cpu_map__nr; 9 perf_cpu_map__nr;
10 perf_cpu_map__cpu; 10 perf_cpu_map__cpu;
11 perf_cpu_map__empty; 11 perf_cpu_map__empty;
12 perf_cpu_map__max;
12 perf_thread_map__new_dummy; 13 perf_thread_map__new_dummy;
13 perf_thread_map__set_pid; 14 perf_thread_map__set_pid;
14 perf_thread_map__comm; 15 perf_thread_map__comm;
diff --git a/tools/perf/perf.c b/tools/perf/perf.c
index 1193b923e801..bb40a108b8f7 100644
--- a/tools/perf/perf.c
+++ b/tools/perf/perf.c
@@ -20,7 +20,7 @@
20#include "util/bpf-loader.h" 20#include "util/bpf-loader.h"
21#include "util/debug.h" 21#include "util/debug.h"
22#include "util/event.h" 22#include "util/event.h"
23#include "util/util.h" 23#include "util/util.h" // page_size, usage()
24#include "ui/ui.h" 24#include "ui/ui.h"
25#include "perf-sys.h" 25#include "perf-sys.h"
26#include <api/fs/fs.h> 26#include <api/fs/fs.h>
diff --git a/tools/perf/pmu-events/arch/arm64/arm/cortex-a76-n1/branch.json b/tools/perf/pmu-events/arch/arm64/arm/cortex-a76-n1/branch.json
new file mode 100644
index 000000000000..b5e5d055c70d
--- /dev/null
+++ b/tools/perf/pmu-events/arch/arm64/arm/cortex-a76-n1/branch.json
@@ -0,0 +1,14 @@
1[
2 {
3 "PublicDescription": "Mispredicted or not predicted branch speculatively executed. This event counts any predictable branch instruction which is mispredicted either due to dynamic misprediction or because the MMU is off and the branches are statically predicted not taken.",
4 "EventCode": "0x10",
5 "EventName": "BR_MIS_PRED",
6 "BriefDescription": "Mispredicted or not predicted branch speculatively executed."
7 },
8 {
9 "PublicDescription": "Predictable branch speculatively executed. This event counts all predictable branches.",
10 "EventCode": "0x12",
11 "EventName": "BR_PRED",
12 "BriefDescription": "Predictable branch speculatively executed."
13 }
14]
diff --git a/tools/perf/pmu-events/arch/arm64/arm/cortex-a76-n1/bus.json b/tools/perf/pmu-events/arch/arm64/arm/cortex-a76-n1/bus.json
new file mode 100644
index 000000000000..fce7309ae624
--- /dev/null
+++ b/tools/perf/pmu-events/arch/arm64/arm/cortex-a76-n1/bus.json
@@ -0,0 +1,24 @@
1[
2 {
3 "EventCode": "0x11",
4 "EventName": "CPU_CYCLES",
5 "BriefDescription": "The number of core clock cycles."
6 },
7 {
8 "PublicDescription": "Bus access. This event counts for every beat of data transferred over the data channels between the core and the SCU. If both read and write data beats are transferred on a given cycle, this event is counted twice on that cycle. This event counts the sum of BUS_ACCESS_RD and BUS_ACCESS_WR.",
9 "EventCode": "0x19",
10 "EventName": "BUS_ACCESS",
11 "BriefDescription": "Bus access."
12 },
13 {
14 "EventCode": "0x1D",
15 "EventName": "BUS_CYCLES",
16 "BriefDescription": "Bus cycles. This event duplicates CPU_CYCLES."
17 },
18 {
19 "ArchStdEvent": "BUS_ACCESS_RD"
20 },
21 {
22 "ArchStdEvent": "BUS_ACCESS_WR"
23 }
24]
diff --git a/tools/perf/pmu-events/arch/arm64/arm/cortex-a76-n1/cache.json b/tools/perf/pmu-events/arch/arm64/arm/cortex-a76-n1/cache.json
new file mode 100644
index 000000000000..24594081c199
--- /dev/null
+++ b/tools/perf/pmu-events/arch/arm64/arm/cortex-a76-n1/cache.json
@@ -0,0 +1,207 @@
1[
2 {
3 "PublicDescription": "L1 instruction cache refill. This event counts any instruction fetch which misses in the cache.",
4 "EventCode": "0x01",
5 "EventName": "L1I_CACHE_REFILL",
6 "BriefDescription": "L1 instruction cache refill"
7 },
8 {
9 "PublicDescription": "L1 instruction TLB refill. This event counts any refill of the instruction L1 TLB from the L2 TLB. This includes refills that result in a translation fault.",
10 "EventCode": "0x02",
11 "EventName": "L1I_TLB_REFILL",
12 "BriefDescription": "L1 instruction TLB refill"
13 },
14 {
15 "PublicDescription": "L1 data cache refill. This event counts any load or store operation or page table walk access which causes data to be read from outside the L1, including accesses which do not allocate into L1.",
16 "EventCode": "0x03",
17 "EventName": "L1D_CACHE_REFILL",
18 "BriefDescription": "L1 data cache refill"
19 },
20 {
21 "PublicDescription": "L1 data cache access. This event counts any load or store operation or page table walk access which looks up in the L1 data cache. In particular, any access which could count the L1D_CACHE_REFILL event causes this event to count.",
22 "EventCode": "0x04",
23 "EventName": "L1D_CACHE",
24 "BriefDescription": "L1 data cache access"
25 },
26 {
27 "PublicDescription": "L1 data TLB refill. This event counts any refill of the data L1 TLB from the L2 TLB. This includes refills that result in a translation fault.",
28 "EventCode": "0x05",
29 "EventName": "L1D_TLB_REFILL",
30 "BriefDescription": "L1 data TLB refill"
31 },
32 {
33 "PublicDescription": "Level 1 instruction cache access or Level 0 Macro-op cache access. This event counts any instruction fetch which accesses the L1 instruction cache or L0 Macro-op cache.",
34 "EventCode": "0x14",
35 "EventName": "L1I_CACHE",
36 "BriefDescription": "L1 instruction cache access"
37 },
38 {
39 "PublicDescription": "L1 data cache Write-Back. This event counts any write-back of data from the L1 data cache to L2 or L3. This counts both victim line evictions and snoops, including cache maintenance operations.",
40 "EventCode": "0x15",
41 "EventName": "L1D_CACHE_WB",
42 "BriefDescription": "L1 data cache Write-Back"
43 },
44 {
45 "PublicDescription": "L2 data cache access. This event counts any transaction from L1 which looks up in the L2 cache, and any write-back from the L1 to the L2. Snoops from outside the core and cache maintenance operations are not counted.",
46 "EventCode": "0x16",
47 "EventName": "L2D_CACHE",
48 "BriefDescription": "L2 data cache access"
49 },
50 {
51 "PublicDescription": "L2 data cache refill. This event counts any cacheable transaction from L1 which causes data to be read from outside the core. L2 refills caused by stashes into L2 should not be counted",
52 "EventCode": "0x17",
53 "EventName": "L2D_CACHE_REFILL",
54 "BriefDescription": "L2 data cache refill"
55 },
56 {
57 "PublicDescription": "L2 data cache write-back. This event counts any write-back of data from the L2 cache to outside the core. This includes snoops to the L2 which return data, regardless of whether they cause an invalidation. Invalidations from the L2 which do not write data outside of the core and snoops which return data from the L1 are not counted",
58 "EventCode": "0x18",
59 "EventName": "L2D_CACHE_WB",
60 "BriefDescription": "L2 data cache write-back"
61 },
62 {
63 "PublicDescription": "L2 data cache allocation without refill. This event counts any full cache line write into the L2 cache which does not cause a linefill, including write-backs from L1 to L2 and full-line writes which do not allocate into L1.",
64 "EventCode": "0x20",
65 "EventName": "L2D_CACHE_ALLOCATE",
66 "BriefDescription": "L2 data cache allocation without refill"
67 },
68 {
69 "PublicDescription": "Level 1 data TLB access. This event counts any load or store operation which accesses the data L1 TLB. If both a load and a store are executed on a cycle, this event counts twice. This event counts regardless of whether the MMU is enabled.",
70 "EventCode": "0x25",
71 "EventName": "L1D_TLB",
72 "BriefDescription": "Level 1 data TLB access."
73 },
74 {
75 "PublicDescription": "Level 1 instruction TLB access. This event counts any instruction fetch which accesses the instruction L1 TLB.This event counts regardless of whether the MMU is enabled.",
76 "EventCode": "0x26",
77 "EventName": "L1I_TLB",
78 "BriefDescription": "Level 1 instruction TLB access"
79 },
80 {
81 "PublicDescription": "This event counts any full cache line write into the L3 cache which does not cause a linefill, including write-backs from L2 to L3 and full-line writes which do not allocate into L2",
82 "EventCode": "0x29",
83 "EventName": "L3D_CACHE_ALLOCATE",
84 "BriefDescription": "Allocation without refill"
85 },
86 {
87 "PublicDescription": "Attributable Level 3 unified cache refill. This event counts for any cacheable read transaction returning datafrom the SCU for which the data source was outside the cluster. Transactions such as ReadUnique are counted here as 'read' transactions, even though they can be generated by store instructions.",
88 "EventCode": "0x2A",
89 "EventName": "L3D_CACHE_REFILL",
90 "BriefDescription": "Attributable Level 3 unified cache refill."
91 },
92 {
93 "PublicDescription": "Attributable Level 3 unified cache access. This event counts for any cacheable read transaction returning datafrom the SCU, or for any cacheable write to the SCU.",
94 "EventCode": "0x2B",
95 "EventName": "L3D_CACHE",
96 "BriefDescription": "Attributable Level 3 unified cache access."
97 },
98 {
99 "PublicDescription": "Attributable L2 data or unified TLB refill. This event counts on anyrefill of the L2 TLB, caused by either an instruction or data access.This event does not count if the MMU is disabled.",
100 "EventCode": "0x2D",
101 "EventName": "L2D_TLB_REFILL",
102 "BriefDescription": "Attributable L2 data or unified TLB refill"
103 },
104 {
105 "PublicDescription": "Attributable L2 data or unified TLB access. This event counts on any access to the L2 TLB (caused by a refill of any of the L1 TLBs). This event does not count if the MMU is disabled.",
106 "EventCode": "0x2F",
107 "EventName": "L2D_TLB",
108 "BriefDescription": "Attributable L2 data or unified TLB access"
109 },
110 {
111 "PublicDescription": "Access to data TLB that caused a page table walk. This event counts on any data access which causes L2D_TLB_REFILL to count.",
112 "EventCode": "0x34",
113 "EventName": "DTLB_WALK",
114 "BriefDescription": "Access to data TLB that caused a page table walk."
115 },
116 {
117 "PublicDescription": "Access to instruction TLB that caused a page table walk. This event counts on any instruction access which causes L2D_TLB_REFILL to count.",
118 "EventCode": "0x35",
119 "EventName": "ITLB_WALK",
120 "BriefDescription": "Access to instruction TLB that caused a page table walk."
121 },
122 {
123 "EventCode": "0x36",
124 "EventName": "LL_CACHE_RD",
125 "BriefDescription": "Last level cache access, read"
126 },
127 {
128 "EventCode": "0x37",
129 "EventName": "LL_CACHE_MISS_RD",
130 "BriefDescription": "Last level cache miss, read"
131 },
132 {
133 "ArchStdEvent": "L1D_CACHE_INVAL"
134 },
135 {
136 "ArchStdEvent": "L1D_CACHE_RD"
137 },
138 {
139 "ArchStdEvent": "L1D_CACHE_REFILL_INNER"
140 },
141 {
142 "ArchStdEvent": "L1D_CACHE_REFILL_OUTER"
143 },
144 {
145 "ArchStdEvent": "L1D_CACHE_REFILL_RD"
146 },
147 {
148 "ArchStdEvent": "L1D_CACHE_REFILL_WR"
149 },
150 {
151 "ArchStdEvent": "L1D_CACHE_WB_CLEAN"
152 },
153 {
154 "ArchStdEvent": "L1D_CACHE_WB_VICTIM"
155 },
156 {
157 "ArchStdEvent": "L1D_CACHE_WR"
158 },
159 {
160 "ArchStdEvent": "L1D_TLB_RD"
161 },
162 {
163 "ArchStdEvent": "L1D_TLB_REFILL_RD"
164 },
165 {
166 "ArchStdEvent": "L1D_TLB_REFILL_WR"
167 },
168 {
169 "ArchStdEvent": "L1D_TLB_WR"
170 },
171 {
172 "ArchStdEvent": "L2D_CACHE_INVAL"
173 },
174 {
175 "ArchStdEvent": "L2D_CACHE_RD"
176 },
177 {
178 "ArchStdEvent": "L2D_CACHE_REFILL_RD"
179 },
180 {
181 "ArchStdEvent": "L2D_CACHE_REFILL_WR"
182 },
183 {
184 "ArchStdEvent": "L2D_CACHE_WB_CLEAN"
185 },
186 {
187 "ArchStdEvent": "L2D_CACHE_WB_VICTIM"
188 },
189 {
190 "ArchStdEvent": "L2D_CACHE_WR"
191 },
192 {
193 "ArchStdEvent": "L2D_TLB_RD"
194 },
195 {
196 "ArchStdEvent": "L2D_TLB_REFILL_RD"
197 },
198 {
199 "ArchStdEvent": "L2D_TLB_REFILL_WR"
200 },
201 {
202 "ArchStdEvent": "L2D_TLB_WR"
203 },
204 {
205 "ArchStdEvent": "L3D_CACHE_RD"
206 }
207]
diff --git a/tools/perf/pmu-events/arch/arm64/arm/cortex-a76-n1/exception.json b/tools/perf/pmu-events/arch/arm64/arm/cortex-a76-n1/exception.json
new file mode 100644
index 000000000000..98d29c862320
--- /dev/null
+++ b/tools/perf/pmu-events/arch/arm64/arm/cortex-a76-n1/exception.json
@@ -0,0 +1,52 @@
1[
2 {
3 "EventCode": "0x09",
4 "EventName": "EXC_TAKEN",
5 "BriefDescription": "Exception taken."
6 },
7 {
8 "PublicDescription": "Local memory error. This event counts any correctable or uncorrectable memory error (ECC or parity) in the protected core RAMs",
9 "EventCode": "0x1A",
10 "EventName": "MEMORY_ERROR",
11 "BriefDescription": "Local memory error."
12 },
13 {
14 "ArchStdEvent": "EXC_DABORT"
15 },
16 {
17 "ArchStdEvent": "EXC_FIQ"
18 },
19 {
20 "ArchStdEvent": "EXC_HVC"
21 },
22 {
23 "ArchStdEvent": "EXC_IRQ"
24 },
25 {
26 "ArchStdEvent": "EXC_PABORT"
27 },
28 {
29 "ArchStdEvent": "EXC_SMC"
30 },
31 {
32 "ArchStdEvent": "EXC_SVC"
33 },
34 {
35 "ArchStdEvent": "EXC_TRAP_DABORT"
36 },
37 {
38 "ArchStdEvent": "EXC_TRAP_FIQ"
39 },
40 {
41 "ArchStdEvent": "EXC_TRAP_IRQ"
42 },
43 {
44 "ArchStdEvent": "EXC_TRAP_OTHER"
45 },
46 {
47 "ArchStdEvent": "EXC_TRAP_PABORT"
48 },
49 {
50 "ArchStdEvent": "EXC_UNDEF"
51 }
52]
diff --git a/tools/perf/pmu-events/arch/arm64/arm/cortex-a76-n1/instruction.json b/tools/perf/pmu-events/arch/arm64/arm/cortex-a76-n1/instruction.json
new file mode 100644
index 000000000000..c153ac706d8d
--- /dev/null
+++ b/tools/perf/pmu-events/arch/arm64/arm/cortex-a76-n1/instruction.json
@@ -0,0 +1,108 @@
1[
2 {
3 "PublicDescription": "Software increment. Instruction architecturally executed (condition code check pass).",
4 "EventCode": "0x00",
5 "EventName": "SW_INCR",
6 "BriefDescription": "Software increment."
7 },
8 {
9 "PublicDescription": "Instruction architecturally executed. This event counts all retired instructions, including those that fail their condition check.",
10 "EventCode": "0x08",
11 "EventName": "INST_RETIRED",
12 "BriefDescription": "Instruction architecturally executed."
13 },
14 {
15 "EventCode": "0x0A",
16 "EventName": "EXC_RETURN",
17 "BriefDescription": "Instruction architecturally executed, condition code check pass, exception return."
18 },
19 {
20 "PublicDescription": "Instruction architecturally executed, condition code check pass, write to CONTEXTIDR. This event only counts writes to CONTEXTIDR in AArch32 state, and via the CONTEXTIDR_EL1 mnemonic in AArch64 state.",
21 "EventCode": "0x0B",
22 "EventName": "CID_WRITE_RETIRED",
23 "BriefDescription": "Instruction architecturally executed, condition code check pass, write to CONTEXTIDR."
24 },
25 {
26 "EventCode": "0x1B",
27 "EventName": "INST_SPEC",
28 "BriefDescription": "Operation speculatively executed"
29 },
30 {
31 "PublicDescription": "Instruction architecturally executed, condition code check pass, write to TTBR. This event only counts writes to TTBR0/TTBR1 in AArch32 state and TTBR0_EL1/TTBR1_EL1 in AArch64 state.",
32 "EventCode": "0x1C",
33 "EventName": "TTBR_WRITE_RETIRED",
34 "BriefDescription": "Instruction architecturally executed, condition code check pass, write to TTBR"
35 },
36 {
37 "PublicDescription": "Instruction architecturally executed, branch. This event counts all branches, taken or not. This excludes exception entries, debug entries and CCFAIL branches.",
38 "EventCode": "0x21",
39 "EventName": "BR_RETIRED",
40 "BriefDescription": "Instruction architecturally executed, branch."
41 },
42 {
43 "PublicDescription": "Instruction architecturally executed, mispredicted branch. This event counts any branch counted by BR_RETIRED which is not correctly predicted and causes a pipeline flush.",
44 "EventCode": "0x22",
45 "EventName": "BR_MIS_PRED_RETIRED",
46 "BriefDescription": "Instruction architecturally executed, mispredicted branch."
47 },
48 {
49 "ArchStdEvent": "ASE_SPEC"
50 },
51 {
52 "ArchStdEvent": "BR_IMMED_SPEC"
53 },
54 {
55 "ArchStdEvent": "BR_INDIRECT_SPEC"
56 },
57 {
58 "ArchStdEvent": "BR_RETURN_SPEC"
59 },
60 {
61 "ArchStdEvent": "CRYPTO_SPEC"
62 },
63 {
64 "ArchStdEvent": "DMB_SPEC"
65 },
66 {
67 "ArchStdEvent": "DP_SPEC"
68 },
69 {
70 "ArchStdEvent": "DSB_SPEC"
71 },
72 {
73 "ArchStdEvent": "ISB_SPEC"
74 },
75 {
76 "ArchStdEvent": "LDREX_SPEC"
77 },
78 {
79 "ArchStdEvent": "LDST_SPEC"
80 },
81 {
82 "ArchStdEvent": "LD_SPEC"
83 },
84 {
85 "ArchStdEvent": "PC_WRITE_SPEC"
86 },
87 {
88 "ArchStdEvent": "RC_LD_SPEC"
89 },
90 {
91 "ArchStdEvent": "RC_ST_SPEC"
92 },
93 {
94 "ArchStdEvent": "STREX_FAIL_SPEC"
95 },
96 {
97 "ArchStdEvent": "STREX_PASS_SPEC"
98 },
99 {
100 "ArchStdEvent": "STREX_SPEC"
101 },
102 {
103 "ArchStdEvent": "ST_SPEC"
104 },
105 {
106 "ArchStdEvent": "VFP_SPEC"
107 }
108]
diff --git a/tools/perf/pmu-events/arch/arm64/arm/cortex-a76-n1/memory.json b/tools/perf/pmu-events/arch/arm64/arm/cortex-a76-n1/memory.json
new file mode 100644
index 000000000000..b86643253f19
--- /dev/null
+++ b/tools/perf/pmu-events/arch/arm64/arm/cortex-a76-n1/memory.json
@@ -0,0 +1,23 @@
1[
2 {
3 "PublicDescription": "Data memory access. This event counts memory accesses due to load or store instructions. This event counts the sum of MEM_ACCESS_RD and MEM_ACCESS_WR.",
4 "EventCode": "0x13",
5 "EventName": "MEM_ACCESS",
6 "BriefDescription": "Data memory access"
7 },
8 {
9 "ArchStdEvent": "MEM_ACCESS_RD"
10 },
11 {
12 "ArchStdEvent": "MEM_ACCESS_WR"
13 },
14 {
15 "ArchStdEvent": "UNALIGNED_LD_SPEC"
16 },
17 {
18 "ArchStdEvent": "UNALIGNED_ST_SPEC"
19 },
20 {
21 "ArchStdEvent": "UNALIGNED_LDST_SPEC"
22 }
23]
diff --git a/tools/perf/pmu-events/arch/arm64/arm/cortex-a76-n1/other.json b/tools/perf/pmu-events/arch/arm64/arm/cortex-a76-n1/other.json
new file mode 100644
index 000000000000..8bde029a62d5
--- /dev/null
+++ b/tools/perf/pmu-events/arch/arm64/arm/cortex-a76-n1/other.json
@@ -0,0 +1,7 @@
1[
2 {
3 "EventCode": "0x31",
4 "EventName": "REMOTE_ACCESS",
5 "BriefDescription": "Access to another socket in a multi-socket system"
6 }
7]
diff --git a/tools/perf/pmu-events/arch/arm64/arm/cortex-a76-n1/pipeline.json b/tools/perf/pmu-events/arch/arm64/arm/cortex-a76-n1/pipeline.json
new file mode 100644
index 000000000000..010a647f9d02
--- /dev/null
+++ b/tools/perf/pmu-events/arch/arm64/arm/cortex-a76-n1/pipeline.json
@@ -0,0 +1,14 @@
1[
2 {
3 "PublicDescription": "No operation issued because of the frontend. The counter counts on any cycle when there are no fetched instructions available to dispatch.",
4 "EventCode": "0x23",
5 "EventName": "STALL_FRONTEND",
6 "BriefDescription": "No operation issued because of the frontend."
7 },
8 {
9 "PublicDescription": "No operation issued because of the backend. The counter counts on any cycle fetched instructions are not dispatched due to resource constraints.",
10 "EventCode": "0x24",
11 "EventName": "STALL_BACKEND",
12 "BriefDescription": "No operation issued because of the backend."
13 }
14]
diff --git a/tools/perf/pmu-events/arch/arm64/mapfile.csv b/tools/perf/pmu-events/arch/arm64/mapfile.csv
index 927fcddcb4aa..0d609149b82a 100644
--- a/tools/perf/pmu-events/arch/arm64/mapfile.csv
+++ b/tools/perf/pmu-events/arch/arm64/mapfile.csv
@@ -16,6 +16,8 @@
160x00000000420f1000,v1,arm/cortex-a53,core 160x00000000420f1000,v1,arm/cortex-a53,core
170x00000000410fd070,v1,arm/cortex-a57-a72,core 170x00000000410fd070,v1,arm/cortex-a57-a72,core
180x00000000410fd080,v1,arm/cortex-a57-a72,core 180x00000000410fd080,v1,arm/cortex-a57-a72,core
190x00000000410fd0b0,v1,arm/cortex-a76-n1,core
200x00000000410fd0c0,v1,arm/cortex-a76-n1,core
190x00000000420f5160,v1,cavium/thunderx2,core 210x00000000420f5160,v1,cavium/thunderx2,core
200x00000000430f0af0,v1,cavium/thunderx2,core 220x00000000430f0af0,v1,cavium/thunderx2,core
210x00000000480fd010,v1,hisilicon/hip08,core 230x00000000480fd010,v1,hisilicon/hip08,core
diff --git a/tools/perf/tests/bitmap.c b/tools/perf/tests/bitmap.c
index db2aadff3708..96c137360918 100644
--- a/tools/perf/tests/bitmap.c
+++ b/tools/perf/tests/bitmap.c
@@ -2,8 +2,8 @@
2#include <linux/compiler.h> 2#include <linux/compiler.h>
3#include <linux/bitmap.h> 3#include <linux/bitmap.h>
4#include <perf/cpumap.h> 4#include <perf/cpumap.h>
5#include <internal/cpumap.h>
5#include "tests.h" 6#include "tests.h"
6#include "cpumap.h"
7#include "debug.h" 7#include "debug.h"
8 8
9#define NBITS 100 9#define NBITS 100
diff --git a/tools/perf/tests/clang.c b/tools/perf/tests/clang.c
index f45fe11dcf50..2577d3ed1531 100644
--- a/tools/perf/tests/clang.c
+++ b/tools/perf/tests/clang.c
@@ -1,7 +1,5 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2#include "tests.h" 2#include "tests.h"
3#include "debug.h"
4#include "util.h"
5#include "c++/clang-c.h" 3#include "c++/clang-c.h"
6#include <linux/kernel.h> 4#include <linux/kernel.h>
7 5
diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c
index c1c29e08e7fb..fd02c1f1d976 100644
--- a/tools/perf/tests/code-reading.c
+++ b/tools/perf/tests/code-reading.c
@@ -19,12 +19,12 @@
19#include "evlist.h" 19#include "evlist.h"
20#include "evsel.h" 20#include "evsel.h"
21#include "thread_map.h" 21#include "thread_map.h"
22#include "cpumap.h"
23#include "machine.h" 22#include "machine.h"
24#include "map.h" 23#include "map.h"
25#include "symbol.h" 24#include "symbol.h"
26#include "event.h" 25#include "event.h"
27#include "record.h" 26#include "record.h"
27#include "util/synthetic-events.h"
28#include "thread.h" 28#include "thread.h"
29 29
30#include "tests.h" 30#include "tests.h"
diff --git a/tools/perf/tests/cpumap.c b/tools/perf/tests/cpumap.c
index 39493de50117..8a0d236202b0 100644
--- a/tools/perf/tests/cpumap.c
+++ b/tools/perf/tests/cpumap.c
@@ -3,6 +3,7 @@
3#include <stdio.h> 3#include <stdio.h>
4#include "cpumap.h" 4#include "cpumap.h"
5#include "event.h" 5#include "event.h"
6#include "util/synthetic-events.h"
6#include <string.h> 7#include <string.h>
7#include <linux/bitops.h> 8#include <linux/bitops.h>
8#include <perf/cpumap.h> 9#include <perf/cpumap.h>
diff --git a/tools/perf/tests/dso-data.c b/tools/perf/tests/dso-data.c
index a4874d4ce7ef..627c1aaf1c9e 100644
--- a/tools/perf/tests/dso-data.c
+++ b/tools/perf/tests/dso-data.c
@@ -10,7 +10,6 @@
10#include <sys/resource.h> 10#include <sys/resource.h>
11#include <api/fs/fs.h> 11#include <api/fs/fs.h>
12#include "dso.h" 12#include "dso.h"
13#include "util.h"
14#include "machine.h" 13#include "machine.h"
15#include "symbol.h" 14#include "symbol.h"
16#include "tests.h" 15#include "tests.h"
diff --git a/tools/perf/tests/dwarf-unwind.c b/tools/perf/tests/dwarf-unwind.c
index 4125255ff637..4f4ecbcbe87e 100644
--- a/tools/perf/tests/dwarf-unwind.c
+++ b/tools/perf/tests/dwarf-unwind.c
@@ -15,6 +15,7 @@
15#include "symbol.h" 15#include "symbol.h"
16#include "thread.h" 16#include "thread.h"
17#include "callchain.h" 17#include "callchain.h"
18#include "util/synthetic-events.h"
18 19
19#if defined (__x86_64__) || defined (__i386__) || defined (__powerpc__) 20#if defined (__x86_64__) || defined (__i386__) || defined (__powerpc__)
20#include "arch-tests.h" 21#include "arch-tests.h"
diff --git a/tools/perf/tests/event-times.c b/tools/perf/tests/event-times.c
index d824a726906c..0228ba435a2a 100644
--- a/tools/perf/tests/event-times.c
+++ b/tools/perf/tests/event-times.c
@@ -9,7 +9,6 @@
9#include "tests.h" 9#include "tests.h"
10#include "evlist.h" 10#include "evlist.h"
11#include "evsel.h" 11#include "evsel.h"
12#include "util.h"
13#include "debug.h" 12#include "debug.h"
14#include "parse-events.h" 13#include "parse-events.h"
15#include "thread_map.h" 14#include "thread_map.h"
diff --git a/tools/perf/tests/event_update.c b/tools/perf/tests/event_update.c
index cac4290e233a..0497d900ced2 100644
--- a/tools/perf/tests/event_update.c
+++ b/tools/perf/tests/event_update.c
@@ -2,10 +2,12 @@
2#include <linux/compiler.h> 2#include <linux/compiler.h>
3#include <perf/cpumap.h> 3#include <perf/cpumap.h>
4#include <string.h> 4#include <string.h>
5#include "cpumap.h"
5#include "evlist.h" 6#include "evlist.h"
6#include "evsel.h" 7#include "evsel.h"
7#include "header.h" 8#include "header.h"
8#include "machine.h" 9#include "machine.h"
10#include "util/synthetic-events.h"
9#include "tool.h" 11#include "tool.h"
10#include "tests.h" 12#include "tests.h"
11#include "debug.h" 13#include "debug.h"
@@ -92,7 +94,7 @@ int test__event_update(struct test *test __maybe_unused, int subtest __maybe_unu
92 94
93 evsel = perf_evlist__first(evlist); 95 evsel = perf_evlist__first(evlist);
94 96
95 TEST_ASSERT_VAL("failed to allos ids", 97 TEST_ASSERT_VAL("failed to allocate ids",
96 !perf_evsel__alloc_id(evsel, 1, 1)); 98 !perf_evsel__alloc_id(evsel, 1, 1));
97 99
98 perf_evlist__id_add(evlist, evsel, 0, 0, 123); 100 perf_evlist__id_add(evlist, evsel, 0, 0, 123);
diff --git a/tools/perf/tests/hists_common.c b/tools/perf/tests/hists_common.c
index de110d8f169b..6f34d08b84e5 100644
--- a/tools/perf/tests/hists_common.c
+++ b/tools/perf/tests/hists_common.c
@@ -2,6 +2,7 @@
2#include <inttypes.h> 2#include <inttypes.h>
3#include "util/debug.h" 3#include "util/debug.h"
4#include "util/dso.h" 4#include "util/dso.h"
5#include "util/event.h" // struct perf_sample
5#include "util/map.h" 6#include "util/map.h"
6#include "util/symbol.h" 7#include "util/symbol.h"
7#include "util/sort.h" 8#include "util/sort.h"
@@ -10,6 +11,7 @@
10#include "util/thread.h" 11#include "util/thread.h"
11#include "tests/hists_common.h" 12#include "tests/hists_common.h"
12#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/perf_event.h>
13 15
14static struct { 16static struct {
15 u32 pid; 17 u32 pid;
diff --git a/tools/perf/tests/keep-tracking.c b/tools/perf/tests/keep-tracking.c
index 9f0762d987fa..df0fd5a44e04 100644
--- a/tools/perf/tests/keep-tracking.c
+++ b/tools/perf/tests/keep-tracking.c
@@ -12,7 +12,6 @@
12#include "evsel.h" 12#include "evsel.h"
13#include "record.h" 13#include "record.h"
14#include "thread_map.h" 14#include "thread_map.h"
15#include "cpumap.h"
16#include "tests.h" 15#include "tests.h"
17 16
18#define CHECK__(x) { \ 17#define CHECK__(x) { \
@@ -143,7 +142,7 @@ int test__keep_tracking(struct test *test __maybe_unused, int subtest __maybe_un
143 142
144 found = find_comm(evlist, comm); 143 found = find_comm(evlist, comm);
145 if (found != 1) { 144 if (found != 1) {
146 pr_debug("Seconf time, failed to find tracking event.\n"); 145 pr_debug("Second time, failed to find tracking event.\n");
147 goto out_err; 146 goto out_err;
148 } 147 }
149 148
diff --git a/tools/perf/tests/llvm.c b/tools/perf/tests/llvm.c
index 022e4c9cf092..ae6cda81c209 100644
--- a/tools/perf/tests/llvm.c
+++ b/tools/perf/tests/llvm.c
@@ -7,7 +7,6 @@
7#include "llvm.h" 7#include "llvm.h"
8#include "tests.h" 8#include "tests.h"
9#include "debug.h" 9#include "debug.h"
10#include "util.h"
11 10
12#ifdef HAVE_LIBBPF_SUPPORT 11#ifdef HAVE_LIBBPF_SUPPORT
13static int test__bpf_parsing(void *obj_buf, size_t obj_buf_sz) 12static int test__bpf_parsing(void *obj_buf, size_t obj_buf_sz)
diff --git a/tools/perf/tests/make b/tools/perf/tests/make
index 70c48475896d..6b3afed5d910 100644
--- a/tools/perf/tests/make
+++ b/tools/perf/tests/make
@@ -327,6 +327,10 @@ make_kernelsrc_tools:
327 (make -C ../../tools $(PARALLEL_OPT) $(K_O_OPT) perf) > $@ 2>&1 && \ 327 (make -C ../../tools $(PARALLEL_OPT) $(K_O_OPT) perf) > $@ 2>&1 && \
328 test -x $(KERNEL_O)/tools/perf/perf && rm -f $@ || (cat $@ ; false) 328 test -x $(KERNEL_O)/tools/perf/perf && rm -f $@ || (cat $@ ; false)
329 329
330make_libperf:
331 @echo "- make -C lib";
332 make -C lib clean >$@ 2>&1; make -C lib >>$@ 2>&1 && rm $@
333
330FEATURES_DUMP_FILE := $(FULL_O)/BUILD_TEST_FEATURE_DUMP 334FEATURES_DUMP_FILE := $(FULL_O)/BUILD_TEST_FEATURE_DUMP
331FEATURES_DUMP_FILE_STATIC := $(FULL_O)/BUILD_TEST_FEATURE_DUMP_STATIC 335FEATURES_DUMP_FILE_STATIC := $(FULL_O)/BUILD_TEST_FEATURE_DUMP_STATIC
332 336
@@ -365,5 +369,5 @@ $(foreach t,$(run),$(if $(findstring make_static,$(t)),\
365 $(eval $(t) := $($(t)) FEATURES_DUMP=$(FEATURES_DUMP_FILE)))) 369 $(eval $(t) := $($(t)) FEATURES_DUMP=$(FEATURES_DUMP_FILE))))
366endif 370endif
367 371
368.PHONY: all $(run) $(run_O) tarpkg clean make_kernelsrc make_kernelsrc_tools 372.PHONY: all $(run) $(run_O) tarpkg clean make_kernelsrc make_kernelsrc_tools make_libperf
369endif # ifndef MK 373endif # ifndef MK
diff --git a/tools/perf/tests/mem2node.c b/tools/perf/tests/mem2node.c
index 7672ade70f20..a258bd51f1a4 100644
--- a/tools/perf/tests/mem2node.c
+++ b/tools/perf/tests/mem2node.c
@@ -4,7 +4,7 @@
4#include <linux/kernel.h> 4#include <linux/kernel.h>
5#include <linux/zalloc.h> 5#include <linux/zalloc.h>
6#include <perf/cpumap.h> 6#include <perf/cpumap.h>
7#include "cpumap.h" 7#include <internal/cpumap.h>
8#include "debug.h" 8#include "debug.h"
9#include "env.h" 9#include "env.h"
10#include "mem2node.h" 10#include "mem2node.h"
diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c
index 85e1d7337dc0..042757629e90 100644
--- a/tools/perf/tests/mmap-basic.c
+++ b/tools/perf/tests/mmap-basic.c
@@ -10,7 +10,6 @@
10#include "evlist.h" 10#include "evlist.h"
11#include "evsel.h" 11#include "evsel.h"
12#include "thread_map.h" 12#include "thread_map.h"
13#include "cpumap.h"
14#include "tests.h" 13#include "tests.h"
15#include <linux/err.h> 14#include <linux/err.h>
16#include <linux/kernel.h> 15#include <linux/kernel.h>
@@ -53,7 +52,7 @@ int test__basic_mmap(struct test *test __maybe_unused, int subtest __maybe_unuse
53 52
54 cpus = perf_cpu_map__new(NULL); 53 cpus = perf_cpu_map__new(NULL);
55 if (cpus == NULL) { 54 if (cpus == NULL) {
56 pr_debug("cpu_map__new\n"); 55 pr_debug("perf_cpu_map__new\n");
57 goto out_free_threads; 56 goto out_free_threads;
58 } 57 }
59 58
diff --git a/tools/perf/tests/mmap-thread-lookup.c b/tools/perf/tests/mmap-thread-lookup.c
index 360d70deb855..33b496d194f4 100644
--- a/tools/perf/tests/mmap-thread-lookup.c
+++ b/tools/perf/tests/mmap-thread-lookup.c
@@ -8,13 +8,15 @@
8#include <stdlib.h> 8#include <stdlib.h>
9#include <stdio.h> 9#include <stdio.h>
10#include "debug.h" 10#include "debug.h"
11#include "event.h"
11#include "tests.h" 12#include "tests.h"
12#include "machine.h" 13#include "machine.h"
13#include "thread_map.h" 14#include "thread_map.h"
14#include "map.h" 15#include "map.h"
15#include "symbol.h" 16#include "symbol.h"
17#include "util/synthetic-events.h"
16#include "thread.h" 18#include "thread.h"
17#include "util.h" 19#include "util.h" // page_size
18 20
19#define THREADS 4 21#define THREADS 4
20 22
diff --git a/tools/perf/tests/openat-syscall-all-cpus.c b/tools/perf/tests/openat-syscall-all-cpus.c
index 9171f77cd9cd..93c176523e38 100644
--- a/tools/perf/tests/openat-syscall-all-cpus.c
+++ b/tools/perf/tests/openat-syscall-all-cpus.c
@@ -14,7 +14,8 @@
14#include "evsel.h" 14#include "evsel.h"
15#include "tests.h" 15#include "tests.h"
16#include "thread_map.h" 16#include "thread_map.h"
17#include "cpumap.h" 17#include <perf/cpumap.h>
18#include <internal/cpumap.h>
18#include "debug.h" 19#include "debug.h"
19#include "stat.h" 20#include "stat.h"
20#include "util/counts.h" 21#include "util/counts.h"
@@ -37,7 +38,7 @@ int test__openat_syscall_event_on_all_cpus(struct test *test __maybe_unused, int
37 38
38 cpus = perf_cpu_map__new(NULL); 39 cpus = perf_cpu_map__new(NULL);
39 if (cpus == NULL) { 40 if (cpus == NULL) {
40 pr_debug("cpu_map__new\n"); 41 pr_debug("perf_cpu_map__new\n");
41 goto out_thread_map_delete; 42 goto out_thread_map_delete;
42 } 43 }
43 44
diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c
index 02ba696fb87f..c25c8e7b41e5 100644
--- a/tools/perf/tests/parse-events.c
+++ b/tools/perf/tests/parse-events.c
@@ -6,7 +6,6 @@
6#include "tests.h" 6#include "tests.h"
7#include "debug.h" 7#include "debug.h"
8#include "pmu.h" 8#include "pmu.h"
9#include "util.h"
10#include <dirent.h> 9#include <dirent.h>
11#include <errno.h> 10#include <errno.h>
12#include <sys/types.h> 11#include <sys/types.h>
diff --git a/tools/perf/tests/parse-no-sample-id-all.c b/tools/perf/tests/parse-no-sample-id-all.c
index 8284752a60c8..adf3c9c4a416 100644
--- a/tools/perf/tests/parse-no-sample-id-all.c
+++ b/tools/perf/tests/parse-no-sample-id-all.c
@@ -1,4 +1,3 @@
1// SPDX-License-Identifier: GPL-2.0
2#include <linux/kernel.h> 1#include <linux/kernel.h>
3#include <linux/types.h> 2#include <linux/types.h>
4#include <stddef.h> 3#include <stddef.h>
@@ -8,7 +7,6 @@
8#include "event.h" 7#include "event.h"
9#include "evlist.h" 8#include "evlist.h"
10#include "header.h" 9#include "header.h"
11#include "util.h"
12#include "debug.h" 10#include "debug.h"
13 11
14static int process_event(struct evlist **pevlist, union perf_event *event) 12static int process_event(struct evlist **pevlist, union perf_event *event)
diff --git a/tools/perf/tests/perf-hooks.c b/tools/perf/tests/perf-hooks.c
index a693bcf017ea..dbc27199c65e 100644
--- a/tools/perf/tests/perf-hooks.c
+++ b/tools/perf/tests/perf-hooks.c
@@ -4,7 +4,6 @@
4 4
5#include "tests.h" 5#include "tests.h"
6#include "debug.h" 6#include "debug.h"
7#include "util.h"
8#include "perf-hooks.h" 7#include "perf-hooks.h"
9 8
10static void sigsegv_handler(int sig __maybe_unused) 9static void sigsegv_handler(int sig __maybe_unused)
diff --git a/tools/perf/tests/pmu.c b/tools/perf/tests/pmu.c
index 14a78898d79e..74379ff1f7fa 100644
--- a/tools/perf/tests/pmu.c
+++ b/tools/perf/tests/pmu.c
@@ -1,7 +1,6 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2#include "parse-events.h" 2#include "parse-events.h"
3#include "pmu.h" 3#include "pmu.h"
4#include "util.h"
5#include "tests.h" 4#include "tests.h"
6#include <errno.h> 5#include <errno.h>
7#include <stdio.h> 6#include <stdio.h>
diff --git a/tools/perf/tests/sample-parsing.c b/tools/perf/tests/sample-parsing.c
index 5fcc06817076..3a02426db9a6 100644
--- a/tools/perf/tests/sample-parsing.c
+++ b/tools/perf/tests/sample-parsing.c
@@ -9,10 +9,10 @@
9 9
10#include "map_symbol.h" 10#include "map_symbol.h"
11#include "branch.h" 11#include "branch.h"
12#include "util.h"
13#include "event.h" 12#include "event.h"
14#include "evsel.h" 13#include "evsel.h"
15#include "debug.h" 14#include "debug.h"
15#include "util/synthetic-events.h"
16 16
17#include "tests.h" 17#include "tests.h"
18 18
diff --git a/tools/perf/tests/stat.c b/tools/perf/tests/stat.c
index cc10b4116c9f..c1911501c39c 100644
--- a/tools/perf/tests/stat.c
+++ b/tools/perf/tests/stat.c
@@ -5,6 +5,7 @@
5#include "stat.h" 5#include "stat.h"
6#include "counts.h" 6#include "counts.h"
7#include "debug.h" 7#include "debug.h"
8#include "util/synthetic-events.h"
8 9
9static bool has_term(struct perf_record_stat_config *config, 10static bool has_term(struct perf_record_stat_config *config,
10 u64 tag, u64 val) 11 u64 tag, u64 val)
diff --git a/tools/perf/tests/switch-tracking.c b/tools/perf/tests/switch-tracking.c
index 1a60fa1219f5..3fb1ff7b8a2f 100644
--- a/tools/perf/tests/switch-tracking.c
+++ b/tools/perf/tests/switch-tracking.c
@@ -14,7 +14,6 @@
14#include "evlist.h" 14#include "evlist.h"
15#include "evsel.h" 15#include "evsel.h"
16#include "thread_map.h" 16#include "thread_map.h"
17#include "cpumap.h"
18#include "record.h" 17#include "record.h"
19#include "tests.h" 18#include "tests.h"
20 19
diff --git a/tools/perf/tests/task-exit.c b/tools/perf/tests/task-exit.c
index f610e8c0a083..088c7708b03a 100644
--- a/tools/perf/tests/task-exit.c
+++ b/tools/perf/tests/task-exit.c
@@ -4,12 +4,12 @@
4#include "evsel.h" 4#include "evsel.h"
5#include "target.h" 5#include "target.h"
6#include "thread_map.h" 6#include "thread_map.h"
7#include "cpumap.h"
8#include "tests.h" 7#include "tests.h"
9 8
10#include <errno.h> 9#include <errno.h>
11#include <signal.h> 10#include <signal.h>
12#include <linux/string.h> 11#include <linux/string.h>
12#include <perf/cpumap.h>
13#include <perf/evlist.h> 13#include <perf/evlist.h>
14 14
15static int exited; 15static int exited;
diff --git a/tools/perf/tests/thread-map.c b/tools/perf/tests/thread-map.c
index 39168c57943b..28f51c4bd373 100644
--- a/tools/perf/tests/thread-map.c
+++ b/tools/perf/tests/thread-map.c
@@ -8,6 +8,7 @@
8#include "thread_map.h" 8#include "thread_map.h"
9#include "debug.h" 9#include "debug.h"
10#include "event.h" 10#include "event.h"
11#include "util/synthetic-events.h"
11#include <linux/zalloc.h> 12#include <linux/zalloc.h>
12#include <perf/event.h> 13#include <perf/event.h>
13 14
diff --git a/tools/perf/tests/topology.c b/tools/perf/tests/topology.c
index a4f9f5182b47..7d845d913d7d 100644
--- a/tools/perf/tests/topology.c
+++ b/tools/perf/tests/topology.c
@@ -3,8 +3,8 @@
3#include <stdlib.h> 3#include <stdlib.h>
4#include <stdio.h> 4#include <stdio.h>
5#include <perf/cpumap.h> 5#include <perf/cpumap.h>
6#include "cpumap.h"
6#include "tests.h" 7#include "tests.h"
7#include "util.h"
8#include "session.h" 8#include "session.h"
9#include "evlist.h" 9#include "evlist.h"
10#include "debug.h" 10#include "debug.h"
diff --git a/tools/perf/tests/vmlinux-kallsyms.c b/tools/perf/tests/vmlinux-kallsyms.c
index 01f434c067c6..7f28775875c2 100644
--- a/tools/perf/tests/vmlinux-kallsyms.c
+++ b/tools/perf/tests/vmlinux-kallsyms.c
@@ -7,7 +7,7 @@
7#include "dso.h" 7#include "dso.h"
8#include "map.h" 8#include "map.h"
9#include "symbol.h" 9#include "symbol.h"
10#include "util.h" 10#include "util.h" // page_size
11#include "tests.h" 11#include "tests.h"
12#include "debug.h" 12#include "debug.h"
13#include "machine.h" 13#include "machine.h"
diff --git a/tools/perf/ui/browser.c b/tools/perf/ui/browser.c
index f93d40b1c203..781afe42e90e 100644
--- a/tools/perf/ui/browser.c
+++ b/tools/perf/ui/browser.c
@@ -1,5 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2#include "../util/util.h"
3#include "../util/string2.h" 2#include "../util/string2.h"
4#include "../util/config.h" 3#include "../util/config.h"
5#include "libslang.h" 4#include "libslang.h"
diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c
index ac74ed2c23a0..82207db8f97c 100644
--- a/tools/perf/ui/browsers/annotate.c
+++ b/tools/perf/ui/browsers/annotate.c
@@ -2,7 +2,6 @@
2#include "../browser.h" 2#include "../browser.h"
3#include "../helpline.h" 3#include "../helpline.h"
4#include "../ui.h" 4#include "../ui.h"
5#include "../util.h"
6#include "../../util/annotate.h" 5#include "../../util/annotate.h"
7#include "../../util/debug.h" 6#include "../../util/debug.h"
8#include "../../util/dso.h" 7#include "../../util/dso.h"
diff --git a/tools/perf/ui/browsers/header.c b/tools/perf/ui/browsers/header.c
index 0f59a7001479..57e6e4332f74 100644
--- a/tools/perf/ui/browsers/header.c
+++ b/tools/perf/ui/browsers/header.c
@@ -1,5 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2#include "util/debug.h"
3#include "ui/browser.h" 2#include "ui/browser.h"
4#include "ui/keysyms.h" 3#include "ui/keysyms.h"
5#include "ui/ui.h" 4#include "ui/ui.h"
diff --git a/tools/perf/ui/browsers/map.c b/tools/perf/ui/browsers/map.c
index 893b065971f6..3d49b916c9e4 100644
--- a/tools/perf/ui/browsers/map.c
+++ b/tools/perf/ui/browsers/map.c
@@ -5,7 +5,6 @@
5#include <stdlib.h> 5#include <stdlib.h>
6#include <string.h> 6#include <string.h>
7#include <linux/bitops.h> 7#include <linux/bitops.h>
8#include "../../util/util.h"
9#include "../../util/debug.h" 8#include "../../util/debug.h"
10#include "../../util/map.h" 9#include "../../util/map.h"
11#include "../../util/dso.h" 10#include "../../util/dso.h"
diff --git a/tools/perf/ui/browsers/res_sample.c b/tools/perf/ui/browsers/res_sample.c
index f16a38fea45e..76d356a18790 100644
--- a/tools/perf/ui/browsers/res_sample.c
+++ b/tools/perf/ui/browsers/res_sample.c
@@ -7,7 +7,7 @@
7#include "config.h" 7#include "config.h"
8#include "time-utils.h" 8#include "time-utils.h"
9#include "../util.h" 9#include "../util.h"
10#include "../../util/util.h" 10#include "../../util/util.h" // perf_exe()
11#include "../../perf.h" 11#include "../../perf.h"
12#include <stdlib.h> 12#include <stdlib.h>
13#include <string.h> 13#include <string.h>
diff --git a/tools/perf/ui/browsers/scripts.c b/tools/perf/ui/browsers/scripts.c
index 586a21acc13d..fc733a6354d4 100644
--- a/tools/perf/ui/browsers/scripts.c
+++ b/tools/perf/ui/browsers/scripts.c
@@ -1,7 +1,8 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2#include "../../builtin.h" 2#include "../../builtin.h"
3#include "../../perf.h" 3#include "../../perf.h"
4#include "../../util/util.h" 4#include "../../util/util.h" // perf_exe()
5#include "../util.h"
5#include "../../util/hist.h" 6#include "../../util/hist.h"
6#include "../../util/debug.h" 7#include "../../util/debug.h"
7#include "../../util/symbol.h" 8#include "../../util/symbol.h"
diff --git a/tools/perf/ui/gtk/helpline.c b/tools/perf/ui/gtk/helpline.c
index e166da9ec767..e40a006aead8 100644
--- a/tools/perf/ui/gtk/helpline.c
+++ b/tools/perf/ui/gtk/helpline.c
@@ -6,7 +6,6 @@
6#include "gtk.h" 6#include "gtk.h"
7#include "../ui.h" 7#include "../ui.h"
8#include "../helpline.h" 8#include "../helpline.h"
9#include "../../util/debug.h"
10 9
11static void gtk_helpline_pop(void) 10static void gtk_helpline_pop(void)
12{ 11{
diff --git a/tools/perf/ui/gtk/progress.c b/tools/perf/ui/gtk/progress.c
index b6ad8857da78..eea6fcde518a 100644
--- a/tools/perf/ui/gtk/progress.c
+++ b/tools/perf/ui/gtk/progress.c
@@ -3,7 +3,6 @@
3 3
4#include "gtk.h" 4#include "gtk.h"
5#include "../progress.h" 5#include "../progress.h"
6#include "util.h"
7 6
8static GtkWidget *dialog; 7static GtkWidget *dialog;
9static GtkWidget *progress; 8static GtkWidget *progress;
diff --git a/tools/perf/ui/gtk/setup.c b/tools/perf/ui/gtk/setup.c
index 1a2616b97b5c..f5eee4d66873 100644
--- a/tools/perf/ui/gtk/setup.c
+++ b/tools/perf/ui/gtk/setup.c
@@ -1,6 +1,7 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2#include "gtk.h" 2#include "gtk.h"
3#include "../../util/debug.h" 3#include <linux/compiler.h>
4#include "../util.h"
4 5
5extern struct perf_error_ops perf_gtk_eops; 6extern struct perf_error_ops perf_gtk_eops;
6 7
diff --git a/tools/perf/ui/gtk/util.c b/tools/perf/ui/gtk/util.c
index c2c558958b9c..c47f5c387838 100644
--- a/tools/perf/ui/gtk/util.c
+++ b/tools/perf/ui/gtk/util.c
@@ -1,6 +1,5 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2#include "../util.h" 2#include "../util.h"
3#include "../../util/debug.h"
4#include "gtk.h" 3#include "gtk.h"
5 4
6#include <stdlib.h> 5#include <stdlib.h>
diff --git a/tools/perf/ui/helpline.c b/tools/perf/ui/helpline.c
index 54bcd08df87e..911182b3f5e6 100644
--- a/tools/perf/ui/helpline.c
+++ b/tools/perf/ui/helpline.c
@@ -3,10 +3,8 @@
3#include <stdlib.h> 3#include <stdlib.h>
4#include <string.h> 4#include <string.h>
5 5
6#include "../util/debug.h"
7#include "helpline.h" 6#include "helpline.h"
8#include "ui.h" 7#include "ui.h"
9#include "../util/util.h"
10 8
11char ui_helpline__current[512]; 9char ui_helpline__current[512];
12 10
diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c
index 3e533de7d852..f73675500061 100644
--- a/tools/perf/ui/hist.c
+++ b/tools/perf/ui/hist.c
@@ -8,7 +8,6 @@
8#include "../util/callchain.h" 8#include "../util/callchain.h"
9#include "../util/debug.h" 9#include "../util/debug.h"
10#include "../util/hist.h" 10#include "../util/hist.h"
11#include "../util/util.h"
12#include "../util/sort.h" 11#include "../util/sort.h"
13#include "../util/evsel.h" 12#include "../util/evsel.h"
14#include "../util/evlist.h" 13#include "../util/evlist.h"
diff --git a/tools/perf/ui/setup.c b/tools/perf/ui/setup.c
index c7a86b4be9f5..700335cde618 100644
--- a/tools/perf/ui/setup.c
+++ b/tools/perf/ui/setup.c
@@ -1,11 +1,11 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2#include <pthread.h> 2#include <pthread.h>
3#include <dlfcn.h> 3#include <dlfcn.h>
4#include <unistd.h>
4 5
5#include <subcmd/pager.h> 6#include <subcmd/pager.h>
6#include "../util/debug.h" 7#include "../util/debug.h"
7#include "../util/hist.h" 8#include "../util/hist.h"
8#include "../util/util.h"
9#include "ui.h" 9#include "ui.h"
10 10
11pthread_mutex_t ui__lock = PTHREAD_MUTEX_INITIALIZER; 11pthread_mutex_t ui__lock = PTHREAD_MUTEX_INITIALIZER;
diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c
index 832ca6cfbe30..5365606e9dad 100644
--- a/tools/perf/ui/stdio/hist.c
+++ b/tools/perf/ui/stdio/hist.c
@@ -5,6 +5,7 @@
5 5
6#include "../../util/callchain.h" 6#include "../../util/callchain.h"
7#include "../../util/debug.h" 7#include "../../util/debug.h"
8#include "../../util/event.h"
8#include "../../util/hist.h" 9#include "../../util/hist.h"
9#include "../../util/map.h" 10#include "../../util/map.h"
10#include "../../util/map_groups.h" 11#include "../../util/map_groups.h"
diff --git a/tools/perf/ui/tui/helpline.c b/tools/perf/ui/tui/helpline.c
index 5f188f678c55..298d6af82fdd 100644
--- a/tools/perf/ui/tui/helpline.c
+++ b/tools/perf/ui/tui/helpline.c
@@ -6,7 +6,6 @@
6#include <linux/kernel.h> 6#include <linux/kernel.h>
7#include <linux/string.h> 7#include <linux/string.h>
8 8
9#include "../../util/debug.h"
10#include "../helpline.h" 9#include "../helpline.h"
11#include "../ui.h" 10#include "../ui.h"
12#include "../libslang.h" 11#include "../libslang.h"
diff --git a/tools/perf/ui/tui/setup.c b/tools/perf/ui/tui/setup.c
index 56651a4f5aa0..e9bfe856a5de 100644
--- a/tools/perf/ui/tui/setup.c
+++ b/tools/perf/ui/tui/setup.c
@@ -2,13 +2,13 @@
2#include <signal.h> 2#include <signal.h>
3#include <stdbool.h> 3#include <stdbool.h>
4#include <stdlib.h> 4#include <stdlib.h>
5#include <unistd.h>
5#include <linux/kernel.h> 6#include <linux/kernel.h>
6#ifdef HAVE_BACKTRACE_SUPPORT 7#ifdef HAVE_BACKTRACE_SUPPORT
7#include <execinfo.h> 8#include <execinfo.h>
8#endif 9#endif
9 10
10#include "../../util/debug.h" 11#include "../../util/debug.h"
11#include "../../util/util.h"
12#include "../../perf.h" 12#include "../../perf.h"
13#include "../browser.h" 13#include "../browser.h"
14#include "../helpline.h" 14#include "../helpline.h"
diff --git a/tools/perf/ui/tui/util.c b/tools/perf/ui/tui/util.c
index 087d9ab054c8..b98dd0e31dc1 100644
--- a/tools/perf/ui/tui/util.c
+++ b/tools/perf/ui/tui/util.c
@@ -5,7 +5,6 @@
5#include <stdlib.h> 5#include <stdlib.h>
6#include <sys/ttydefaults.h> 6#include <sys/ttydefaults.h>
7 7
8#include "../../util/debug.h"
9#include "../browser.h" 8#include "../browser.h"
10#include "../keysyms.h" 9#include "../keysyms.h"
11#include "../helpline.h" 10#include "../helpline.h"
diff --git a/tools/perf/util/Build b/tools/perf/util/Build
index 0b4d8e0d474c..fd89d6a8cd65 100644
--- a/tools/perf/util/Build
+++ b/tools/perf/util/Build
@@ -86,6 +86,7 @@ perf-y += stat-display.o
86perf-y += record.o 86perf-y += record.o
87perf-y += srcline.o 87perf-y += srcline.o
88perf-y += srccode.o 88perf-y += srccode.o
89perf-y += synthetic-events.o
89perf-y += data.o 90perf-y += data.o
90perf-y += tsc.o 91perf-y += tsc.o
91perf-y += cloexec.o 92perf-y += cloexec.o
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index 1748f528b6e9..d441cca6a517 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -14,7 +14,7 @@
14#include <bpf/btf.h> 14#include <bpf/btf.h>
15#include <bpf/libbpf.h> 15#include <bpf/libbpf.h>
16#include <linux/btf.h> 16#include <linux/btf.h>
17#include "util.h" 17#include "util.h" // hex_width()
18#include "ui/ui.h" 18#include "ui/ui.h"
19#include "sort.h" 19#include "sort.h"
20#include "build-id.h" 20#include "build-id.h"
diff --git a/tools/perf/util/arm-spe.c b/tools/perf/util/arm-spe.c
index 8a7340f6a2a2..53be12b23ff4 100644
--- a/tools/perf/util/arm-spe.c
+++ b/tools/perf/util/arm-spe.c
@@ -16,7 +16,6 @@
16#include <linux/log2.h> 16#include <linux/log2.h>
17#include <linux/zalloc.h> 17#include <linux/zalloc.h>
18 18
19#include "cpumap.h"
20#include "color.h" 19#include "color.h"
21#include "evsel.h" 20#include "evsel.h"
22#include "machine.h" 21#include "machine.h"
diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c
index 6f25224a3def..0e8c89cf7cad 100644
--- a/tools/perf/util/auxtrace.c
+++ b/tools/perf/util/auxtrace.c
@@ -31,8 +31,8 @@
31#include "map.h" 31#include "map.h"
32#include "pmu.h" 32#include "pmu.h"
33#include "evsel.h" 33#include "evsel.h"
34#include "cpumap.h"
35#include "symbol.h" 34#include "symbol.h"
35#include "util/synthetic-events.h"
36#include "thread_map.h" 36#include "thread_map.h"
37#include "asm/bug.h" 37#include "asm/bug.h"
38#include "auxtrace.h" 38#include "auxtrace.h"
@@ -50,10 +50,12 @@
50#include "intel-bts.h" 50#include "intel-bts.h"
51#include "arm-spe.h" 51#include "arm-spe.h"
52#include "s390-cpumsf.h" 52#include "s390-cpumsf.h"
53#include "util.h" 53#include "util.h" // page_size
54 54
55#include <linux/ctype.h> 55#include <linux/ctype.h>
56#include <linux/kernel.h>
56#include "symbol/kallsyms.h" 57#include "symbol/kallsyms.h"
58#include <internal/lib.h>
57 59
58static bool auxtrace__dont_decode(struct perf_session *session) 60static bool auxtrace__dont_decode(struct perf_session *session)
59{ 61{
diff --git a/tools/perf/util/auxtrace.h b/tools/perf/util/auxtrace.h
index 37e70dc01436..b110aec1da4d 100644
--- a/tools/perf/util/auxtrace.h
+++ b/tools/perf/util/auxtrace.h
@@ -11,21 +11,22 @@
11#include <errno.h> 11#include <errno.h>
12#include <stdbool.h> 12#include <stdbool.h>
13#include <stddef.h> 13#include <stddef.h>
14#include <stdio.h> // FILE
14#include <linux/list.h> 15#include <linux/list.h>
15#include <linux/perf_event.h> 16#include <linux/perf_event.h>
16#include <linux/types.h> 17#include <linux/types.h>
17#include <asm/bitsperlong.h> 18#include <asm/bitsperlong.h>
18#include <asm/barrier.h> 19#include <asm/barrier.h>
19 20
20#include "event.h"
21
22union perf_event; 21union perf_event;
23struct perf_session; 22struct perf_session;
24struct evlist; 23struct evlist;
25struct perf_tool; 24struct perf_tool;
26struct perf_mmap; 25struct perf_mmap;
26struct perf_sample;
27struct option; 27struct option;
28struct record_opts; 28struct record_opts;
29struct perf_record_auxtrace_error;
29struct perf_record_auxtrace_info; 30struct perf_record_auxtrace_info;
30struct events_stats; 31struct events_stats;
31 32
@@ -524,10 +525,6 @@ void auxtrace_synth_error(struct perf_record_auxtrace_error *auxtrace_error, int
524 int code, int cpu, pid_t pid, pid_t tid, u64 ip, 525 int code, int cpu, pid_t pid, pid_t tid, u64 ip,
525 const char *msg, u64 timestamp); 526 const char *msg, u64 timestamp);
526 527
527int perf_event__synthesize_auxtrace_info(struct auxtrace_record *itr,
528 struct perf_tool *tool,
529 struct perf_session *session,
530 perf_event__handler_t process);
531int perf_event__process_auxtrace_info(struct perf_session *session, 528int perf_event__process_auxtrace_info(struct perf_session *session,
532 union perf_event *event); 529 union perf_event *event);
533s64 perf_event__process_auxtrace(struct perf_session *session, 530s64 perf_event__process_auxtrace(struct perf_session *session,
@@ -604,15 +601,6 @@ void auxtrace_record__free(struct auxtrace_record *itr __maybe_unused)
604{ 601{
605} 602}
606 603
607static inline int
608perf_event__synthesize_auxtrace_info(struct auxtrace_record *itr __maybe_unused,
609 struct perf_tool *tool __maybe_unused,
610 struct perf_session *session __maybe_unused,
611 perf_event__handler_t process __maybe_unused)
612{
613 return -EINVAL;
614}
615
616static inline 604static inline
617int auxtrace_record__options(struct auxtrace_record *itr __maybe_unused, 605int auxtrace_record__options(struct auxtrace_record *itr __maybe_unused,
618 struct evlist *evlist __maybe_unused, 606 struct evlist *evlist __maybe_unused,
diff --git a/tools/perf/util/bpf-event.c b/tools/perf/util/bpf-event.c
index 7a3d4b125323..f7ed5d122e22 100644
--- a/tools/perf/util/bpf-event.c
+++ b/tools/perf/util/bpf-event.c
@@ -16,6 +16,7 @@
16#include "map.h" 16#include "map.h"
17#include "evlist.h" 17#include "evlist.h"
18#include "record.h" 18#include "record.h"
19#include "util/synthetic-events.h"
19 20
20#define ptr_to_u64(ptr) ((__u64)(unsigned long)(ptr)) 21#define ptr_to_u64(ptr) ((__u64)(unsigned long)(ptr))
21 22
diff --git a/tools/perf/util/bpf-event.h b/tools/perf/util/bpf-event.h
index a01c2fd68c03..81fdc88e6c1a 100644
--- a/tools/perf/util/bpf-event.h
+++ b/tools/perf/util/bpf-event.h
@@ -6,9 +6,9 @@
6#include <linux/rbtree.h> 6#include <linux/rbtree.h>
7#include <pthread.h> 7#include <pthread.h>
8#include <api/fd/array.h> 8#include <api/fd/array.h>
9#include "event.h"
10#include <stdio.h> 9#include <stdio.h>
11 10
11struct bpf_prog_info;
12struct machine; 12struct machine;
13union perf_event; 13union perf_event;
14struct perf_env; 14struct perf_env;
@@ -33,11 +33,6 @@ struct btf_node {
33#ifdef HAVE_LIBBPF_SUPPORT 33#ifdef HAVE_LIBBPF_SUPPORT
34int machine__process_bpf(struct machine *machine, union perf_event *event, 34int machine__process_bpf(struct machine *machine, union perf_event *event,
35 struct perf_sample *sample); 35 struct perf_sample *sample);
36
37int perf_event__synthesize_bpf_events(struct perf_session *session,
38 perf_event__handler_t process,
39 struct machine *machine,
40 struct record_opts *opts);
41int bpf_event__add_sb_event(struct evlist **evlist, 36int bpf_event__add_sb_event(struct evlist **evlist,
42 struct perf_env *env); 37 struct perf_env *env);
43void bpf_event__print_bpf_prog_info(struct bpf_prog_info *info, 38void bpf_event__print_bpf_prog_info(struct bpf_prog_info *info,
@@ -51,14 +46,6 @@ static inline int machine__process_bpf(struct machine *machine __maybe_unused,
51 return 0; 46 return 0;
52} 47}
53 48
54static inline int perf_event__synthesize_bpf_events(struct perf_session *session __maybe_unused,
55 perf_event__handler_t process __maybe_unused,
56 struct machine *machine __maybe_unused,
57 struct record_opts *opts __maybe_unused)
58{
59 return 0;
60}
61
62static inline int bpf_event__add_sb_event(struct evlist **evlist __maybe_unused, 49static inline int bpf_event__add_sb_event(struct evlist **evlist __maybe_unused,
63 struct perf_env *env __maybe_unused) 50 struct perf_env *env __maybe_unused)
64{ 51{
diff --git a/tools/perf/util/branch.c b/tools/perf/util/branch.c
index 9d1e090084a2..2285b1eb3128 100644
--- a/tools/perf/util/branch.c
+++ b/tools/perf/util/branch.c
@@ -1,5 +1,3 @@
1#include "util/util.h"
2#include "util/debug.h"
3#include "util/map_symbol.h" 1#include "util/map_symbol.h"
4#include "util/branch.h" 2#include "util/branch.h"
5#include <linux/kernel.h> 3#include <linux/kernel.h>
diff --git a/tools/perf/util/branch.h b/tools/perf/util/branch.h
index 06f66dad0b79..88e00d268f6f 100644
--- a/tools/perf/util/branch.h
+++ b/tools/perf/util/branch.h
@@ -1,8 +1,15 @@
1#ifndef _PERF_BRANCH_H 1#ifndef _PERF_BRANCH_H
2#define _PERF_BRANCH_H 1 2#define _PERF_BRANCH_H 1
3 3/*
4 * The linux/stddef.h isn't need here, but is needed for __always_inline used
5 * in files included from uapi/linux/perf_event.h such as
6 * /usr/include/linux/swab.h and /usr/include/linux/byteorder/little_endian.h,
7 * detected in at least musl libc, used in Alpine Linux. -acme
8 */
4#include <stdio.h> 9#include <stdio.h>
5#include <stdint.h> 10#include <stdint.h>
11#include <linux/compiler.h>
12#include <linux/stddef.h>
6#include <linux/perf_event.h> 13#include <linux/perf_event.h>
7#include <linux/types.h> 14#include <linux/types.h>
8 15
diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c
index e5fb77755d9e..7928c398a063 100644
--- a/tools/perf/util/build-id.c
+++ b/tools/perf/util/build-id.c
@@ -7,7 +7,7 @@
7 * Copyright (C) 2009, 2010 Red Hat Inc. 7 * Copyright (C) 2009, 2010 Red Hat Inc.
8 * Copyright (C) 2009, 2010 Arnaldo Carvalho de Melo <acme@redhat.com> 8 * Copyright (C) 2009, 2010 Arnaldo Carvalho de Melo <acme@redhat.com>
9 */ 9 */
10#include "util.h" 10#include "util.h" // copyfile_ns(), lsdir(), mkdir_p(), rm_rf()
11#include <dirent.h> 11#include <dirent.h>
12#include <errno.h> 12#include <errno.h>
13#include <stdio.h> 13#include <stdio.h>
diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c
index c14646c1f2eb..9a9b56ed3f0a 100644
--- a/tools/perf/util/callchain.c
+++ b/tools/perf/util/callchain.c
@@ -23,6 +23,7 @@
23 23
24#include "debug.h" 24#include "debug.h"
25#include "dso.h" 25#include "dso.h"
26#include "event.h"
26#include "hist.h" 27#include "hist.h"
27#include "sort.h" 28#include "sort.h"
28#include "machine.h" 29#include "machine.h"
diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h
index b042ceef4114..83398e5bbe4b 100644
--- a/tools/perf/util/callchain.h
+++ b/tools/perf/util/callchain.h
@@ -4,12 +4,15 @@
4 4
5#include <linux/list.h> 5#include <linux/list.h>
6#include <linux/rbtree.h> 6#include <linux/rbtree.h>
7#include "event.h"
8#include "map_symbol.h" 7#include "map_symbol.h"
9#include "branch.h" 8#include "branch.h"
10 9
10struct addr_location;
11struct evsel; 11struct evsel;
12struct ip_callchain;
12struct map; 13struct map;
14struct perf_sample;
15struct thread;
13 16
14#define HELP_PAD "\t\t\t\t" 17#define HELP_PAD "\t\t\t\t"
15 18
diff --git a/tools/perf/util/cloexec.c b/tools/perf/util/cloexec.c
index 4e904fcb2783..a12872f2856a 100644
--- a/tools/perf/util/cloexec.c
+++ b/tools/perf/util/cloexec.c
@@ -1,7 +1,7 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2#include <errno.h> 2#include <errno.h>
3#include <sched.h> 3#include <sched.h>
4#include "util.h" 4#include "util.h" // for sched_getcpu()
5#include "../perf-sys.h" 5#include "../perf-sys.h"
6#include "cloexec.h" 6#include "cloexec.h"
7#include "event.h" 7#include "event.h"
diff --git a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
index 37d7c492b155..cd92a99eb89d 100644
--- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
+++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
@@ -17,7 +17,6 @@
17#include "cs-etm.h" 17#include "cs-etm.h"
18#include "cs-etm-decoder.h" 18#include "cs-etm-decoder.h"
19#include "intlist.h" 19#include "intlist.h"
20#include "util.h"
21 20
22/* use raw logging */ 21/* use raw logging */
23#ifdef CS_DEBUG_RAW 22#ifdef CS_DEBUG_RAW
diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
index 707afdbd9529..6021974577d5 100644
--- a/tools/perf/util/cs-etm.c
+++ b/tools/perf/util/cs-etm.c
@@ -35,7 +35,7 @@
35#include "thread.h" 35#include "thread.h"
36#include "thread-stack.h" 36#include "thread-stack.h"
37#include <tools/libc_compat.h> 37#include <tools/libc_compat.h>
38#include "util.h" 38#include "util/synthetic-events.h"
39 39
40#define MAX_TIMESTAMP (~0ULL) 40#define MAX_TIMESTAMP (~0ULL)
41 41
diff --git a/tools/perf/util/data.c b/tools/perf/util/data.c
index e75c3a279fe8..88fba2ba549f 100644
--- a/tools/perf/util/data.c
+++ b/tools/perf/util/data.c
@@ -13,9 +13,10 @@
13#include <dirent.h> 13#include <dirent.h>
14 14
15#include "data.h" 15#include "data.h"
16#include "util.h" 16#include "util.h" // rm_rf_perf_data()
17#include "debug.h" 17#include "debug.h"
18#include "header.h" 18#include "header.h"
19#include <internal/lib.h>
19 20
20static void close_dir(struct perf_data_file *files, int nr) 21static void close_dir(struct perf_data_file *files, int nr)
21{ 22{
diff --git a/tools/perf/util/debug.c b/tools/perf/util/debug.c
index a1b59bd35519..e55114f0336f 100644
--- a/tools/perf/util/debug.c
+++ b/tools/perf/util/debug.c
@@ -17,7 +17,6 @@
17#include "event.h" 17#include "event.h"
18#include "debug.h" 18#include "debug.h"
19#include "print_binary.h" 19#include "print_binary.h"
20#include "util.h"
21#include "target.h" 20#include "target.h"
22#include "ui/helpline.h" 21#include "ui/helpline.h"
23#include "ui/ui.h" 22#include "ui/ui.h"
diff --git a/tools/perf/util/debug.h b/tools/perf/util/debug.h
index b2deee987ffa..d25ae1c4cee9 100644
--- a/tools/perf/util/debug.h
+++ b/tools/perf/util/debug.h
@@ -3,9 +3,9 @@
3#ifndef __PERF_DEBUG_H 3#ifndef __PERF_DEBUG_H
4#define __PERF_DEBUG_H 4#define __PERF_DEBUG_H
5 5
6#include <stdarg.h>
6#include <stdbool.h> 7#include <stdbool.h>
7#include <linux/compiler.h> 8#include <linux/compiler.h>
8#include "../ui/util.h"
9 9
10extern int verbose; 10extern int verbose;
11extern bool quiet, dump_trace; 11extern bool quiet, dump_trace;
diff --git a/tools/perf/util/demangle-java.c b/tools/perf/util/demangle-java.c
index 763328c151e9..6fb7f34c0814 100644
--- a/tools/perf/util/demangle-java.c
+++ b/tools/perf/util/demangle-java.c
@@ -3,7 +3,6 @@
3#include <stdio.h> 3#include <stdio.h>
4#include <stdlib.h> 4#include <stdlib.h>
5#include <string.h> 5#include <string.h>
6#include "debug.h"
7#include "symbol.h" 6#include "symbol.h"
8 7
9#include "demangle-java.h" 8#include "demangle-java.h"
diff --git a/tools/perf/util/demangle-rust.c b/tools/perf/util/demangle-rust.c
index 423afbbd386b..a659fc69f73a 100644
--- a/tools/perf/util/demangle-rust.c
+++ b/tools/perf/util/demangle-rust.c
@@ -1,6 +1,5 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2#include <string.h> 2#include <string.h>
3#include "util.h"
4#include "debug.h" 3#include "debug.h"
5 4
6#include "demangle-rust.h" 5#include "demangle-rust.h"
diff --git a/tools/perf/util/dwarf-regs.c b/tools/perf/util/dwarf-regs.c
index db55eddce8cd..1b49ecee5aff 100644
--- a/tools/perf/util/dwarf-regs.c
+++ b/tools/perf/util/dwarf-regs.c
@@ -5,7 +5,6 @@
5 * Written by: Masami Hiramatsu <mhiramat@kernel.org> 5 * Written by: Masami Hiramatsu <mhiramat@kernel.org>
6 */ 6 */
7 7
8#include <util.h>
9#include <debug.h> 8#include <debug.h>
10#include <dwarf-regs.h> 9#include <dwarf-regs.h>
11#include <elf.h> 10#include <elf.h>
diff --git a/tools/perf/util/env.h b/tools/perf/util/env.h
index d8e083d42610..db40906e2937 100644
--- a/tools/perf/util/env.h
+++ b/tools/perf/util/env.h
@@ -4,9 +4,10 @@
4 4
5#include <linux/types.h> 5#include <linux/types.h>
6#include <linux/rbtree.h> 6#include <linux/rbtree.h>
7#include "cpumap.h"
8#include "rwsem.h" 7#include "rwsem.h"
9 8
9struct perf_cpu_map;
10
10struct cpu_topology_map { 11struct cpu_topology_map {
11 int socket_id; 12 int socket_id;
12 int die_id; 13 int die_id;
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index f4afbb858ebb..fc1e5a991008 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -1,16 +1,16 @@
1#include <dirent.h>
2#include <errno.h> 1#include <errno.h>
3#include <fcntl.h> 2#include <fcntl.h>
4#include <inttypes.h> 3#include <inttypes.h>
5#include <linux/kernel.h> 4#include <linux/kernel.h>
6#include <linux/types.h> 5#include <linux/types.h>
6#include <perf/cpumap.h>
7#include <sys/types.h> 7#include <sys/types.h>
8#include <sys/stat.h> 8#include <sys/stat.h>
9#include <unistd.h> 9#include <unistd.h>
10#include <uapi/linux/mman.h> /* To get things like MAP_HUGETLB even on older libc headers */ 10#include <uapi/linux/mman.h> /* To get things like MAP_HUGETLB even on older libc headers */
11#include <api/fs/fs.h>
12#include <linux/perf_event.h> 11#include <linux/perf_event.h>
13#include <linux/zalloc.h> 12#include <linux/zalloc.h>
13#include "cpumap.h"
14#include "dso.h" 14#include "dso.h"
15#include "event.h" 15#include "event.h"
16#include "debug.h" 16#include "debug.h"
@@ -24,6 +24,7 @@
24#include "time-utils.h" 24#include "time-utils.h"
25#include <linux/ctype.h> 25#include <linux/ctype.h>
26#include "map.h" 26#include "map.h"
27#include "util/namespaces.h"
27#include "symbol.h" 28#include "symbol.h"
28#include "symbol/kallsyms.h" 29#include "symbol/kallsyms.h"
29#include "asm/bug.h" 30#include "asm/bug.h"
@@ -33,8 +34,6 @@
33#include "tool.h" 34#include "tool.h"
34#include "../perf.h" 35#include "../perf.h"
35 36
36#define DEFAULT_PROC_MAP_PARSE_TIMEOUT 500
37
38static const char *perf_event__names[] = { 37static const char *perf_event__names[] = {
39 [0] = "TOTAL", 38 [0] = "TOTAL",
40 [PERF_RECORD_MMAP] = "MMAP", 39 [PERF_RECORD_MMAP] = "MMAP",
@@ -75,18 +74,6 @@ static const char *perf_event__names[] = {
75 [PERF_RECORD_COMPRESSED] = "COMPRESSED", 74 [PERF_RECORD_COMPRESSED] = "COMPRESSED",
76}; 75};
77 76
78static const char *perf_ns__names[] = {
79 [NET_NS_INDEX] = "net",
80 [UTS_NS_INDEX] = "uts",
81 [IPC_NS_INDEX] = "ipc",
82 [PID_NS_INDEX] = "pid",
83 [USER_NS_INDEX] = "user",
84 [MNT_NS_INDEX] = "mnt",
85 [CGROUP_NS_INDEX] = "cgroup",
86};
87
88unsigned int proc_map_timeout = DEFAULT_PROC_MAP_PARSE_TIMEOUT;
89
90const char *perf_event__name(unsigned int id) 77const char *perf_event__name(unsigned int id)
91{ 78{
92 if (id >= ARRAY_SIZE(perf_event__names)) 79 if (id >= ARRAY_SIZE(perf_event__names))
@@ -96,775 +83,6 @@ const char *perf_event__name(unsigned int id)
96 return perf_event__names[id]; 83 return perf_event__names[id];
97} 84}
98 85
99static const char *perf_ns__name(unsigned int id)
100{
101 if (id >= ARRAY_SIZE(perf_ns__names))
102 return "UNKNOWN";
103 return perf_ns__names[id];
104}
105
106int perf_tool__process_synth_event(struct perf_tool *tool,
107 union perf_event *event,
108 struct machine *machine,
109 perf_event__handler_t process)
110{
111 struct perf_sample synth_sample = {
112 .pid = -1,
113 .tid = -1,
114 .time = -1,
115 .stream_id = -1,
116 .cpu = -1,
117 .period = 1,
118 .cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK,
119 };
120
121 return process(tool, event, &synth_sample, machine);
122};
123
124/*
125 * Assumes that the first 4095 bytes of /proc/pid/stat contains
126 * the comm, tgid and ppid.
127 */
128static int perf_event__get_comm_ids(pid_t pid, char *comm, size_t len,
129 pid_t *tgid, pid_t *ppid)
130{
131 char filename[PATH_MAX];
132 char bf[4096];
133 int fd;
134 size_t size = 0;
135 ssize_t n;
136 char *name, *tgids, *ppids;
137
138 *tgid = -1;
139 *ppid = -1;
140
141 snprintf(filename, sizeof(filename), "/proc/%d/status", pid);
142
143 fd = open(filename, O_RDONLY);
144 if (fd < 0) {
145 pr_debug("couldn't open %s\n", filename);
146 return -1;
147 }
148
149 n = read(fd, bf, sizeof(bf) - 1);
150 close(fd);
151 if (n <= 0) {
152 pr_warning("Couldn't get COMM, tigd and ppid for pid %d\n",
153 pid);
154 return -1;
155 }
156 bf[n] = '\0';
157
158 name = strstr(bf, "Name:");
159 tgids = strstr(bf, "Tgid:");
160 ppids = strstr(bf, "PPid:");
161
162 if (name) {
163 char *nl;
164
165 name = skip_spaces(name + 5); /* strlen("Name:") */
166 nl = strchr(name, '\n');
167 if (nl)
168 *nl = '\0';
169
170 size = strlen(name);
171 if (size >= len)
172 size = len - 1;
173 memcpy(comm, name, size);
174 comm[size] = '\0';
175 } else {
176 pr_debug("Name: string not found for pid %d\n", pid);
177 }
178
179 if (tgids) {
180 tgids += 5; /* strlen("Tgid:") */
181 *tgid = atoi(tgids);
182 } else {
183 pr_debug("Tgid: string not found for pid %d\n", pid);
184 }
185
186 if (ppids) {
187 ppids += 5; /* strlen("PPid:") */
188 *ppid = atoi(ppids);
189 } else {
190 pr_debug("PPid: string not found for pid %d\n", pid);
191 }
192
193 return 0;
194}
195
196static int perf_event__prepare_comm(union perf_event *event, pid_t pid,
197 struct machine *machine,
198 pid_t *tgid, pid_t *ppid)
199{
200 size_t size;
201
202 *ppid = -1;
203
204 memset(&event->comm, 0, sizeof(event->comm));
205
206 if (machine__is_host(machine)) {
207 if (perf_event__get_comm_ids(pid, event->comm.comm,
208 sizeof(event->comm.comm),
209 tgid, ppid) != 0) {
210 return -1;
211 }
212 } else {
213 *tgid = machine->pid;
214 }
215
216 if (*tgid < 0)
217 return -1;
218
219 event->comm.pid = *tgid;
220 event->comm.header.type = PERF_RECORD_COMM;
221
222 size = strlen(event->comm.comm) + 1;
223 size = PERF_ALIGN(size, sizeof(u64));
224 memset(event->comm.comm + size, 0, machine->id_hdr_size);
225 event->comm.header.size = (sizeof(event->comm) -
226 (sizeof(event->comm.comm) - size) +
227 machine->id_hdr_size);
228 event->comm.tid = pid;
229
230 return 0;
231}
232
233pid_t perf_event__synthesize_comm(struct perf_tool *tool,
234 union perf_event *event, pid_t pid,
235 perf_event__handler_t process,
236 struct machine *machine)
237{
238 pid_t tgid, ppid;
239
240 if (perf_event__prepare_comm(event, pid, machine, &tgid, &ppid) != 0)
241 return -1;
242
243 if (perf_tool__process_synth_event(tool, event, machine, process) != 0)
244 return -1;
245
246 return tgid;
247}
248
249static void perf_event__get_ns_link_info(pid_t pid, const char *ns,
250 struct perf_ns_link_info *ns_link_info)
251{
252 struct stat64 st;
253 char proc_ns[128];
254
255 sprintf(proc_ns, "/proc/%u/ns/%s", pid, ns);
256 if (stat64(proc_ns, &st) == 0) {
257 ns_link_info->dev = st.st_dev;
258 ns_link_info->ino = st.st_ino;
259 }
260}
261
262int perf_event__synthesize_namespaces(struct perf_tool *tool,
263 union perf_event *event,
264 pid_t pid, pid_t tgid,
265 perf_event__handler_t process,
266 struct machine *machine)
267{
268 u32 idx;
269 struct perf_ns_link_info *ns_link_info;
270
271 if (!tool || !tool->namespace_events)
272 return 0;
273
274 memset(&event->namespaces, 0, (sizeof(event->namespaces) +
275 (NR_NAMESPACES * sizeof(struct perf_ns_link_info)) +
276 machine->id_hdr_size));
277
278 event->namespaces.pid = tgid;
279 event->namespaces.tid = pid;
280
281 event->namespaces.nr_namespaces = NR_NAMESPACES;
282
283 ns_link_info = event->namespaces.link_info;
284
285 for (idx = 0; idx < event->namespaces.nr_namespaces; idx++)
286 perf_event__get_ns_link_info(pid, perf_ns__name(idx),
287 &ns_link_info[idx]);
288
289 event->namespaces.header.type = PERF_RECORD_NAMESPACES;
290
291 event->namespaces.header.size = (sizeof(event->namespaces) +
292 (NR_NAMESPACES * sizeof(struct perf_ns_link_info)) +
293 machine->id_hdr_size);
294
295 if (perf_tool__process_synth_event(tool, event, machine, process) != 0)
296 return -1;
297
298 return 0;
299}
300
301static int perf_event__synthesize_fork(struct perf_tool *tool,
302 union perf_event *event,
303 pid_t pid, pid_t tgid, pid_t ppid,
304 perf_event__handler_t process,
305 struct machine *machine)
306{
307 memset(&event->fork, 0, sizeof(event->fork) + machine->id_hdr_size);
308
309 /*
310 * for main thread set parent to ppid from status file. For other
311 * threads set parent pid to main thread. ie., assume main thread
312 * spawns all threads in a process
313 */
314 if (tgid == pid) {
315 event->fork.ppid = ppid;
316 event->fork.ptid = ppid;
317 } else {
318 event->fork.ppid = tgid;
319 event->fork.ptid = tgid;
320 }
321 event->fork.pid = tgid;
322 event->fork.tid = pid;
323 event->fork.header.type = PERF_RECORD_FORK;
324 event->fork.header.misc = PERF_RECORD_MISC_FORK_EXEC;
325
326 event->fork.header.size = (sizeof(event->fork) + machine->id_hdr_size);
327
328 if (perf_tool__process_synth_event(tool, event, machine, process) != 0)
329 return -1;
330
331 return 0;
332}
333
334int perf_event__synthesize_mmap_events(struct perf_tool *tool,
335 union perf_event *event,
336 pid_t pid, pid_t tgid,
337 perf_event__handler_t process,
338 struct machine *machine,
339 bool mmap_data)
340{
341 char filename[PATH_MAX];
342 FILE *fp;
343 unsigned long long t;
344 bool truncation = false;
345 unsigned long long timeout = proc_map_timeout * 1000000ULL;
346 int rc = 0;
347 const char *hugetlbfs_mnt = hugetlbfs__mountpoint();
348 int hugetlbfs_mnt_len = hugetlbfs_mnt ? strlen(hugetlbfs_mnt) : 0;
349
350 if (machine__is_default_guest(machine))
351 return 0;
352
353 snprintf(filename, sizeof(filename), "%s/proc/%d/task/%d/maps",
354 machine->root_dir, pid, pid);
355
356 fp = fopen(filename, "r");
357 if (fp == NULL) {
358 /*
359 * We raced with a task exiting - just return:
360 */
361 pr_debug("couldn't open %s\n", filename);
362 return -1;
363 }
364
365 event->header.type = PERF_RECORD_MMAP2;
366 t = rdclock();
367
368 while (1) {
369 char bf[BUFSIZ];
370 char prot[5];
371 char execname[PATH_MAX];
372 char anonstr[] = "//anon";
373 unsigned int ino;
374 size_t size;
375 ssize_t n;
376
377 if (fgets(bf, sizeof(bf), fp) == NULL)
378 break;
379
380 if ((rdclock() - t) > timeout) {
381 pr_warning("Reading %s time out. "
382 "You may want to increase "
383 "the time limit by --proc-map-timeout\n",
384 filename);
385 truncation = true;
386 goto out;
387 }
388
389 /* ensure null termination since stack will be reused. */
390 strcpy(execname, "");
391
392 /* 00400000-0040c000 r-xp 00000000 fd:01 41038 /bin/cat */
393 n = sscanf(bf, "%"PRI_lx64"-%"PRI_lx64" %s %"PRI_lx64" %x:%x %u %[^\n]\n",
394 &event->mmap2.start, &event->mmap2.len, prot,
395 &event->mmap2.pgoff, &event->mmap2.maj,
396 &event->mmap2.min,
397 &ino, execname);
398
399 /*
400 * Anon maps don't have the execname.
401 */
402 if (n < 7)
403 continue;
404
405 event->mmap2.ino = (u64)ino;
406
407 /*
408 * Just like the kernel, see __perf_event_mmap in kernel/perf_event.c
409 */
410 if (machine__is_host(machine))
411 event->header.misc = PERF_RECORD_MISC_USER;
412 else
413 event->header.misc = PERF_RECORD_MISC_GUEST_USER;
414
415 /* map protection and flags bits */
416 event->mmap2.prot = 0;
417 event->mmap2.flags = 0;
418 if (prot[0] == 'r')
419 event->mmap2.prot |= PROT_READ;
420 if (prot[1] == 'w')
421 event->mmap2.prot |= PROT_WRITE;
422 if (prot[2] == 'x')
423 event->mmap2.prot |= PROT_EXEC;
424
425 if (prot[3] == 's')
426 event->mmap2.flags |= MAP_SHARED;
427 else
428 event->mmap2.flags |= MAP_PRIVATE;
429
430 if (prot[2] != 'x') {
431 if (!mmap_data || prot[0] != 'r')
432 continue;
433
434 event->header.misc |= PERF_RECORD_MISC_MMAP_DATA;
435 }
436
437out:
438 if (truncation)
439 event->header.misc |= PERF_RECORD_MISC_PROC_MAP_PARSE_TIMEOUT;
440
441 if (!strcmp(execname, ""))
442 strcpy(execname, anonstr);
443
444 if (hugetlbfs_mnt_len &&
445 !strncmp(execname, hugetlbfs_mnt, hugetlbfs_mnt_len)) {
446 strcpy(execname, anonstr);
447 event->mmap2.flags |= MAP_HUGETLB;
448 }
449
450 size = strlen(execname) + 1;
451 memcpy(event->mmap2.filename, execname, size);
452 size = PERF_ALIGN(size, sizeof(u64));
453 event->mmap2.len -= event->mmap.start;
454 event->mmap2.header.size = (sizeof(event->mmap2) -
455 (sizeof(event->mmap2.filename) - size));
456 memset(event->mmap2.filename + size, 0, machine->id_hdr_size);
457 event->mmap2.header.size += machine->id_hdr_size;
458 event->mmap2.pid = tgid;
459 event->mmap2.tid = pid;
460
461 if (perf_tool__process_synth_event(tool, event, machine, process) != 0) {
462 rc = -1;
463 break;
464 }
465
466 if (truncation)
467 break;
468 }
469
470 fclose(fp);
471 return rc;
472}
473
474int perf_event__synthesize_modules(struct perf_tool *tool,
475 perf_event__handler_t process,
476 struct machine *machine)
477{
478 int rc = 0;
479 struct map *pos;
480 struct maps *maps = machine__kernel_maps(machine);
481 union perf_event *event = zalloc((sizeof(event->mmap) +
482 machine->id_hdr_size));
483 if (event == NULL) {
484 pr_debug("Not enough memory synthesizing mmap event "
485 "for kernel modules\n");
486 return -1;
487 }
488
489 event->header.type = PERF_RECORD_MMAP;
490
491 /*
492 * kernel uses 0 for user space maps, see kernel/perf_event.c
493 * __perf_event_mmap
494 */
495 if (machine__is_host(machine))
496 event->header.misc = PERF_RECORD_MISC_KERNEL;
497 else
498 event->header.misc = PERF_RECORD_MISC_GUEST_KERNEL;
499
500 for (pos = maps__first(maps); pos; pos = map__next(pos)) {
501 size_t size;
502
503 if (!__map__is_kmodule(pos))
504 continue;
505
506 size = PERF_ALIGN(pos->dso->long_name_len + 1, sizeof(u64));
507 event->mmap.header.type = PERF_RECORD_MMAP;
508 event->mmap.header.size = (sizeof(event->mmap) -
509 (sizeof(event->mmap.filename) - size));
510 memset(event->mmap.filename + size, 0, machine->id_hdr_size);
511 event->mmap.header.size += machine->id_hdr_size;
512 event->mmap.start = pos->start;
513 event->mmap.len = pos->end - pos->start;
514 event->mmap.pid = machine->pid;
515
516 memcpy(event->mmap.filename, pos->dso->long_name,
517 pos->dso->long_name_len + 1);
518 if (perf_tool__process_synth_event(tool, event, machine, process) != 0) {
519 rc = -1;
520 break;
521 }
522 }
523
524 free(event);
525 return rc;
526}
527
528static int __event__synthesize_thread(union perf_event *comm_event,
529 union perf_event *mmap_event,
530 union perf_event *fork_event,
531 union perf_event *namespaces_event,
532 pid_t pid, int full,
533 perf_event__handler_t process,
534 struct perf_tool *tool,
535 struct machine *machine,
536 bool mmap_data)
537{
538 char filename[PATH_MAX];
539 DIR *tasks;
540 struct dirent *dirent;
541 pid_t tgid, ppid;
542 int rc = 0;
543
544 /* special case: only send one comm event using passed in pid */
545 if (!full) {
546 tgid = perf_event__synthesize_comm(tool, comm_event, pid,
547 process, machine);
548
549 if (tgid == -1)
550 return -1;
551
552 if (perf_event__synthesize_namespaces(tool, namespaces_event, pid,
553 tgid, process, machine) < 0)
554 return -1;
555
556 /*
557 * send mmap only for thread group leader
558 * see thread__init_map_groups
559 */
560 if (pid == tgid &&
561 perf_event__synthesize_mmap_events(tool, mmap_event, pid, tgid,
562 process, machine, mmap_data))
563 return -1;
564
565 return 0;
566 }
567
568 if (machine__is_default_guest(machine))
569 return 0;
570
571 snprintf(filename, sizeof(filename), "%s/proc/%d/task",
572 machine->root_dir, pid);
573
574 tasks = opendir(filename);
575 if (tasks == NULL) {
576 pr_debug("couldn't open %s\n", filename);
577 return 0;
578 }
579
580 while ((dirent = readdir(tasks)) != NULL) {
581 char *end;
582 pid_t _pid;
583
584 _pid = strtol(dirent->d_name, &end, 10);
585 if (*end)
586 continue;
587
588 rc = -1;
589 if (perf_event__prepare_comm(comm_event, _pid, machine,
590 &tgid, &ppid) != 0)
591 break;
592
593 if (perf_event__synthesize_fork(tool, fork_event, _pid, tgid,
594 ppid, process, machine) < 0)
595 break;
596
597 if (perf_event__synthesize_namespaces(tool, namespaces_event, _pid,
598 tgid, process, machine) < 0)
599 break;
600
601 /*
602 * Send the prepared comm event
603 */
604 if (perf_tool__process_synth_event(tool, comm_event, machine, process) != 0)
605 break;
606
607 rc = 0;
608 if (_pid == pid) {
609 /* process the parent's maps too */
610 rc = perf_event__synthesize_mmap_events(tool, mmap_event, pid, tgid,
611 process, machine, mmap_data);
612 if (rc)
613 break;
614 }
615 }
616
617 closedir(tasks);
618 return rc;
619}
620
621int perf_event__synthesize_thread_map(struct perf_tool *tool,
622 struct perf_thread_map *threads,
623 perf_event__handler_t process,
624 struct machine *machine,
625 bool mmap_data)
626{
627 union perf_event *comm_event, *mmap_event, *fork_event;
628 union perf_event *namespaces_event;
629 int err = -1, thread, j;
630
631 comm_event = malloc(sizeof(comm_event->comm) + machine->id_hdr_size);
632 if (comm_event == NULL)
633 goto out;
634
635 mmap_event = malloc(sizeof(mmap_event->mmap2) + machine->id_hdr_size);
636 if (mmap_event == NULL)
637 goto out_free_comm;
638
639 fork_event = malloc(sizeof(fork_event->fork) + machine->id_hdr_size);
640 if (fork_event == NULL)
641 goto out_free_mmap;
642
643 namespaces_event = malloc(sizeof(namespaces_event->namespaces) +
644 (NR_NAMESPACES * sizeof(struct perf_ns_link_info)) +
645 machine->id_hdr_size);
646 if (namespaces_event == NULL)
647 goto out_free_fork;
648
649 err = 0;
650 for (thread = 0; thread < threads->nr; ++thread) {
651 if (__event__synthesize_thread(comm_event, mmap_event,
652 fork_event, namespaces_event,
653 perf_thread_map__pid(threads, thread), 0,
654 process, tool, machine,
655 mmap_data)) {
656 err = -1;
657 break;
658 }
659
660 /*
661 * comm.pid is set to thread group id by
662 * perf_event__synthesize_comm
663 */
664 if ((int) comm_event->comm.pid != perf_thread_map__pid(threads, thread)) {
665 bool need_leader = true;
666
667 /* is thread group leader in thread_map? */
668 for (j = 0; j < threads->nr; ++j) {
669 if ((int) comm_event->comm.pid == perf_thread_map__pid(threads, j)) {
670 need_leader = false;
671 break;
672 }
673 }
674
675 /* if not, generate events for it */
676 if (need_leader &&
677 __event__synthesize_thread(comm_event, mmap_event,
678 fork_event, namespaces_event,
679 comm_event->comm.pid, 0,
680 process, tool, machine,
681 mmap_data)) {
682 err = -1;
683 break;
684 }
685 }
686 }
687 free(namespaces_event);
688out_free_fork:
689 free(fork_event);
690out_free_mmap:
691 free(mmap_event);
692out_free_comm:
693 free(comm_event);
694out:
695 return err;
696}
697
698static int __perf_event__synthesize_threads(struct perf_tool *tool,
699 perf_event__handler_t process,
700 struct machine *machine,
701 bool mmap_data,
702 struct dirent **dirent,
703 int start,
704 int num)
705{
706 union perf_event *comm_event, *mmap_event, *fork_event;
707 union perf_event *namespaces_event;
708 int err = -1;
709 char *end;
710 pid_t pid;
711 int i;
712
713 comm_event = malloc(sizeof(comm_event->comm) + machine->id_hdr_size);
714 if (comm_event == NULL)
715 goto out;
716
717 mmap_event = malloc(sizeof(mmap_event->mmap2) + machine->id_hdr_size);
718 if (mmap_event == NULL)
719 goto out_free_comm;
720
721 fork_event = malloc(sizeof(fork_event->fork) + machine->id_hdr_size);
722 if (fork_event == NULL)
723 goto out_free_mmap;
724
725 namespaces_event = malloc(sizeof(namespaces_event->namespaces) +
726 (NR_NAMESPACES * sizeof(struct perf_ns_link_info)) +
727 machine->id_hdr_size);
728 if (namespaces_event == NULL)
729 goto out_free_fork;
730
731 for (i = start; i < start + num; i++) {
732 if (!isdigit(dirent[i]->d_name[0]))
733 continue;
734
735 pid = (pid_t)strtol(dirent[i]->d_name, &end, 10);
736 /* only interested in proper numerical dirents */
737 if (*end)
738 continue;
739 /*
740 * We may race with exiting thread, so don't stop just because
741 * one thread couldn't be synthesized.
742 */
743 __event__synthesize_thread(comm_event, mmap_event, fork_event,
744 namespaces_event, pid, 1, process,
745 tool, machine, mmap_data);
746 }
747 err = 0;
748
749 free(namespaces_event);
750out_free_fork:
751 free(fork_event);
752out_free_mmap:
753 free(mmap_event);
754out_free_comm:
755 free(comm_event);
756out:
757 return err;
758}
759
760struct synthesize_threads_arg {
761 struct perf_tool *tool;
762 perf_event__handler_t process;
763 struct machine *machine;
764 bool mmap_data;
765 struct dirent **dirent;
766 int num;
767 int start;
768};
769
770static void *synthesize_threads_worker(void *arg)
771{
772 struct synthesize_threads_arg *args = arg;
773
774 __perf_event__synthesize_threads(args->tool, args->process,
775 args->machine, args->mmap_data,
776 args->dirent,
777 args->start, args->num);
778 return NULL;
779}
780
781int perf_event__synthesize_threads(struct perf_tool *tool,
782 perf_event__handler_t process,
783 struct machine *machine,
784 bool mmap_data,
785 unsigned int nr_threads_synthesize)
786{
787 struct synthesize_threads_arg *args = NULL;
788 pthread_t *synthesize_threads = NULL;
789 char proc_path[PATH_MAX];
790 struct dirent **dirent;
791 int num_per_thread;
792 int m, n, i, j;
793 int thread_nr;
794 int base = 0;
795 int err = -1;
796
797
798 if (machine__is_default_guest(machine))
799 return 0;
800
801 snprintf(proc_path, sizeof(proc_path), "%s/proc", machine->root_dir);
802 n = scandir(proc_path, &dirent, 0, alphasort);
803 if (n < 0)
804 return err;
805
806 if (nr_threads_synthesize == UINT_MAX)
807 thread_nr = sysconf(_SC_NPROCESSORS_ONLN);
808 else
809 thread_nr = nr_threads_synthesize;
810
811 if (thread_nr <= 1) {
812 err = __perf_event__synthesize_threads(tool, process,
813 machine, mmap_data,
814 dirent, base, n);
815 goto free_dirent;
816 }
817 if (thread_nr > n)
818 thread_nr = n;
819
820 synthesize_threads = calloc(sizeof(pthread_t), thread_nr);
821 if (synthesize_threads == NULL)
822 goto free_dirent;
823
824 args = calloc(sizeof(*args), thread_nr);
825 if (args == NULL)
826 goto free_threads;
827
828 num_per_thread = n / thread_nr;
829 m = n % thread_nr;
830 for (i = 0; i < thread_nr; i++) {
831 args[i].tool = tool;
832 args[i].process = process;
833 args[i].machine = machine;
834 args[i].mmap_data = mmap_data;
835 args[i].dirent = dirent;
836 }
837 for (i = 0; i < m; i++) {
838 args[i].num = num_per_thread + 1;
839 args[i].start = i * args[i].num;
840 }
841 if (i != 0)
842 base = args[i-1].start + args[i-1].num;
843 for (j = i; j < thread_nr; j++) {
844 args[j].num = num_per_thread;
845 args[j].start = base + (j - i) * args[i].num;
846 }
847
848 for (i = 0; i < thread_nr; i++) {
849 if (pthread_create(&synthesize_threads[i], NULL,
850 synthesize_threads_worker, &args[i]))
851 goto out_join;
852 }
853 err = 0;
854out_join:
855 for (i = 0; i < thread_nr; i++)
856 pthread_join(synthesize_threads[i], NULL);
857 free(args);
858free_threads:
859 free(synthesize_threads);
860free_dirent:
861 for (i = 0; i < n; i++)
862 zfree(&dirent[i]);
863 free(dirent);
864
865 return err;
866}
867
868struct process_symbol_args { 86struct process_symbol_args {
869 const char *name; 87 const char *name;
870 u64 start; 88 u64 start;
@@ -899,327 +117,6 @@ int kallsyms__get_function_start(const char *kallsyms_filename,
899 return 0; 117 return 0;
900} 118}
901 119
902int __weak perf_event__synthesize_extra_kmaps(struct perf_tool *tool __maybe_unused,
903 perf_event__handler_t process __maybe_unused,
904 struct machine *machine __maybe_unused)
905{
906 return 0;
907}
908
909static int __perf_event__synthesize_kernel_mmap(struct perf_tool *tool,
910 perf_event__handler_t process,
911 struct machine *machine)
912{
913 size_t size;
914 struct map *map = machine__kernel_map(machine);
915 struct kmap *kmap;
916 int err;
917 union perf_event *event;
918
919 if (map == NULL)
920 return -1;
921
922 kmap = map__kmap(map);
923 if (!kmap->ref_reloc_sym)
924 return -1;
925
926 /*
927 * We should get this from /sys/kernel/sections/.text, but till that is
928 * available use this, and after it is use this as a fallback for older
929 * kernels.
930 */
931 event = zalloc((sizeof(event->mmap) + machine->id_hdr_size));
932 if (event == NULL) {
933 pr_debug("Not enough memory synthesizing mmap event "
934 "for kernel modules\n");
935 return -1;
936 }
937
938 if (machine__is_host(machine)) {
939 /*
940 * kernel uses PERF_RECORD_MISC_USER for user space maps,
941 * see kernel/perf_event.c __perf_event_mmap
942 */
943 event->header.misc = PERF_RECORD_MISC_KERNEL;
944 } else {
945 event->header.misc = PERF_RECORD_MISC_GUEST_KERNEL;
946 }
947
948 size = snprintf(event->mmap.filename, sizeof(event->mmap.filename),
949 "%s%s", machine->mmap_name, kmap->ref_reloc_sym->name) + 1;
950 size = PERF_ALIGN(size, sizeof(u64));
951 event->mmap.header.type = PERF_RECORD_MMAP;
952 event->mmap.header.size = (sizeof(event->mmap) -
953 (sizeof(event->mmap.filename) - size) + machine->id_hdr_size);
954 event->mmap.pgoff = kmap->ref_reloc_sym->addr;
955 event->mmap.start = map->start;
956 event->mmap.len = map->end - event->mmap.start;
957 event->mmap.pid = machine->pid;
958
959 err = perf_tool__process_synth_event(tool, event, machine, process);
960 free(event);
961
962 return err;
963}
964
965int perf_event__synthesize_kernel_mmap(struct perf_tool *tool,
966 perf_event__handler_t process,
967 struct machine *machine)
968{
969 int err;
970
971 err = __perf_event__synthesize_kernel_mmap(tool, process, machine);
972 if (err < 0)
973 return err;
974
975 return perf_event__synthesize_extra_kmaps(tool, process, machine);
976}
977
978int perf_event__synthesize_thread_map2(struct perf_tool *tool,
979 struct perf_thread_map *threads,
980 perf_event__handler_t process,
981 struct machine *machine)
982{
983 union perf_event *event;
984 int i, err, size;
985
986 size = sizeof(event->thread_map);
987 size += threads->nr * sizeof(event->thread_map.entries[0]);
988
989 event = zalloc(size);
990 if (!event)
991 return -ENOMEM;
992
993 event->header.type = PERF_RECORD_THREAD_MAP;
994 event->header.size = size;
995 event->thread_map.nr = threads->nr;
996
997 for (i = 0; i < threads->nr; i++) {
998 struct perf_record_thread_map_entry *entry = &event->thread_map.entries[i];
999 char *comm = perf_thread_map__comm(threads, i);
1000
1001 if (!comm)
1002 comm = (char *) "";
1003
1004 entry->pid = perf_thread_map__pid(threads, i);
1005 strncpy((char *) &entry->comm, comm, sizeof(entry->comm));
1006 }
1007
1008 err = process(tool, event, NULL, machine);
1009
1010 free(event);
1011 return err;
1012}
1013
1014static void synthesize_cpus(struct cpu_map_entries *cpus,
1015 struct perf_cpu_map *map)
1016{
1017 int i;
1018
1019 cpus->nr = map->nr;
1020
1021 for (i = 0; i < map->nr; i++)
1022 cpus->cpu[i] = map->map[i];
1023}
1024
1025static void synthesize_mask(struct perf_record_record_cpu_map *mask,
1026 struct perf_cpu_map *map, int max)
1027{
1028 int i;
1029
1030 mask->nr = BITS_TO_LONGS(max);
1031 mask->long_size = sizeof(long);
1032
1033 for (i = 0; i < map->nr; i++)
1034 set_bit(map->map[i], mask->mask);
1035}
1036
1037static size_t cpus_size(struct perf_cpu_map *map)
1038{
1039 return sizeof(struct cpu_map_entries) + map->nr * sizeof(u16);
1040}
1041
1042static size_t mask_size(struct perf_cpu_map *map, int *max)
1043{
1044 int i;
1045
1046 *max = 0;
1047
1048 for (i = 0; i < map->nr; i++) {
1049 /* bit possition of the cpu is + 1 */
1050 int bit = map->map[i] + 1;
1051
1052 if (bit > *max)
1053 *max = bit;
1054 }
1055
1056 return sizeof(struct perf_record_record_cpu_map) + BITS_TO_LONGS(*max) * sizeof(long);
1057}
1058
1059void *cpu_map_data__alloc(struct perf_cpu_map *map, size_t *size, u16 *type, int *max)
1060{
1061 size_t size_cpus, size_mask;
1062 bool is_dummy = perf_cpu_map__empty(map);
1063
1064 /*
1065 * Both array and mask data have variable size based
1066 * on the number of cpus and their actual values.
1067 * The size of the 'struct perf_record_cpu_map_data' is:
1068 *
1069 * array = size of 'struct cpu_map_entries' +
1070 * number of cpus * sizeof(u64)
1071 *
1072 * mask = size of 'struct perf_record_record_cpu_map' +
1073 * maximum cpu bit converted to size of longs
1074 *
1075 * and finaly + the size of 'struct perf_record_cpu_map_data'.
1076 */
1077 size_cpus = cpus_size(map);
1078 size_mask = mask_size(map, max);
1079
1080 if (is_dummy || (size_cpus < size_mask)) {
1081 *size += size_cpus;
1082 *type = PERF_CPU_MAP__CPUS;
1083 } else {
1084 *size += size_mask;
1085 *type = PERF_CPU_MAP__MASK;
1086 }
1087
1088 *size += sizeof(struct perf_record_cpu_map_data);
1089 *size = PERF_ALIGN(*size, sizeof(u64));
1090 return zalloc(*size);
1091}
1092
1093void cpu_map_data__synthesize(struct perf_record_cpu_map_data *data, struct perf_cpu_map *map,
1094 u16 type, int max)
1095{
1096 data->type = type;
1097
1098 switch (type) {
1099 case PERF_CPU_MAP__CPUS:
1100 synthesize_cpus((struct cpu_map_entries *) data->data, map);
1101 break;
1102 case PERF_CPU_MAP__MASK:
1103 synthesize_mask((struct perf_record_record_cpu_map *)data->data, map, max);
1104 default:
1105 break;
1106 };
1107}
1108
1109static struct perf_record_cpu_map *cpu_map_event__new(struct perf_cpu_map *map)
1110{
1111 size_t size = sizeof(struct perf_record_cpu_map);
1112 struct perf_record_cpu_map *event;
1113 int max;
1114 u16 type;
1115
1116 event = cpu_map_data__alloc(map, &size, &type, &max);
1117 if (!event)
1118 return NULL;
1119
1120 event->header.type = PERF_RECORD_CPU_MAP;
1121 event->header.size = size;
1122 event->data.type = type;
1123
1124 cpu_map_data__synthesize(&event->data, map, type, max);
1125 return event;
1126}
1127
1128int perf_event__synthesize_cpu_map(struct perf_tool *tool,
1129 struct perf_cpu_map *map,
1130 perf_event__handler_t process,
1131 struct machine *machine)
1132{
1133 struct perf_record_cpu_map *event;
1134 int err;
1135
1136 event = cpu_map_event__new(map);
1137 if (!event)
1138 return -ENOMEM;
1139
1140 err = process(tool, (union perf_event *) event, NULL, machine);
1141
1142 free(event);
1143 return err;
1144}
1145
1146int perf_event__synthesize_stat_config(struct perf_tool *tool,
1147 struct perf_stat_config *config,
1148 perf_event__handler_t process,
1149 struct machine *machine)
1150{
1151 struct perf_record_stat_config *event;
1152 int size, i = 0, err;
1153
1154 size = sizeof(*event);
1155 size += (PERF_STAT_CONFIG_TERM__MAX * sizeof(event->data[0]));
1156
1157 event = zalloc(size);
1158 if (!event)
1159 return -ENOMEM;
1160
1161 event->header.type = PERF_RECORD_STAT_CONFIG;
1162 event->header.size = size;
1163 event->nr = PERF_STAT_CONFIG_TERM__MAX;
1164
1165#define ADD(__term, __val) \
1166 event->data[i].tag = PERF_STAT_CONFIG_TERM__##__term; \
1167 event->data[i].val = __val; \
1168 i++;
1169
1170 ADD(AGGR_MODE, config->aggr_mode)
1171 ADD(INTERVAL, config->interval)
1172 ADD(SCALE, config->scale)
1173
1174 WARN_ONCE(i != PERF_STAT_CONFIG_TERM__MAX,
1175 "stat config terms unbalanced\n");
1176#undef ADD
1177
1178 err = process(tool, (union perf_event *) event, NULL, machine);
1179
1180 free(event);
1181 return err;
1182}
1183
1184int perf_event__synthesize_stat(struct perf_tool *tool,
1185 u32 cpu, u32 thread, u64 id,
1186 struct perf_counts_values *count,
1187 perf_event__handler_t process,
1188 struct machine *machine)
1189{
1190 struct perf_record_stat event;
1191
1192 event.header.type = PERF_RECORD_STAT;
1193 event.header.size = sizeof(event);
1194 event.header.misc = 0;
1195
1196 event.id = id;
1197 event.cpu = cpu;
1198 event.thread = thread;
1199 event.val = count->val;
1200 event.ena = count->ena;
1201 event.run = count->run;
1202
1203 return process(tool, (union perf_event *) &event, NULL, machine);
1204}
1205
1206int perf_event__synthesize_stat_round(struct perf_tool *tool,
1207 u64 evtime, u64 type,
1208 perf_event__handler_t process,
1209 struct machine *machine)
1210{
1211 struct perf_record_stat_round event;
1212
1213 event.header.type = PERF_RECORD_STAT_ROUND;
1214 event.header.size = sizeof(event);
1215 event.header.misc = 0;
1216
1217 event.time = evtime;
1218 event.type = type;
1219
1220 return process(tool, (union perf_event *) &event, NULL, machine);
1221}
1222
1223void perf_event__read_stat_config(struct perf_stat_config *config, 120void perf_event__read_stat_config(struct perf_stat_config *config,
1224 struct perf_record_stat_config *event) 121 struct perf_record_stat_config *event)
1225{ 122{
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index 47ad81d47b1a..a0a0c91cde4a 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -279,54 +279,13 @@ enum {
279 279
280void perf_event__print_totals(void); 280void perf_event__print_totals(void);
281 281
282struct perf_tool;
283struct perf_thread_map;
284struct perf_cpu_map; 282struct perf_cpu_map;
283struct perf_record_stat_config;
285struct perf_stat_config; 284struct perf_stat_config;
286struct perf_counts_values; 285struct perf_tool;
287
288typedef int (*perf_event__handler_t)(struct perf_tool *tool,
289 union perf_event *event,
290 struct perf_sample *sample,
291 struct machine *machine);
292 286
293int perf_event__synthesize_thread_map(struct perf_tool *tool,
294 struct perf_thread_map *threads,
295 perf_event__handler_t process,
296 struct machine *machine, bool mmap_data);
297int perf_event__synthesize_thread_map2(struct perf_tool *tool,
298 struct perf_thread_map *threads,
299 perf_event__handler_t process,
300 struct machine *machine);
301int perf_event__synthesize_cpu_map(struct perf_tool *tool,
302 struct perf_cpu_map *cpus,
303 perf_event__handler_t process,
304 struct machine *machine);
305int perf_event__synthesize_threads(struct perf_tool *tool,
306 perf_event__handler_t process,
307 struct machine *machine, bool mmap_data,
308 unsigned int nr_threads_synthesize);
309int perf_event__synthesize_kernel_mmap(struct perf_tool *tool,
310 perf_event__handler_t process,
311 struct machine *machine);
312int perf_event__synthesize_stat_config(struct perf_tool *tool,
313 struct perf_stat_config *config,
314 perf_event__handler_t process,
315 struct machine *machine);
316void perf_event__read_stat_config(struct perf_stat_config *config, 287void perf_event__read_stat_config(struct perf_stat_config *config,
317 struct perf_record_stat_config *event); 288 struct perf_record_stat_config *event);
318int perf_event__synthesize_stat(struct perf_tool *tool,
319 u32 cpu, u32 thread, u64 id,
320 struct perf_counts_values *count,
321 perf_event__handler_t process,
322 struct machine *machine);
323int perf_event__synthesize_stat_round(struct perf_tool *tool,
324 u64 time, u64 type,
325 perf_event__handler_t process,
326 struct machine *machine);
327int perf_event__synthesize_modules(struct perf_tool *tool,
328 perf_event__handler_t process,
329 struct machine *machine);
330 289
331int perf_event__process_comm(struct perf_tool *tool, 290int perf_event__process_comm(struct perf_tool *tool,
332 union perf_event *event, 291 union perf_event *event,
@@ -380,10 +339,6 @@ int perf_event__process_bpf(struct perf_tool *tool,
380 union perf_event *event, 339 union perf_event *event,
381 struct perf_sample *sample, 340 struct perf_sample *sample,
382 struct machine *machine); 341 struct machine *machine);
383int perf_tool__process_synth_event(struct perf_tool *tool,
384 union perf_event *event,
385 struct machine *machine,
386 perf_event__handler_t process);
387int perf_event__process(struct perf_tool *tool, 342int perf_event__process(struct perf_tool *tool,
388 union perf_event *event, 343 union perf_event *event,
389 struct perf_sample *sample, 344 struct perf_sample *sample,
@@ -405,34 +360,6 @@ void thread__resolve(struct thread *thread, struct addr_location *al,
405 360
406const char *perf_event__name(unsigned int id); 361const char *perf_event__name(unsigned int id);
407 362
408size_t perf_event__sample_event_size(const struct perf_sample *sample, u64 type,
409 u64 read_format);
410int perf_event__synthesize_sample(union perf_event *event, u64 type,
411 u64 read_format,
412 const struct perf_sample *sample);
413
414pid_t perf_event__synthesize_comm(struct perf_tool *tool,
415 union perf_event *event, pid_t pid,
416 perf_event__handler_t process,
417 struct machine *machine);
418
419int perf_event__synthesize_namespaces(struct perf_tool *tool,
420 union perf_event *event,
421 pid_t pid, pid_t tgid,
422 perf_event__handler_t process,
423 struct machine *machine);
424
425int perf_event__synthesize_mmap_events(struct perf_tool *tool,
426 union perf_event *event,
427 pid_t pid, pid_t tgid,
428 perf_event__handler_t process,
429 struct machine *machine,
430 bool mmap_data);
431
432int perf_event__synthesize_extra_kmaps(struct perf_tool *tool,
433 perf_event__handler_t process,
434 struct machine *machine);
435
436size_t perf_event__fprintf_comm(union perf_event *event, FILE *fp); 363size_t perf_event__fprintf_comm(union perf_event *event, FILE *fp);
437size_t perf_event__fprintf_mmap(union perf_event *event, FILE *fp); 364size_t perf_event__fprintf_mmap(union perf_event *event, FILE *fp);
438size_t perf_event__fprintf_mmap2(union perf_event *event, FILE *fp); 365size_t perf_event__fprintf_mmap2(union perf_event *event, FILE *fp);
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 095924aa186b..ea9517d506d8 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -16,7 +16,7 @@
16#include "evsel.h" 16#include "evsel.h"
17#include "debug.h" 17#include "debug.h"
18#include "units.h" 18#include "units.h"
19#include "util.h" 19#include "util.h" // page_size
20#include "../perf.h" 20#include "../perf.h"
21#include "asm/bug.h" 21#include "asm/bug.h"
22#include "bpf-event.h" 22#include "bpf-event.h"
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 85825384f9e8..8e335d168503 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -31,7 +31,7 @@
31#include "event.h" 31#include "event.h"
32#include "evsel.h" 32#include "evsel.h"
33#include "evlist.h" 33#include "evlist.h"
34#include "cpumap.h" 34#include <perf/cpumap.h>
35#include "thread_map.h" 35#include "thread_map.h"
36#include "target.h" 36#include "target.h"
37#include "perf_regs.h" 37#include "perf_regs.h"
@@ -45,6 +45,7 @@
45#include "../perf-sys.h" 45#include "../perf-sys.h"
46#include "util/parse-branch-options.h" 46#include "util/parse-branch-options.h"
47#include <internal/xyarray.h> 47#include <internal/xyarray.h>
48#include <internal/lib.h>
48 49
49#include <linux/ctype.h> 50#include <linux/ctype.h>
50 51
@@ -2419,283 +2420,6 @@ int perf_evsel__parse_sample_timestamp(struct evsel *evsel,
2419 return 0; 2420 return 0;
2420} 2421}
2421 2422
2422size_t perf_event__sample_event_size(const struct perf_sample *sample, u64 type,
2423 u64 read_format)
2424{
2425 size_t sz, result = sizeof(struct perf_record_sample);
2426
2427 if (type & PERF_SAMPLE_IDENTIFIER)
2428 result += sizeof(u64);
2429
2430 if (type & PERF_SAMPLE_IP)
2431 result += sizeof(u64);
2432
2433 if (type & PERF_SAMPLE_TID)
2434 result += sizeof(u64);
2435
2436 if (type & PERF_SAMPLE_TIME)
2437 result += sizeof(u64);
2438
2439 if (type & PERF_SAMPLE_ADDR)
2440 result += sizeof(u64);
2441
2442 if (type & PERF_SAMPLE_ID)
2443 result += sizeof(u64);
2444
2445 if (type & PERF_SAMPLE_STREAM_ID)
2446 result += sizeof(u64);
2447
2448 if (type & PERF_SAMPLE_CPU)
2449 result += sizeof(u64);
2450
2451 if (type & PERF_SAMPLE_PERIOD)
2452 result += sizeof(u64);
2453
2454 if (type & PERF_SAMPLE_READ) {
2455 result += sizeof(u64);
2456 if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
2457 result += sizeof(u64);
2458 if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
2459 result += sizeof(u64);
2460 /* PERF_FORMAT_ID is forced for PERF_SAMPLE_READ */
2461 if (read_format & PERF_FORMAT_GROUP) {
2462 sz = sample->read.group.nr *
2463 sizeof(struct sample_read_value);
2464 result += sz;
2465 } else {
2466 result += sizeof(u64);
2467 }
2468 }
2469
2470 if (type & PERF_SAMPLE_CALLCHAIN) {
2471 sz = (sample->callchain->nr + 1) * sizeof(u64);
2472 result += sz;
2473 }
2474
2475 if (type & PERF_SAMPLE_RAW) {
2476 result += sizeof(u32);
2477 result += sample->raw_size;
2478 }
2479
2480 if (type & PERF_SAMPLE_BRANCH_STACK) {
2481 sz = sample->branch_stack->nr * sizeof(struct branch_entry);
2482 sz += sizeof(u64);
2483 result += sz;
2484 }
2485
2486 if (type & PERF_SAMPLE_REGS_USER) {
2487 if (sample->user_regs.abi) {
2488 result += sizeof(u64);
2489 sz = hweight64(sample->user_regs.mask) * sizeof(u64);
2490 result += sz;
2491 } else {
2492 result += sizeof(u64);
2493 }
2494 }
2495
2496 if (type & PERF_SAMPLE_STACK_USER) {
2497 sz = sample->user_stack.size;
2498 result += sizeof(u64);
2499 if (sz) {
2500 result += sz;
2501 result += sizeof(u64);
2502 }
2503 }
2504
2505 if (type & PERF_SAMPLE_WEIGHT)
2506 result += sizeof(u64);
2507
2508 if (type & PERF_SAMPLE_DATA_SRC)
2509 result += sizeof(u64);
2510
2511 if (type & PERF_SAMPLE_TRANSACTION)
2512 result += sizeof(u64);
2513
2514 if (type & PERF_SAMPLE_REGS_INTR) {
2515 if (sample->intr_regs.abi) {
2516 result += sizeof(u64);
2517 sz = hweight64(sample->intr_regs.mask) * sizeof(u64);
2518 result += sz;
2519 } else {
2520 result += sizeof(u64);
2521 }
2522 }
2523
2524 if (type & PERF_SAMPLE_PHYS_ADDR)
2525 result += sizeof(u64);
2526
2527 return result;
2528}
2529
2530int perf_event__synthesize_sample(union perf_event *event, u64 type,
2531 u64 read_format,
2532 const struct perf_sample *sample)
2533{
2534 __u64 *array;
2535 size_t sz;
2536 /*
2537 * used for cross-endian analysis. See git commit 65014ab3
2538 * for why this goofiness is needed.
2539 */
2540 union u64_swap u;
2541
2542 array = event->sample.array;
2543
2544 if (type & PERF_SAMPLE_IDENTIFIER) {
2545 *array = sample->id;
2546 array++;
2547 }
2548
2549 if (type & PERF_SAMPLE_IP) {
2550 *array = sample->ip;
2551 array++;
2552 }
2553
2554 if (type & PERF_SAMPLE_TID) {
2555 u.val32[0] = sample->pid;
2556 u.val32[1] = sample->tid;
2557 *array = u.val64;
2558 array++;
2559 }
2560
2561 if (type & PERF_SAMPLE_TIME) {
2562 *array = sample->time;
2563 array++;
2564 }
2565
2566 if (type & PERF_SAMPLE_ADDR) {
2567 *array = sample->addr;
2568 array++;
2569 }
2570
2571 if (type & PERF_SAMPLE_ID) {
2572 *array = sample->id;
2573 array++;
2574 }
2575
2576 if (type & PERF_SAMPLE_STREAM_ID) {
2577 *array = sample->stream_id;
2578 array++;
2579 }
2580
2581 if (type & PERF_SAMPLE_CPU) {
2582 u.val32[0] = sample->cpu;
2583 u.val32[1] = 0;
2584 *array = u.val64;
2585 array++;
2586 }
2587
2588 if (type & PERF_SAMPLE_PERIOD) {
2589 *array = sample->period;
2590 array++;
2591 }
2592
2593 if (type & PERF_SAMPLE_READ) {
2594 if (read_format & PERF_FORMAT_GROUP)
2595 *array = sample->read.group.nr;
2596 else
2597 *array = sample->read.one.value;
2598 array++;
2599
2600 if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) {
2601 *array = sample->read.time_enabled;
2602 array++;
2603 }
2604
2605 if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) {
2606 *array = sample->read.time_running;
2607 array++;
2608 }
2609
2610 /* PERF_FORMAT_ID is forced for PERF_SAMPLE_READ */
2611 if (read_format & PERF_FORMAT_GROUP) {
2612 sz = sample->read.group.nr *
2613 sizeof(struct sample_read_value);
2614 memcpy(array, sample->read.group.values, sz);
2615 array = (void *)array + sz;
2616 } else {
2617 *array = sample->read.one.id;
2618 array++;
2619 }
2620 }
2621
2622 if (type & PERF_SAMPLE_CALLCHAIN) {
2623 sz = (sample->callchain->nr + 1) * sizeof(u64);
2624 memcpy(array, sample->callchain, sz);
2625 array = (void *)array + sz;
2626 }
2627
2628 if (type & PERF_SAMPLE_RAW) {
2629 u.val32[0] = sample->raw_size;
2630 *array = u.val64;
2631 array = (void *)array + sizeof(u32);
2632
2633 memcpy(array, sample->raw_data, sample->raw_size);
2634 array = (void *)array + sample->raw_size;
2635 }
2636
2637 if (type & PERF_SAMPLE_BRANCH_STACK) {
2638 sz = sample->branch_stack->nr * sizeof(struct branch_entry);
2639 sz += sizeof(u64);
2640 memcpy(array, sample->branch_stack, sz);
2641 array = (void *)array + sz;
2642 }
2643
2644 if (type & PERF_SAMPLE_REGS_USER) {
2645 if (sample->user_regs.abi) {
2646 *array++ = sample->user_regs.abi;
2647 sz = hweight64(sample->user_regs.mask) * sizeof(u64);
2648 memcpy(array, sample->user_regs.regs, sz);
2649 array = (void *)array + sz;
2650 } else {
2651 *array++ = 0;
2652 }
2653 }
2654
2655 if (type & PERF_SAMPLE_STACK_USER) {
2656 sz = sample->user_stack.size;
2657 *array++ = sz;
2658 if (sz) {
2659 memcpy(array, sample->user_stack.data, sz);
2660 array = (void *)array + sz;
2661 *array++ = sz;
2662 }
2663 }
2664
2665 if (type & PERF_SAMPLE_WEIGHT) {
2666 *array = sample->weight;
2667 array++;
2668 }
2669
2670 if (type & PERF_SAMPLE_DATA_SRC) {
2671 *array = sample->data_src;
2672 array++;
2673 }
2674
2675 if (type & PERF_SAMPLE_TRANSACTION) {
2676 *array = sample->transaction;
2677 array++;
2678 }
2679
2680 if (type & PERF_SAMPLE_REGS_INTR) {
2681 if (sample->intr_regs.abi) {
2682 *array++ = sample->intr_regs.abi;
2683 sz = hweight64(sample->intr_regs.mask) * sizeof(u64);
2684 memcpy(array, sample->intr_regs.regs, sz);
2685 array = (void *)array + sz;
2686 } else {
2687 *array++ = 0;
2688 }
2689 }
2690
2691 if (type & PERF_SAMPLE_PHYS_ADDR) {
2692 *array = sample->phys_addr;
2693 array++;
2694 }
2695
2696 return 0;
2697}
2698
2699struct tep_format_field *perf_evsel__field(struct evsel *evsel, const char *name) 2423struct tep_format_field *perf_evsel__field(struct evsel *evsel, const char *name)
2700{ 2424{
2701 return tep_find_field(evsel->tp_format, name); 2425 return tep_find_field(evsel->tp_format, name);
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 68321d10eb2d..74df298acb31 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -179,11 +179,6 @@ struct evsel {
179 } side_band; 179 } side_band;
180}; 180};
181 181
182union u64_swap {
183 u64 val64;
184 u32 val32[2];
185};
186
187struct perf_missing_features { 182struct perf_missing_features {
188 bool sample_id_all; 183 bool sample_id_all;
189 bool exclude_guest; 184 bool exclude_guest;
diff --git a/tools/perf/util/evsel_fprintf.c b/tools/perf/util/evsel_fprintf.c
index 496fec01f5d1..a8cbdf4c2753 100644
--- a/tools/perf/util/evsel_fprintf.c
+++ b/tools/perf/util/evsel_fprintf.c
@@ -4,6 +4,7 @@
4#include <stdbool.h> 4#include <stdbool.h>
5#include <traceevent/event-parse.h> 5#include <traceevent/event-parse.h>
6#include "evsel.h" 6#include "evsel.h"
7#include "util/event.h"
7#include "callchain.h" 8#include "callchain.h"
8#include "map.h" 9#include "map.h"
9#include "strlist.h" 10#include "strlist.h"
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index b0c34dda30a0..5722ff717777 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -42,11 +42,12 @@
42#include "tool.h" 42#include "tool.h"
43#include "time-utils.h" 43#include "time-utils.h"
44#include "units.h" 44#include "units.h"
45#include "util.h" 45#include "util.h" // page_size, perf_exe()
46#include "cputopo.h" 46#include "cputopo.h"
47#include "bpf-event.h" 47#include "bpf-event.h"
48 48
49#include <linux/ctype.h> 49#include <linux/ctype.h>
50#include <internal/lib.h>
50 51
51/* 52/*
52 * magic2 = "PERFILE2" 53 * magic2 = "PERFILE2"
@@ -70,15 +71,6 @@ struct perf_file_attr {
70 struct perf_file_section ids; 71 struct perf_file_section ids;
71}; 72};
72 73
73struct feat_fd {
74 struct perf_header *ph;
75 int fd;
76 void *buf; /* Either buf != NULL or fd >= 0 */
77 ssize_t offset;
78 size_t size;
79 struct evsel *events;
80};
81
82void perf_header__set_feat(struct perf_header *header, int feat) 74void perf_header__set_feat(struct perf_header *header, int feat)
83{ 75{
84 set_bit(feat, header->adds_features); 76 set_bit(feat, header->adds_features);
@@ -2823,15 +2815,6 @@ static int process_compressed(struct feat_fd *ff,
2823 return 0; 2815 return 0;
2824} 2816}
2825 2817
2826struct feature_ops {
2827 int (*write)(struct feat_fd *ff, struct evlist *evlist);
2828 void (*print)(struct feat_fd *ff, FILE *fp);
2829 int (*process)(struct feat_fd *ff, void *data);
2830 const char *name;
2831 bool full_only;
2832 bool synthesize;
2833};
2834
2835#define FEAT_OPR(n, func, __full_only) \ 2818#define FEAT_OPR(n, func, __full_only) \
2836 [HEADER_##n] = { \ 2819 [HEADER_##n] = { \
2837 .name = __stringify(n), \ 2820 .name = __stringify(n), \
@@ -2858,8 +2841,10 @@ struct feature_ops {
2858#define process_branch_stack NULL 2841#define process_branch_stack NULL
2859#define process_stat NULL 2842#define process_stat NULL
2860 2843
2844// Only used in util/synthetic-events.c
2845const struct perf_header_feature_ops feat_ops[HEADER_LAST_FEATURE];
2861 2846
2862static const struct feature_ops feat_ops[HEADER_LAST_FEATURE] = { 2847const struct perf_header_feature_ops feat_ops[HEADER_LAST_FEATURE] = {
2863 FEAT_OPN(TRACING_DATA, tracing_data, false), 2848 FEAT_OPN(TRACING_DATA, tracing_data, false),
2864 FEAT_OPN(BUILD_ID, build_id, false), 2849 FEAT_OPN(BUILD_ID, build_id, false),
2865 FEAT_OPR(HOSTNAME, hostname, false), 2850 FEAT_OPR(HOSTNAME, hostname, false),
@@ -3656,105 +3641,6 @@ out_delete_evlist:
3656 return -ENOMEM; 3641 return -ENOMEM;
3657} 3642}
3658 3643
3659int perf_event__synthesize_attr(struct perf_tool *tool,
3660 struct perf_event_attr *attr, u32 ids, u64 *id,
3661 perf_event__handler_t process)
3662{
3663 union perf_event *ev;
3664 size_t size;
3665 int err;
3666
3667 size = sizeof(struct perf_event_attr);
3668 size = PERF_ALIGN(size, sizeof(u64));
3669 size += sizeof(struct perf_event_header);
3670 size += ids * sizeof(u64);
3671
3672 ev = zalloc(size);
3673
3674 if (ev == NULL)
3675 return -ENOMEM;
3676
3677 ev->attr.attr = *attr;
3678 memcpy(ev->attr.id, id, ids * sizeof(u64));
3679
3680 ev->attr.header.type = PERF_RECORD_HEADER_ATTR;
3681 ev->attr.header.size = (u16)size;
3682
3683 if (ev->attr.header.size == size)
3684 err = process(tool, ev, NULL, NULL);
3685 else
3686 err = -E2BIG;
3687
3688 free(ev);
3689
3690 return err;
3691}
3692
3693int perf_event__synthesize_features(struct perf_tool *tool,
3694 struct perf_session *session,
3695 struct evlist *evlist,
3696 perf_event__handler_t process)
3697{
3698 struct perf_header *header = &session->header;
3699 struct feat_fd ff;
3700 struct perf_record_header_feature *fe;
3701 size_t sz, sz_hdr;
3702 int feat, ret;
3703
3704 sz_hdr = sizeof(fe->header);
3705 sz = sizeof(union perf_event);
3706 /* get a nice alignment */
3707 sz = PERF_ALIGN(sz, page_size);
3708
3709 memset(&ff, 0, sizeof(ff));
3710
3711 ff.buf = malloc(sz);
3712 if (!ff.buf)
3713 return -ENOMEM;
3714
3715 ff.size = sz - sz_hdr;
3716 ff.ph = &session->header;
3717
3718 for_each_set_bit(feat, header->adds_features, HEADER_FEAT_BITS) {
3719 if (!feat_ops[feat].synthesize) {
3720 pr_debug("No record header feature for header :%d\n", feat);
3721 continue;
3722 }
3723
3724 ff.offset = sizeof(*fe);
3725
3726 ret = feat_ops[feat].write(&ff, evlist);
3727 if (ret || ff.offset <= (ssize_t)sizeof(*fe)) {
3728 pr_debug("Error writing feature\n");
3729 continue;
3730 }
3731 /* ff.buf may have changed due to realloc in do_write() */
3732 fe = ff.buf;
3733 memset(fe, 0, sizeof(*fe));
3734
3735 fe->feat_id = feat;
3736 fe->header.type = PERF_RECORD_HEADER_FEATURE;
3737 fe->header.size = ff.offset;
3738
3739 ret = process(tool, ff.buf, NULL, NULL);
3740 if (ret) {
3741 free(ff.buf);
3742 return ret;
3743 }
3744 }
3745
3746 /* Send HEADER_LAST_FEATURE mark. */
3747 fe = ff.buf;
3748 fe->feat_id = HEADER_LAST_FEATURE;
3749 fe->header.type = PERF_RECORD_HEADER_FEATURE;
3750 fe->header.size = sizeof(*fe);
3751
3752 ret = process(tool, ff.buf, NULL, NULL);
3753
3754 free(ff.buf);
3755 return ret;
3756}
3757
3758int perf_event__process_feature(struct perf_session *session, 3644int perf_event__process_feature(struct perf_session *session,
3759 union perf_event *event) 3645 union perf_event *event)
3760{ 3646{
@@ -3797,113 +3683,6 @@ int perf_event__process_feature(struct perf_session *session,
3797 return 0; 3683 return 0;
3798} 3684}
3799 3685
3800static struct perf_record_event_update *
3801event_update_event__new(size_t size, u64 type, u64 id)
3802{
3803 struct perf_record_event_update *ev;
3804
3805 size += sizeof(*ev);
3806 size = PERF_ALIGN(size, sizeof(u64));
3807
3808 ev = zalloc(size);
3809 if (ev) {
3810 ev->header.type = PERF_RECORD_EVENT_UPDATE;
3811 ev->header.size = (u16)size;
3812 ev->type = type;
3813 ev->id = id;
3814 }
3815 return ev;
3816}
3817
3818int
3819perf_event__synthesize_event_update_unit(struct perf_tool *tool,
3820 struct evsel *evsel,
3821 perf_event__handler_t process)
3822{
3823 struct perf_record_event_update *ev;
3824 size_t size = strlen(evsel->unit);
3825 int err;
3826
3827 ev = event_update_event__new(size + 1, PERF_EVENT_UPDATE__UNIT, evsel->id[0]);
3828 if (ev == NULL)
3829 return -ENOMEM;
3830
3831 strlcpy(ev->data, evsel->unit, size + 1);
3832 err = process(tool, (union perf_event *)ev, NULL, NULL);
3833 free(ev);
3834 return err;
3835}
3836
3837int
3838perf_event__synthesize_event_update_scale(struct perf_tool *tool,
3839 struct evsel *evsel,
3840 perf_event__handler_t process)
3841{
3842 struct perf_record_event_update *ev;
3843 struct perf_record_event_update_scale *ev_data;
3844 int err;
3845
3846 ev = event_update_event__new(sizeof(*ev_data), PERF_EVENT_UPDATE__SCALE, evsel->id[0]);
3847 if (ev == NULL)
3848 return -ENOMEM;
3849
3850 ev_data = (struct perf_record_event_update_scale *)ev->data;
3851 ev_data->scale = evsel->scale;
3852 err = process(tool, (union perf_event*) ev, NULL, NULL);
3853 free(ev);
3854 return err;
3855}
3856
3857int
3858perf_event__synthesize_event_update_name(struct perf_tool *tool,
3859 struct evsel *evsel,
3860 perf_event__handler_t process)
3861{
3862 struct perf_record_event_update *ev;
3863 size_t len = strlen(evsel->name);
3864 int err;
3865
3866 ev = event_update_event__new(len + 1, PERF_EVENT_UPDATE__NAME, evsel->id[0]);
3867 if (ev == NULL)
3868 return -ENOMEM;
3869
3870 strlcpy(ev->data, evsel->name, len + 1);
3871 err = process(tool, (union perf_event*) ev, NULL, NULL);
3872 free(ev);
3873 return err;
3874}
3875
3876int
3877perf_event__synthesize_event_update_cpus(struct perf_tool *tool,
3878 struct evsel *evsel,
3879 perf_event__handler_t process)
3880{
3881 size_t size = sizeof(struct perf_record_event_update);
3882 struct perf_record_event_update *ev;
3883 int max, err;
3884 u16 type;
3885
3886 if (!evsel->core.own_cpus)
3887 return 0;
3888
3889 ev = cpu_map_data__alloc(evsel->core.own_cpus, &size, &type, &max);
3890 if (!ev)
3891 return -ENOMEM;
3892
3893 ev->header.type = PERF_RECORD_EVENT_UPDATE;
3894 ev->header.size = (u16)size;
3895 ev->type = PERF_EVENT_UPDATE__CPUS;
3896 ev->id = evsel->id[0];
3897
3898 cpu_map_data__synthesize((struct perf_record_cpu_map_data *)ev->data,
3899 evsel->core.own_cpus,
3900 type, max);
3901
3902 err = process(tool, (union perf_event*) ev, NULL, NULL);
3903 free(ev);
3904 return err;
3905}
3906
3907size_t perf_event__fprintf_event_update(union perf_event *event, FILE *fp) 3686size_t perf_event__fprintf_event_update(union perf_event *event, FILE *fp)
3908{ 3687{
3909 struct perf_record_event_update *ev = &event->event_update; 3688 struct perf_record_event_update *ev = &event->event_update;
@@ -3943,93 +3722,6 @@ size_t perf_event__fprintf_event_update(union perf_event *event, FILE *fp)
3943 return ret; 3722 return ret;
3944} 3723}
3945 3724
3946int perf_event__synthesize_attrs(struct perf_tool *tool,
3947 struct evlist *evlist,
3948 perf_event__handler_t process)
3949{
3950 struct evsel *evsel;
3951 int err = 0;
3952
3953 evlist__for_each_entry(evlist, evsel) {
3954 err = perf_event__synthesize_attr(tool, &evsel->core.attr, evsel->ids,
3955 evsel->id, process);
3956 if (err) {
3957 pr_debug("failed to create perf header attribute\n");
3958 return err;
3959 }
3960 }
3961
3962 return err;
3963}
3964
3965static bool has_unit(struct evsel *counter)
3966{
3967 return counter->unit && *counter->unit;
3968}
3969
3970static bool has_scale(struct evsel *counter)
3971{
3972 return counter->scale != 1;
3973}
3974
3975int perf_event__synthesize_extra_attr(struct perf_tool *tool,
3976 struct evlist *evsel_list,
3977 perf_event__handler_t process,
3978 bool is_pipe)
3979{
3980 struct evsel *counter;
3981 int err;
3982
3983 /*
3984 * Synthesize other events stuff not carried within
3985 * attr event - unit, scale, name
3986 */
3987 evlist__for_each_entry(evsel_list, counter) {
3988 if (!counter->supported)
3989 continue;
3990
3991 /*
3992 * Synthesize unit and scale only if it's defined.
3993 */
3994 if (has_unit(counter)) {
3995 err = perf_event__synthesize_event_update_unit(tool, counter, process);
3996 if (err < 0) {
3997 pr_err("Couldn't synthesize evsel unit.\n");
3998 return err;
3999 }
4000 }
4001
4002 if (has_scale(counter)) {
4003 err = perf_event__synthesize_event_update_scale(tool, counter, process);
4004 if (err < 0) {
4005 pr_err("Couldn't synthesize evsel counter.\n");
4006 return err;
4007 }
4008 }
4009
4010 if (counter->core.own_cpus) {
4011 err = perf_event__synthesize_event_update_cpus(tool, counter, process);
4012 if (err < 0) {
4013 pr_err("Couldn't synthesize evsel cpus.\n");
4014 return err;
4015 }
4016 }
4017
4018 /*
4019 * Name is needed only for pipe output,
4020 * perf.data carries event names.
4021 */
4022 if (is_pipe) {
4023 err = perf_event__synthesize_event_update_name(tool, counter, process);
4024 if (err < 0) {
4025 pr_err("Couldn't synthesize evsel name.\n");
4026 return err;
4027 }
4028 }
4029 }
4030 return 0;
4031}
4032
4033int perf_event__process_attr(struct perf_tool *tool __maybe_unused, 3725int perf_event__process_attr(struct perf_tool *tool __maybe_unused,
4034 union perf_event *event, 3726 union perf_event *event,
4035 struct evlist **pevlist) 3727 struct evlist **pevlist)
@@ -4114,55 +3806,6 @@ int perf_event__process_event_update(struct perf_tool *tool __maybe_unused,
4114 return 0; 3806 return 0;
4115} 3807}
4116 3808
4117int perf_event__synthesize_tracing_data(struct perf_tool *tool, int fd,
4118 struct evlist *evlist,
4119 perf_event__handler_t process)
4120{
4121 union perf_event ev;
4122 struct tracing_data *tdata;
4123 ssize_t size = 0, aligned_size = 0, padding;
4124 struct feat_fd ff;
4125 int err __maybe_unused = 0;
4126
4127 /*
4128 * We are going to store the size of the data followed
4129 * by the data contents. Since the fd descriptor is a pipe,
4130 * we cannot seek back to store the size of the data once
4131 * we know it. Instead we:
4132 *
4133 * - write the tracing data to the temp file
4134 * - get/write the data size to pipe
4135 * - write the tracing data from the temp file
4136 * to the pipe
4137 */
4138 tdata = tracing_data_get(&evlist->core.entries, fd, true);
4139 if (!tdata)
4140 return -1;
4141
4142 memset(&ev, 0, sizeof(ev));
4143
4144 ev.tracing_data.header.type = PERF_RECORD_HEADER_TRACING_DATA;
4145 size = tdata->size;
4146 aligned_size = PERF_ALIGN(size, sizeof(u64));
4147 padding = aligned_size - size;
4148 ev.tracing_data.header.size = sizeof(ev.tracing_data);
4149 ev.tracing_data.size = aligned_size;
4150
4151 process(tool, &ev, NULL, NULL);
4152
4153 /*
4154 * The put function will copy all the tracing data
4155 * stored in temp file to the pipe.
4156 */
4157 tracing_data_put(tdata);
4158
4159 ff = (struct feat_fd){ .fd = fd };
4160 if (write_padded(&ff, NULL, 0, padding))
4161 return -1;
4162
4163 return aligned_size;
4164}
4165
4166int perf_event__process_tracing_data(struct perf_session *session, 3809int perf_event__process_tracing_data(struct perf_session *session,
4167 union perf_event *event) 3810 union perf_event *event)
4168{ 3811{
@@ -4202,34 +3845,6 @@ int perf_event__process_tracing_data(struct perf_session *session,
4202 return size_read + padding; 3845 return size_read + padding;
4203} 3846}
4204 3847
4205int perf_event__synthesize_build_id(struct perf_tool *tool,
4206 struct dso *pos, u16 misc,
4207 perf_event__handler_t process,
4208 struct machine *machine)
4209{
4210 union perf_event ev;
4211 size_t len;
4212 int err = 0;
4213
4214 if (!pos->hit)
4215 return err;
4216
4217 memset(&ev, 0, sizeof(ev));
4218
4219 len = pos->long_name_len + 1;
4220 len = PERF_ALIGN(len, NAME_ALIGN);
4221 memcpy(&ev.build_id.build_id, pos->build_id, sizeof(pos->build_id));
4222 ev.build_id.header.type = PERF_RECORD_HEADER_BUILD_ID;
4223 ev.build_id.header.misc = misc;
4224 ev.build_id.pid = machine->pid;
4225 ev.build_id.header.size = sizeof(ev.build_id) + len;
4226 memcpy(&ev.build_id.filename, pos->long_name, pos->long_name_len);
4227
4228 err = process(tool, &ev, NULL, machine);
4229
4230 return err;
4231}
4232
4233int perf_event__process_build_id(struct perf_session *session, 3848int perf_event__process_build_id(struct perf_session *session,
4234 union perf_event *event) 3849 union perf_event *event)
4235{ 3850{
diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h
index 3e48ae3c49b1..ca53a929e9fd 100644
--- a/tools/perf/util/header.h
+++ b/tools/perf/util/header.h
@@ -5,10 +5,10 @@
5#include <linux/stddef.h> 5#include <linux/stddef.h>
6#include <linux/perf_event.h> 6#include <linux/perf_event.h>
7#include <sys/types.h> 7#include <sys/types.h>
8#include <stdio.h> // FILE
8#include <stdbool.h> 9#include <stdbool.h>
9#include <linux/bitmap.h> 10#include <linux/bitmap.h>
10#include <linux/types.h> 11#include <linux/types.h>
11#include "event.h"
12#include "env.h" 12#include "env.h"
13#include "pmu.h" 13#include "pmu.h"
14 14
@@ -92,8 +92,28 @@ struct perf_header {
92 struct perf_env env; 92 struct perf_env env;
93}; 93};
94 94
95struct feat_fd {
96 struct perf_header *ph;
97 int fd;
98 void *buf; /* Either buf != NULL or fd >= 0 */
99 ssize_t offset;
100 size_t size;
101 struct evsel *events;
102};
103
104struct perf_header_feature_ops {
105 int (*write)(struct feat_fd *ff, struct evlist *evlist);
106 void (*print)(struct feat_fd *ff, FILE *fp);
107 int (*process)(struct feat_fd *ff, void *data);
108 const char *name;
109 bool full_only;
110 bool synthesize;
111};
112
95struct evlist; 113struct evlist;
96struct perf_session; 114struct perf_session;
115struct perf_tool;
116union perf_event;
97 117
98int perf_session__read_header(struct perf_session *session); 118int perf_session__read_header(struct perf_session *session);
99int perf_session__write_header(struct perf_session *session, 119int perf_session__write_header(struct perf_session *session,
@@ -115,54 +135,16 @@ int perf_header__process_sections(struct perf_header *header, int fd,
115 135
116int perf_header__fprintf_info(struct perf_session *s, FILE *fp, bool full); 136int perf_header__fprintf_info(struct perf_session *s, FILE *fp, bool full);
117 137
118int perf_event__synthesize_features(struct perf_tool *tool,
119 struct perf_session *session,
120 struct evlist *evlist,
121 perf_event__handler_t process);
122
123int perf_event__synthesize_extra_attr(struct perf_tool *tool,
124 struct evlist *evsel_list,
125 perf_event__handler_t process,
126 bool is_pipe);
127
128int perf_event__process_feature(struct perf_session *session, 138int perf_event__process_feature(struct perf_session *session,
129 union perf_event *event); 139 union perf_event *event);
130
131int perf_event__synthesize_attr(struct perf_tool *tool,
132 struct perf_event_attr *attr, u32 ids, u64 *id,
133 perf_event__handler_t process);
134int perf_event__synthesize_attrs(struct perf_tool *tool,
135 struct evlist *evlist,
136 perf_event__handler_t process);
137int perf_event__synthesize_event_update_unit(struct perf_tool *tool,
138 struct evsel *evsel,
139 perf_event__handler_t process);
140int perf_event__synthesize_event_update_scale(struct perf_tool *tool,
141 struct evsel *evsel,
142 perf_event__handler_t process);
143int perf_event__synthesize_event_update_name(struct perf_tool *tool,
144 struct evsel *evsel,
145 perf_event__handler_t process);
146int perf_event__synthesize_event_update_cpus(struct perf_tool *tool,
147 struct evsel *evsel,
148 perf_event__handler_t process);
149int perf_event__process_attr(struct perf_tool *tool, union perf_event *event, 140int perf_event__process_attr(struct perf_tool *tool, union perf_event *event,
150 struct evlist **pevlist); 141 struct evlist **pevlist);
151int perf_event__process_event_update(struct perf_tool *tool, 142int perf_event__process_event_update(struct perf_tool *tool,
152 union perf_event *event, 143 union perf_event *event,
153 struct evlist **pevlist); 144 struct evlist **pevlist);
154size_t perf_event__fprintf_event_update(union perf_event *event, FILE *fp); 145size_t perf_event__fprintf_event_update(union perf_event *event, FILE *fp);
155
156int perf_event__synthesize_tracing_data(struct perf_tool *tool,
157 int fd, struct evlist *evlist,
158 perf_event__handler_t process);
159int perf_event__process_tracing_data(struct perf_session *session, 146int perf_event__process_tracing_data(struct perf_session *session,
160 union perf_event *event); 147 union perf_event *event);
161
162int perf_event__synthesize_build_id(struct perf_tool *tool,
163 struct dso *pos, u16 misc,
164 perf_event__handler_t process,
165 struct machine *machine);
166int perf_event__process_build_id(struct perf_session *session, 148int perf_event__process_build_id(struct perf_session *session,
167 union perf_event *event); 149 union perf_event *event);
168bool is_perf_magic(u64 magic); 150bool is_perf_magic(u64 magic);
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index 34803e33dc80..6a186b668303 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -15,6 +15,7 @@ struct addr_location;
15struct map_symbol; 15struct map_symbol;
16struct mem_info; 16struct mem_info;
17struct branch_info; 17struct branch_info;
18struct branch_stack;
18struct block_info; 19struct block_info;
19struct symbol; 20struct symbol;
20struct ui_progress; 21struct ui_progress;
diff --git a/tools/perf/util/intel-bts.c b/tools/perf/util/intel-bts.c
index aacffa2b0362..3888d4cd3ed1 100644
--- a/tools/perf/util/intel-bts.c
+++ b/tools/perf/util/intel-bts.c
@@ -14,7 +14,6 @@
14#include <linux/log2.h> 14#include <linux/log2.h>
15#include <linux/zalloc.h> 15#include <linux/zalloc.h>
16 16
17#include "cpumap.h"
18#include "color.h" 17#include "color.h"
19#include "evsel.h" 18#include "evsel.h"
20#include "evlist.h" 19#include "evlist.h"
@@ -29,6 +28,7 @@
29#include "auxtrace.h" 28#include "auxtrace.h"
30#include "intel-pt-decoder/intel-pt-insn-decoder.h" 29#include "intel-pt-decoder/intel-pt-insn-decoder.h"
31#include "intel-bts.h" 30#include "intel-bts.h"
31#include "util/synthetic-events.h"
32 32
33#define MAX_TIMESTAMP (~0ULL) 33#define MAX_TIMESTAMP (~0ULL)
34 34
diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c
index 9b56fb74bedf..bcdc0359f7cf 100644
--- a/tools/perf/util/intel-pt.c
+++ b/tools/perf/util/intel-pt.c
@@ -33,6 +33,7 @@
33#include "tsc.h" 33#include "tsc.h"
34#include "intel-pt.h" 34#include "intel-pt.h"
35#include "config.h" 35#include "config.h"
36#include "util/synthetic-events.h"
36#include "time-utils.h" 37#include "time-utils.h"
37 38
38#include "../arch/x86/include/uapi/asm/perf_regs.h" 39#include "../arch/x86/include/uapi/asm/perf_regs.h"
diff --git a/tools/perf/util/jitdump.c b/tools/perf/util/jitdump.c
index b80f29bfc7bb..9f9c6c6a2fd3 100644
--- a/tools/perf/util/jitdump.c
+++ b/tools/perf/util/jitdump.c
@@ -15,7 +15,6 @@
15#include <linux/stringify.h> 15#include <linux/stringify.h>
16 16
17#include "build-id.h" 17#include "build-id.h"
18#include "util.h"
19#include "event.h" 18#include "event.h"
20#include "debug.h" 19#include "debug.h"
21#include "evlist.h" 20#include "evlist.h"
@@ -27,7 +26,6 @@
27#include "jit.h" 26#include "jit.h"
28#include "jitdump.h" 27#include "jitdump.h"
29#include "genelf.h" 28#include "genelf.h"
30#include "../builtin.h"
31 29
32#include <linux/ctype.h> 30#include <linux/ctype.h>
33#include <linux/zalloc.h> 31#include <linux/zalloc.h>
diff --git a/tools/perf/util/kvm-stat.h b/tools/perf/util/kvm-stat.h
index 46913637085b..6f0fa05b62b6 100644
--- a/tools/perf/util/kvm-stat.h
+++ b/tools/perf/util/kvm-stat.h
@@ -2,6 +2,8 @@
2#ifndef __PERF_KVM_STAT_H 2#ifndef __PERF_KVM_STAT_H
3#define __PERF_KVM_STAT_H 3#define __PERF_KVM_STAT_H
4 4
5#ifdef HAVE_KVM_STAT_SUPPORT
6
5#include "tool.h" 7#include "tool.h"
6#include "stat.h" 8#include "stat.h"
7#include "record.h" 9#include "record.h"
@@ -144,5 +146,7 @@ extern const int decode_str_len;
144extern const char *kvm_exit_reason; 146extern const char *kvm_exit_reason;
145extern const char *kvm_entry_trace; 147extern const char *kvm_entry_trace;
146extern const char *kvm_exit_trace; 148extern const char *kvm_exit_trace;
149#endif /* HAVE_KVM_STAT_SUPPORT */
147 150
151extern int kvm_add_default_arch_event(int *argc, const char **argv);
148#endif /* __PERF_KVM_STAT_H */ 152#endif /* __PERF_KVM_STAT_H */
diff --git a/tools/perf/util/libunwind/arm64.c b/tools/perf/util/libunwind/arm64.c
index 66756e6be111..6b4e5a0892f8 100644
--- a/tools/perf/util/libunwind/arm64.c
+++ b/tools/perf/util/libunwind/arm64.c
@@ -22,7 +22,6 @@
22#define LIBUNWIND__ARCH_REG_SP PERF_REG_ARM64_SP 22#define LIBUNWIND__ARCH_REG_SP PERF_REG_ARM64_SP
23 23
24#include "unwind.h" 24#include "unwind.h"
25#include "debug.h"
26#include "libunwind-aarch64.h" 25#include "libunwind-aarch64.h"
27#include <../../../../arch/arm64/include/uapi/asm/perf_regs.h> 26#include <../../../../arch/arm64/include/uapi/asm/perf_regs.h>
28#include "../../arch/arm64/util/unwind-libunwind.c" 27#include "../../arch/arm64/util/unwind-libunwind.c"
diff --git a/tools/perf/util/libunwind/x86_32.c b/tools/perf/util/libunwind/x86_32.c
index c5e568188e19..21c216c40a3b 100644
--- a/tools/perf/util/libunwind/x86_32.c
+++ b/tools/perf/util/libunwind/x86_32.c
@@ -22,7 +22,6 @@
22#define LIBUNWIND__ARCH_REG_SP PERF_REG_X86_SP 22#define LIBUNWIND__ARCH_REG_SP PERF_REG_X86_SP
23 23
24#include "unwind.h" 24#include "unwind.h"
25#include "debug.h"
26#include "libunwind-x86.h" 25#include "libunwind-x86.h"
27#include <../../../../arch/x86/include/uapi/asm/perf_regs.h> 26#include <../../../../arch/x86/include/uapi/asm/perf_regs.h>
28 27
diff --git a/tools/perf/util/llvm-utils.c b/tools/perf/util/llvm-utils.c
index 55fb4b3b1157..8d04e3d070b1 100644
--- a/tools/perf/util/llvm-utils.c
+++ b/tools/perf/util/llvm-utils.c
@@ -8,6 +8,7 @@
8#include <limits.h> 8#include <limits.h>
9#include <stdio.h> 9#include <stdio.h>
10#include <stdlib.h> 10#include <stdlib.h>
11#include <unistd.h>
11#include <linux/err.h> 12#include <linux/err.h>
12#include <linux/string.h> 13#include <linux/string.h>
13#include <linux/zalloc.h> 14#include <linux/zalloc.h>
diff --git a/tools/perf/util/lzma.c b/tools/perf/util/lzma.c
index 397447066033..39062df02629 100644
--- a/tools/perf/util/lzma.c
+++ b/tools/perf/util/lzma.c
@@ -7,10 +7,10 @@
7#include <sys/stat.h> 7#include <sys/stat.h>
8#include <fcntl.h> 8#include <fcntl.h>
9#include "compress.h" 9#include "compress.h"
10#include "util.h"
11#include "debug.h" 10#include "debug.h"
12#include <string.h> 11#include <string.h>
13#include <unistd.h> 12#include <unistd.h>
13#include <internal/lib.h>
14 14
15#define BUFSIZE 8192 15#define BUFSIZE 8192
16 16
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index b4749d3eed08..0535338f2d7a 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -2609,21 +2609,6 @@ int machines__for_each_thread(struct machines *machines,
2609 return rc; 2609 return rc;
2610} 2610}
2611 2611
2612int __machine__synthesize_threads(struct machine *machine, struct perf_tool *tool,
2613 struct target *target, struct perf_thread_map *threads,
2614 perf_event__handler_t process, bool data_mmap,
2615 unsigned int nr_threads_synthesize)
2616{
2617 if (target__has_task(target))
2618 return perf_event__synthesize_thread_map(tool, threads, process, machine, data_mmap);
2619 else if (target__has_cpu(target))
2620 return perf_event__synthesize_threads(tool, process,
2621 machine, data_mmap,
2622 nr_threads_synthesize);
2623 /* command specified */
2624 return 0;
2625}
2626
2627pid_t machine__get_current_tid(struct machine *machine, int cpu) 2612pid_t machine__get_current_tid(struct machine *machine, int cpu)
2628{ 2613{
2629 int nr_cpus = min(machine->env->nr_cpus_online, MAX_NR_CPUS); 2614 int nr_cpus = min(machine->env->nr_cpus_online, MAX_NR_CPUS);
diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h
index ffd391a925a6..18e13c0ccd6a 100644
--- a/tools/perf/util/machine.h
+++ b/tools/perf/util/machine.h
@@ -6,7 +6,6 @@
6#include <linux/rbtree.h> 6#include <linux/rbtree.h>
7#include "map_groups.h" 7#include "map_groups.h"
8#include "dsos.h" 8#include "dsos.h"
9#include "event.h"
10#include "rwsem.h" 9#include "rwsem.h"
11 10
12struct addr_location; 11struct addr_location;
@@ -252,20 +251,6 @@ int machines__for_each_thread(struct machines *machines,
252 int (*fn)(struct thread *thread, void *p), 251 int (*fn)(struct thread *thread, void *p),
253 void *priv); 252 void *priv);
254 253
255int __machine__synthesize_threads(struct machine *machine, struct perf_tool *tool,
256 struct target *target, struct perf_thread_map *threads,
257 perf_event__handler_t process, bool data_mmap,
258 unsigned int nr_threads_synthesize);
259static inline
260int machine__synthesize_threads(struct machine *machine, struct target *target,
261 struct perf_thread_map *threads, bool data_mmap,
262 unsigned int nr_threads_synthesize)
263{
264 return __machine__synthesize_threads(machine, NULL, target, threads,
265 perf_event__process, data_mmap,
266 nr_threads_synthesize);
267}
268
269pid_t machine__get_current_tid(struct machine *machine, int cpu); 254pid_t machine__get_current_tid(struct machine *machine, int cpu);
270int machine__set_current_tid(struct machine *machine, int cpu, pid_t pid, 255int machine__set_current_tid(struct machine *machine, int cpu, pid_t pid,
271 pid_t tid); 256 pid_t tid);
diff --git a/tools/perf/util/memswap.h b/tools/perf/util/memswap.h
index 1e29ff903ca9..2c38e8c2d548 100644
--- a/tools/perf/util/memswap.h
+++ b/tools/perf/util/memswap.h
@@ -2,6 +2,13 @@
2#ifndef PERF_MEMSWAP_H_ 2#ifndef PERF_MEMSWAP_H_
3#define PERF_MEMSWAP_H_ 3#define PERF_MEMSWAP_H_
4 4
5#include <linux/types.h>
6
7union u64_swap {
8 u64 val64;
9 u32 val32[2];
10};
11
5void mem_bswap_64(void *src, int byte_size); 12void mem_bswap_64(void *src, int byte_size);
6void mem_bswap_32(void *src, int byte_size); 13void mem_bswap_32(void *src, int byte_size);
7 14
diff --git a/tools/perf/util/namespaces.c b/tools/perf/util/namespaces.c
index 99be15dd2b6b..285d6f30d912 100644
--- a/tools/perf/util/namespaces.c
+++ b/tools/perf/util/namespaces.c
@@ -17,8 +17,26 @@
17#include <string.h> 17#include <string.h>
18#include <unistd.h> 18#include <unistd.h>
19#include <asm/bug.h> 19#include <asm/bug.h>
20#include <linux/kernel.h>
20#include <linux/zalloc.h> 21#include <linux/zalloc.h>
21 22
23static const char *perf_ns__names[] = {
24 [NET_NS_INDEX] = "net",
25 [UTS_NS_INDEX] = "uts",
26 [IPC_NS_INDEX] = "ipc",
27 [PID_NS_INDEX] = "pid",
28 [USER_NS_INDEX] = "user",
29 [MNT_NS_INDEX] = "mnt",
30 [CGROUP_NS_INDEX] = "cgroup",
31};
32
33const char *perf_ns__name(unsigned int id)
34{
35 if (id >= ARRAY_SIZE(perf_ns__names))
36 return "UNKNOWN";
37 return perf_ns__names[id];
38}
39
22struct namespaces *namespaces__new(struct perf_record_namespaces *event) 40struct namespaces *namespaces__new(struct perf_record_namespaces *event)
23{ 41{
24 struct namespaces *namespaces; 42 struct namespaces *namespaces;
diff --git a/tools/perf/util/namespaces.h b/tools/perf/util/namespaces.h
index 40edef56cb52..4b33f684eddd 100644
--- a/tools/perf/util/namespaces.h
+++ b/tools/perf/util/namespaces.h
@@ -66,4 +66,6 @@ static inline void __nsinfo__zput(struct nsinfo **nsip)
66 66
67#define nsinfo__zput(nsi) __nsinfo__zput(&nsi) 67#define nsinfo__zput(nsi) __nsinfo__zput(&nsi)
68 68
69const char *perf_ns__name(unsigned int id);
70
69#endif /* __PERF_NAMESPACES_H */ 71#endif /* __PERF_NAMESPACES_H */
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 5ec21d21113c..a33a1d5059a2 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -30,7 +30,6 @@
30#include "parse-events-flex.h" 30#include "parse-events-flex.h"
31#include "pmu.h" 31#include "pmu.h"
32#include "thread_map.h" 32#include "thread_map.h"
33#include "cpumap.h"
34#include "probe-file.h" 33#include "probe-file.h"
35#include "asm/bug.h" 34#include "asm/bug.h"
36#include "util/parse-branch-options.h" 35#include "util/parse-branch-options.h"
diff --git a/tools/perf/util/perf-hooks.c b/tools/perf/util/perf-hooks.c
index e635c594f773..7a0ab3507bd5 100644
--- a/tools/perf/util/perf-hooks.c
+++ b/tools/perf/util/perf-hooks.c
@@ -12,7 +12,6 @@
12#include <setjmp.h> 12#include <setjmp.h>
13#include <linux/err.h> 13#include <linux/err.h>
14#include <linux/kernel.h> 14#include <linux/kernel.h>
15#include "util/util.h"
16#include "util/debug.h" 15#include "util/debug.h"
17#include "util/perf-hooks.h" 16#include "util/perf-hooks.h"
18 17
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index fb597fa94234..5608da82ad23 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -20,7 +20,6 @@
20#include "debug.h" 20#include "debug.h"
21#include "pmu.h" 21#include "pmu.h"
22#include "parse-events.h" 22#include "parse-events.h"
23#include "cpumap.h"
24#include "header.h" 23#include "header.h"
25#include "pmu-events/pmu-events.h" 24#include "pmu-events/pmu-events.h"
26#include "string2.h" 25#include "string2.h"
diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c
index d13db55a2feb..b659466ea498 100644
--- a/tools/perf/util/probe-file.c
+++ b/tools/perf/util/probe-file.c
@@ -16,6 +16,7 @@
16#include "strlist.h" 16#include "strlist.h"
17#include "strfilter.h" 17#include "strfilter.h"
18#include "debug.h" 18#include "debug.h"
19#include "build-id.h"
19#include "dso.h" 20#include "dso.h"
20#include "color.h" 21#include "color.h"
21#include "symbol.h" 22#include "symbol.h"
diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c
index 07ca4535e6f7..0ba19dd75510 100644
--- a/tools/perf/util/python.c
+++ b/tools/perf/util/python.c
@@ -6,12 +6,10 @@
6#include <linux/err.h> 6#include <linux/err.h>
7#include <perf/cpumap.h> 7#include <perf/cpumap.h>
8#include <traceevent/event-parse.h> 8#include <traceevent/event-parse.h>
9#include "debug.h"
10#include "evlist.h" 9#include "evlist.h"
11#include "callchain.h" 10#include "callchain.h"
12#include "evsel.h" 11#include "evsel.h"
13#include "event.h" 12#include "event.h"
14#include "cpumap.h"
15#include "print_binary.h" 13#include "print_binary.h"
16#include "thread_map.h" 14#include "thread_map.h"
17#include "trace-event.h" 15#include "trace-event.h"
@@ -61,6 +59,8 @@ int parse_callchain_record(const char *arg __maybe_unused,
61 */ 59 */
62int verbose; 60int verbose;
63 61
62int eprintf(int level, int var, const char *fmt, ...);
63
64int eprintf(int level, int var, const char *fmt, ...) 64int eprintf(int level, int var, const char *fmt, ...)
65{ 65{
66 va_list args; 66 va_list args;
diff --git a/tools/perf/util/record.c b/tools/perf/util/record.c
index 286fe816c0f3..8a015fc0aba0 100644
--- a/tools/perf/util/record.c
+++ b/tools/perf/util/record.c
@@ -2,7 +2,6 @@
2#include "debug.h" 2#include "debug.h"
3#include "evlist.h" 3#include "evlist.h"
4#include "evsel.h" 4#include "evsel.h"
5#include "cpumap.h"
6#include "parse-events.h" 5#include "parse-events.h"
7#include <errno.h> 6#include <errno.h>
8#include <limits.h> 7#include <limits.h>
@@ -10,7 +9,6 @@
10#include <api/fs/fs.h> 9#include <api/fs/fs.h>
11#include <subcmd/parse-options.h> 10#include <subcmd/parse-options.h>
12#include <perf/cpumap.h> 11#include <perf/cpumap.h>
13#include "util.h"
14#include "cloexec.h" 12#include "cloexec.h"
15#include "record.h" 13#include "record.h"
16#include "../perf-sys.h" 14#include "../perf-sys.h"
diff --git a/tools/perf/util/rwsem.c b/tools/perf/util/rwsem.c
index 5e52e7baa7b6..f3d29d8ddc99 100644
--- a/tools/perf/util/rwsem.c
+++ b/tools/perf/util/rwsem.c
@@ -1,3 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0
1#include "util.h" 2#include "util.h"
2#include "rwsem.h" 3#include "rwsem.h"
3 4
diff --git a/tools/perf/util/s390-cpumsf.c b/tools/perf/util/s390-cpumsf.c
index 24a99909d8b3..6785cd87aa4d 100644
--- a/tools/perf/util/s390-cpumsf.c
+++ b/tools/perf/util/s390-cpumsf.c
@@ -151,7 +151,6 @@
151#include <sys/stat.h> 151#include <sys/stat.h>
152#include <sys/types.h> 152#include <sys/types.h>
153 153
154#include "cpumap.h"
155#include "color.h" 154#include "color.h"
156#include "evsel.h" 155#include "evsel.h"
157#include "evlist.h" 156#include "evlist.h"
diff --git a/tools/perf/util/s390-sample-raw.c b/tools/perf/util/s390-sample-raw.c
index 4d9593e331ea..05b43ab4eeef 100644
--- a/tools/perf/util/s390-sample-raw.c
+++ b/tools/perf/util/s390-sample-raw.c
@@ -22,7 +22,6 @@
22#include <asm/byteorder.h> 22#include <asm/byteorder.h>
23 23
24#include "debug.h" 24#include "debug.h"
25#include "util.h"
26#include "session.h" 25#include "session.h"
27#include "evlist.h" 26#include "evlist.h"
28#include "color.h" 27#include "color.h"
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
index 666a56e88d8e..5d341efc3237 100644
--- a/tools/perf/util/scripting-engines/trace-event-python.c
+++ b/tools/perf/util/scripting-engines/trace-event-python.c
@@ -37,7 +37,6 @@
37#include "../dso.h" 37#include "../dso.h"
38#include "../callchain.h" 38#include "../callchain.h"
39#include "../evsel.h" 39#include "../evsel.h"
40#include "../util.h"
41#include "../event.h" 40#include "../event.h"
42#include "../thread.h" 41#include "../thread.h"
43#include "../comm.h" 42#include "../comm.h"
@@ -49,7 +48,6 @@
49#include "map.h" 48#include "map.h"
50#include "symbol.h" 49#include "symbol.h"
51#include "thread_map.h" 50#include "thread_map.h"
52#include "cpumap.h"
53#include "print_binary.h" 51#include "print_binary.h"
54#include "stat.h" 52#include "stat.h"
55#include "mem-events.h" 53#include "mem-events.h"
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index e9e4a04f15db..58b5bc34ba12 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -22,7 +22,6 @@
22#include "symbol.h" 22#include "symbol.h"
23#include "session.h" 23#include "session.h"
24#include "tool.h" 24#include "tool.h"
25#include "cpumap.h"
26#include "perf_regs.h" 25#include "perf_regs.h"
27#include "asm/bug.h" 26#include "asm/bug.h"
28#include "auxtrace.h" 27#include "auxtrace.h"
@@ -34,6 +33,7 @@
34#include "ui/progress.h" 33#include "ui/progress.h"
35#include "../perf.h" 34#include "../perf.h"
36#include "arch/common.h" 35#include "arch/common.h"
36#include <internal/lib.h>
37 37
38#ifdef HAVE_ZSTD_SUPPORT 38#ifdef HAVE_ZSTD_SUPPORT
39static int perf_session__process_compressed_event(struct perf_session *session, 39static int perf_session__process_compressed_event(struct perf_session *session,
@@ -2412,73 +2412,3 @@ int perf_event__process_id_index(struct perf_session *session,
2412 } 2412 }
2413 return 0; 2413 return 0;
2414} 2414}
2415
2416int perf_event__synthesize_id_index(struct perf_tool *tool,
2417 perf_event__handler_t process,
2418 struct evlist *evlist,
2419 struct machine *machine)
2420{
2421 union perf_event *ev;
2422 struct evsel *evsel;
2423 size_t nr = 0, i = 0, sz, max_nr, n;
2424 int err;
2425
2426 pr_debug2("Synthesizing id index\n");
2427
2428 max_nr = (UINT16_MAX - sizeof(struct perf_record_id_index)) /
2429 sizeof(struct id_index_entry);
2430
2431 evlist__for_each_entry(evlist, evsel)
2432 nr += evsel->ids;
2433
2434 n = nr > max_nr ? max_nr : nr;
2435 sz = sizeof(struct perf_record_id_index) + n * sizeof(struct id_index_entry);
2436 ev = zalloc(sz);
2437 if (!ev)
2438 return -ENOMEM;
2439
2440 ev->id_index.header.type = PERF_RECORD_ID_INDEX;
2441 ev->id_index.header.size = sz;
2442 ev->id_index.nr = n;
2443
2444 evlist__for_each_entry(evlist, evsel) {
2445 u32 j;
2446
2447 for (j = 0; j < evsel->ids; j++) {
2448 struct id_index_entry *e;
2449 struct perf_sample_id *sid;
2450
2451 if (i >= n) {
2452 err = process(tool, ev, NULL, machine);
2453 if (err)
2454 goto out_err;
2455 nr -= n;
2456 i = 0;
2457 }
2458
2459 e = &ev->id_index.entries[i++];
2460
2461 e->id = evsel->id[j];
2462
2463 sid = perf_evlist__id2sid(evlist, e->id);
2464 if (!sid) {
2465 free(ev);
2466 return -ENOENT;
2467 }
2468
2469 e->idx = sid->idx;
2470 e->cpu = sid->cpu;
2471 e->tid = sid->tid;
2472 }
2473 }
2474
2475 sz = sizeof(struct perf_record_id_index) + nr * sizeof(struct id_index_entry);
2476 ev->id_index.header.size = sz;
2477 ev->id_index.nr = nr;
2478
2479 err = process(tool, ev, NULL, machine);
2480out_err:
2481 free(ev);
2482
2483 return err;
2484}
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index b7aa076ab6fd..b4c9428c18f0 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -138,9 +138,4 @@ int perf_session__deliver_synth_event(struct perf_session *session,
138int perf_event__process_id_index(struct perf_session *session, 138int perf_event__process_id_index(struct perf_session *session,
139 union perf_event *event); 139 union perf_event *event);
140 140
141int perf_event__synthesize_id_index(struct perf_tool *tool,
142 perf_event__handler_t process,
143 struct evlist *evlist,
144 struct machine *machine);
145
146#endif /* __PERF_SESSION_H */ 141#endif /* __PERF_SESSION_H */
diff --git a/tools/perf/util/srccode.c b/tools/perf/util/srccode.c
index adfcf1ff464c..b402f9ca89ab 100644
--- a/tools/perf/util/srccode.c
+++ b/tools/perf/util/srccode.c
@@ -15,7 +15,7 @@
15#include <string.h> 15#include <string.h>
16#include "srccode.h" 16#include "srccode.h"
17#include "debug.h" 17#include "debug.h"
18#include "util.h" 18#include "util.h" // page_size
19 19
20#define MAXSRCCACHE (32*1024*1024) 20#define MAXSRCCACHE (32*1024*1024)
21#define MAXSRCFILES 64 21#define MAXSRCFILES 64
diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c
index 8f1ea27f976f..fcd54342c04c 100644
--- a/tools/perf/util/stat.c
+++ b/tools/perf/util/stat.c
@@ -4,6 +4,7 @@
4#include <math.h> 4#include <math.h>
5#include <string.h> 5#include <string.h>
6#include "counts.h" 6#include "counts.h"
7#include "cpumap.h"
7#include "debug.h" 8#include "debug.h"
8#include "header.h" 9#include "header.h"
9#include "stat.h" 10#include "stat.h"
@@ -161,6 +162,15 @@ static void perf_evsel__free_prev_raw_counts(struct evsel *evsel)
161 evsel->prev_raw_counts = NULL; 162 evsel->prev_raw_counts = NULL;
162} 163}
163 164
165static void perf_evsel__reset_prev_raw_counts(struct evsel *evsel)
166{
167 if (evsel->prev_raw_counts) {
168 evsel->prev_raw_counts->aggr.val = 0;
169 evsel->prev_raw_counts->aggr.ena = 0;
170 evsel->prev_raw_counts->aggr.run = 0;
171 }
172}
173
164static int perf_evsel__alloc_stats(struct evsel *evsel, bool alloc_raw) 174static int perf_evsel__alloc_stats(struct evsel *evsel, bool alloc_raw)
165{ 175{
166 int ncpus = perf_evsel__nr_cpus(evsel); 176 int ncpus = perf_evsel__nr_cpus(evsel);
@@ -211,6 +221,14 @@ void perf_evlist__reset_stats(struct evlist *evlist)
211 } 221 }
212} 222}
213 223
224void perf_evlist__reset_prev_raw_counts(struct evlist *evlist)
225{
226 struct evsel *evsel;
227
228 evlist__for_each_entry(evlist, evsel)
229 perf_evsel__reset_prev_raw_counts(evsel);
230}
231
214static void zero_per_pkg(struct evsel *counter) 232static void zero_per_pkg(struct evsel *counter)
215{ 233{
216 if (counter->per_pkg_mask) 234 if (counter->per_pkg_mask)
@@ -493,45 +511,3 @@ int create_perf_stat_counter(struct evsel *evsel,
493 511
494 return perf_evsel__open_per_thread(evsel, evsel->core.threads); 512 return perf_evsel__open_per_thread(evsel, evsel->core.threads);
495} 513}
496
497int perf_stat_synthesize_config(struct perf_stat_config *config,
498 struct perf_tool *tool,
499 struct evlist *evlist,
500 perf_event__handler_t process,
501 bool attrs)
502{
503 int err;
504
505 if (attrs) {
506 err = perf_event__synthesize_attrs(tool, evlist, process);
507 if (err < 0) {
508 pr_err("Couldn't synthesize attrs.\n");
509 return err;
510 }
511 }
512
513 err = perf_event__synthesize_extra_attr(tool, evlist, process,
514 attrs);
515
516 err = perf_event__synthesize_thread_map2(tool, evlist->core.threads,
517 process, NULL);
518 if (err < 0) {
519 pr_err("Couldn't synthesize thread map.\n");
520 return err;
521 }
522
523 err = perf_event__synthesize_cpu_map(tool, evlist->core.cpus,
524 process, NULL);
525 if (err < 0) {
526 pr_err("Couldn't synthesize thread map.\n");
527 return err;
528 }
529
530 err = perf_event__synthesize_stat_config(tool, config, process, NULL);
531 if (err < 0) {
532 pr_err("Couldn't synthesize config.\n");
533 return err;
534 }
535
536 return 0;
537}
diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h
index 14fe3e548229..edbeb2f63e8d 100644
--- a/tools/perf/util/stat.h
+++ b/tools/perf/util/stat.h
@@ -7,8 +7,9 @@
7#include <sys/types.h> 7#include <sys/types.h>
8#include <sys/resource.h> 8#include <sys/resource.h>
9#include "rblist.h" 9#include "rblist.h"
10#include "event.h"
11 10
11struct perf_cpu_map;
12struct perf_stat_config;
12struct timespec; 13struct timespec;
13 14
14struct stats { 15struct stats {
@@ -192,6 +193,7 @@ void perf_stat__collect_metric_expr(struct evlist *);
192int perf_evlist__alloc_stats(struct evlist *evlist, bool alloc_raw); 193int perf_evlist__alloc_stats(struct evlist *evlist, bool alloc_raw);
193void perf_evlist__free_stats(struct evlist *evlist); 194void perf_evlist__free_stats(struct evlist *evlist);
194void perf_evlist__reset_stats(struct evlist *evlist); 195void perf_evlist__reset_stats(struct evlist *evlist);
196void perf_evlist__reset_prev_raw_counts(struct evlist *evlist);
195 197
196int perf_stat_process_counter(struct perf_stat_config *config, 198int perf_stat_process_counter(struct perf_stat_config *config,
197 struct evsel *counter); 199 struct evsel *counter);
@@ -210,11 +212,6 @@ size_t perf_event__fprintf_stat_config(union perf_event *event, FILE *fp);
210int create_perf_stat_counter(struct evsel *evsel, 212int create_perf_stat_counter(struct evsel *evsel,
211 struct perf_stat_config *config, 213 struct perf_stat_config *config,
212 struct target *target); 214 struct target *target);
213int perf_stat_synthesize_config(struct perf_stat_config *config,
214 struct perf_tool *tool,
215 struct evlist *evlist,
216 perf_event__handler_t process,
217 bool attrs);
218void 215void
219perf_evlist__print_counters(struct evlist *evlist, 216perf_evlist__print_counters(struct evlist *evlist,
220 struct perf_stat_config *config, 217 struct perf_stat_config *config,
diff --git a/tools/perf/util/svghelper.c b/tools/perf/util/svghelper.c
index 582f4a69cd48..96f941e01681 100644
--- a/tools/perf/util/svghelper.c
+++ b/tools/perf/util/svghelper.c
@@ -17,11 +17,11 @@
17#include <linux/string.h> 17#include <linux/string.h>
18#include <linux/time64.h> 18#include <linux/time64.h>
19#include <linux/zalloc.h> 19#include <linux/zalloc.h>
20#include <internal/cpumap.h>
20#include <perf/cpumap.h> 21#include <perf/cpumap.h>
21 22
22#include "env.h" 23#include "env.h"
23#include "svghelper.h" 24#include "svghelper.h"
24#include "cpumap.h"
25 25
26static u64 first_time, last_time; 26static u64 first_time, last_time;
27static u64 turbo_frequency, max_freq; 27static u64 turbo_frequency, max_freq;
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
index 9428639872a6..6fbfdf8bf61f 100644
--- a/tools/perf/util/symbol-elf.c
+++ b/tools/perf/util/symbol-elf.c
@@ -7,6 +7,7 @@
7#include <unistd.h> 7#include <unistd.h>
8#include <inttypes.h> 8#include <inttypes.h>
9 9
10#include "dso.h"
10#include "map.h" 11#include "map.h"
11#include "map_groups.h" 12#include "map_groups.h"
12#include "symbol.h" 13#include "symbol.h"
@@ -18,8 +19,10 @@
18#include "debug.h" 19#include "debug.h"
19#include "util.h" 20#include "util.h"
20#include <linux/ctype.h> 21#include <linux/ctype.h>
22#include <linux/kernel.h>
21#include <linux/zalloc.h> 23#include <linux/zalloc.h>
22#include <symbol/kallsyms.h> 24#include <symbol/kallsyms.h>
25#include <internal/lib.h>
23 26
24#ifndef EM_AARCH64 27#ifndef EM_AARCH64
25#define EM_AARCH64 183 /* ARM 64 bit */ 28#define EM_AARCH64 183 /* ARM 64 bit */
diff --git a/tools/perf/util/symbol-minimal.c b/tools/perf/util/symbol-minimal.c
index 7e2813ec9498..d6e99af263ec 100644
--- a/tools/perf/util/symbol-minimal.c
+++ b/tools/perf/util/symbol-minimal.c
@@ -1,8 +1,6 @@
1// SPDX-License-Identifier: GPL-2.0
2#include "dso.h" 1#include "dso.h"
3#include "symbol.h" 2#include "symbol.h"
4#include "symsrc.h" 3#include "symsrc.h"
5#include "util.h"
6 4
7#include <errno.h> 5#include <errno.h>
8#include <unistd.h> 6#include <unistd.h>
@@ -13,6 +11,7 @@
13#include <byteswap.h> 11#include <byteswap.h>
14#include <sys/stat.h> 12#include <sys/stat.h>
15#include <linux/zalloc.h> 13#include <linux/zalloc.h>
14#include <internal/lib.h>
16 15
17static bool check_need_swap(int file_endian) 16static bool check_need_swap(int file_endian)
18{ 17{
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 765c75df2904..a8f80e427674 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -19,7 +19,7 @@
19#include "build-id.h" 19#include "build-id.h"
20#include "cap.h" 20#include "cap.h"
21#include "dso.h" 21#include "dso.h"
22#include "util.h" 22#include "util.h" // lsdir()
23#include "debug.h" 23#include "debug.h"
24#include "event.h" 24#include "event.h"
25#include "machine.h" 25#include "machine.h"
diff --git a/tools/perf/util/synthetic-events.c b/tools/perf/util/synthetic-events.c
new file mode 100644
index 000000000000..8322028a9a97
--- /dev/null
+++ b/tools/perf/util/synthetic-events.c
@@ -0,0 +1,1884 @@
1// SPDX-License-Identifier: GPL-2.0-only
2
3#include "util/debug.h"
4#include "util/dso.h"
5#include "util/event.h"
6#include "util/evlist.h"
7#include "util/machine.h"
8#include "util/map.h"
9#include "util/map_symbol.h"
10#include "util/branch.h"
11#include "util/memswap.h"
12#include "util/namespaces.h"
13#include "util/session.h"
14#include "util/stat.h"
15#include "util/symbol.h"
16#include "util/synthetic-events.h"
17#include "util/target.h"
18#include "util/time-utils.h"
19#include "util/util.h"
20#include <linux/bitops.h>
21#include <linux/kernel.h>
22#include <linux/string.h>
23#include <linux/zalloc.h>
24#include <linux/perf_event.h>
25#include <asm/bug.h>
26#include <perf/evsel.h>
27#include <internal/cpumap.h>
28#include <perf/cpumap.h>
29#include <internal/threadmap.h>
30#include <perf/threadmap.h>
31#include <symbol/kallsyms.h>
32#include <dirent.h>
33#include <errno.h>
34#include <inttypes.h>
35#include <stdio.h>
36#include <string.h>
37#include <uapi/linux/mman.h> /* To get things like MAP_HUGETLB even on older libc headers */
38#include <api/fs/fs.h>
39#include <sys/types.h>
40#include <sys/stat.h>
41#include <fcntl.h>
42#include <unistd.h>
43
44#define DEFAULT_PROC_MAP_PARSE_TIMEOUT 500
45
46unsigned int proc_map_timeout = DEFAULT_PROC_MAP_PARSE_TIMEOUT;
47
48int perf_tool__process_synth_event(struct perf_tool *tool,
49 union perf_event *event,
50 struct machine *machine,
51 perf_event__handler_t process)
52{
53 struct perf_sample synth_sample = {
54 .pid = -1,
55 .tid = -1,
56 .time = -1,
57 .stream_id = -1,
58 .cpu = -1,
59 .period = 1,
60 .cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK,
61 };
62
63 return process(tool, event, &synth_sample, machine);
64};
65
66/*
67 * Assumes that the first 4095 bytes of /proc/pid/stat contains
68 * the comm, tgid and ppid.
69 */
70static int perf_event__get_comm_ids(pid_t pid, char *comm, size_t len,
71 pid_t *tgid, pid_t *ppid)
72{
73 char filename[PATH_MAX];
74 char bf[4096];
75 int fd;
76 size_t size = 0;
77 ssize_t n;
78 char *name, *tgids, *ppids;
79
80 *tgid = -1;
81 *ppid = -1;
82
83 snprintf(filename, sizeof(filename), "/proc/%d/status", pid);
84
85 fd = open(filename, O_RDONLY);
86 if (fd < 0) {
87 pr_debug("couldn't open %s\n", filename);
88 return -1;
89 }
90
91 n = read(fd, bf, sizeof(bf) - 1);
92 close(fd);
93 if (n <= 0) {
94 pr_warning("Couldn't get COMM, tigd and ppid for pid %d\n",
95 pid);
96 return -1;
97 }
98 bf[n] = '\0';
99
100 name = strstr(bf, "Name:");
101 tgids = strstr(bf, "Tgid:");
102 ppids = strstr(bf, "PPid:");
103
104 if (name) {
105 char *nl;
106
107 name = skip_spaces(name + 5); /* strlen("Name:") */
108 nl = strchr(name, '\n');
109 if (nl)
110 *nl = '\0';
111
112 size = strlen(name);
113 if (size >= len)
114 size = len - 1;
115 memcpy(comm, name, size);
116 comm[size] = '\0';
117 } else {
118 pr_debug("Name: string not found for pid %d\n", pid);
119 }
120
121 if (tgids) {
122 tgids += 5; /* strlen("Tgid:") */
123 *tgid = atoi(tgids);
124 } else {
125 pr_debug("Tgid: string not found for pid %d\n", pid);
126 }
127
128 if (ppids) {
129 ppids += 5; /* strlen("PPid:") */
130 *ppid = atoi(ppids);
131 } else {
132 pr_debug("PPid: string not found for pid %d\n", pid);
133 }
134
135 return 0;
136}
137
138static int perf_event__prepare_comm(union perf_event *event, pid_t pid,
139 struct machine *machine,
140 pid_t *tgid, pid_t *ppid)
141{
142 size_t size;
143
144 *ppid = -1;
145
146 memset(&event->comm, 0, sizeof(event->comm));
147
148 if (machine__is_host(machine)) {
149 if (perf_event__get_comm_ids(pid, event->comm.comm,
150 sizeof(event->comm.comm),
151 tgid, ppid) != 0) {
152 return -1;
153 }
154 } else {
155 *tgid = machine->pid;
156 }
157
158 if (*tgid < 0)
159 return -1;
160
161 event->comm.pid = *tgid;
162 event->comm.header.type = PERF_RECORD_COMM;
163
164 size = strlen(event->comm.comm) + 1;
165 size = PERF_ALIGN(size, sizeof(u64));
166 memset(event->comm.comm + size, 0, machine->id_hdr_size);
167 event->comm.header.size = (sizeof(event->comm) -
168 (sizeof(event->comm.comm) - size) +
169 machine->id_hdr_size);
170 event->comm.tid = pid;
171
172 return 0;
173}
174
175pid_t perf_event__synthesize_comm(struct perf_tool *tool,
176 union perf_event *event, pid_t pid,
177 perf_event__handler_t process,
178 struct machine *machine)
179{
180 pid_t tgid, ppid;
181
182 if (perf_event__prepare_comm(event, pid, machine, &tgid, &ppid) != 0)
183 return -1;
184
185 if (perf_tool__process_synth_event(tool, event, machine, process) != 0)
186 return -1;
187
188 return tgid;
189}
190
191static void perf_event__get_ns_link_info(pid_t pid, const char *ns,
192 struct perf_ns_link_info *ns_link_info)
193{
194 struct stat64 st;
195 char proc_ns[128];
196
197 sprintf(proc_ns, "/proc/%u/ns/%s", pid, ns);
198 if (stat64(proc_ns, &st) == 0) {
199 ns_link_info->dev = st.st_dev;
200 ns_link_info->ino = st.st_ino;
201 }
202}
203
204int perf_event__synthesize_namespaces(struct perf_tool *tool,
205 union perf_event *event,
206 pid_t pid, pid_t tgid,
207 perf_event__handler_t process,
208 struct machine *machine)
209{
210 u32 idx;
211 struct perf_ns_link_info *ns_link_info;
212
213 if (!tool || !tool->namespace_events)
214 return 0;
215
216 memset(&event->namespaces, 0, (sizeof(event->namespaces) +
217 (NR_NAMESPACES * sizeof(struct perf_ns_link_info)) +
218 machine->id_hdr_size));
219
220 event->namespaces.pid = tgid;
221 event->namespaces.tid = pid;
222
223 event->namespaces.nr_namespaces = NR_NAMESPACES;
224
225 ns_link_info = event->namespaces.link_info;
226
227 for (idx = 0; idx < event->namespaces.nr_namespaces; idx++)
228 perf_event__get_ns_link_info(pid, perf_ns__name(idx),
229 &ns_link_info[idx]);
230
231 event->namespaces.header.type = PERF_RECORD_NAMESPACES;
232
233 event->namespaces.header.size = (sizeof(event->namespaces) +
234 (NR_NAMESPACES * sizeof(struct perf_ns_link_info)) +
235 machine->id_hdr_size);
236
237 if (perf_tool__process_synth_event(tool, event, machine, process) != 0)
238 return -1;
239
240 return 0;
241}
242
243static int perf_event__synthesize_fork(struct perf_tool *tool,
244 union perf_event *event,
245 pid_t pid, pid_t tgid, pid_t ppid,
246 perf_event__handler_t process,
247 struct machine *machine)
248{
249 memset(&event->fork, 0, sizeof(event->fork) + machine->id_hdr_size);
250
251 /*
252 * for main thread set parent to ppid from status file. For other
253 * threads set parent pid to main thread. ie., assume main thread
254 * spawns all threads in a process
255 */
256 if (tgid == pid) {
257 event->fork.ppid = ppid;
258 event->fork.ptid = ppid;
259 } else {
260 event->fork.ppid = tgid;
261 event->fork.ptid = tgid;
262 }
263 event->fork.pid = tgid;
264 event->fork.tid = pid;
265 event->fork.header.type = PERF_RECORD_FORK;
266 event->fork.header.misc = PERF_RECORD_MISC_FORK_EXEC;
267
268 event->fork.header.size = (sizeof(event->fork) + machine->id_hdr_size);
269
270 if (perf_tool__process_synth_event(tool, event, machine, process) != 0)
271 return -1;
272
273 return 0;
274}
275
276int perf_event__synthesize_mmap_events(struct perf_tool *tool,
277 union perf_event *event,
278 pid_t pid, pid_t tgid,
279 perf_event__handler_t process,
280 struct machine *machine,
281 bool mmap_data)
282{
283 char filename[PATH_MAX];
284 FILE *fp;
285 unsigned long long t;
286 bool truncation = false;
287 unsigned long long timeout = proc_map_timeout * 1000000ULL;
288 int rc = 0;
289 const char *hugetlbfs_mnt = hugetlbfs__mountpoint();
290 int hugetlbfs_mnt_len = hugetlbfs_mnt ? strlen(hugetlbfs_mnt) : 0;
291
292 if (machine__is_default_guest(machine))
293 return 0;
294
295 snprintf(filename, sizeof(filename), "%s/proc/%d/task/%d/maps",
296 machine->root_dir, pid, pid);
297
298 fp = fopen(filename, "r");
299 if (fp == NULL) {
300 /*
301 * We raced with a task exiting - just return:
302 */
303 pr_debug("couldn't open %s\n", filename);
304 return -1;
305 }
306
307 event->header.type = PERF_RECORD_MMAP2;
308 t = rdclock();
309
310 while (1) {
311 char bf[BUFSIZ];
312 char prot[5];
313 char execname[PATH_MAX];
314 char anonstr[] = "//anon";
315 unsigned int ino;
316 size_t size;
317 ssize_t n;
318
319 if (fgets(bf, sizeof(bf), fp) == NULL)
320 break;
321
322 if ((rdclock() - t) > timeout) {
323 pr_warning("Reading %s time out. "
324 "You may want to increase "
325 "the time limit by --proc-map-timeout\n",
326 filename);
327 truncation = true;
328 goto out;
329 }
330
331 /* ensure null termination since stack will be reused. */
332 strcpy(execname, "");
333
334 /* 00400000-0040c000 r-xp 00000000 fd:01 41038 /bin/cat */
335 n = sscanf(bf, "%"PRI_lx64"-%"PRI_lx64" %s %"PRI_lx64" %x:%x %u %[^\n]\n",
336 &event->mmap2.start, &event->mmap2.len, prot,
337 &event->mmap2.pgoff, &event->mmap2.maj,
338 &event->mmap2.min,
339 &ino, execname);
340
341 /*
342 * Anon maps don't have the execname.
343 */
344 if (n < 7)
345 continue;
346
347 event->mmap2.ino = (u64)ino;
348
349 /*
350 * Just like the kernel, see __perf_event_mmap in kernel/perf_event.c
351 */
352 if (machine__is_host(machine))
353 event->header.misc = PERF_RECORD_MISC_USER;
354 else
355 event->header.misc = PERF_RECORD_MISC_GUEST_USER;
356
357 /* map protection and flags bits */
358 event->mmap2.prot = 0;
359 event->mmap2.flags = 0;
360 if (prot[0] == 'r')
361 event->mmap2.prot |= PROT_READ;
362 if (prot[1] == 'w')
363 event->mmap2.prot |= PROT_WRITE;
364 if (prot[2] == 'x')
365 event->mmap2.prot |= PROT_EXEC;
366
367 if (prot[3] == 's')
368 event->mmap2.flags |= MAP_SHARED;
369 else
370 event->mmap2.flags |= MAP_PRIVATE;
371
372 if (prot[2] != 'x') {
373 if (!mmap_data || prot[0] != 'r')
374 continue;
375
376 event->header.misc |= PERF_RECORD_MISC_MMAP_DATA;
377 }
378
379out:
380 if (truncation)
381 event->header.misc |= PERF_RECORD_MISC_PROC_MAP_PARSE_TIMEOUT;
382
383 if (!strcmp(execname, ""))
384 strcpy(execname, anonstr);
385
386 if (hugetlbfs_mnt_len &&
387 !strncmp(execname, hugetlbfs_mnt, hugetlbfs_mnt_len)) {
388 strcpy(execname, anonstr);
389 event->mmap2.flags |= MAP_HUGETLB;
390 }
391
392 size = strlen(execname) + 1;
393 memcpy(event->mmap2.filename, execname, size);
394 size = PERF_ALIGN(size, sizeof(u64));
395 event->mmap2.len -= event->mmap.start;
396 event->mmap2.header.size = (sizeof(event->mmap2) -
397 (sizeof(event->mmap2.filename) - size));
398 memset(event->mmap2.filename + size, 0, machine->id_hdr_size);
399 event->mmap2.header.size += machine->id_hdr_size;
400 event->mmap2.pid = tgid;
401 event->mmap2.tid = pid;
402
403 if (perf_tool__process_synth_event(tool, event, machine, process) != 0) {
404 rc = -1;
405 break;
406 }
407
408 if (truncation)
409 break;
410 }
411
412 fclose(fp);
413 return rc;
414}
415
416int perf_event__synthesize_modules(struct perf_tool *tool, perf_event__handler_t process,
417 struct machine *machine)
418{
419 int rc = 0;
420 struct map *pos;
421 struct maps *maps = machine__kernel_maps(machine);
422 union perf_event *event = zalloc((sizeof(event->mmap) +
423 machine->id_hdr_size));
424 if (event == NULL) {
425 pr_debug("Not enough memory synthesizing mmap event "
426 "for kernel modules\n");
427 return -1;
428 }
429
430 event->header.type = PERF_RECORD_MMAP;
431
432 /*
433 * kernel uses 0 for user space maps, see kernel/perf_event.c
434 * __perf_event_mmap
435 */
436 if (machine__is_host(machine))
437 event->header.misc = PERF_RECORD_MISC_KERNEL;
438 else
439 event->header.misc = PERF_RECORD_MISC_GUEST_KERNEL;
440
441 for (pos = maps__first(maps); pos; pos = map__next(pos)) {
442 size_t size;
443
444 if (!__map__is_kmodule(pos))
445 continue;
446
447 size = PERF_ALIGN(pos->dso->long_name_len + 1, sizeof(u64));
448 event->mmap.header.type = PERF_RECORD_MMAP;
449 event->mmap.header.size = (sizeof(event->mmap) -
450 (sizeof(event->mmap.filename) - size));
451 memset(event->mmap.filename + size, 0, machine->id_hdr_size);
452 event->mmap.header.size += machine->id_hdr_size;
453 event->mmap.start = pos->start;
454 event->mmap.len = pos->end - pos->start;
455 event->mmap.pid = machine->pid;
456
457 memcpy(event->mmap.filename, pos->dso->long_name,
458 pos->dso->long_name_len + 1);
459 if (perf_tool__process_synth_event(tool, event, machine, process) != 0) {
460 rc = -1;
461 break;
462 }
463 }
464
465 free(event);
466 return rc;
467}
468
469static int __event__synthesize_thread(union perf_event *comm_event,
470 union perf_event *mmap_event,
471 union perf_event *fork_event,
472 union perf_event *namespaces_event,
473 pid_t pid, int full, perf_event__handler_t process,
474 struct perf_tool *tool, struct machine *machine, bool mmap_data)
475{
476 char filename[PATH_MAX];
477 DIR *tasks;
478 struct dirent *dirent;
479 pid_t tgid, ppid;
480 int rc = 0;
481
482 /* special case: only send one comm event using passed in pid */
483 if (!full) {
484 tgid = perf_event__synthesize_comm(tool, comm_event, pid,
485 process, machine);
486
487 if (tgid == -1)
488 return -1;
489
490 if (perf_event__synthesize_namespaces(tool, namespaces_event, pid,
491 tgid, process, machine) < 0)
492 return -1;
493
494 /*
495 * send mmap only for thread group leader
496 * see thread__init_map_groups
497 */
498 if (pid == tgid &&
499 perf_event__synthesize_mmap_events(tool, mmap_event, pid, tgid,
500 process, machine, mmap_data))
501 return -1;
502
503 return 0;
504 }
505
506 if (machine__is_default_guest(machine))
507 return 0;
508
509 snprintf(filename, sizeof(filename), "%s/proc/%d/task",
510 machine->root_dir, pid);
511
512 tasks = opendir(filename);
513 if (tasks == NULL) {
514 pr_debug("couldn't open %s\n", filename);
515 return 0;
516 }
517
518 while ((dirent = readdir(tasks)) != NULL) {
519 char *end;
520 pid_t _pid;
521
522 _pid = strtol(dirent->d_name, &end, 10);
523 if (*end)
524 continue;
525
526 rc = -1;
527 if (perf_event__prepare_comm(comm_event, _pid, machine,
528 &tgid, &ppid) != 0)
529 break;
530
531 if (perf_event__synthesize_fork(tool, fork_event, _pid, tgid,
532 ppid, process, machine) < 0)
533 break;
534
535 if (perf_event__synthesize_namespaces(tool, namespaces_event, _pid,
536 tgid, process, machine) < 0)
537 break;
538
539 /*
540 * Send the prepared comm event
541 */
542 if (perf_tool__process_synth_event(tool, comm_event, machine, process) != 0)
543 break;
544
545 rc = 0;
546 if (_pid == pid) {
547 /* process the parent's maps too */
548 rc = perf_event__synthesize_mmap_events(tool, mmap_event, pid, tgid,
549 process, machine, mmap_data);
550 if (rc)
551 break;
552 }
553 }
554
555 closedir(tasks);
556 return rc;
557}
558
559int perf_event__synthesize_thread_map(struct perf_tool *tool,
560 struct perf_thread_map *threads,
561 perf_event__handler_t process,
562 struct machine *machine,
563 bool mmap_data)
564{
565 union perf_event *comm_event, *mmap_event, *fork_event;
566 union perf_event *namespaces_event;
567 int err = -1, thread, j;
568
569 comm_event = malloc(sizeof(comm_event->comm) + machine->id_hdr_size);
570 if (comm_event == NULL)
571 goto out;
572
573 mmap_event = malloc(sizeof(mmap_event->mmap2) + machine->id_hdr_size);
574 if (mmap_event == NULL)
575 goto out_free_comm;
576
577 fork_event = malloc(sizeof(fork_event->fork) + machine->id_hdr_size);
578 if (fork_event == NULL)
579 goto out_free_mmap;
580
581 namespaces_event = malloc(sizeof(namespaces_event->namespaces) +
582 (NR_NAMESPACES * sizeof(struct perf_ns_link_info)) +
583 machine->id_hdr_size);
584 if (namespaces_event == NULL)
585 goto out_free_fork;
586
587 err = 0;
588 for (thread = 0; thread < threads->nr; ++thread) {
589 if (__event__synthesize_thread(comm_event, mmap_event,
590 fork_event, namespaces_event,
591 perf_thread_map__pid(threads, thread), 0,
592 process, tool, machine,
593 mmap_data)) {
594 err = -1;
595 break;
596 }
597
598 /*
599 * comm.pid is set to thread group id by
600 * perf_event__synthesize_comm
601 */
602 if ((int) comm_event->comm.pid != perf_thread_map__pid(threads, thread)) {
603 bool need_leader = true;
604
605 /* is thread group leader in thread_map? */
606 for (j = 0; j < threads->nr; ++j) {
607 if ((int) comm_event->comm.pid == perf_thread_map__pid(threads, j)) {
608 need_leader = false;
609 break;
610 }
611 }
612
613 /* if not, generate events for it */
614 if (need_leader &&
615 __event__synthesize_thread(comm_event, mmap_event,
616 fork_event, namespaces_event,
617 comm_event->comm.pid, 0,
618 process, tool, machine,
619 mmap_data)) {
620 err = -1;
621 break;
622 }
623 }
624 }
625 free(namespaces_event);
626out_free_fork:
627 free(fork_event);
628out_free_mmap:
629 free(mmap_event);
630out_free_comm:
631 free(comm_event);
632out:
633 return err;
634}
635
636static int __perf_event__synthesize_threads(struct perf_tool *tool,
637 perf_event__handler_t process,
638 struct machine *machine,
639 bool mmap_data,
640 struct dirent **dirent,
641 int start,
642 int num)
643{
644 union perf_event *comm_event, *mmap_event, *fork_event;
645 union perf_event *namespaces_event;
646 int err = -1;
647 char *end;
648 pid_t pid;
649 int i;
650
651 comm_event = malloc(sizeof(comm_event->comm) + machine->id_hdr_size);
652 if (comm_event == NULL)
653 goto out;
654
655 mmap_event = malloc(sizeof(mmap_event->mmap2) + machine->id_hdr_size);
656 if (mmap_event == NULL)
657 goto out_free_comm;
658
659 fork_event = malloc(sizeof(fork_event->fork) + machine->id_hdr_size);
660 if (fork_event == NULL)
661 goto out_free_mmap;
662
663 namespaces_event = malloc(sizeof(namespaces_event->namespaces) +
664 (NR_NAMESPACES * sizeof(struct perf_ns_link_info)) +
665 machine->id_hdr_size);
666 if (namespaces_event == NULL)
667 goto out_free_fork;
668
669 for (i = start; i < start + num; i++) {
670 if (!isdigit(dirent[i]->d_name[0]))
671 continue;
672
673 pid = (pid_t)strtol(dirent[i]->d_name, &end, 10);
674 /* only interested in proper numerical dirents */
675 if (*end)
676 continue;
677 /*
678 * We may race with exiting thread, so don't stop just because
679 * one thread couldn't be synthesized.
680 */
681 __event__synthesize_thread(comm_event, mmap_event, fork_event,
682 namespaces_event, pid, 1, process,
683 tool, machine, mmap_data);
684 }
685 err = 0;
686
687 free(namespaces_event);
688out_free_fork:
689 free(fork_event);
690out_free_mmap:
691 free(mmap_event);
692out_free_comm:
693 free(comm_event);
694out:
695 return err;
696}
697
698struct synthesize_threads_arg {
699 struct perf_tool *tool;
700 perf_event__handler_t process;
701 struct machine *machine;
702 bool mmap_data;
703 struct dirent **dirent;
704 int num;
705 int start;
706};
707
708static void *synthesize_threads_worker(void *arg)
709{
710 struct synthesize_threads_arg *args = arg;
711
712 __perf_event__synthesize_threads(args->tool, args->process,
713 args->machine, args->mmap_data,
714 args->dirent,
715 args->start, args->num);
716 return NULL;
717}
718
719int perf_event__synthesize_threads(struct perf_tool *tool,
720 perf_event__handler_t process,
721 struct machine *machine,
722 bool mmap_data,
723 unsigned int nr_threads_synthesize)
724{
725 struct synthesize_threads_arg *args = NULL;
726 pthread_t *synthesize_threads = NULL;
727 char proc_path[PATH_MAX];
728 struct dirent **dirent;
729 int num_per_thread;
730 int m, n, i, j;
731 int thread_nr;
732 int base = 0;
733 int err = -1;
734
735
736 if (machine__is_default_guest(machine))
737 return 0;
738
739 snprintf(proc_path, sizeof(proc_path), "%s/proc", machine->root_dir);
740 n = scandir(proc_path, &dirent, 0, alphasort);
741 if (n < 0)
742 return err;
743
744 if (nr_threads_synthesize == UINT_MAX)
745 thread_nr = sysconf(_SC_NPROCESSORS_ONLN);
746 else
747 thread_nr = nr_threads_synthesize;
748
749 if (thread_nr <= 1) {
750 err = __perf_event__synthesize_threads(tool, process,
751 machine, mmap_data,
752 dirent, base, n);
753 goto free_dirent;
754 }
755 if (thread_nr > n)
756 thread_nr = n;
757
758 synthesize_threads = calloc(sizeof(pthread_t), thread_nr);
759 if (synthesize_threads == NULL)
760 goto free_dirent;
761
762 args = calloc(sizeof(*args), thread_nr);
763 if (args == NULL)
764 goto free_threads;
765
766 num_per_thread = n / thread_nr;
767 m = n % thread_nr;
768 for (i = 0; i < thread_nr; i++) {
769 args[i].tool = tool;
770 args[i].process = process;
771 args[i].machine = machine;
772 args[i].mmap_data = mmap_data;
773 args[i].dirent = dirent;
774 }
775 for (i = 0; i < m; i++) {
776 args[i].num = num_per_thread + 1;
777 args[i].start = i * args[i].num;
778 }
779 if (i != 0)
780 base = args[i-1].start + args[i-1].num;
781 for (j = i; j < thread_nr; j++) {
782 args[j].num = num_per_thread;
783 args[j].start = base + (j - i) * args[i].num;
784 }
785
786 for (i = 0; i < thread_nr; i++) {
787 if (pthread_create(&synthesize_threads[i], NULL,
788 synthesize_threads_worker, &args[i]))
789 goto out_join;
790 }
791 err = 0;
792out_join:
793 for (i = 0; i < thread_nr; i++)
794 pthread_join(synthesize_threads[i], NULL);
795 free(args);
796free_threads:
797 free(synthesize_threads);
798free_dirent:
799 for (i = 0; i < n; i++)
800 zfree(&dirent[i]);
801 free(dirent);
802
803 return err;
804}
805
806int __weak perf_event__synthesize_extra_kmaps(struct perf_tool *tool __maybe_unused,
807 perf_event__handler_t process __maybe_unused,
808 struct machine *machine __maybe_unused)
809{
810 return 0;
811}
812
813static int __perf_event__synthesize_kernel_mmap(struct perf_tool *tool,
814 perf_event__handler_t process,
815 struct machine *machine)
816{
817 size_t size;
818 struct map *map = machine__kernel_map(machine);
819 struct kmap *kmap;
820 int err;
821 union perf_event *event;
822
823 if (map == NULL)
824 return -1;
825
826 kmap = map__kmap(map);
827 if (!kmap->ref_reloc_sym)
828 return -1;
829
830 /*
831 * We should get this from /sys/kernel/sections/.text, but till that is
832 * available use this, and after it is use this as a fallback for older
833 * kernels.
834 */
835 event = zalloc((sizeof(event->mmap) + machine->id_hdr_size));
836 if (event == NULL) {
837 pr_debug("Not enough memory synthesizing mmap event "
838 "for kernel modules\n");
839 return -1;
840 }
841
842 if (machine__is_host(machine)) {
843 /*
844 * kernel uses PERF_RECORD_MISC_USER for user space maps,
845 * see kernel/perf_event.c __perf_event_mmap
846 */
847 event->header.misc = PERF_RECORD_MISC_KERNEL;
848 } else {
849 event->header.misc = PERF_RECORD_MISC_GUEST_KERNEL;
850 }
851
852 size = snprintf(event->mmap.filename, sizeof(event->mmap.filename),
853 "%s%s", machine->mmap_name, kmap->ref_reloc_sym->name) + 1;
854 size = PERF_ALIGN(size, sizeof(u64));
855 event->mmap.header.type = PERF_RECORD_MMAP;
856 event->mmap.header.size = (sizeof(event->mmap) -
857 (sizeof(event->mmap.filename) - size) + machine->id_hdr_size);
858 event->mmap.pgoff = kmap->ref_reloc_sym->addr;
859 event->mmap.start = map->start;
860 event->mmap.len = map->end - event->mmap.start;
861 event->mmap.pid = machine->pid;
862
863 err = perf_tool__process_synth_event(tool, event, machine, process);
864 free(event);
865
866 return err;
867}
868
869int perf_event__synthesize_kernel_mmap(struct perf_tool *tool,
870 perf_event__handler_t process,
871 struct machine *machine)
872{
873 int err;
874
875 err = __perf_event__synthesize_kernel_mmap(tool, process, machine);
876 if (err < 0)
877 return err;
878
879 return perf_event__synthesize_extra_kmaps(tool, process, machine);
880}
881
882int perf_event__synthesize_thread_map2(struct perf_tool *tool,
883 struct perf_thread_map *threads,
884 perf_event__handler_t process,
885 struct machine *machine)
886{
887 union perf_event *event;
888 int i, err, size;
889
890 size = sizeof(event->thread_map);
891 size += threads->nr * sizeof(event->thread_map.entries[0]);
892
893 event = zalloc(size);
894 if (!event)
895 return -ENOMEM;
896
897 event->header.type = PERF_RECORD_THREAD_MAP;
898 event->header.size = size;
899 event->thread_map.nr = threads->nr;
900
901 for (i = 0; i < threads->nr; i++) {
902 struct perf_record_thread_map_entry *entry = &event->thread_map.entries[i];
903 char *comm = perf_thread_map__comm(threads, i);
904
905 if (!comm)
906 comm = (char *) "";
907
908 entry->pid = perf_thread_map__pid(threads, i);
909 strncpy((char *) &entry->comm, comm, sizeof(entry->comm));
910 }
911
912 err = process(tool, event, NULL, machine);
913
914 free(event);
915 return err;
916}
917
918static void synthesize_cpus(struct cpu_map_entries *cpus,
919 struct perf_cpu_map *map)
920{
921 int i;
922
923 cpus->nr = map->nr;
924
925 for (i = 0; i < map->nr; i++)
926 cpus->cpu[i] = map->map[i];
927}
928
929static void synthesize_mask(struct perf_record_record_cpu_map *mask,
930 struct perf_cpu_map *map, int max)
931{
932 int i;
933
934 mask->nr = BITS_TO_LONGS(max);
935 mask->long_size = sizeof(long);
936
937 for (i = 0; i < map->nr; i++)
938 set_bit(map->map[i], mask->mask);
939}
940
941static size_t cpus_size(struct perf_cpu_map *map)
942{
943 return sizeof(struct cpu_map_entries) + map->nr * sizeof(u16);
944}
945
946static size_t mask_size(struct perf_cpu_map *map, int *max)
947{
948 int i;
949
950 *max = 0;
951
952 for (i = 0; i < map->nr; i++) {
953 /* bit possition of the cpu is + 1 */
954 int bit = map->map[i] + 1;
955
956 if (bit > *max)
957 *max = bit;
958 }
959
960 return sizeof(struct perf_record_record_cpu_map) + BITS_TO_LONGS(*max) * sizeof(long);
961}
962
963void *cpu_map_data__alloc(struct perf_cpu_map *map, size_t *size, u16 *type, int *max)
964{
965 size_t size_cpus, size_mask;
966 bool is_dummy = perf_cpu_map__empty(map);
967
968 /*
969 * Both array and mask data have variable size based
970 * on the number of cpus and their actual values.
971 * The size of the 'struct perf_record_cpu_map_data' is:
972 *
973 * array = size of 'struct cpu_map_entries' +
974 * number of cpus * sizeof(u64)
975 *
976 * mask = size of 'struct perf_record_record_cpu_map' +
977 * maximum cpu bit converted to size of longs
978 *
979 * and finaly + the size of 'struct perf_record_cpu_map_data'.
980 */
981 size_cpus = cpus_size(map);
982 size_mask = mask_size(map, max);
983
984 if (is_dummy || (size_cpus < size_mask)) {
985 *size += size_cpus;
986 *type = PERF_CPU_MAP__CPUS;
987 } else {
988 *size += size_mask;
989 *type = PERF_CPU_MAP__MASK;
990 }
991
992 *size += sizeof(struct perf_record_cpu_map_data);
993 *size = PERF_ALIGN(*size, sizeof(u64));
994 return zalloc(*size);
995}
996
997void cpu_map_data__synthesize(struct perf_record_cpu_map_data *data, struct perf_cpu_map *map,
998 u16 type, int max)
999{
1000 data->type = type;
1001
1002 switch (type) {
1003 case PERF_CPU_MAP__CPUS:
1004 synthesize_cpus((struct cpu_map_entries *) data->data, map);
1005 break;
1006 case PERF_CPU_MAP__MASK:
1007 synthesize_mask((struct perf_record_record_cpu_map *)data->data, map, max);
1008 default:
1009 break;
1010 };
1011}
1012
1013static struct perf_record_cpu_map *cpu_map_event__new(struct perf_cpu_map *map)
1014{
1015 size_t size = sizeof(struct perf_record_cpu_map);
1016 struct perf_record_cpu_map *event;
1017 int max;
1018 u16 type;
1019
1020 event = cpu_map_data__alloc(map, &size, &type, &max);
1021 if (!event)
1022 return NULL;
1023
1024 event->header.type = PERF_RECORD_CPU_MAP;
1025 event->header.size = size;
1026 event->data.type = type;
1027
1028 cpu_map_data__synthesize(&event->data, map, type, max);
1029 return event;
1030}
1031
1032int perf_event__synthesize_cpu_map(struct perf_tool *tool,
1033 struct perf_cpu_map *map,
1034 perf_event__handler_t process,
1035 struct machine *machine)
1036{
1037 struct perf_record_cpu_map *event;
1038 int err;
1039
1040 event = cpu_map_event__new(map);
1041 if (!event)
1042 return -ENOMEM;
1043
1044 err = process(tool, (union perf_event *) event, NULL, machine);
1045
1046 free(event);
1047 return err;
1048}
1049
1050int perf_event__synthesize_stat_config(struct perf_tool *tool,
1051 struct perf_stat_config *config,
1052 perf_event__handler_t process,
1053 struct machine *machine)
1054{
1055 struct perf_record_stat_config *event;
1056 int size, i = 0, err;
1057
1058 size = sizeof(*event);
1059 size += (PERF_STAT_CONFIG_TERM__MAX * sizeof(event->data[0]));
1060
1061 event = zalloc(size);
1062 if (!event)
1063 return -ENOMEM;
1064
1065 event->header.type = PERF_RECORD_STAT_CONFIG;
1066 event->header.size = size;
1067 event->nr = PERF_STAT_CONFIG_TERM__MAX;
1068
1069#define ADD(__term, __val) \
1070 event->data[i].tag = PERF_STAT_CONFIG_TERM__##__term; \
1071 event->data[i].val = __val; \
1072 i++;
1073
1074 ADD(AGGR_MODE, config->aggr_mode)
1075 ADD(INTERVAL, config->interval)
1076 ADD(SCALE, config->scale)
1077
1078 WARN_ONCE(i != PERF_STAT_CONFIG_TERM__MAX,
1079 "stat config terms unbalanced\n");
1080#undef ADD
1081
1082 err = process(tool, (union perf_event *) event, NULL, machine);
1083
1084 free(event);
1085 return err;
1086}
1087
1088int perf_event__synthesize_stat(struct perf_tool *tool,
1089 u32 cpu, u32 thread, u64 id,
1090 struct perf_counts_values *count,
1091 perf_event__handler_t process,
1092 struct machine *machine)
1093{
1094 struct perf_record_stat event;
1095
1096 event.header.type = PERF_RECORD_STAT;
1097 event.header.size = sizeof(event);
1098 event.header.misc = 0;
1099
1100 event.id = id;
1101 event.cpu = cpu;
1102 event.thread = thread;
1103 event.val = count->val;
1104 event.ena = count->ena;
1105 event.run = count->run;
1106
1107 return process(tool, (union perf_event *) &event, NULL, machine);
1108}
1109
1110int perf_event__synthesize_stat_round(struct perf_tool *tool,
1111 u64 evtime, u64 type,
1112 perf_event__handler_t process,
1113 struct machine *machine)
1114{
1115 struct perf_record_stat_round event;
1116
1117 event.header.type = PERF_RECORD_STAT_ROUND;
1118 event.header.size = sizeof(event);
1119 event.header.misc = 0;
1120
1121 event.time = evtime;
1122 event.type = type;
1123
1124 return process(tool, (union perf_event *) &event, NULL, machine);
1125}
1126
1127size_t perf_event__sample_event_size(const struct perf_sample *sample, u64 type, u64 read_format)
1128{
1129 size_t sz, result = sizeof(struct perf_record_sample);
1130
1131 if (type & PERF_SAMPLE_IDENTIFIER)
1132 result += sizeof(u64);
1133
1134 if (type & PERF_SAMPLE_IP)
1135 result += sizeof(u64);
1136
1137 if (type & PERF_SAMPLE_TID)
1138 result += sizeof(u64);
1139
1140 if (type & PERF_SAMPLE_TIME)
1141 result += sizeof(u64);
1142
1143 if (type & PERF_SAMPLE_ADDR)
1144 result += sizeof(u64);
1145
1146 if (type & PERF_SAMPLE_ID)
1147 result += sizeof(u64);
1148
1149 if (type & PERF_SAMPLE_STREAM_ID)
1150 result += sizeof(u64);
1151
1152 if (type & PERF_SAMPLE_CPU)
1153 result += sizeof(u64);
1154
1155 if (type & PERF_SAMPLE_PERIOD)
1156 result += sizeof(u64);
1157
1158 if (type & PERF_SAMPLE_READ) {
1159 result += sizeof(u64);
1160 if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
1161 result += sizeof(u64);
1162 if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
1163 result += sizeof(u64);
1164 /* PERF_FORMAT_ID is forced for PERF_SAMPLE_READ */
1165 if (read_format & PERF_FORMAT_GROUP) {
1166 sz = sample->read.group.nr *
1167 sizeof(struct sample_read_value);
1168 result += sz;
1169 } else {
1170 result += sizeof(u64);
1171 }
1172 }
1173
1174 if (type & PERF_SAMPLE_CALLCHAIN) {
1175 sz = (sample->callchain->nr + 1) * sizeof(u64);
1176 result += sz;
1177 }
1178
1179 if (type & PERF_SAMPLE_RAW) {
1180 result += sizeof(u32);
1181 result += sample->raw_size;
1182 }
1183
1184 if (type & PERF_SAMPLE_BRANCH_STACK) {
1185 sz = sample->branch_stack->nr * sizeof(struct branch_entry);
1186 sz += sizeof(u64);
1187 result += sz;
1188 }
1189
1190 if (type & PERF_SAMPLE_REGS_USER) {
1191 if (sample->user_regs.abi) {
1192 result += sizeof(u64);
1193 sz = hweight64(sample->user_regs.mask) * sizeof(u64);
1194 result += sz;
1195 } else {
1196 result += sizeof(u64);
1197 }
1198 }
1199
1200 if (type & PERF_SAMPLE_STACK_USER) {
1201 sz = sample->user_stack.size;
1202 result += sizeof(u64);
1203 if (sz) {
1204 result += sz;
1205 result += sizeof(u64);
1206 }
1207 }
1208
1209 if (type & PERF_SAMPLE_WEIGHT)
1210 result += sizeof(u64);
1211
1212 if (type & PERF_SAMPLE_DATA_SRC)
1213 result += sizeof(u64);
1214
1215 if (type & PERF_SAMPLE_TRANSACTION)
1216 result += sizeof(u64);
1217
1218 if (type & PERF_SAMPLE_REGS_INTR) {
1219 if (sample->intr_regs.abi) {
1220 result += sizeof(u64);
1221 sz = hweight64(sample->intr_regs.mask) * sizeof(u64);
1222 result += sz;
1223 } else {
1224 result += sizeof(u64);
1225 }
1226 }
1227
1228 if (type & PERF_SAMPLE_PHYS_ADDR)
1229 result += sizeof(u64);
1230
1231 return result;
1232}
1233
1234int perf_event__synthesize_sample(union perf_event *event, u64 type, u64 read_format,
1235 const struct perf_sample *sample)
1236{
1237 __u64 *array;
1238 size_t sz;
1239 /*
1240 * used for cross-endian analysis. See git commit 65014ab3
1241 * for why this goofiness is needed.
1242 */
1243 union u64_swap u;
1244
1245 array = event->sample.array;
1246
1247 if (type & PERF_SAMPLE_IDENTIFIER) {
1248 *array = sample->id;
1249 array++;
1250 }
1251
1252 if (type & PERF_SAMPLE_IP) {
1253 *array = sample->ip;
1254 array++;
1255 }
1256
1257 if (type & PERF_SAMPLE_TID) {
1258 u.val32[0] = sample->pid;
1259 u.val32[1] = sample->tid;
1260 *array = u.val64;
1261 array++;
1262 }
1263
1264 if (type & PERF_SAMPLE_TIME) {
1265 *array = sample->time;
1266 array++;
1267 }
1268
1269 if (type & PERF_SAMPLE_ADDR) {
1270 *array = sample->addr;
1271 array++;
1272 }
1273
1274 if (type & PERF_SAMPLE_ID) {
1275 *array = sample->id;
1276 array++;
1277 }
1278
1279 if (type & PERF_SAMPLE_STREAM_ID) {
1280 *array = sample->stream_id;
1281 array++;
1282 }
1283
1284 if (type & PERF_SAMPLE_CPU) {
1285 u.val32[0] = sample->cpu;
1286 u.val32[1] = 0;
1287 *array = u.val64;
1288 array++;
1289 }
1290
1291 if (type & PERF_SAMPLE_PERIOD) {
1292 *array = sample->period;
1293 array++;
1294 }
1295
1296 if (type & PERF_SAMPLE_READ) {
1297 if (read_format & PERF_FORMAT_GROUP)
1298 *array = sample->read.group.nr;
1299 else
1300 *array = sample->read.one.value;
1301 array++;
1302
1303 if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) {
1304 *array = sample->read.time_enabled;
1305 array++;
1306 }
1307
1308 if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) {
1309 *array = sample->read.time_running;
1310 array++;
1311 }
1312
1313 /* PERF_FORMAT_ID is forced for PERF_SAMPLE_READ */
1314 if (read_format & PERF_FORMAT_GROUP) {
1315 sz = sample->read.group.nr *
1316 sizeof(struct sample_read_value);
1317 memcpy(array, sample->read.group.values, sz);
1318 array = (void *)array + sz;
1319 } else {
1320 *array = sample->read.one.id;
1321 array++;
1322 }
1323 }
1324
1325 if (type & PERF_SAMPLE_CALLCHAIN) {
1326 sz = (sample->callchain->nr + 1) * sizeof(u64);
1327 memcpy(array, sample->callchain, sz);
1328 array = (void *)array + sz;
1329 }
1330
1331 if (type & PERF_SAMPLE_RAW) {
1332 u.val32[0] = sample->raw_size;
1333 *array = u.val64;
1334 array = (void *)array + sizeof(u32);
1335
1336 memcpy(array, sample->raw_data, sample->raw_size);
1337 array = (void *)array + sample->raw_size;
1338 }
1339
1340 if (type & PERF_SAMPLE_BRANCH_STACK) {
1341 sz = sample->branch_stack->nr * sizeof(struct branch_entry);
1342 sz += sizeof(u64);
1343 memcpy(array, sample->branch_stack, sz);
1344 array = (void *)array + sz;
1345 }
1346
1347 if (type & PERF_SAMPLE_REGS_USER) {
1348 if (sample->user_regs.abi) {
1349 *array++ = sample->user_regs.abi;
1350 sz = hweight64(sample->user_regs.mask) * sizeof(u64);
1351 memcpy(array, sample->user_regs.regs, sz);
1352 array = (void *)array + sz;
1353 } else {
1354 *array++ = 0;
1355 }
1356 }
1357
1358 if (type & PERF_SAMPLE_STACK_USER) {
1359 sz = sample->user_stack.size;
1360 *array++ = sz;
1361 if (sz) {
1362 memcpy(array, sample->user_stack.data, sz);
1363 array = (void *)array + sz;
1364 *array++ = sz;
1365 }
1366 }
1367
1368 if (type & PERF_SAMPLE_WEIGHT) {
1369 *array = sample->weight;
1370 array++;
1371 }
1372
1373 if (type & PERF_SAMPLE_DATA_SRC) {
1374 *array = sample->data_src;
1375 array++;
1376 }
1377
1378 if (type & PERF_SAMPLE_TRANSACTION) {
1379 *array = sample->transaction;
1380 array++;
1381 }
1382
1383 if (type & PERF_SAMPLE_REGS_INTR) {
1384 if (sample->intr_regs.abi) {
1385 *array++ = sample->intr_regs.abi;
1386 sz = hweight64(sample->intr_regs.mask) * sizeof(u64);
1387 memcpy(array, sample->intr_regs.regs, sz);
1388 array = (void *)array + sz;
1389 } else {
1390 *array++ = 0;
1391 }
1392 }
1393
1394 if (type & PERF_SAMPLE_PHYS_ADDR) {
1395 *array = sample->phys_addr;
1396 array++;
1397 }
1398
1399 return 0;
1400}
1401
1402int perf_event__synthesize_id_index(struct perf_tool *tool, perf_event__handler_t process,
1403 struct evlist *evlist, struct machine *machine)
1404{
1405 union perf_event *ev;
1406 struct evsel *evsel;
1407 size_t nr = 0, i = 0, sz, max_nr, n;
1408 int err;
1409
1410 pr_debug2("Synthesizing id index\n");
1411
1412 max_nr = (UINT16_MAX - sizeof(struct perf_record_id_index)) /
1413 sizeof(struct id_index_entry);
1414
1415 evlist__for_each_entry(evlist, evsel)
1416 nr += evsel->ids;
1417
1418 n = nr > max_nr ? max_nr : nr;
1419 sz = sizeof(struct perf_record_id_index) + n * sizeof(struct id_index_entry);
1420 ev = zalloc(sz);
1421 if (!ev)
1422 return -ENOMEM;
1423
1424 ev->id_index.header.type = PERF_RECORD_ID_INDEX;
1425 ev->id_index.header.size = sz;
1426 ev->id_index.nr = n;
1427
1428 evlist__for_each_entry(evlist, evsel) {
1429 u32 j;
1430
1431 for (j = 0; j < evsel->ids; j++) {
1432 struct id_index_entry *e;
1433 struct perf_sample_id *sid;
1434
1435 if (i >= n) {
1436 err = process(tool, ev, NULL, machine);
1437 if (err)
1438 goto out_err;
1439 nr -= n;
1440 i = 0;
1441 }
1442
1443 e = &ev->id_index.entries[i++];
1444
1445 e->id = evsel->id[j];
1446
1447 sid = perf_evlist__id2sid(evlist, e->id);
1448 if (!sid) {
1449 free(ev);
1450 return -ENOENT;
1451 }
1452
1453 e->idx = sid->idx;
1454 e->cpu = sid->cpu;
1455 e->tid = sid->tid;
1456 }
1457 }
1458
1459 sz = sizeof(struct perf_record_id_index) + nr * sizeof(struct id_index_entry);
1460 ev->id_index.header.size = sz;
1461 ev->id_index.nr = nr;
1462
1463 err = process(tool, ev, NULL, machine);
1464out_err:
1465 free(ev);
1466
1467 return err;
1468}
1469
1470int __machine__synthesize_threads(struct machine *machine, struct perf_tool *tool,
1471 struct target *target, struct perf_thread_map *threads,
1472 perf_event__handler_t process, bool data_mmap,
1473 unsigned int nr_threads_synthesize)
1474{
1475 if (target__has_task(target))
1476 return perf_event__synthesize_thread_map(tool, threads, process, machine, data_mmap);
1477 else if (target__has_cpu(target))
1478 return perf_event__synthesize_threads(tool, process,
1479 machine, data_mmap,
1480 nr_threads_synthesize);
1481 /* command specified */
1482 return 0;
1483}
1484
1485int machine__synthesize_threads(struct machine *machine, struct target *target,
1486 struct perf_thread_map *threads, bool data_mmap,
1487 unsigned int nr_threads_synthesize)
1488{
1489 return __machine__synthesize_threads(machine, NULL, target, threads,
1490 perf_event__process, data_mmap,
1491 nr_threads_synthesize);
1492}
1493
1494static struct perf_record_event_update *event_update_event__new(size_t size, u64 type, u64 id)
1495{
1496 struct perf_record_event_update *ev;
1497
1498 size += sizeof(*ev);
1499 size = PERF_ALIGN(size, sizeof(u64));
1500
1501 ev = zalloc(size);
1502 if (ev) {
1503 ev->header.type = PERF_RECORD_EVENT_UPDATE;
1504 ev->header.size = (u16)size;
1505 ev->type = type;
1506 ev->id = id;
1507 }
1508 return ev;
1509}
1510
1511int perf_event__synthesize_event_update_unit(struct perf_tool *tool, struct evsel *evsel,
1512 perf_event__handler_t process)
1513{
1514 size_t size = strlen(evsel->unit);
1515 struct perf_record_event_update *ev;
1516 int err;
1517
1518 ev = event_update_event__new(size + 1, PERF_EVENT_UPDATE__UNIT, evsel->id[0]);
1519 if (ev == NULL)
1520 return -ENOMEM;
1521
1522 strlcpy(ev->data, evsel->unit, size + 1);
1523 err = process(tool, (union perf_event *)ev, NULL, NULL);
1524 free(ev);
1525 return err;
1526}
1527
1528int perf_event__synthesize_event_update_scale(struct perf_tool *tool, struct evsel *evsel,
1529 perf_event__handler_t process)
1530{
1531 struct perf_record_event_update *ev;
1532 struct perf_record_event_update_scale *ev_data;
1533 int err;
1534
1535 ev = event_update_event__new(sizeof(*ev_data), PERF_EVENT_UPDATE__SCALE, evsel->id[0]);
1536 if (ev == NULL)
1537 return -ENOMEM;
1538
1539 ev_data = (struct perf_record_event_update_scale *)ev->data;
1540 ev_data->scale = evsel->scale;
1541 err = process(tool, (union perf_event *)ev, NULL, NULL);
1542 free(ev);
1543 return err;
1544}
1545
1546int perf_event__synthesize_event_update_name(struct perf_tool *tool, struct evsel *evsel,
1547 perf_event__handler_t process)
1548{
1549 struct perf_record_event_update *ev;
1550 size_t len = strlen(evsel->name);
1551 int err;
1552
1553 ev = event_update_event__new(len + 1, PERF_EVENT_UPDATE__NAME, evsel->id[0]);
1554 if (ev == NULL)
1555 return -ENOMEM;
1556
1557 strlcpy(ev->data, evsel->name, len + 1);
1558 err = process(tool, (union perf_event *)ev, NULL, NULL);
1559 free(ev);
1560 return err;
1561}
1562
1563int perf_event__synthesize_event_update_cpus(struct perf_tool *tool, struct evsel *evsel,
1564 perf_event__handler_t process)
1565{
1566 size_t size = sizeof(struct perf_record_event_update);
1567 struct perf_record_event_update *ev;
1568 int max, err;
1569 u16 type;
1570
1571 if (!evsel->core.own_cpus)
1572 return 0;
1573
1574 ev = cpu_map_data__alloc(evsel->core.own_cpus, &size, &type, &max);
1575 if (!ev)
1576 return -ENOMEM;
1577
1578 ev->header.type = PERF_RECORD_EVENT_UPDATE;
1579 ev->header.size = (u16)size;
1580 ev->type = PERF_EVENT_UPDATE__CPUS;
1581 ev->id = evsel->id[0];
1582
1583 cpu_map_data__synthesize((struct perf_record_cpu_map_data *)ev->data,
1584 evsel->core.own_cpus, type, max);
1585
1586 err = process(tool, (union perf_event *)ev, NULL, NULL);
1587 free(ev);
1588 return err;
1589}
1590
1591int perf_event__synthesize_attrs(struct perf_tool *tool, struct evlist *evlist,
1592 perf_event__handler_t process)
1593{
1594 struct evsel *evsel;
1595 int err = 0;
1596
1597 evlist__for_each_entry(evlist, evsel) {
1598 err = perf_event__synthesize_attr(tool, &evsel->core.attr, evsel->ids,
1599 evsel->id, process);
1600 if (err) {
1601 pr_debug("failed to create perf header attribute\n");
1602 return err;
1603 }
1604 }
1605
1606 return err;
1607}
1608
1609static bool has_unit(struct evsel *evsel)
1610{
1611 return evsel->unit && *evsel->unit;
1612}
1613
1614static bool has_scale(struct evsel *evsel)
1615{
1616 return evsel->scale != 1;
1617}
1618
1619int perf_event__synthesize_extra_attr(struct perf_tool *tool, struct evlist *evsel_list,
1620 perf_event__handler_t process, bool is_pipe)
1621{
1622 struct evsel *evsel;
1623 int err;
1624
1625 /*
1626 * Synthesize other events stuff not carried within
1627 * attr event - unit, scale, name
1628 */
1629 evlist__for_each_entry(evsel_list, evsel) {
1630 if (!evsel->supported)
1631 continue;
1632
1633 /*
1634 * Synthesize unit and scale only if it's defined.
1635 */
1636 if (has_unit(evsel)) {
1637 err = perf_event__synthesize_event_update_unit(tool, evsel, process);
1638 if (err < 0) {
1639 pr_err("Couldn't synthesize evsel unit.\n");
1640 return err;
1641 }
1642 }
1643
1644 if (has_scale(evsel)) {
1645 err = perf_event__synthesize_event_update_scale(tool, evsel, process);
1646 if (err < 0) {
1647 pr_err("Couldn't synthesize evsel evsel.\n");
1648 return err;
1649 }
1650 }
1651
1652 if (evsel->core.own_cpus) {
1653 err = perf_event__synthesize_event_update_cpus(tool, evsel, process);
1654 if (err < 0) {
1655 pr_err("Couldn't synthesize evsel cpus.\n");
1656 return err;
1657 }
1658 }
1659
1660 /*
1661 * Name is needed only for pipe output,
1662 * perf.data carries event names.
1663 */
1664 if (is_pipe) {
1665 err = perf_event__synthesize_event_update_name(tool, evsel, process);
1666 if (err < 0) {
1667 pr_err("Couldn't synthesize evsel name.\n");
1668 return err;
1669 }
1670 }
1671 }
1672 return 0;
1673}
1674
1675int perf_event__synthesize_attr(struct perf_tool *tool, struct perf_event_attr *attr,
1676 u32 ids, u64 *id, perf_event__handler_t process)
1677{
1678 union perf_event *ev;
1679 size_t size;
1680 int err;
1681
1682 size = sizeof(struct perf_event_attr);
1683 size = PERF_ALIGN(size, sizeof(u64));
1684 size += sizeof(struct perf_event_header);
1685 size += ids * sizeof(u64);
1686
1687 ev = zalloc(size);
1688
1689 if (ev == NULL)
1690 return -ENOMEM;
1691
1692 ev->attr.attr = *attr;
1693 memcpy(ev->attr.id, id, ids * sizeof(u64));
1694
1695 ev->attr.header.type = PERF_RECORD_HEADER_ATTR;
1696 ev->attr.header.size = (u16)size;
1697
1698 if (ev->attr.header.size == size)
1699 err = process(tool, ev, NULL, NULL);
1700 else
1701 err = -E2BIG;
1702
1703 free(ev);
1704
1705 return err;
1706}
1707
1708int perf_event__synthesize_tracing_data(struct perf_tool *tool, int fd, struct evlist *evlist,
1709 perf_event__handler_t process)
1710{
1711 union perf_event ev;
1712 struct tracing_data *tdata;
1713 ssize_t size = 0, aligned_size = 0, padding;
1714 struct feat_fd ff;
1715
1716 /*
1717 * We are going to store the size of the data followed
1718 * by the data contents. Since the fd descriptor is a pipe,
1719 * we cannot seek back to store the size of the data once
1720 * we know it. Instead we:
1721 *
1722 * - write the tracing data to the temp file
1723 * - get/write the data size to pipe
1724 * - write the tracing data from the temp file
1725 * to the pipe
1726 */
1727 tdata = tracing_data_get(&evlist->core.entries, fd, true);
1728 if (!tdata)
1729 return -1;
1730
1731 memset(&ev, 0, sizeof(ev));
1732
1733 ev.tracing_data.header.type = PERF_RECORD_HEADER_TRACING_DATA;
1734 size = tdata->size;
1735 aligned_size = PERF_ALIGN(size, sizeof(u64));
1736 padding = aligned_size - size;
1737 ev.tracing_data.header.size = sizeof(ev.tracing_data);
1738 ev.tracing_data.size = aligned_size;
1739
1740 process(tool, &ev, NULL, NULL);
1741
1742 /*
1743 * The put function will copy all the tracing data
1744 * stored in temp file to the pipe.
1745 */
1746 tracing_data_put(tdata);
1747
1748 ff = (struct feat_fd){ .fd = fd };
1749 if (write_padded(&ff, NULL, 0, padding))
1750 return -1;
1751
1752 return aligned_size;
1753}
1754
1755int perf_event__synthesize_build_id(struct perf_tool *tool, struct dso *pos, u16 misc,
1756 perf_event__handler_t process, struct machine *machine)
1757{
1758 union perf_event ev;
1759 size_t len;
1760
1761 if (!pos->hit)
1762 return 0;
1763
1764 memset(&ev, 0, sizeof(ev));
1765
1766 len = pos->long_name_len + 1;
1767 len = PERF_ALIGN(len, NAME_ALIGN);
1768 memcpy(&ev.build_id.build_id, pos->build_id, sizeof(pos->build_id));
1769 ev.build_id.header.type = PERF_RECORD_HEADER_BUILD_ID;
1770 ev.build_id.header.misc = misc;
1771 ev.build_id.pid = machine->pid;
1772 ev.build_id.header.size = sizeof(ev.build_id) + len;
1773 memcpy(&ev.build_id.filename, pos->long_name, pos->long_name_len);
1774
1775 return process(tool, &ev, NULL, machine);
1776}
1777
1778int perf_event__synthesize_stat_events(struct perf_stat_config *config, struct perf_tool *tool,
1779 struct evlist *evlist, perf_event__handler_t process, bool attrs)
1780{
1781 int err;
1782
1783 if (attrs) {
1784 err = perf_event__synthesize_attrs(tool, evlist, process);
1785 if (err < 0) {
1786 pr_err("Couldn't synthesize attrs.\n");
1787 return err;
1788 }
1789 }
1790
1791 err = perf_event__synthesize_extra_attr(tool, evlist, process, attrs);
1792 err = perf_event__synthesize_thread_map2(tool, evlist->core.threads, process, NULL);
1793 if (err < 0) {
1794 pr_err("Couldn't synthesize thread map.\n");
1795 return err;
1796 }
1797
1798 err = perf_event__synthesize_cpu_map(tool, evlist->core.cpus, process, NULL);
1799 if (err < 0) {
1800 pr_err("Couldn't synthesize thread map.\n");
1801 return err;
1802 }
1803
1804 err = perf_event__synthesize_stat_config(tool, config, process, NULL);
1805 if (err < 0) {
1806 pr_err("Couldn't synthesize config.\n");
1807 return err;
1808 }
1809
1810 return 0;
1811}
1812
1813int __weak perf_event__synth_time_conv(const struct perf_event_mmap_page *pc __maybe_unused,
1814 struct perf_tool *tool __maybe_unused,
1815 perf_event__handler_t process __maybe_unused,
1816 struct machine *machine __maybe_unused)
1817{
1818 return 0;
1819}
1820
1821extern const struct perf_header_feature_ops feat_ops[HEADER_LAST_FEATURE];
1822
1823int perf_event__synthesize_features(struct perf_tool *tool, struct perf_session *session,
1824 struct evlist *evlist, perf_event__handler_t process)
1825{
1826 struct perf_header *header = &session->header;
1827 struct perf_record_header_feature *fe;
1828 struct feat_fd ff;
1829 size_t sz, sz_hdr;
1830 int feat, ret;
1831
1832 sz_hdr = sizeof(fe->header);
1833 sz = sizeof(union perf_event);
1834 /* get a nice alignment */
1835 sz = PERF_ALIGN(sz, page_size);
1836
1837 memset(&ff, 0, sizeof(ff));
1838
1839 ff.buf = malloc(sz);
1840 if (!ff.buf)
1841 return -ENOMEM;
1842
1843 ff.size = sz - sz_hdr;
1844 ff.ph = &session->header;
1845
1846 for_each_set_bit(feat, header->adds_features, HEADER_FEAT_BITS) {
1847 if (!feat_ops[feat].synthesize) {
1848 pr_debug("No record header feature for header :%d\n", feat);
1849 continue;
1850 }
1851
1852 ff.offset = sizeof(*fe);
1853
1854 ret = feat_ops[feat].write(&ff, evlist);
1855 if (ret || ff.offset <= (ssize_t)sizeof(*fe)) {
1856 pr_debug("Error writing feature\n");
1857 continue;
1858 }
1859 /* ff.buf may have changed due to realloc in do_write() */
1860 fe = ff.buf;
1861 memset(fe, 0, sizeof(*fe));
1862
1863 fe->feat_id = feat;
1864 fe->header.type = PERF_RECORD_HEADER_FEATURE;
1865 fe->header.size = ff.offset;
1866
1867 ret = process(tool, ff.buf, NULL, NULL);
1868 if (ret) {
1869 free(ff.buf);
1870 return ret;
1871 }
1872 }
1873
1874 /* Send HEADER_LAST_FEATURE mark. */
1875 fe = ff.buf;
1876 fe->feat_id = HEADER_LAST_FEATURE;
1877 fe->header.type = PERF_RECORD_HEADER_FEATURE;
1878 fe->header.size = sizeof(*fe);
1879
1880 ret = process(tool, ff.buf, NULL, NULL);
1881
1882 free(ff.buf);
1883 return ret;
1884}
diff --git a/tools/perf/util/synthetic-events.h b/tools/perf/util/synthetic-events.h
new file mode 100644
index 000000000000..baead0cdc381
--- /dev/null
+++ b/tools/perf/util/synthetic-events.h
@@ -0,0 +1,103 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef __PERF_SYNTHETIC_EVENTS_H
3#define __PERF_SYNTHETIC_EVENTS_H
4
5#include <stdbool.h>
6#include <sys/types.h> // pid_t
7#include <linux/compiler.h>
8#include <linux/types.h>
9
10struct auxtrace_record;
11struct dso;
12struct evlist;
13struct evsel;
14struct machine;
15struct perf_counts_values;
16struct perf_cpu_map;
17struct perf_event_attr;
18struct perf_event_mmap_page;
19struct perf_sample;
20struct perf_session;
21struct perf_stat_config;
22struct perf_thread_map;
23struct perf_tool;
24struct record_opts;
25struct target;
26
27union perf_event;
28
29typedef int (*perf_event__handler_t)(struct perf_tool *tool, union perf_event *event,
30 struct perf_sample *sample, struct machine *machine);
31
32int perf_event__synthesize_attrs(struct perf_tool *tool, struct evlist *evlist, perf_event__handler_t process);
33int perf_event__synthesize_attr(struct perf_tool *tool, struct perf_event_attr *attr, u32 ids, u64 *id, perf_event__handler_t process);
34int perf_event__synthesize_build_id(struct perf_tool *tool, struct dso *pos, u16 misc, perf_event__handler_t process, struct machine *machine);
35int perf_event__synthesize_cpu_map(struct perf_tool *tool, struct perf_cpu_map *cpus, perf_event__handler_t process, struct machine *machine);
36int perf_event__synthesize_event_update_cpus(struct perf_tool *tool, struct evsel *evsel, perf_event__handler_t process);
37int perf_event__synthesize_event_update_name(struct perf_tool *tool, struct evsel *evsel, perf_event__handler_t process);
38int perf_event__synthesize_event_update_scale(struct perf_tool *tool, struct evsel *evsel, perf_event__handler_t process);
39int perf_event__synthesize_event_update_unit(struct perf_tool *tool, struct evsel *evsel, perf_event__handler_t process);
40int perf_event__synthesize_extra_attr(struct perf_tool *tool, struct evlist *evsel_list, perf_event__handler_t process, bool is_pipe);
41int perf_event__synthesize_extra_kmaps(struct perf_tool *tool, perf_event__handler_t process, struct machine *machine);
42int perf_event__synthesize_features(struct perf_tool *tool, struct perf_session *session, struct evlist *evlist, perf_event__handler_t process);
43int perf_event__synthesize_id_index(struct perf_tool *tool, perf_event__handler_t process, struct evlist *evlist, struct machine *machine);
44int perf_event__synthesize_kernel_mmap(struct perf_tool *tool, perf_event__handler_t process, struct machine *machine);
45int perf_event__synthesize_mmap_events(struct perf_tool *tool, union perf_event *event, pid_t pid, pid_t tgid, perf_event__handler_t process, struct machine *machine, bool mmap_data);
46int perf_event__synthesize_modules(struct perf_tool *tool, perf_event__handler_t process, struct machine *machine);
47int perf_event__synthesize_namespaces(struct perf_tool *tool, union perf_event *event, pid_t pid, pid_t tgid, perf_event__handler_t process, struct machine *machine);
48int perf_event__synthesize_sample(union perf_event *event, u64 type, u64 read_format, const struct perf_sample *sample);
49int perf_event__synthesize_stat_config(struct perf_tool *tool, struct perf_stat_config *config, perf_event__handler_t process, struct machine *machine);
50int perf_event__synthesize_stat_events(struct perf_stat_config *config, struct perf_tool *tool, struct evlist *evlist, perf_event__handler_t process, bool attrs);
51int perf_event__synthesize_stat_round(struct perf_tool *tool, u64 time, u64 type, perf_event__handler_t process, struct machine *machine);
52int 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);
53int perf_event__synthesize_thread_map2(struct perf_tool *tool, struct perf_thread_map *threads, perf_event__handler_t process, struct machine *machine);
54int 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);
55int perf_event__synthesize_threads(struct perf_tool *tool, perf_event__handler_t process, struct machine *machine, bool mmap_data, unsigned int nr_threads_synthesize);
56int perf_event__synthesize_tracing_data(struct perf_tool *tool, int fd, struct evlist *evlist, perf_event__handler_t process);
57int perf_event__synth_time_conv(const struct perf_event_mmap_page *pc, struct perf_tool *tool, perf_event__handler_t process, struct machine *machine);
58pid_t perf_event__synthesize_comm(struct perf_tool *tool, union perf_event *event, pid_t pid, perf_event__handler_t process, struct machine *machine);
59
60int perf_tool__process_synth_event(struct perf_tool *tool, union perf_event *event, struct machine *machine, perf_event__handler_t process);
61
62size_t perf_event__sample_event_size(const struct perf_sample *sample, u64 type, u64 read_format);
63
64int __machine__synthesize_threads(struct machine *machine, struct perf_tool *tool,
65 struct target *target, struct perf_thread_map *threads,
66 perf_event__handler_t process, bool data_mmap,
67 unsigned int nr_threads_synthesize);
68int machine__synthesize_threads(struct machine *machine, struct target *target,
69 struct perf_thread_map *threads, bool data_mmap,
70 unsigned int nr_threads_synthesize);
71
72#ifdef HAVE_AUXTRACE_SUPPORT
73int perf_event__synthesize_auxtrace_info(struct auxtrace_record *itr, struct perf_tool *tool,
74 struct perf_session *session, perf_event__handler_t process);
75
76#else // HAVE_AUXTRACE_SUPPORT
77
78#include <errno.h>
79
80static inline int
81perf_event__synthesize_auxtrace_info(struct auxtrace_record *itr __maybe_unused,
82 struct perf_tool *tool __maybe_unused,
83 struct perf_session *session __maybe_unused,
84 perf_event__handler_t process __maybe_unused)
85{
86 return -EINVAL;
87}
88#endif // HAVE_AUXTRACE_SUPPORT
89
90#ifdef HAVE_LIBBPF_SUPPORT
91int perf_event__synthesize_bpf_events(struct perf_session *session, perf_event__handler_t process,
92 struct machine *machine, struct record_opts *opts);
93#else // HAVE_LIBBPF_SUPPORT
94static inline int perf_event__synthesize_bpf_events(struct perf_session *session __maybe_unused,
95 perf_event__handler_t process __maybe_unused,
96 struct machine *machine __maybe_unused,
97 struct record_opts *opts __maybe_unused)
98{
99 return 0;
100}
101#endif // HAVE_LIBBPF_SUPPORT
102
103#endif // __PERF_SYNTHETIC_EVENTS_H
diff --git a/tools/perf/util/target.c b/tools/perf/util/target.c
index 565f7aef7e6c..a3db13dea937 100644
--- a/tools/perf/util/target.c
+++ b/tools/perf/util/target.c
@@ -6,8 +6,6 @@
6 */ 6 */
7 7
8#include "target.h" 8#include "target.h"
9#include "util.h"
10#include "debug.h"
11 9
12#include <pwd.h> 10#include <pwd.h>
13#include <stdio.h> 11#include <stdio.h>
diff --git a/tools/perf/util/top.c b/tools/perf/util/top.c
index 51fb574998bb..ef96e3dd6902 100644
--- a/tools/perf/util/top.c
+++ b/tools/perf/util/top.c
@@ -5,7 +5,6 @@
5 * Refactored from builtin-top.c, see that files for further copyright notes. 5 * Refactored from builtin-top.c, see that files for further copyright notes.
6 */ 6 */
7 7
8#include "cpumap.h"
9#include "event.h" 8#include "event.h"
10#include "evlist.h" 9#include "evlist.h"
11#include "evsel.h" 10#include "evsel.h"
diff --git a/tools/perf/util/trace-event-info.c b/tools/perf/util/trace-event-info.c
index d63d542b2cde..fe07e7550930 100644
--- a/tools/perf/util/trace-event-info.c
+++ b/tools/perf/util/trace-event-info.c
@@ -2,7 +2,7 @@
2/* 2/*
3 * Copyright (C) 2008,2009, Steven Rostedt <srostedt@redhat.com> 3 * Copyright (C) 2008,2009, Steven Rostedt <srostedt@redhat.com>
4 */ 4 */
5#include "util.h" 5#include "util.h" // page_size
6#include <dirent.h> 6#include <dirent.h>
7#include <mntent.h> 7#include <mntent.h>
8#include <stdio.h> 8#include <stdio.h>
diff --git a/tools/perf/util/trace-event-read.c b/tools/perf/util/trace-event-read.c
index b6c0db068be0..8593d3c200c6 100644
--- a/tools/perf/util/trace-event-read.c
+++ b/tools/perf/util/trace-event-read.c
@@ -15,7 +15,6 @@
15#include <unistd.h> 15#include <unistd.h>
16#include <errno.h> 16#include <errno.h>
17 17
18#include "util.h"
19#include "trace-event.h" 18#include "trace-event.h"
20#include "debug.h" 19#include "debug.h"
21 20
diff --git a/tools/perf/util/trace-event.c b/tools/perf/util/trace-event.c
index 01b9d89bf5bf..b3ee651e3d91 100644
--- a/tools/perf/util/trace-event.c
+++ b/tools/perf/util/trace-event.c
@@ -14,7 +14,6 @@
14#include <api/fs/fs.h> 14#include <api/fs/fs.h>
15#include "trace-event.h" 15#include "trace-event.h"
16#include "machine.h" 16#include "machine.h"
17#include "util.h"
18 17
19/* 18/*
20 * global trace_event object used by trace_event__tp_format 19 * global trace_event object used by trace_event__tp_format
diff --git a/tools/perf/util/tsc.h b/tools/perf/util/tsc.h
index e0c3af34ac8d..3c5a632ee57c 100644
--- a/tools/perf/util/tsc.h
+++ b/tools/perf/util/tsc.h
@@ -4,13 +4,12 @@
4 4
5#include <linux/types.h> 5#include <linux/types.h>
6 6
7#include "event.h"
8
9struct perf_tsc_conversion { 7struct perf_tsc_conversion {
10 u16 time_shift; 8 u16 time_shift;
11 u32 time_mult; 9 u32 time_mult;
12 u64 time_zero; 10 u64 time_zero;
13}; 11};
12
14struct perf_event_mmap_page; 13struct perf_event_mmap_page;
15 14
16int perf_read_tsc_conversion(const struct perf_event_mmap_page *pc, 15int perf_read_tsc_conversion(const struct perf_event_mmap_page *pc,
@@ -20,13 +19,4 @@ u64 perf_time_to_tsc(u64 ns, struct perf_tsc_conversion *tc);
20u64 tsc_to_perf_time(u64 cyc, struct perf_tsc_conversion *tc); 19u64 tsc_to_perf_time(u64 cyc, struct perf_tsc_conversion *tc);
21u64 rdtsc(void); 20u64 rdtsc(void);
22 21
23struct perf_event_mmap_page; 22#endif // __PERF_TSC_H
24struct perf_tool;
25struct machine;
26
27int perf_event__synth_time_conv(const struct perf_event_mmap_page *pc,
28 struct perf_tool *tool,
29 perf_event__handler_t process,
30 struct machine *machine);
31
32#endif
diff --git a/tools/perf/util/unwind-libdw.c b/tools/perf/util/unwind-libdw.c
index 9ece188ae48a..15f6e46d7124 100644
--- a/tools/perf/util/unwind-libdw.c
+++ b/tools/perf/util/unwind-libdw.c
@@ -17,7 +17,6 @@
17#include "event.h" 17#include "event.h"
18#include "perf_regs.h" 18#include "perf_regs.h"
19#include "callchain.h" 19#include "callchain.h"
20#include "util.h"
21 20
22static char *debuginfo_path; 21static char *debuginfo_path;
23 22
diff --git a/tools/perf/util/unwind-libunwind-local.c b/tools/perf/util/unwind-libunwind-local.c
index ebdbb056510c..1800887b2255 100644
--- a/tools/perf/util/unwind-libunwind-local.c
+++ b/tools/perf/util/unwind-libunwind-local.c
@@ -37,7 +37,6 @@
37#include "unwind.h" 37#include "unwind.h"
38#include "map.h" 38#include "map.h"
39#include "symbol.h" 39#include "symbol.h"
40#include "util.h"
41#include "debug.h" 40#include "debug.h"
42#include "asm/bug.h" 41#include "asm/bug.h"
43#include "dso.h" 42#include "dso.h"
diff --git a/tools/perf/util/usage.c b/tools/perf/util/usage.c
index 3949a60b00ae..196438ee4c9d 100644
--- a/tools/perf/util/usage.c
+++ b/tools/perf/util/usage.c
@@ -8,7 +8,6 @@
8 * Copyright (C) Linus Torvalds, 2005 8 * Copyright (C) Linus Torvalds, 2005
9 */ 9 */
10#include "util.h" 10#include "util.h"
11#include "debug.h"
12#include <stdio.h> 11#include <stdio.h>
13#include <stdlib.h> 12#include <stdlib.h>
14#include <linux/compiler.h> 13#include <linux/compiler.h>
diff --git a/tools/perf/util/vdso.c b/tools/perf/util/vdso.c
index e5e6599603f4..ba4b4395f35d 100644
--- a/tools/perf/util/vdso.c
+++ b/tools/perf/util/vdso.c
@@ -11,7 +11,7 @@
11 11
12#include "vdso.h" 12#include "vdso.h"
13#include "dso.h" 13#include "dso.h"
14#include "util.h" 14#include <internal/lib.h>
15#include "map.h" 15#include "map.h"
16#include "symbol.h" 16#include "symbol.h"
17#include "machine.h" 17#include "machine.h"
diff --git a/tools/perf/util/zlib.c b/tools/perf/util/zlib.c
index 59d456f716e9..78d2297c1b67 100644
--- a/tools/perf/util/zlib.c
+++ b/tools/perf/util/zlib.c
@@ -7,11 +7,9 @@
7#include <sys/mman.h> 7#include <sys/mman.h>
8#include <zlib.h> 8#include <zlib.h>
9#include <linux/compiler.h> 9#include <linux/compiler.h>
10#include <internal/lib.h>
10 11
11#include "util/compress.h" 12#include "util/compress.h"
12#include "util/util.h"
13#include "util/debug.h"
14
15 13
16#define CHUNK_SIZE 16384 14#define CHUNK_SIZE 16384
17 15