diff options
| author | Ingo Molnar <mingo@kernel.org> | 2017-11-03 10:06:53 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@kernel.org> | 2017-11-03 10:06:53 -0400 |
| commit | 340b5319c98eb14f7a70947a38e17d06f5beea88 (patch) | |
| tree | ece6aeb203be9207ae16eb2ffb985fddc42db46d | |
| parent | 0d3d73aac2ff05c78387aa9dcc2c8aa3804405e7 (diff) | |
| parent | 7285cf3325b4a1dfb336d31eebc27dfbc30fb9aa (diff) | |
Merge tag 'perf-core-for-mingo-4.15-20171103' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core
Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo:
- Beautify the 'kcmp' and 'prctl' syscall arguments in 'perf trace'
(Arnaldo Carvalho de Melo)
- Implement a way to print formatted output to per-event files in 'perf script'
to facilitate generate flamegraphs, elliminating the need to write scripts to
do that separation (yuzhoujian, Arnaldo Carvalho de Melo)
Make 'perf stat --per-thread' update shadow stats to show metrics (Jiri Olsa)
- Fix double mapping al->addr in callchain processing for children without self
period (Namhyung Kim)
- Fix memory leak in addr2inlines() when libbfd is not used (Namhyung Kim)
- Show correct function name for srcline of callchains when libbfd is not used
(Namhyung Kim)
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
47 files changed, 999 insertions, 381 deletions
diff --git a/tools/include/uapi/linux/kcmp.h b/tools/include/uapi/linux/kcmp.h new file mode 100644 index 000000000000..481e103da78e --- /dev/null +++ b/tools/include/uapi/linux/kcmp.h | |||
| @@ -0,0 +1,27 @@ | |||
| 1 | #ifndef _UAPI_LINUX_KCMP_H | ||
| 2 | #define _UAPI_LINUX_KCMP_H | ||
| 3 | |||
| 4 | #include <linux/types.h> | ||
| 5 | |||
| 6 | /* Comparison type */ | ||
| 7 | enum kcmp_type { | ||
| 8 | KCMP_FILE, | ||
| 9 | KCMP_VM, | ||
| 10 | KCMP_FILES, | ||
| 11 | KCMP_FS, | ||
| 12 | KCMP_SIGHAND, | ||
| 13 | KCMP_IO, | ||
| 14 | KCMP_SYSVSEM, | ||
| 15 | KCMP_EPOLL_TFD, | ||
| 16 | |||
| 17 | KCMP_TYPES, | ||
| 18 | }; | ||
| 19 | |||
| 20 | /* Slot for KCMP_EPOLL_TFD */ | ||
| 21 | struct kcmp_epoll_slot { | ||
| 22 | __u32 efd; /* epoll file descriptor */ | ||
| 23 | __u32 tfd; /* target file number */ | ||
| 24 | __u32 toff; /* target offset within same numbered sequence */ | ||
| 25 | }; | ||
| 26 | |||
| 27 | #endif /* _UAPI_LINUX_KCMP_H */ | ||
diff --git a/tools/include/uapi/linux/prctl.h b/tools/include/uapi/linux/prctl.h new file mode 100644 index 000000000000..a8d0759a9e40 --- /dev/null +++ b/tools/include/uapi/linux/prctl.h | |||
| @@ -0,0 +1,200 @@ | |||
| 1 | #ifndef _LINUX_PRCTL_H | ||
| 2 | #define _LINUX_PRCTL_H | ||
| 3 | |||
| 4 | #include <linux/types.h> | ||
| 5 | |||
| 6 | /* Values to pass as first argument to prctl() */ | ||
| 7 | |||
| 8 | #define PR_SET_PDEATHSIG 1 /* Second arg is a signal */ | ||
| 9 | #define PR_GET_PDEATHSIG 2 /* Second arg is a ptr to return the signal */ | ||
| 10 | |||
| 11 | /* Get/set current->mm->dumpable */ | ||
| 12 | #define PR_GET_DUMPABLE 3 | ||
| 13 | #define PR_SET_DUMPABLE 4 | ||
| 14 | |||
| 15 | /* Get/set unaligned access control bits (if meaningful) */ | ||
| 16 | #define PR_GET_UNALIGN 5 | ||
| 17 | #define PR_SET_UNALIGN 6 | ||
| 18 | # define PR_UNALIGN_NOPRINT 1 /* silently fix up unaligned user accesses */ | ||
| 19 | # define PR_UNALIGN_SIGBUS 2 /* generate SIGBUS on unaligned user access */ | ||
| 20 | |||
| 21 | /* Get/set whether or not to drop capabilities on setuid() away from | ||
| 22 | * uid 0 (as per security/commoncap.c) */ | ||
| 23 | #define PR_GET_KEEPCAPS 7 | ||
| 24 | #define PR_SET_KEEPCAPS 8 | ||
| 25 | |||
| 26 | /* Get/set floating-point emulation control bits (if meaningful) */ | ||
| 27 | #define PR_GET_FPEMU 9 | ||
| 28 | #define PR_SET_FPEMU 10 | ||
| 29 | # define PR_FPEMU_NOPRINT 1 /* silently emulate fp operations accesses */ | ||
| 30 | # define PR_FPEMU_SIGFPE 2 /* don't emulate fp operations, send SIGFPE instead */ | ||
| 31 | |||
| 32 | /* Get/set floating-point exception mode (if meaningful) */ | ||
| 33 | #define PR_GET_FPEXC 11 | ||
| 34 | #define PR_SET_FPEXC 12 | ||
| 35 | # define PR_FP_EXC_SW_ENABLE 0x80 /* Use FPEXC for FP exception enables */ | ||
| 36 | # define PR_FP_EXC_DIV 0x010000 /* floating point divide by zero */ | ||
| 37 | # define PR_FP_EXC_OVF 0x020000 /* floating point overflow */ | ||
| 38 | # define PR_FP_EXC_UND 0x040000 /* floating point underflow */ | ||
| 39 | # define PR_FP_EXC_RES 0x080000 /* floating point inexact result */ | ||
| 40 | # define PR_FP_EXC_INV 0x100000 /* floating point invalid operation */ | ||
| 41 | # define PR_FP_EXC_DISABLED 0 /* FP exceptions disabled */ | ||
| 42 | # define PR_FP_EXC_NONRECOV 1 /* async non-recoverable exc. mode */ | ||
| 43 | # define PR_FP_EXC_ASYNC 2 /* async recoverable exception mode */ | ||
| 44 | # define PR_FP_EXC_PRECISE 3 /* precise exception mode */ | ||
| 45 | |||
| 46 | /* Get/set whether we use statistical process timing or accurate timestamp | ||
| 47 | * based process timing */ | ||
| 48 | #define PR_GET_TIMING 13 | ||
| 49 | #define PR_SET_TIMING 14 | ||
| 50 | # define PR_TIMING_STATISTICAL 0 /* Normal, traditional, | ||
| 51 | statistical process timing */ | ||
| 52 | # define PR_TIMING_TIMESTAMP 1 /* Accurate timestamp based | ||
| 53 | process timing */ | ||
| 54 | |||
| 55 | #define PR_SET_NAME 15 /* Set process name */ | ||
| 56 | #define PR_GET_NAME 16 /* Get process name */ | ||
| 57 | |||
| 58 | /* Get/set process endian */ | ||
| 59 | #define PR_GET_ENDIAN 19 | ||
| 60 | #define PR_SET_ENDIAN 20 | ||
| 61 | # define PR_ENDIAN_BIG 0 | ||
| 62 | # define PR_ENDIAN_LITTLE 1 /* True little endian mode */ | ||
| 63 | # define PR_ENDIAN_PPC_LITTLE 2 /* "PowerPC" pseudo little endian */ | ||
| 64 | |||
| 65 | /* Get/set process seccomp mode */ | ||
| 66 | #define PR_GET_SECCOMP 21 | ||
| 67 | #define PR_SET_SECCOMP 22 | ||
| 68 | |||
| 69 | /* Get/set the capability bounding set (as per security/commoncap.c) */ | ||
| 70 | #define PR_CAPBSET_READ 23 | ||
| 71 | #define PR_CAPBSET_DROP 24 | ||
| 72 | |||
| 73 | /* Get/set the process' ability to use the timestamp counter instruction */ | ||
| 74 | #define PR_GET_TSC 25 | ||
| 75 | #define PR_SET_TSC 26 | ||
| 76 | # define PR_TSC_ENABLE 1 /* allow the use of the timestamp counter */ | ||
| 77 | # define PR_TSC_SIGSEGV 2 /* throw a SIGSEGV instead of reading the TSC */ | ||
| 78 | |||
| 79 | /* Get/set securebits (as per security/commoncap.c) */ | ||
| 80 | #define PR_GET_SECUREBITS 27 | ||
| 81 | #define PR_SET_SECUREBITS 28 | ||
| 82 | |||
| 83 | /* | ||
| 84 | * Get/set the timerslack as used by poll/select/nanosleep | ||
| 85 | * A value of 0 means "use default" | ||
| 86 | */ | ||
| 87 | #define PR_SET_TIMERSLACK 29 | ||
| 88 | #define PR_GET_TIMERSLACK 30 | ||
| 89 | |||
| 90 | #define PR_TASK_PERF_EVENTS_DISABLE 31 | ||
| 91 | #define PR_TASK_PERF_EVENTS_ENABLE 32 | ||
| 92 | |||
| 93 | /* | ||
| 94 | * Set early/late kill mode for hwpoison memory corruption. | ||
| 95 | * This influences when the process gets killed on a memory corruption. | ||
| 96 | */ | ||
| 97 | #define PR_MCE_KILL 33 | ||
| 98 | # define PR_MCE_KILL_CLEAR 0 | ||
| 99 | # define PR_MCE_KILL_SET 1 | ||
| 100 | |||
| 101 | # define PR_MCE_KILL_LATE 0 | ||
| 102 | # define PR_MCE_KILL_EARLY 1 | ||
| 103 | # define PR_MCE_KILL_DEFAULT 2 | ||
| 104 | |||
| 105 | #define PR_MCE_KILL_GET 34 | ||
| 106 | |||
| 107 | /* | ||
| 108 | * Tune up process memory map specifics. | ||
| 109 | */ | ||
| 110 | #define PR_SET_MM 35 | ||
| 111 | # define PR_SET_MM_START_CODE 1 | ||
| 112 | # define PR_SET_MM_END_CODE 2 | ||
| 113 | # define PR_SET_MM_START_DATA 3 | ||
| 114 | # define PR_SET_MM_END_DATA 4 | ||
| 115 | # define PR_SET_MM_START_STACK 5 | ||
| 116 | # define PR_SET_MM_START_BRK 6 | ||
| 117 | # define PR_SET_MM_BRK 7 | ||
| 118 | # define PR_SET_MM_ARG_START 8 | ||
| 119 | # define PR_SET_MM_ARG_END 9 | ||
| 120 | # define PR_SET_MM_ENV_START 10 | ||
| 121 | # define PR_SET_MM_ENV_END 11 | ||
| 122 | # define PR_SET_MM_AUXV 12 | ||
| 123 | # define PR_SET_MM_EXE_FILE 13 | ||
| 124 | # define PR_SET_MM_MAP 14 | ||
| 125 | # define PR_SET_MM_MAP_SIZE 15 | ||
| 126 | |||
| 127 | /* | ||
| 128 | * This structure provides new memory descriptor | ||
| 129 | * map which mostly modifies /proc/pid/stat[m] | ||
| 130 | * output for a task. This mostly done in a | ||
| 131 | * sake of checkpoint/restore functionality. | ||
| 132 | */ | ||
| 133 | struct prctl_mm_map { | ||
| 134 | __u64 start_code; /* code section bounds */ | ||
| 135 | __u64 end_code; | ||
| 136 | __u64 start_data; /* data section bounds */ | ||
| 137 | __u64 end_data; | ||
| 138 | __u64 start_brk; /* heap for brk() syscall */ | ||
| 139 | __u64 brk; | ||
| 140 | __u64 start_stack; /* stack starts at */ | ||
| 141 | __u64 arg_start; /* command line arguments bounds */ | ||
| 142 | __u64 arg_end; | ||
| 143 | __u64 env_start; /* environment variables bounds */ | ||
| 144 | __u64 env_end; | ||
| 145 | __u64 *auxv; /* auxiliary vector */ | ||
| 146 | __u32 auxv_size; /* vector size */ | ||
| 147 | __u32 exe_fd; /* /proc/$pid/exe link file */ | ||
| 148 | }; | ||
| 149 | |||
| 150 | /* | ||
| 151 | * Set specific pid that is allowed to ptrace the current task. | ||
| 152 | * A value of 0 mean "no process". | ||
| 153 | */ | ||
| 154 | #define PR_SET_PTRACER 0x59616d61 | ||
| 155 | # define PR_SET_PTRACER_ANY ((unsigned long)-1) | ||
| 156 | |||
| 157 | #define PR_SET_CHILD_SUBREAPER 36 | ||
| 158 | #define PR_GET_CHILD_SUBREAPER 37 | ||
| 159 | |||
| 160 | /* | ||
| 161 | * If no_new_privs is set, then operations that grant new privileges (i.e. | ||
| 162 | * execve) will either fail or not grant them. This affects suid/sgid, | ||
| 163 | * file capabilities, and LSMs. | ||
| 164 | * | ||
| 165 | * Operations that merely manipulate or drop existing privileges (setresuid, | ||
| 166 | * capset, etc.) will still work. Drop those privileges if you want them gone. | ||
| 167 | * | ||
| 168 | * Changing LSM security domain is considered a new privilege. So, for example, | ||
| 169 | * asking selinux for a specific new context (e.g. with runcon) will result | ||
| 170 | * in execve returning -EPERM. | ||
| 171 | * | ||
| 172 | * See Documentation/prctl/no_new_privs.txt for more details. | ||
| 173 | */ | ||
| 174 | #define PR_SET_NO_NEW_PRIVS 38 | ||
| 175 | #define PR_GET_NO_NEW_PRIVS 39 | ||
| 176 | |||
| 177 | #define PR_GET_TID_ADDRESS 40 | ||
| 178 | |||
| 179 | #define PR_SET_THP_DISABLE 41 | ||
| 180 | #define PR_GET_THP_DISABLE 42 | ||
| 181 | |||
| 182 | /* | ||
| 183 | * Tell the kernel to start/stop helping userspace manage bounds tables. | ||
| 184 | */ | ||
| 185 | #define PR_MPX_ENABLE_MANAGEMENT 43 | ||
| 186 | #define PR_MPX_DISABLE_MANAGEMENT 44 | ||
| 187 | |||
| 188 | #define PR_SET_FP_MODE 45 | ||
| 189 | #define PR_GET_FP_MODE 46 | ||
| 190 | # define PR_FP_MODE_FR (1 << 0) /* 64b FP registers */ | ||
| 191 | # define PR_FP_MODE_FRE (1 << 1) /* 32b compatibility */ | ||
| 192 | |||
| 193 | /* Control the ambient capability set */ | ||
| 194 | #define PR_CAP_AMBIENT 47 | ||
| 195 | # define PR_CAP_AMBIENT_IS_SET 1 | ||
| 196 | # define PR_CAP_AMBIENT_RAISE 2 | ||
| 197 | # define PR_CAP_AMBIENT_LOWER 3 | ||
| 198 | # define PR_CAP_AMBIENT_CLEAR_ALL 4 | ||
| 199 | |||
| 200 | #endif /* _LINUX_PRCTL_H */ | ||
diff --git a/tools/perf/Documentation/perf-script.txt b/tools/perf/Documentation/perf-script.txt index 25e677344728..2811fcf684cb 100644 --- a/tools/perf/Documentation/perf-script.txt +++ b/tools/perf/Documentation/perf-script.txt | |||
| @@ -325,6 +325,10 @@ include::itrace.txt[] | |||
| 325 | Set the maximum number of program blocks to print with brstackasm for | 325 | Set the maximum number of program blocks to print with brstackasm for |
| 326 | each sample. | 326 | each sample. |
| 327 | 327 | ||
| 328 | --per-event-dump:: | ||
| 329 | Create per event files with a "perf.data.EVENT.dump" name instead of | ||
| 330 | printing to stdout, useful, for instance, for generating flamegraphs. | ||
| 331 | |||
| 328 | --inline:: | 332 | --inline:: |
| 329 | If a callgraph address belongs to an inlined function, the inline stack | 333 | If a callgraph address belongs to an inlined function, the inline stack |
| 330 | will be printed. Each entry has function name and file/line. Enabled by | 334 | will be printed. Each entry has function name and file/line. Enabled by |
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 5f7408118a2d..68cf1360a3f3 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf | |||
| @@ -420,6 +420,13 @@ sndrv_pcm_ioctl_tbl := $(srctree)/tools/perf/trace/beauty/sndrv_pcm_ioctl.sh | |||
| 420 | $(sndrv_pcm_ioctl_array): $(sndrv_pcm_hdr_dir)/asound.h $(sndrv_pcm_ioctl_tbl) | 420 | $(sndrv_pcm_ioctl_array): $(sndrv_pcm_hdr_dir)/asound.h $(sndrv_pcm_ioctl_tbl) |
| 421 | $(Q)$(SHELL) '$(sndrv_pcm_ioctl_tbl)' $(sndrv_pcm_hdr_dir) > $@ | 421 | $(Q)$(SHELL) '$(sndrv_pcm_ioctl_tbl)' $(sndrv_pcm_hdr_dir) > $@ |
| 422 | 422 | ||
| 423 | kcmp_type_array := $(beauty_outdir)/kcmp_type_array.c | ||
| 424 | kcmp_hdr_dir := $(srctree)/tools/include/uapi/linux/ | ||
| 425 | kcmp_type_tbl := $(srctree)/tools/perf/trace/beauty/kcmp_type.sh | ||
| 426 | |||
| 427 | $(kcmp_type_array): $(kcmp_hdr_dir)/kcmp.h $(kcmp_type_tbl) | ||
| 428 | $(Q)$(SHELL) '$(kcmp_type_tbl)' $(kcmp_hdr_dir) > $@ | ||
| 429 | |||
| 423 | kvm_ioctl_array := $(beauty_ioctl_outdir)/kvm_ioctl_array.c | 430 | kvm_ioctl_array := $(beauty_ioctl_outdir)/kvm_ioctl_array.c |
| 424 | kvm_hdr_dir := $(srctree)/tools/include/uapi/linux | 431 | kvm_hdr_dir := $(srctree)/tools/include/uapi/linux |
| 425 | kvm_ioctl_tbl := $(srctree)/tools/perf/trace/beauty/kvm_ioctl.sh | 432 | kvm_ioctl_tbl := $(srctree)/tools/perf/trace/beauty/kvm_ioctl.sh |
| @@ -448,6 +455,13 @@ madvise_behavior_tbl := $(srctree)/tools/perf/trace/beauty/madvise_behavior.sh | |||
| 448 | $(madvise_behavior_array): $(madvise_hdr_dir)/mman-common.h $(madvise_behavior_tbl) | 455 | $(madvise_behavior_array): $(madvise_hdr_dir)/mman-common.h $(madvise_behavior_tbl) |
| 449 | $(Q)$(SHELL) '$(madvise_behavior_tbl)' $(madvise_hdr_dir) > $@ | 456 | $(Q)$(SHELL) '$(madvise_behavior_tbl)' $(madvise_hdr_dir) > $@ |
| 450 | 457 | ||
| 458 | prctl_option_array := $(beauty_outdir)/prctl_option_array.c | ||
| 459 | prctl_hdr_dir := $(srctree)/tools/include/uapi/linux/ | ||
| 460 | prctl_option_tbl := $(srctree)/tools/perf/trace/beauty/prctl_option.sh | ||
| 461 | |||
| 462 | $(prctl_option_array): $(prctl_hdr_dir)/prctl.h $(prctl_option_tbl) | ||
| 463 | $(Q)$(SHELL) '$(prctl_option_tbl)' $(prctl_hdr_dir) > $@ | ||
| 464 | |||
| 451 | all: shell_compatibility_test $(ALL_PROGRAMS) $(LANG_BINDINGS) $(OTHER_PROGRAMS) | 465 | all: shell_compatibility_test $(ALL_PROGRAMS) $(LANG_BINDINGS) $(OTHER_PROGRAMS) |
| 452 | 466 | ||
| 453 | $(OUTPUT)python/perf.so: $(PYTHON_EXT_SRCS) $(PYTHON_EXT_DEPS) $(LIBTRACEEVENT_DYNAMIC_LIST) | 467 | $(OUTPUT)python/perf.so: $(PYTHON_EXT_SRCS) $(PYTHON_EXT_DEPS) $(LIBTRACEEVENT_DYNAMIC_LIST) |
| @@ -546,10 +560,12 @@ prepare: $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h archheaders $(drm_ioc | |||
| 546 | $(pkey_alloc_access_rights_array) \ | 560 | $(pkey_alloc_access_rights_array) \ |
| 547 | $(sndrv_pcm_ioctl_array) \ | 561 | $(sndrv_pcm_ioctl_array) \ |
| 548 | $(sndrv_ctl_ioctl_array) \ | 562 | $(sndrv_ctl_ioctl_array) \ |
| 563 | $(kcmp_type_array) \ | ||
| 549 | $(kvm_ioctl_array) \ | 564 | $(kvm_ioctl_array) \ |
| 550 | $(vhost_virtio_ioctl_array) \ | 565 | $(vhost_virtio_ioctl_array) \ |
| 551 | $(madvise_behavior_array) \ | 566 | $(madvise_behavior_array) \ |
| 552 | $(perf_ioctl_array) | 567 | $(perf_ioctl_array) \ |
| 568 | $(prctl_option_array) | ||
| 553 | 569 | ||
| 554 | $(OUTPUT)%.o: %.c prepare FORCE | 570 | $(OUTPUT)%.o: %.c prepare FORCE |
| 555 | $(Q)$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=$(build-dir) $@ | 571 | $(Q)$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=$(build-dir) $@ |
| @@ -828,8 +844,10 @@ clean:: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clea | |||
| 828 | $(OUTPUT)$(sndrv_ctl_ioctl_array) \ | 844 | $(OUTPUT)$(sndrv_ctl_ioctl_array) \ |
| 829 | $(OUTPUT)$(sndrv_pcm_ioctl_array) \ | 845 | $(OUTPUT)$(sndrv_pcm_ioctl_array) \ |
| 830 | $(OUTPUT)$(kvm_ioctl_array) \ | 846 | $(OUTPUT)$(kvm_ioctl_array) \ |
| 847 | $(OUTPUT)$(kcmp_type_array) \ | ||
| 831 | $(OUTPUT)$(vhost_virtio_ioctl_array) \ | 848 | $(OUTPUT)$(vhost_virtio_ioctl_array) \ |
| 832 | $(OUTPUT)$(perf_ioctl_array) | 849 | $(OUTPUT)$(perf_ioctl_array) \ |
| 850 | $(OUTPUT)$(prctl_option_array) | ||
| 833 | $(QUIET_SUBDIR0)Documentation $(QUIET_SUBDIR1) clean | 851 | $(QUIET_SUBDIR0)Documentation $(QUIET_SUBDIR1) clean |
| 834 | 852 | ||
| 835 | # | 853 | # |
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index c38373195c4a..2d5c87578f83 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c | |||
| @@ -356,7 +356,7 @@ static int __cmd_annotate(struct perf_annotate *ann) | |||
| 356 | } | 356 | } |
| 357 | 357 | ||
| 358 | if (total_nr_samples == 0) { | 358 | if (total_nr_samples == 0) { |
| 359 | ui__error("The %s file has no samples!\n", session->file->path); | 359 | ui__error("The %s file has no samples!\n", session->data->file.path); |
| 360 | goto out; | 360 | goto out; |
| 361 | } | 361 | } |
| 362 | 362 | ||
| @@ -400,7 +400,7 @@ int cmd_annotate(int argc, const char **argv) | |||
| 400 | .ordering_requires_timestamps = true, | 400 | .ordering_requires_timestamps = true, |
| 401 | }, | 401 | }, |
| 402 | }; | 402 | }; |
| 403 | struct perf_data_file file = { | 403 | struct perf_data data = { |
| 404 | .mode = PERF_DATA_MODE_READ, | 404 | .mode = PERF_DATA_MODE_READ, |
| 405 | }; | 405 | }; |
| 406 | struct option options[] = { | 406 | struct option options[] = { |
| @@ -410,7 +410,7 @@ int cmd_annotate(int argc, const char **argv) | |||
| 410 | "only consider symbols in these dsos"), | 410 | "only consider symbols in these dsos"), |
| 411 | OPT_STRING('s', "symbol", &annotate.sym_hist_filter, "symbol", | 411 | OPT_STRING('s', "symbol", &annotate.sym_hist_filter, "symbol", |
| 412 | "symbol to annotate"), | 412 | "symbol to annotate"), |
| 413 | OPT_BOOLEAN('f', "force", &file.force, "don't complain, do it"), | 413 | OPT_BOOLEAN('f', "force", &data.force, "don't complain, do it"), |
| 414 | OPT_INCR('v', "verbose", &verbose, | 414 | OPT_INCR('v', "verbose", &verbose, |
| 415 | "be more verbose (show symbol address, etc)"), | 415 | "be more verbose (show symbol address, etc)"), |
| 416 | OPT_BOOLEAN('q', "quiet", &quiet, "do now show any message"), | 416 | OPT_BOOLEAN('q', "quiet", &quiet, "do now show any message"), |
| @@ -482,9 +482,9 @@ int cmd_annotate(int argc, const char **argv) | |||
| 482 | if (quiet) | 482 | if (quiet) |
| 483 | perf_quiet_option(); | 483 | perf_quiet_option(); |
| 484 | 484 | ||
| 485 | file.path = input_name; | 485 | data.file.path = input_name; |
| 486 | 486 | ||
| 487 | annotate.session = perf_session__new(&file, false, &annotate.tool); | 487 | annotate.session = perf_session__new(&data, false, &annotate.tool); |
| 488 | if (annotate.session == NULL) | 488 | if (annotate.session == NULL) |
| 489 | return -1; | 489 | return -1; |
| 490 | 490 | ||
diff --git a/tools/perf/builtin-buildid-cache.c b/tools/perf/builtin-buildid-cache.c index e3eb6240ced0..cb2453b29365 100644 --- a/tools/perf/builtin-buildid-cache.c +++ b/tools/perf/builtin-buildid-cache.c | |||
| @@ -311,7 +311,7 @@ int cmd_buildid_cache(int argc, const char **argv) | |||
| 311 | *kcore_filename = NULL; | 311 | *kcore_filename = NULL; |
| 312 | char sbuf[STRERR_BUFSIZE]; | 312 | char sbuf[STRERR_BUFSIZE]; |
| 313 | 313 | ||
| 314 | struct perf_data_file file = { | 314 | struct perf_data data = { |
| 315 | .mode = PERF_DATA_MODE_READ, | 315 | .mode = PERF_DATA_MODE_READ, |
| 316 | }; | 316 | }; |
| 317 | struct perf_session *session = NULL; | 317 | struct perf_session *session = NULL; |
| @@ -352,10 +352,10 @@ int cmd_buildid_cache(int argc, const char **argv) | |||
| 352 | nsi = nsinfo__new(ns_id); | 352 | nsi = nsinfo__new(ns_id); |
| 353 | 353 | ||
| 354 | if (missing_filename) { | 354 | if (missing_filename) { |
| 355 | file.path = missing_filename; | 355 | data.file.path = missing_filename; |
| 356 | file.force = force; | 356 | data.force = force; |
| 357 | 357 | ||
| 358 | session = perf_session__new(&file, false, NULL); | 358 | session = perf_session__new(&data, false, NULL); |
| 359 | if (session == NULL) | 359 | if (session == NULL) |
| 360 | return -1; | 360 | return -1; |
| 361 | } | 361 | } |
diff --git a/tools/perf/builtin-buildid-list.c b/tools/perf/builtin-buildid-list.c index fdaca16e0c74..00099a830b0d 100644 --- a/tools/perf/builtin-buildid-list.c +++ b/tools/perf/builtin-buildid-list.c | |||
| @@ -50,10 +50,12 @@ static bool dso__skip_buildid(struct dso *dso, int with_hits) | |||
| 50 | static int perf_session__list_build_ids(bool force, bool with_hits) | 50 | static int perf_session__list_build_ids(bool force, bool with_hits) |
| 51 | { | 51 | { |
| 52 | struct perf_session *session; | 52 | struct perf_session *session; |
| 53 | struct perf_data_file file = { | 53 | struct perf_data data = { |
| 54 | .path = input_name, | 54 | .file = { |
| 55 | .mode = PERF_DATA_MODE_READ, | 55 | .path = input_name, |
| 56 | .force = force, | 56 | }, |
| 57 | .mode = PERF_DATA_MODE_READ, | ||
| 58 | .force = force, | ||
| 57 | }; | 59 | }; |
| 58 | 60 | ||
| 59 | symbol__elf_init(); | 61 | symbol__elf_init(); |
| @@ -63,7 +65,7 @@ static int perf_session__list_build_ids(bool force, bool with_hits) | |||
| 63 | if (filename__fprintf_build_id(input_name, stdout) > 0) | 65 | if (filename__fprintf_build_id(input_name, stdout) > 0) |
| 64 | goto out; | 66 | goto out; |
| 65 | 67 | ||
| 66 | session = perf_session__new(&file, false, &build_id__mark_dso_hit_ops); | 68 | session = perf_session__new(&data, false, &build_id__mark_dso_hit_ops); |
| 67 | if (session == NULL) | 69 | if (session == NULL) |
| 68 | return -1; | 70 | return -1; |
| 69 | 71 | ||
| @@ -71,7 +73,7 @@ static int perf_session__list_build_ids(bool force, bool with_hits) | |||
| 71 | * We take all buildids when the file contains AUX area tracing data | 73 | * We take all buildids when the file contains AUX area tracing data |
| 72 | * because we do not decode the trace because it would take too long. | 74 | * because we do not decode the trace because it would take too long. |
| 73 | */ | 75 | */ |
| 74 | if (!perf_data_file__is_pipe(&file) && | 76 | if (!perf_data__is_pipe(&data) && |
| 75 | perf_header__has_feat(&session->header, HEADER_AUXTRACE)) | 77 | perf_header__has_feat(&session->header, HEADER_AUXTRACE)) |
| 76 | with_hits = false; | 78 | with_hits = false; |
| 77 | 79 | ||
| @@ -79,7 +81,7 @@ static int perf_session__list_build_ids(bool force, bool with_hits) | |||
| 79 | * in pipe-mode, the only way to get the buildids is to parse | 81 | * in pipe-mode, the only way to get the buildids is to parse |
| 80 | * the record stream. Buildids are stored as RECORD_HEADER_BUILD_ID | 82 | * the record stream. Buildids are stored as RECORD_HEADER_BUILD_ID |
| 81 | */ | 83 | */ |
| 82 | if (with_hits || perf_data_file__is_pipe(&file)) | 84 | if (with_hits || perf_data__is_pipe(&data)) |
| 83 | perf_session__process_events(session); | 85 | perf_session__process_events(session); |
| 84 | 86 | ||
| 85 | perf_session__fprintf_dsos_buildid(session, stdout, dso__skip_buildid, with_hits); | 87 | perf_session__fprintf_dsos_buildid(session, stdout, dso__skip_buildid, with_hits); |
diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c index bb1ee22bd221..9590fdcc6484 100644 --- a/tools/perf/builtin-c2c.c +++ b/tools/perf/builtin-c2c.c | |||
| @@ -2523,7 +2523,7 @@ static int perf_c2c__report(int argc, const char **argv) | |||
| 2523 | { | 2523 | { |
| 2524 | struct perf_session *session; | 2524 | struct perf_session *session; |
| 2525 | struct ui_progress prog; | 2525 | struct ui_progress prog; |
| 2526 | struct perf_data_file file = { | 2526 | struct perf_data data = { |
| 2527 | .mode = PERF_DATA_MODE_READ, | 2527 | .mode = PERF_DATA_MODE_READ, |
| 2528 | }; | 2528 | }; |
| 2529 | char callchain_default_opt[] = CALLCHAIN_DEFAULT_OPT; | 2529 | char callchain_default_opt[] = CALLCHAIN_DEFAULT_OPT; |
| @@ -2572,8 +2572,8 @@ static int perf_c2c__report(int argc, const char **argv) | |||
| 2572 | if (!input_name || !strlen(input_name)) | 2572 | if (!input_name || !strlen(input_name)) |
| 2573 | input_name = "perf.data"; | 2573 | input_name = "perf.data"; |
| 2574 | 2574 | ||
| 2575 | file.path = input_name; | 2575 | data.file.path = input_name; |
| 2576 | file.force = symbol_conf.force; | 2576 | data.force = symbol_conf.force; |
| 2577 | 2577 | ||
| 2578 | err = setup_display(display); | 2578 | err = setup_display(display); |
| 2579 | if (err) | 2579 | if (err) |
| @@ -2591,7 +2591,7 @@ static int perf_c2c__report(int argc, const char **argv) | |||
| 2591 | goto out; | 2591 | goto out; |
| 2592 | } | 2592 | } |
| 2593 | 2593 | ||
| 2594 | session = perf_session__new(&file, 0, &c2c.tool); | 2594 | session = perf_session__new(&data, 0, &c2c.tool); |
| 2595 | if (session == NULL) { | 2595 | if (session == NULL) { |
| 2596 | pr_debug("No memory for session\n"); | 2596 | pr_debug("No memory for session\n"); |
| 2597 | goto out; | 2597 | goto out; |
| @@ -2611,7 +2611,7 @@ static int perf_c2c__report(int argc, const char **argv) | |||
| 2611 | goto out_session; | 2611 | goto out_session; |
| 2612 | 2612 | ||
| 2613 | /* No pipe support at the moment. */ | 2613 | /* No pipe support at the moment. */ |
| 2614 | if (perf_data_file__is_pipe(session->file)) { | 2614 | if (perf_data__is_pipe(session->data)) { |
| 2615 | pr_debug("No pipe support at the moment.\n"); | 2615 | pr_debug("No pipe support at the moment.\n"); |
| 2616 | goto out_session; | 2616 | goto out_session; |
| 2617 | } | 2617 | } |
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index 0cd4cf6a344b..67570e6417e5 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c | |||
| @@ -47,7 +47,7 @@ struct diff_hpp_fmt { | |||
| 47 | 47 | ||
| 48 | struct data__file { | 48 | struct data__file { |
| 49 | struct perf_session *session; | 49 | struct perf_session *session; |
| 50 | struct perf_data_file file; | 50 | struct perf_data data; |
| 51 | int idx; | 51 | int idx; |
| 52 | struct hists *hists; | 52 | struct hists *hists; |
| 53 | struct diff_hpp_fmt fmt[PERF_HPP_DIFF__MAX_INDEX]; | 53 | struct diff_hpp_fmt fmt[PERF_HPP_DIFF__MAX_INDEX]; |
| @@ -707,7 +707,7 @@ static void data__fprintf(void) | |||
| 707 | 707 | ||
| 708 | data__for_each_file(i, d) | 708 | data__for_each_file(i, d) |
| 709 | fprintf(stdout, "# [%d] %s %s\n", | 709 | fprintf(stdout, "# [%d] %s %s\n", |
| 710 | d->idx, d->file.path, | 710 | d->idx, d->data.file.path, |
| 711 | !d->idx ? "(Baseline)" : ""); | 711 | !d->idx ? "(Baseline)" : ""); |
| 712 | 712 | ||
| 713 | fprintf(stdout, "#\n"); | 713 | fprintf(stdout, "#\n"); |
| @@ -776,16 +776,16 @@ static int __cmd_diff(void) | |||
| 776 | int ret = -EINVAL, i; | 776 | int ret = -EINVAL, i; |
| 777 | 777 | ||
| 778 | data__for_each_file(i, d) { | 778 | data__for_each_file(i, d) { |
| 779 | d->session = perf_session__new(&d->file, false, &tool); | 779 | d->session = perf_session__new(&d->data, false, &tool); |
| 780 | if (!d->session) { | 780 | if (!d->session) { |
| 781 | pr_err("Failed to open %s\n", d->file.path); | 781 | pr_err("Failed to open %s\n", d->data.file.path); |
| 782 | ret = -1; | 782 | ret = -1; |
| 783 | goto out_delete; | 783 | goto out_delete; |
| 784 | } | 784 | } |
| 785 | 785 | ||
| 786 | ret = perf_session__process_events(d->session); | 786 | ret = perf_session__process_events(d->session); |
| 787 | if (ret) { | 787 | if (ret) { |
| 788 | pr_err("Failed to process %s\n", d->file.path); | 788 | pr_err("Failed to process %s\n", d->data.file.path); |
| 789 | goto out_delete; | 789 | goto out_delete; |
| 790 | } | 790 | } |
| 791 | 791 | ||
| @@ -1286,11 +1286,11 @@ static int data_init(int argc, const char **argv) | |||
| 1286 | return -ENOMEM; | 1286 | return -ENOMEM; |
| 1287 | 1287 | ||
| 1288 | data__for_each_file(i, d) { | 1288 | data__for_each_file(i, d) { |
| 1289 | struct perf_data_file *file = &d->file; | 1289 | struct perf_data *data = &d->data; |
| 1290 | 1290 | ||
| 1291 | file->path = use_default ? defaults[i] : argv[i]; | 1291 | data->file.path = use_default ? defaults[i] : argv[i]; |
| 1292 | file->mode = PERF_DATA_MODE_READ, | 1292 | data->mode = PERF_DATA_MODE_READ, |
| 1293 | file->force = force, | 1293 | data->force = force, |
| 1294 | 1294 | ||
| 1295 | d->idx = i; | 1295 | d->idx = i; |
| 1296 | } | 1296 | } |
diff --git a/tools/perf/builtin-evlist.c b/tools/perf/builtin-evlist.c index 6d210e40d611..93b85dc857b6 100644 --- a/tools/perf/builtin-evlist.c +++ b/tools/perf/builtin-evlist.c | |||
| @@ -21,14 +21,16 @@ static int __cmd_evlist(const char *file_name, struct perf_attr_details *details | |||
| 21 | { | 21 | { |
| 22 | struct perf_session *session; | 22 | struct perf_session *session; |
| 23 | struct perf_evsel *pos; | 23 | struct perf_evsel *pos; |
| 24 | struct perf_data_file file = { | 24 | struct perf_data data = { |
| 25 | .path = file_name, | 25 | .file = { |
| 26 | .mode = PERF_DATA_MODE_READ, | 26 | .path = file_name, |
| 27 | .force = details->force, | 27 | }, |
| 28 | .mode = PERF_DATA_MODE_READ, | ||
| 29 | .force = details->force, | ||
| 28 | }; | 30 | }; |
| 29 | bool has_tracepoint = false; | 31 | bool has_tracepoint = false; |
| 30 | 32 | ||
| 31 | session = perf_session__new(&file, 0, NULL); | 33 | session = perf_session__new(&data, 0, NULL); |
| 32 | if (session == NULL) | 34 | if (session == NULL) |
| 33 | return -1; | 35 | return -1; |
| 34 | 36 | ||
diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index 2b8032908fb2..91e65093d3c2 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c | |||
| @@ -35,7 +35,7 @@ struct perf_inject { | |||
| 35 | bool strip; | 35 | bool strip; |
| 36 | bool jit_mode; | 36 | bool jit_mode; |
| 37 | const char *input_name; | 37 | const char *input_name; |
| 38 | struct perf_data_file output; | 38 | struct perf_data output; |
| 39 | u64 bytes_written; | 39 | u64 bytes_written; |
| 40 | u64 aux_id; | 40 | u64 aux_id; |
| 41 | struct list_head samples; | 41 | struct list_head samples; |
| @@ -52,7 +52,7 @@ static int output_bytes(struct perf_inject *inject, void *buf, size_t sz) | |||
| 52 | { | 52 | { |
| 53 | ssize_t size; | 53 | ssize_t size; |
| 54 | 54 | ||
| 55 | size = perf_data_file__write(&inject->output, buf, sz); | 55 | size = perf_data__write(&inject->output, buf, sz); |
| 56 | if (size < 0) | 56 | if (size < 0) |
| 57 | return -errno; | 57 | return -errno; |
| 58 | 58 | ||
| @@ -145,7 +145,7 @@ static s64 perf_event__repipe_auxtrace(struct perf_tool *tool, | |||
| 145 | if (!inject->output.is_pipe) { | 145 | if (!inject->output.is_pipe) { |
| 146 | off_t offset; | 146 | off_t offset; |
| 147 | 147 | ||
| 148 | offset = lseek(inject->output.fd, 0, SEEK_CUR); | 148 | offset = lseek(inject->output.file.fd, 0, SEEK_CUR); |
| 149 | if (offset == -1) | 149 | if (offset == -1) |
| 150 | return -errno; | 150 | return -errno; |
| 151 | ret = auxtrace_index__auxtrace_event(&session->auxtrace_index, | 151 | ret = auxtrace_index__auxtrace_event(&session->auxtrace_index, |
| @@ -154,11 +154,11 @@ static s64 perf_event__repipe_auxtrace(struct perf_tool *tool, | |||
| 154 | return ret; | 154 | return ret; |
| 155 | } | 155 | } |
| 156 | 156 | ||
| 157 | if (perf_data_file__is_pipe(session->file) || !session->one_mmap) { | 157 | if (perf_data__is_pipe(session->data) || !session->one_mmap) { |
| 158 | ret = output_bytes(inject, event, event->header.size); | 158 | ret = output_bytes(inject, event, event->header.size); |
| 159 | if (ret < 0) | 159 | if (ret < 0) |
| 160 | return ret; | 160 | return ret; |
| 161 | ret = copy_bytes(inject, perf_data_file__fd(session->file), | 161 | ret = copy_bytes(inject, perf_data__fd(session->data), |
| 162 | event->auxtrace.size); | 162 | event->auxtrace.size); |
| 163 | } else { | 163 | } else { |
| 164 | ret = output_bytes(inject, event, | 164 | ret = output_bytes(inject, event, |
| @@ -637,8 +637,8 @@ static int __cmd_inject(struct perf_inject *inject) | |||
| 637 | { | 637 | { |
| 638 | int ret = -EINVAL; | 638 | int ret = -EINVAL; |
| 639 | struct perf_session *session = inject->session; | 639 | struct perf_session *session = inject->session; |
| 640 | struct perf_data_file *file_out = &inject->output; | 640 | struct perf_data *data_out = &inject->output; |
| 641 | int fd = perf_data_file__fd(file_out); | 641 | int fd = perf_data__fd(data_out); |
| 642 | u64 output_data_offset; | 642 | u64 output_data_offset; |
| 643 | 643 | ||
| 644 | signal(SIGINT, sig_handler); | 644 | signal(SIGINT, sig_handler); |
| @@ -693,14 +693,14 @@ static int __cmd_inject(struct perf_inject *inject) | |||
| 693 | if (!inject->itrace_synth_opts.set) | 693 | if (!inject->itrace_synth_opts.set) |
| 694 | auxtrace_index__free(&session->auxtrace_index); | 694 | auxtrace_index__free(&session->auxtrace_index); |
| 695 | 695 | ||
| 696 | if (!file_out->is_pipe) | 696 | if (!data_out->is_pipe) |
| 697 | lseek(fd, output_data_offset, SEEK_SET); | 697 | lseek(fd, output_data_offset, SEEK_SET); |
| 698 | 698 | ||
| 699 | ret = perf_session__process_events(session); | 699 | ret = perf_session__process_events(session); |
| 700 | if (ret) | 700 | if (ret) |
| 701 | return ret; | 701 | return ret; |
| 702 | 702 | ||
| 703 | if (!file_out->is_pipe) { | 703 | if (!data_out->is_pipe) { |
| 704 | if (inject->build_ids) | 704 | if (inject->build_ids) |
| 705 | perf_header__set_feat(&session->header, | 705 | perf_header__set_feat(&session->header, |
| 706 | HEADER_BUILD_ID); | 706 | HEADER_BUILD_ID); |
| @@ -775,11 +775,13 @@ int cmd_inject(int argc, const char **argv) | |||
| 775 | .input_name = "-", | 775 | .input_name = "-", |
| 776 | .samples = LIST_HEAD_INIT(inject.samples), | 776 | .samples = LIST_HEAD_INIT(inject.samples), |
| 777 | .output = { | 777 | .output = { |
| 778 | .path = "-", | 778 | .file = { |
| 779 | .mode = PERF_DATA_MODE_WRITE, | 779 | .path = "-", |
| 780 | }, | ||
| 781 | .mode = PERF_DATA_MODE_WRITE, | ||
| 780 | }, | 782 | }, |
| 781 | }; | 783 | }; |
| 782 | struct perf_data_file file = { | 784 | struct perf_data data = { |
| 783 | .mode = PERF_DATA_MODE_READ, | 785 | .mode = PERF_DATA_MODE_READ, |
| 784 | }; | 786 | }; |
| 785 | int ret; | 787 | int ret; |
| @@ -789,7 +791,7 @@ int cmd_inject(int argc, const char **argv) | |||
| 789 | "Inject build-ids into the output stream"), | 791 | "Inject build-ids into the output stream"), |
| 790 | OPT_STRING('i', "input", &inject.input_name, "file", | 792 | OPT_STRING('i', "input", &inject.input_name, "file", |
| 791 | "input file name"), | 793 | "input file name"), |
| 792 | OPT_STRING('o', "output", &inject.output.path, "file", | 794 | OPT_STRING('o', "output", &inject.output.file.path, "file", |
| 793 | "output file name"), | 795 | "output file name"), |
| 794 | OPT_BOOLEAN('s', "sched-stat", &inject.sched_stat, | 796 | OPT_BOOLEAN('s', "sched-stat", &inject.sched_stat, |
| 795 | "Merge sched-stat and sched-switch for getting events " | 797 | "Merge sched-stat and sched-switch for getting events " |
| @@ -801,7 +803,7 @@ int cmd_inject(int argc, const char **argv) | |||
| 801 | "be more verbose (show build ids, etc)"), | 803 | "be more verbose (show build ids, etc)"), |
| 802 | OPT_STRING(0, "kallsyms", &symbol_conf.kallsyms_name, "file", | 804 | OPT_STRING(0, "kallsyms", &symbol_conf.kallsyms_name, "file", |
| 803 | "kallsyms pathname"), | 805 | "kallsyms pathname"), |
| 804 | OPT_BOOLEAN('f', "force", &file.force, "don't complain, do it"), | 806 | OPT_BOOLEAN('f', "force", &data.force, "don't complain, do it"), |
| 805 | OPT_CALLBACK_OPTARG(0, "itrace", &inject.itrace_synth_opts, | 807 | OPT_CALLBACK_OPTARG(0, "itrace", &inject.itrace_synth_opts, |
| 806 | NULL, "opts", "Instruction Tracing options", | 808 | NULL, "opts", "Instruction Tracing options", |
| 807 | itrace_parse_synth_opts), | 809 | itrace_parse_synth_opts), |
| @@ -829,15 +831,15 @@ int cmd_inject(int argc, const char **argv) | |||
| 829 | return -1; | 831 | return -1; |
| 830 | } | 832 | } |
| 831 | 833 | ||
| 832 | if (perf_data_file__open(&inject.output)) { | 834 | if (perf_data__open(&inject.output)) { |
| 833 | perror("failed to create output file"); | 835 | perror("failed to create output file"); |
| 834 | return -1; | 836 | return -1; |
| 835 | } | 837 | } |
| 836 | 838 | ||
| 837 | inject.tool.ordered_events = inject.sched_stat; | 839 | inject.tool.ordered_events = inject.sched_stat; |
| 838 | 840 | ||
| 839 | file.path = inject.input_name; | 841 | data.file.path = inject.input_name; |
| 840 | inject.session = perf_session__new(&file, true, &inject.tool); | 842 | inject.session = perf_session__new(&data, true, &inject.tool); |
| 841 | if (inject.session == NULL) | 843 | if (inject.session == NULL) |
| 842 | return -1; | 844 | return -1; |
| 843 | 845 | ||
diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index d8f25ef8157b..abcab75cc5b9 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c | |||
| @@ -1893,7 +1893,7 @@ int cmd_kmem(int argc, const char **argv) | |||
| 1893 | { | 1893 | { |
| 1894 | const char * const default_slab_sort = "frag,hit,bytes"; | 1894 | const char * const default_slab_sort = "frag,hit,bytes"; |
| 1895 | const char * const default_page_sort = "bytes,hit"; | 1895 | const char * const default_page_sort = "bytes,hit"; |
| 1896 | struct perf_data_file file = { | 1896 | struct perf_data data = { |
| 1897 | .mode = PERF_DATA_MODE_READ, | 1897 | .mode = PERF_DATA_MODE_READ, |
| 1898 | }; | 1898 | }; |
| 1899 | const struct option kmem_options[] = { | 1899 | const struct option kmem_options[] = { |
| @@ -1909,7 +1909,7 @@ int cmd_kmem(int argc, const char **argv) | |||
| 1909 | "page, order, migtype, gfp", parse_sort_opt), | 1909 | "page, order, migtype, gfp", parse_sort_opt), |
| 1910 | OPT_CALLBACK('l', "line", NULL, "num", "show n lines", parse_line_opt), | 1910 | OPT_CALLBACK('l', "line", NULL, "num", "show n lines", parse_line_opt), |
| 1911 | OPT_BOOLEAN(0, "raw-ip", &raw_ip, "show raw ip instead of symbol"), | 1911 | OPT_BOOLEAN(0, "raw-ip", &raw_ip, "show raw ip instead of symbol"), |
| 1912 | OPT_BOOLEAN('f', "force", &file.force, "don't complain, do it"), | 1912 | OPT_BOOLEAN('f', "force", &data.force, "don't complain, do it"), |
| 1913 | OPT_CALLBACK_NOOPT(0, "slab", NULL, NULL, "Analyze slab allocator", | 1913 | OPT_CALLBACK_NOOPT(0, "slab", NULL, NULL, "Analyze slab allocator", |
| 1914 | parse_slab_opt), | 1914 | parse_slab_opt), |
| 1915 | OPT_CALLBACK_NOOPT(0, "page", NULL, NULL, "Analyze page allocator", | 1915 | OPT_CALLBACK_NOOPT(0, "page", NULL, NULL, "Analyze page allocator", |
| @@ -1949,9 +1949,9 @@ int cmd_kmem(int argc, const char **argv) | |||
| 1949 | return __cmd_record(argc, argv); | 1949 | return __cmd_record(argc, argv); |
| 1950 | } | 1950 | } |
| 1951 | 1951 | ||
| 1952 | file.path = input_name; | 1952 | data.file.path = input_name; |
| 1953 | 1953 | ||
| 1954 | kmem_session = session = perf_session__new(&file, false, &perf_kmem); | 1954 | kmem_session = session = perf_session__new(&data, false, &perf_kmem); |
| 1955 | if (session == NULL) | 1955 | if (session == NULL) |
| 1956 | return -1; | 1956 | return -1; |
| 1957 | 1957 | ||
diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index 721f4f91291a..0af4c092b471 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c | |||
| @@ -1067,10 +1067,12 @@ static int read_events(struct perf_kvm_stat *kvm) | |||
| 1067 | .namespaces = perf_event__process_namespaces, | 1067 | .namespaces = perf_event__process_namespaces, |
| 1068 | .ordered_events = true, | 1068 | .ordered_events = true, |
| 1069 | }; | 1069 | }; |
| 1070 | struct perf_data_file file = { | 1070 | struct perf_data file = { |
| 1071 | .path = kvm->file_name, | 1071 | .file = { |
| 1072 | .mode = PERF_DATA_MODE_READ, | 1072 | .path = kvm->file_name, |
| 1073 | .force = kvm->force, | 1073 | }, |
| 1074 | .mode = PERF_DATA_MODE_READ, | ||
| 1075 | .force = kvm->force, | ||
| 1074 | }; | 1076 | }; |
| 1075 | 1077 | ||
| 1076 | kvm->tool = eops; | 1078 | kvm->tool = eops; |
| @@ -1358,7 +1360,7 @@ static int kvm_events_live(struct perf_kvm_stat *kvm, | |||
| 1358 | "perf kvm stat live [<options>]", | 1360 | "perf kvm stat live [<options>]", |
| 1359 | NULL | 1361 | NULL |
| 1360 | }; | 1362 | }; |
| 1361 | struct perf_data_file file = { | 1363 | struct perf_data data = { |
| 1362 | .mode = PERF_DATA_MODE_WRITE, | 1364 | .mode = PERF_DATA_MODE_WRITE, |
| 1363 | }; | 1365 | }; |
| 1364 | 1366 | ||
| @@ -1432,7 +1434,7 @@ static int kvm_events_live(struct perf_kvm_stat *kvm, | |||
| 1432 | /* | 1434 | /* |
| 1433 | * perf session | 1435 | * perf session |
| 1434 | */ | 1436 | */ |
| 1435 | kvm->session = perf_session__new(&file, false, &kvm->tool); | 1437 | kvm->session = perf_session__new(&data, false, &kvm->tool); |
| 1436 | if (kvm->session == NULL) { | 1438 | if (kvm->session == NULL) { |
| 1437 | err = -1; | 1439 | err = -1; |
| 1438 | goto out; | 1440 | goto out; |
diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c index ff98652484a7..81af29400b64 100644 --- a/tools/perf/builtin-lock.c +++ b/tools/perf/builtin-lock.c | |||
| @@ -864,13 +864,15 @@ static int __cmd_report(bool display_info) | |||
| 864 | .namespaces = perf_event__process_namespaces, | 864 | .namespaces = perf_event__process_namespaces, |
| 865 | .ordered_events = true, | 865 | .ordered_events = true, |
| 866 | }; | 866 | }; |
| 867 | struct perf_data_file file = { | 867 | struct perf_data data = { |
| 868 | .path = input_name, | 868 | .file = { |
| 869 | .mode = PERF_DATA_MODE_READ, | 869 | .path = input_name, |
| 870 | .force = force, | 870 | }, |
| 871 | .mode = PERF_DATA_MODE_READ, | ||
| 872 | .force = force, | ||
| 871 | }; | 873 | }; |
| 872 | 874 | ||
| 873 | session = perf_session__new(&file, false, &eops); | 875 | session = perf_session__new(&data, false, &eops); |
| 874 | if (!session) { | 876 | if (!session) { |
| 875 | pr_err("Initializing perf session failed\n"); | 877 | pr_err("Initializing perf session failed\n"); |
| 876 | return -1; | 878 | return -1; |
diff --git a/tools/perf/builtin-mem.c b/tools/perf/builtin-mem.c index 6940490bc3f9..f09fd1a1b813 100644 --- a/tools/perf/builtin-mem.c +++ b/tools/perf/builtin-mem.c | |||
| @@ -236,13 +236,15 @@ static int process_sample_event(struct perf_tool *tool, | |||
| 236 | 236 | ||
| 237 | static int report_raw_events(struct perf_mem *mem) | 237 | static int report_raw_events(struct perf_mem *mem) |
| 238 | { | 238 | { |
| 239 | struct perf_data_file file = { | 239 | struct perf_data data = { |
| 240 | .path = input_name, | 240 | .file = { |
| 241 | .mode = PERF_DATA_MODE_READ, | 241 | .path = input_name, |
| 242 | .force = mem->force, | 242 | }, |
| 243 | .mode = PERF_DATA_MODE_READ, | ||
| 244 | .force = mem->force, | ||
| 243 | }; | 245 | }; |
| 244 | int ret; | 246 | int ret; |
| 245 | struct perf_session *session = perf_session__new(&file, false, | 247 | struct perf_session *session = perf_session__new(&data, false, |
| 246 | &mem->tool); | 248 | &mem->tool); |
| 247 | 249 | ||
| 248 | if (session == NULL) | 250 | if (session == NULL) |
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index a6cbf1640269..f4d9fc54b382 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c | |||
| @@ -66,7 +66,7 @@ struct record { | |||
| 66 | struct perf_tool tool; | 66 | struct perf_tool tool; |
| 67 | struct record_opts opts; | 67 | struct record_opts opts; |
| 68 | u64 bytes_written; | 68 | u64 bytes_written; |
| 69 | struct perf_data_file file; | 69 | struct perf_data data; |
| 70 | struct auxtrace_record *itr; | 70 | struct auxtrace_record *itr; |
| 71 | struct perf_evlist *evlist; | 71 | struct perf_evlist *evlist; |
| 72 | struct perf_session *session; | 72 | struct perf_session *session; |
| @@ -107,7 +107,7 @@ static bool switch_output_time(struct record *rec) | |||
| 107 | 107 | ||
| 108 | static int record__write(struct record *rec, void *bf, size_t size) | 108 | static int record__write(struct record *rec, void *bf, size_t size) |
| 109 | { | 109 | { |
| 110 | if (perf_data_file__write(rec->session->file, bf, size) < 0) { | 110 | if (perf_data__write(rec->session->data, bf, size) < 0) { |
| 111 | pr_err("failed to write perf data, error: %m\n"); | 111 | pr_err("failed to write perf data, error: %m\n"); |
| 112 | return -1; | 112 | return -1; |
| 113 | } | 113 | } |
| @@ -173,13 +173,13 @@ static int record__process_auxtrace(struct perf_tool *tool, | |||
| 173 | size_t len1, void *data2, size_t len2) | 173 | size_t len1, void *data2, size_t len2) |
| 174 | { | 174 | { |
| 175 | struct record *rec = container_of(tool, struct record, tool); | 175 | struct record *rec = container_of(tool, struct record, tool); |
| 176 | struct perf_data_file *file = &rec->file; | 176 | struct perf_data *data = &rec->data; |
| 177 | size_t padding; | 177 | size_t padding; |
| 178 | u8 pad[8] = {0}; | 178 | u8 pad[8] = {0}; |
| 179 | 179 | ||
| 180 | if (!perf_data_file__is_pipe(file)) { | 180 | if (!perf_data__is_pipe(data)) { |
| 181 | off_t file_offset; | 181 | off_t file_offset; |
| 182 | int fd = perf_data_file__fd(file); | 182 | int fd = perf_data__fd(data); |
| 183 | int err; | 183 | int err; |
| 184 | 184 | ||
| 185 | file_offset = lseek(fd, 0, SEEK_CUR); | 185 | file_offset = lseek(fd, 0, SEEK_CUR); |
| @@ -398,10 +398,10 @@ static int process_sample_event(struct perf_tool *tool, | |||
| 398 | 398 | ||
| 399 | static int process_buildids(struct record *rec) | 399 | static int process_buildids(struct record *rec) |
| 400 | { | 400 | { |
| 401 | struct perf_data_file *file = &rec->file; | 401 | struct perf_data *data = &rec->data; |
| 402 | struct perf_session *session = rec->session; | 402 | struct perf_session *session = rec->session; |
| 403 | 403 | ||
| 404 | if (file->size == 0) | 404 | if (data->size == 0) |
| 405 | return 0; | 405 | return 0; |
| 406 | 406 | ||
| 407 | /* | 407 | /* |
| @@ -544,14 +544,14 @@ static void record__init_features(struct record *rec) | |||
| 544 | static void | 544 | static void |
| 545 | record__finish_output(struct record *rec) | 545 | record__finish_output(struct record *rec) |
| 546 | { | 546 | { |
| 547 | struct perf_data_file *file = &rec->file; | 547 | struct perf_data *data = &rec->data; |
| 548 | int fd = perf_data_file__fd(file); | 548 | int fd = perf_data__fd(data); |
| 549 | 549 | ||
| 550 | if (file->is_pipe) | 550 | if (data->is_pipe) |
| 551 | return; | 551 | return; |
| 552 | 552 | ||
| 553 | rec->session->header.data_size += rec->bytes_written; | 553 | rec->session->header.data_size += rec->bytes_written; |
| 554 | file->size = lseek(perf_data_file__fd(file), 0, SEEK_CUR); | 554 | data->size = lseek(perf_data__fd(data), 0, SEEK_CUR); |
| 555 | 555 | ||
| 556 | if (!rec->no_buildid) { | 556 | if (!rec->no_buildid) { |
| 557 | process_buildids(rec); | 557 | process_buildids(rec); |
| @@ -590,7 +590,7 @@ static int record__synthesize(struct record *rec, bool tail); | |||
| 590 | static int | 590 | static int |
| 591 | record__switch_output(struct record *rec, bool at_exit) | 591 | record__switch_output(struct record *rec, bool at_exit) |
| 592 | { | 592 | { |
| 593 | struct perf_data_file *file = &rec->file; | 593 | struct perf_data *data = &rec->data; |
| 594 | int fd, err; | 594 | int fd, err; |
| 595 | 595 | ||
| 596 | /* Same Size: "2015122520103046"*/ | 596 | /* Same Size: "2015122520103046"*/ |
| @@ -608,7 +608,7 @@ record__switch_output(struct record *rec, bool at_exit) | |||
| 608 | return -EINVAL; | 608 | return -EINVAL; |
| 609 | } | 609 | } |
| 610 | 610 | ||
| 611 | fd = perf_data_file__switch(file, timestamp, | 611 | fd = perf_data__switch(data, timestamp, |
| 612 | rec->session->header.data_offset, | 612 | rec->session->header.data_offset, |
| 613 | at_exit); | 613 | at_exit); |
| 614 | if (fd >= 0 && !at_exit) { | 614 | if (fd >= 0 && !at_exit) { |
| @@ -618,7 +618,7 @@ record__switch_output(struct record *rec, bool at_exit) | |||
| 618 | 618 | ||
| 619 | if (!quiet) | 619 | if (!quiet) |
| 620 | fprintf(stderr, "[ perf record: Dump %s.%s ]\n", | 620 | fprintf(stderr, "[ perf record: Dump %s.%s ]\n", |
| 621 | file->path, timestamp); | 621 | data->file.path, timestamp); |
| 622 | 622 | ||
| 623 | /* Output tracking events */ | 623 | /* Output tracking events */ |
| 624 | if (!at_exit) { | 624 | if (!at_exit) { |
| @@ -693,16 +693,16 @@ static int record__synthesize(struct record *rec, bool tail) | |||
| 693 | { | 693 | { |
| 694 | struct perf_session *session = rec->session; | 694 | struct perf_session *session = rec->session; |
| 695 | struct machine *machine = &session->machines.host; | 695 | struct machine *machine = &session->machines.host; |
| 696 | struct perf_data_file *file = &rec->file; | 696 | struct perf_data *data = &rec->data; |
| 697 | struct record_opts *opts = &rec->opts; | 697 | struct record_opts *opts = &rec->opts; |
| 698 | struct perf_tool *tool = &rec->tool; | 698 | struct perf_tool *tool = &rec->tool; |
| 699 | int fd = perf_data_file__fd(file); | 699 | int fd = perf_data__fd(data); |
| 700 | int err = 0; | 700 | int err = 0; |
| 701 | 701 | ||
| 702 | if (rec->opts.tail_synthesize != tail) | 702 | if (rec->opts.tail_synthesize != tail) |
| 703 | return 0; | 703 | return 0; |
| 704 | 704 | ||
| 705 | if (file->is_pipe) { | 705 | if (data->is_pipe) { |
| 706 | err = perf_event__synthesize_features( | 706 | err = perf_event__synthesize_features( |
| 707 | tool, session, rec->evlist, process_synthesized_event); | 707 | tool, session, rec->evlist, process_synthesized_event); |
| 708 | if (err < 0) { | 708 | if (err < 0) { |
| @@ -781,7 +781,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) | |||
| 781 | struct machine *machine; | 781 | struct machine *machine; |
| 782 | struct perf_tool *tool = &rec->tool; | 782 | struct perf_tool *tool = &rec->tool; |
| 783 | struct record_opts *opts = &rec->opts; | 783 | struct record_opts *opts = &rec->opts; |
| 784 | struct perf_data_file *file = &rec->file; | 784 | struct perf_data *data = &rec->data; |
| 785 | struct perf_session *session; | 785 | struct perf_session *session; |
| 786 | bool disabled = false, draining = false; | 786 | bool disabled = false, draining = false; |
| 787 | int fd; | 787 | int fd; |
| @@ -807,20 +807,20 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) | |||
| 807 | signal(SIGUSR2, SIG_IGN); | 807 | signal(SIGUSR2, SIG_IGN); |
| 808 | } | 808 | } |
| 809 | 809 | ||
| 810 | session = perf_session__new(file, false, tool); | 810 | session = perf_session__new(data, false, tool); |
| 811 | if (session == NULL) { | 811 | if (session == NULL) { |
| 812 | pr_err("Perf session creation failed.\n"); | 812 | pr_err("Perf session creation failed.\n"); |
| 813 | return -1; | 813 | return -1; |
| 814 | } | 814 | } |
| 815 | 815 | ||
| 816 | fd = perf_data_file__fd(file); | 816 | fd = perf_data__fd(data); |
| 817 | rec->session = session; | 817 | rec->session = session; |
| 818 | 818 | ||
| 819 | record__init_features(rec); | 819 | record__init_features(rec); |
| 820 | 820 | ||
| 821 | if (forks) { | 821 | if (forks) { |
| 822 | err = perf_evlist__prepare_workload(rec->evlist, &opts->target, | 822 | err = perf_evlist__prepare_workload(rec->evlist, &opts->target, |
| 823 | argv, file->is_pipe, | 823 | argv, data->is_pipe, |
| 824 | workload_exec_failed_signal); | 824 | workload_exec_failed_signal); |
| 825 | if (err < 0) { | 825 | if (err < 0) { |
| 826 | pr_err("Couldn't run the workload!\n"); | 826 | pr_err("Couldn't run the workload!\n"); |
| @@ -856,7 +856,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) | |||
| 856 | if (!rec->evlist->nr_groups) | 856 | if (!rec->evlist->nr_groups) |
| 857 | perf_header__clear_feat(&session->header, HEADER_GROUP_DESC); | 857 | perf_header__clear_feat(&session->header, HEADER_GROUP_DESC); |
| 858 | 858 | ||
| 859 | if (file->is_pipe) { | 859 | if (data->is_pipe) { |
| 860 | err = perf_header__write_pipe(fd); | 860 | err = perf_header__write_pipe(fd); |
| 861 | if (err < 0) | 861 | if (err < 0) |
| 862 | goto out_child; | 862 | goto out_child; |
| @@ -1117,8 +1117,8 @@ out_child: | |||
| 1117 | samples[0] = '\0'; | 1117 | samples[0] = '\0'; |
| 1118 | 1118 | ||
| 1119 | fprintf(stderr, "[ perf record: Captured and wrote %.3f MB %s%s%s ]\n", | 1119 | fprintf(stderr, "[ perf record: Captured and wrote %.3f MB %s%s%s ]\n", |
| 1120 | perf_data_file__size(file) / 1024.0 / 1024.0, | 1120 | perf_data__size(data) / 1024.0 / 1024.0, |
| 1121 | file->path, postfix, samples); | 1121 | data->file.path, postfix, samples); |
| 1122 | } | 1122 | } |
| 1123 | 1123 | ||
| 1124 | out_delete_session: | 1124 | out_delete_session: |
| @@ -1482,7 +1482,7 @@ static struct option __record_options[] = { | |||
| 1482 | OPT_STRING('C', "cpu", &record.opts.target.cpu_list, "cpu", | 1482 | OPT_STRING('C', "cpu", &record.opts.target.cpu_list, "cpu", |
| 1483 | "list of cpus to monitor"), | 1483 | "list of cpus to monitor"), |
| 1484 | OPT_U64('c', "count", &record.opts.user_interval, "event period to sample"), | 1484 | OPT_U64('c', "count", &record.opts.user_interval, "event period to sample"), |
| 1485 | OPT_STRING('o', "output", &record.file.path, "file", | 1485 | OPT_STRING('o', "output", &record.data.file.path, "file", |
| 1486 | "output file name"), | 1486 | "output file name"), |
| 1487 | OPT_BOOLEAN_SET('i', "no-inherit", &record.opts.no_inherit, | 1487 | OPT_BOOLEAN_SET('i', "no-inherit", &record.opts.no_inherit, |
| 1488 | &record.opts.no_inherit_set, | 1488 | &record.opts.no_inherit_set, |
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index f9dff652dcbd..3c2d9d4932f3 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c | |||
| @@ -257,7 +257,7 @@ static int report__setup_sample_type(struct report *rep) | |||
| 257 | { | 257 | { |
| 258 | struct perf_session *session = rep->session; | 258 | struct perf_session *session = rep->session; |
| 259 | u64 sample_type = perf_evlist__combined_sample_type(session->evlist); | 259 | u64 sample_type = perf_evlist__combined_sample_type(session->evlist); |
| 260 | bool is_pipe = perf_data_file__is_pipe(session->file); | 260 | bool is_pipe = perf_data__is_pipe(session->data); |
| 261 | 261 | ||
| 262 | if (session->itrace_synth_opts->callchain || | 262 | if (session->itrace_synth_opts->callchain || |
| 263 | (!is_pipe && | 263 | (!is_pipe && |
| @@ -568,7 +568,7 @@ static int __cmd_report(struct report *rep) | |||
| 568 | int ret; | 568 | int ret; |
| 569 | struct perf_session *session = rep->session; | 569 | struct perf_session *session = rep->session; |
| 570 | struct perf_evsel *pos; | 570 | struct perf_evsel *pos; |
| 571 | struct perf_data_file *file = session->file; | 571 | struct perf_data *data = session->data; |
| 572 | 572 | ||
| 573 | signal(SIGINT, sig_handler); | 573 | signal(SIGINT, sig_handler); |
| 574 | 574 | ||
| @@ -637,7 +637,7 @@ static int __cmd_report(struct report *rep) | |||
| 637 | rep->nr_entries += evsel__hists(pos)->nr_entries; | 637 | rep->nr_entries += evsel__hists(pos)->nr_entries; |
| 638 | 638 | ||
| 639 | if (rep->nr_entries == 0) { | 639 | if (rep->nr_entries == 0) { |
| 640 | ui__error("The %s file has no samples!\n", file->path); | 640 | ui__error("The %s file has no samples!\n", data->file.path); |
| 641 | return 0; | 641 | return 0; |
| 642 | } | 642 | } |
| 643 | 643 | ||
| @@ -879,7 +879,7 @@ int cmd_report(int argc, const char **argv) | |||
| 879 | "Show inline function"), | 879 | "Show inline function"), |
| 880 | OPT_END() | 880 | OPT_END() |
| 881 | }; | 881 | }; |
| 882 | struct perf_data_file file = { | 882 | struct perf_data data = { |
| 883 | .mode = PERF_DATA_MODE_READ, | 883 | .mode = PERF_DATA_MODE_READ, |
| 884 | }; | 884 | }; |
| 885 | int ret = hists__init(); | 885 | int ret = hists__init(); |
| @@ -940,11 +940,11 @@ int cmd_report(int argc, const char **argv) | |||
| 940 | input_name = "perf.data"; | 940 | input_name = "perf.data"; |
| 941 | } | 941 | } |
| 942 | 942 | ||
| 943 | file.path = input_name; | 943 | data.file.path = input_name; |
| 944 | file.force = symbol_conf.force; | 944 | data.force = symbol_conf.force; |
| 945 | 945 | ||
| 946 | repeat: | 946 | repeat: |
| 947 | session = perf_session__new(&file, false, &report.tool); | 947 | session = perf_session__new(&data, false, &report.tool); |
| 948 | if (session == NULL) | 948 | if (session == NULL) |
| 949 | return -1; | 949 | return -1; |
| 950 | 950 | ||
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index b7e8812ee80c..47e54348b5ed 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c | |||
| @@ -1700,14 +1700,16 @@ static int perf_sched__read_events(struct perf_sched *sched) | |||
| 1700 | { "sched:sched_migrate_task", process_sched_migrate_task_event, }, | 1700 | { "sched:sched_migrate_task", process_sched_migrate_task_event, }, |
| 1701 | }; | 1701 | }; |
| 1702 | struct perf_session *session; | 1702 | struct perf_session *session; |
| 1703 | struct perf_data_file file = { | 1703 | struct perf_data data = { |
| 1704 | .path = input_name, | 1704 | .file = { |
| 1705 | .mode = PERF_DATA_MODE_READ, | 1705 | .path = input_name, |
| 1706 | .force = sched->force, | 1706 | }, |
| 1707 | .mode = PERF_DATA_MODE_READ, | ||
| 1708 | .force = sched->force, | ||
| 1707 | }; | 1709 | }; |
| 1708 | int rc = -1; | 1710 | int rc = -1; |
| 1709 | 1711 | ||
| 1710 | session = perf_session__new(&file, false, &sched->tool); | 1712 | session = perf_session__new(&data, false, &sched->tool); |
| 1711 | if (session == NULL) { | 1713 | if (session == NULL) { |
| 1712 | pr_debug("No Memory for session\n"); | 1714 | pr_debug("No Memory for session\n"); |
| 1713 | return -1; | 1715 | return -1; |
| @@ -2902,10 +2904,12 @@ static int perf_sched__timehist(struct perf_sched *sched) | |||
| 2902 | const struct perf_evsel_str_handler migrate_handlers[] = { | 2904 | const struct perf_evsel_str_handler migrate_handlers[] = { |
| 2903 | { "sched:sched_migrate_task", timehist_migrate_task_event, }, | 2905 | { "sched:sched_migrate_task", timehist_migrate_task_event, }, |
| 2904 | }; | 2906 | }; |
| 2905 | struct perf_data_file file = { | 2907 | struct perf_data data = { |
| 2906 | .path = input_name, | 2908 | .file = { |
| 2907 | .mode = PERF_DATA_MODE_READ, | 2909 | .path = input_name, |
| 2908 | .force = sched->force, | 2910 | }, |
| 2911 | .mode = PERF_DATA_MODE_READ, | ||
| 2912 | .force = sched->force, | ||
| 2909 | }; | 2913 | }; |
| 2910 | 2914 | ||
| 2911 | struct perf_session *session; | 2915 | struct perf_session *session; |
| @@ -2930,7 +2934,7 @@ static int perf_sched__timehist(struct perf_sched *sched) | |||
| 2930 | 2934 | ||
| 2931 | symbol_conf.use_callchain = sched->show_callchain; | 2935 | symbol_conf.use_callchain = sched->show_callchain; |
| 2932 | 2936 | ||
| 2933 | session = perf_session__new(&file, false, &sched->tool); | 2937 | session = perf_session__new(&data, false, &sched->tool); |
| 2934 | if (session == NULL) | 2938 | if (session == NULL) |
| 2935 | return -ENOMEM; | 2939 | return -ENOMEM; |
| 2936 | 2940 | ||
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index a3add2cd7856..89975e30c0ba 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c | |||
| @@ -210,6 +210,51 @@ static struct { | |||
| 210 | }, | 210 | }, |
| 211 | }; | 211 | }; |
| 212 | 212 | ||
| 213 | struct perf_evsel_script { | ||
| 214 | char *filename; | ||
| 215 | FILE *fp; | ||
| 216 | u64 samples; | ||
| 217 | }; | ||
| 218 | |||
| 219 | static struct perf_evsel_script *perf_evsel_script__new(struct perf_evsel *evsel, | ||
| 220 | struct perf_data *data) | ||
| 221 | { | ||
| 222 | struct perf_evsel_script *es = malloc(sizeof(*es)); | ||
| 223 | |||
| 224 | if (es != NULL) { | ||
| 225 | if (asprintf(&es->filename, "%s.%s.dump", data->file.path, perf_evsel__name(evsel)) < 0) | ||
| 226 | goto out_free; | ||
| 227 | es->fp = fopen(es->filename, "w"); | ||
| 228 | if (es->fp == NULL) | ||
| 229 | goto out_free_filename; | ||
| 230 | es->samples = 0; | ||
| 231 | } | ||
| 232 | |||
| 233 | return es; | ||
| 234 | out_free_filename: | ||
| 235 | zfree(&es->filename); | ||
| 236 | out_free: | ||
| 237 | free(es); | ||
| 238 | return NULL; | ||
| 239 | } | ||
| 240 | |||
| 241 | static void perf_evsel_script__delete(struct perf_evsel_script *es) | ||
| 242 | { | ||
| 243 | zfree(&es->filename); | ||
| 244 | fclose(es->fp); | ||
| 245 | es->fp = NULL; | ||
| 246 | free(es); | ||
| 247 | } | ||
| 248 | |||
| 249 | static int perf_evsel_script__fprintf(struct perf_evsel_script *es, FILE *fp) | ||
| 250 | { | ||
| 251 | struct stat st; | ||
| 252 | |||
| 253 | fstat(fileno(es->fp), &st); | ||
| 254 | return fprintf(fp, "[ perf script: Wrote %.3f MB %s (%" PRIu64 " samples) ]\n", | ||
| 255 | st.st_size / 1024.0 / 1024.0, es->filename, es->samples); | ||
| 256 | } | ||
| 257 | |||
| 213 | static inline int output_type(unsigned int type) | 258 | static inline int output_type(unsigned int type) |
| 214 | { | 259 | { |
| 215 | switch (type) { | 260 | switch (type) { |
| @@ -769,27 +814,26 @@ static int grab_bb(u8 *buffer, u64 start, u64 end, | |||
| 769 | * but the exit is not. Let the caller patch it up. | 814 | * but the exit is not. Let the caller patch it up. |
| 770 | */ | 815 | */ |
| 771 | if (kernel != machine__kernel_ip(machine, end)) { | 816 | if (kernel != machine__kernel_ip(machine, end)) { |
| 772 | printf("\tblock %" PRIx64 "-%" PRIx64 " transfers between kernel and user\n", | 817 | pr_debug("\tblock %" PRIx64 "-%" PRIx64 " transfers between kernel and user\n", start, end); |
| 773 | start, end); | ||
| 774 | return -ENXIO; | 818 | return -ENXIO; |
| 775 | } | 819 | } |
| 776 | 820 | ||
| 777 | memset(&al, 0, sizeof(al)); | 821 | memset(&al, 0, sizeof(al)); |
| 778 | if (end - start > MAXBB - MAXINSN) { | 822 | if (end - start > MAXBB - MAXINSN) { |
| 779 | if (last) | 823 | if (last) |
| 780 | printf("\tbrstack does not reach to final jump (%" PRIx64 "-%" PRIx64 ")\n", start, end); | 824 | pr_debug("\tbrstack does not reach to final jump (%" PRIx64 "-%" PRIx64 ")\n", start, end); |
| 781 | else | 825 | else |
| 782 | printf("\tblock %" PRIx64 "-%" PRIx64 " (%" PRIu64 ") too long to dump\n", start, end, end - start); | 826 | pr_debug("\tblock %" PRIx64 "-%" PRIx64 " (%" PRIu64 ") too long to dump\n", start, end, end - start); |
| 783 | return 0; | 827 | return 0; |
| 784 | } | 828 | } |
| 785 | 829 | ||
| 786 | thread__find_addr_map(thread, *cpumode, MAP__FUNCTION, start, &al); | 830 | thread__find_addr_map(thread, *cpumode, MAP__FUNCTION, start, &al); |
| 787 | if (!al.map || !al.map->dso) { | 831 | if (!al.map || !al.map->dso) { |
| 788 | printf("\tcannot resolve %" PRIx64 "-%" PRIx64 "\n", start, end); | 832 | pr_debug("\tcannot resolve %" PRIx64 "-%" PRIx64 "\n", start, end); |
| 789 | return 0; | 833 | return 0; |
| 790 | } | 834 | } |
| 791 | if (al.map->dso->data.status == DSO_DATA_STATUS_ERROR) { | 835 | if (al.map->dso->data.status == DSO_DATA_STATUS_ERROR) { |
| 792 | printf("\tcannot resolve %" PRIx64 "-%" PRIx64 "\n", start, end); | 836 | pr_debug("\tcannot resolve %" PRIx64 "-%" PRIx64 "\n", start, end); |
| 793 | return 0; | 837 | return 0; |
| 794 | } | 838 | } |
| 795 | 839 | ||
| @@ -802,7 +846,7 @@ static int grab_bb(u8 *buffer, u64 start, u64 end, | |||
| 802 | 846 | ||
| 803 | *is64bit = al.map->dso->is_64_bit; | 847 | *is64bit = al.map->dso->is_64_bit; |
| 804 | if (len <= 0) | 848 | if (len <= 0) |
| 805 | printf("\tcannot fetch code for block at %" PRIx64 "-%" PRIx64 "\n", | 849 | pr_debug("\tcannot fetch code for block at %" PRIx64 "-%" PRIx64 "\n", |
| 806 | start, end); | 850 | start, end); |
| 807 | return len; | 851 | return len; |
| 808 | } | 852 | } |
| @@ -1393,6 +1437,7 @@ struct perf_script { | |||
| 1393 | bool show_switch_events; | 1437 | bool show_switch_events; |
| 1394 | bool show_namespace_events; | 1438 | bool show_namespace_events; |
| 1395 | bool allocated; | 1439 | bool allocated; |
| 1440 | bool per_event_dump; | ||
| 1396 | struct cpu_map *cpus; | 1441 | struct cpu_map *cpus; |
| 1397 | struct thread_map *threads; | 1442 | struct thread_map *threads; |
| 1398 | int name_width; | 1443 | int name_width; |
| @@ -1439,15 +1484,18 @@ static void process_event(struct perf_script *script, | |||
| 1439 | struct thread *thread = al->thread; | 1484 | struct thread *thread = al->thread; |
| 1440 | struct perf_event_attr *attr = &evsel->attr; | 1485 | struct perf_event_attr *attr = &evsel->attr; |
| 1441 | unsigned int type = output_type(attr->type); | 1486 | unsigned int type = output_type(attr->type); |
| 1442 | FILE *fp = stdout; | 1487 | struct perf_evsel_script *es = evsel->priv; |
| 1488 | FILE *fp = es->fp; | ||
| 1443 | 1489 | ||
| 1444 | if (output[type].fields == 0) | 1490 | if (output[type].fields == 0) |
| 1445 | return; | 1491 | return; |
| 1446 | 1492 | ||
| 1493 | ++es->samples; | ||
| 1494 | |||
| 1447 | perf_sample__fprintf_start(sample, thread, evsel, fp); | 1495 | perf_sample__fprintf_start(sample, thread, evsel, fp); |
| 1448 | 1496 | ||
| 1449 | if (PRINT_FIELD(PERIOD)) | 1497 | if (PRINT_FIELD(PERIOD)) |
| 1450 | printf("%10" PRIu64 " ", sample->period); | 1498 | fprintf(fp, "%10" PRIu64 " ", sample->period); |
| 1451 | 1499 | ||
| 1452 | if (PRINT_FIELD(EVNAME)) { | 1500 | if (PRINT_FIELD(EVNAME)) { |
| 1453 | const char *evname = perf_evsel__name(evsel); | 1501 | const char *evname = perf_evsel__name(evsel); |
| @@ -1455,8 +1503,7 @@ static void process_event(struct perf_script *script, | |||
| 1455 | if (!script->name_width) | 1503 | if (!script->name_width) |
| 1456 | script->name_width = perf_evlist__max_name_len(script->session->evlist); | 1504 | script->name_width = perf_evlist__max_name_len(script->session->evlist); |
| 1457 | 1505 | ||
| 1458 | printf("%*s: ", script->name_width, | 1506 | fprintf(fp, "%*s: ", script->name_width, evname ?: "[unknown]"); |
| 1459 | evname ? evname : "[unknown]"); | ||
| 1460 | } | 1507 | } |
| 1461 | 1508 | ||
| 1462 | if (print_flags) | 1509 | if (print_flags) |
| @@ -1467,9 +1514,10 @@ static void process_event(struct perf_script *script, | |||
| 1467 | return; | 1514 | return; |
| 1468 | } | 1515 | } |
| 1469 | 1516 | ||
| 1470 | if (PRINT_FIELD(TRACE)) | 1517 | if (PRINT_FIELD(TRACE)) { |
| 1471 | event_format__print(evsel->tp_format, sample->cpu, | 1518 | event_format__fprintf(evsel->tp_format, sample->cpu, |
| 1472 | sample->raw_data, sample->raw_size); | 1519 | sample->raw_data, sample->raw_size, fp); |
| 1520 | } | ||
| 1473 | 1521 | ||
| 1474 | if (attr->type == PERF_TYPE_SYNTH && PRINT_FIELD(SYNTH)) | 1522 | if (attr->type == PERF_TYPE_SYNTH && PRINT_FIELD(SYNTH)) |
| 1475 | perf_sample__fprintf_synth(sample, evsel, fp); | 1523 | perf_sample__fprintf_synth(sample, evsel, fp); |
| @@ -1513,8 +1561,8 @@ static void process_event(struct perf_script *script, | |||
| 1513 | perf_sample__fprintf_insn(sample, attr, thread, machine, fp); | 1561 | perf_sample__fprintf_insn(sample, attr, thread, machine, fp); |
| 1514 | 1562 | ||
| 1515 | if (PRINT_FIELD(PHYS_ADDR)) | 1563 | if (PRINT_FIELD(PHYS_ADDR)) |
| 1516 | printf("%16" PRIx64, sample->phys_addr); | 1564 | fprintf(fp, "%16" PRIx64, sample->phys_addr); |
| 1517 | printf("\n"); | 1565 | fprintf(fp, "\n"); |
| 1518 | } | 1566 | } |
| 1519 | 1567 | ||
| 1520 | static struct scripting_ops *scripting_ops; | 1568 | static struct scripting_ops *scripting_ops; |
| @@ -1888,6 +1936,65 @@ static void sig_handler(int sig __maybe_unused) | |||
| 1888 | session_done = 1; | 1936 | session_done = 1; |
| 1889 | } | 1937 | } |
| 1890 | 1938 | ||
| 1939 | static void perf_script__fclose_per_event_dump(struct perf_script *script) | ||
| 1940 | { | ||
| 1941 | struct perf_evlist *evlist = script->session->evlist; | ||
| 1942 | struct perf_evsel *evsel; | ||
| 1943 | |||
| 1944 | evlist__for_each_entry(evlist, evsel) { | ||
| 1945 | if (!evsel->priv) | ||
| 1946 | break; | ||
| 1947 | perf_evsel_script__delete(evsel->priv); | ||
| 1948 | evsel->priv = NULL; | ||
| 1949 | } | ||
| 1950 | } | ||
| 1951 | |||
| 1952 | static int perf_script__fopen_per_event_dump(struct perf_script *script) | ||
| 1953 | { | ||
| 1954 | struct perf_evsel *evsel; | ||
| 1955 | |||
| 1956 | evlist__for_each_entry(script->session->evlist, evsel) { | ||
| 1957 | evsel->priv = perf_evsel_script__new(evsel, script->session->data); | ||
| 1958 | if (evsel->priv == NULL) | ||
| 1959 | goto out_err_fclose; | ||
| 1960 | } | ||
| 1961 | |||
| 1962 | return 0; | ||
| 1963 | |||
| 1964 | out_err_fclose: | ||
| 1965 | perf_script__fclose_per_event_dump(script); | ||
| 1966 | return -1; | ||
| 1967 | } | ||
| 1968 | |||
| 1969 | static int perf_script__setup_per_event_dump(struct perf_script *script) | ||
| 1970 | { | ||
| 1971 | struct perf_evsel *evsel; | ||
| 1972 | static struct perf_evsel_script es_stdout; | ||
| 1973 | |||
| 1974 | if (script->per_event_dump) | ||
| 1975 | return perf_script__fopen_per_event_dump(script); | ||
| 1976 | |||
| 1977 | es_stdout.fp = stdout; | ||
| 1978 | |||
| 1979 | evlist__for_each_entry(script->session->evlist, evsel) | ||
| 1980 | evsel->priv = &es_stdout; | ||
| 1981 | |||
| 1982 | return 0; | ||
| 1983 | } | ||
| 1984 | |||
| 1985 | static void perf_script__exit_per_event_dump_stats(struct perf_script *script) | ||
| 1986 | { | ||
| 1987 | struct perf_evsel *evsel; | ||
| 1988 | |||
| 1989 | evlist__for_each_entry(script->session->evlist, evsel) { | ||
| 1990 | struct perf_evsel_script *es = evsel->priv; | ||
| 1991 | |||
| 1992 | perf_evsel_script__fprintf(es, stdout); | ||
| 1993 | perf_evsel_script__delete(es); | ||
| 1994 | evsel->priv = NULL; | ||
| 1995 | } | ||
| 1996 | } | ||
| 1997 | |||
| 1891 | static int __cmd_script(struct perf_script *script) | 1998 | static int __cmd_script(struct perf_script *script) |
| 1892 | { | 1999 | { |
| 1893 | int ret; | 2000 | int ret; |
| @@ -1909,8 +2016,16 @@ static int __cmd_script(struct perf_script *script) | |||
| 1909 | if (script->show_namespace_events) | 2016 | if (script->show_namespace_events) |
| 1910 | script->tool.namespaces = process_namespaces_event; | 2017 | script->tool.namespaces = process_namespaces_event; |
| 1911 | 2018 | ||
| 2019 | if (perf_script__setup_per_event_dump(script)) { | ||
| 2020 | pr_err("Couldn't create the per event dump files\n"); | ||
| 2021 | return -1; | ||
| 2022 | } | ||
| 2023 | |||
| 1912 | ret = perf_session__process_events(script->session); | 2024 | ret = perf_session__process_events(script->session); |
| 1913 | 2025 | ||
| 2026 | if (script->per_event_dump) | ||
| 2027 | perf_script__exit_per_event_dump_stats(script); | ||
| 2028 | |||
| 1914 | if (debug_mode) | 2029 | if (debug_mode) |
| 1915 | pr_err("Misordered timestamps: %" PRIu64 "\n", nr_unordered); | 2030 | pr_err("Misordered timestamps: %" PRIu64 "\n", nr_unordered); |
| 1916 | 2031 | ||
| @@ -2475,14 +2590,16 @@ int find_scripts(char **scripts_array, char **scripts_path_array) | |||
| 2475 | char scripts_path[MAXPATHLEN], lang_path[MAXPATHLEN]; | 2590 | char scripts_path[MAXPATHLEN], lang_path[MAXPATHLEN]; |
| 2476 | DIR *scripts_dir, *lang_dir; | 2591 | DIR *scripts_dir, *lang_dir; |
| 2477 | struct perf_session *session; | 2592 | struct perf_session *session; |
| 2478 | struct perf_data_file file = { | 2593 | struct perf_data data = { |
| 2479 | .path = input_name, | 2594 | .file = { |
| 2480 | .mode = PERF_DATA_MODE_READ, | 2595 | .path = input_name, |
| 2596 | }, | ||
| 2597 | .mode = PERF_DATA_MODE_READ, | ||
| 2481 | }; | 2598 | }; |
| 2482 | char *temp; | 2599 | char *temp; |
| 2483 | int i = 0; | 2600 | int i = 0; |
| 2484 | 2601 | ||
| 2485 | session = perf_session__new(&file, false, NULL); | 2602 | session = perf_session__new(&data, false, NULL); |
| 2486 | if (!session) | 2603 | if (!session) |
| 2487 | return -1; | 2604 | return -1; |
| 2488 | 2605 | ||
| @@ -2760,7 +2877,7 @@ int cmd_script(int argc, const char **argv) | |||
| 2760 | .ordering_requires_timestamps = true, | 2877 | .ordering_requires_timestamps = true, |
| 2761 | }, | 2878 | }, |
| 2762 | }; | 2879 | }; |
| 2763 | struct perf_data_file file = { | 2880 | struct perf_data data = { |
| 2764 | .mode = PERF_DATA_MODE_READ, | 2881 | .mode = PERF_DATA_MODE_READ, |
| 2765 | }; | 2882 | }; |
| 2766 | const struct option options[] = { | 2883 | const struct option options[] = { |
| @@ -2828,6 +2945,8 @@ int cmd_script(int argc, const char **argv) | |||
| 2828 | "Show context switch events (if recorded)"), | 2945 | "Show context switch events (if recorded)"), |
| 2829 | OPT_BOOLEAN('\0', "show-namespace-events", &script.show_namespace_events, | 2946 | OPT_BOOLEAN('\0', "show-namespace-events", &script.show_namespace_events, |
| 2830 | "Show namespace events (if recorded)"), | 2947 | "Show namespace events (if recorded)"), |
| 2948 | OPT_BOOLEAN('\0', "per-event-dump", &script.per_event_dump, | ||
| 2949 | "Dump trace output to files named by the monitored events"), | ||
| 2831 | OPT_BOOLEAN('f', "force", &symbol_conf.force, "don't complain, do it"), | 2950 | OPT_BOOLEAN('f', "force", &symbol_conf.force, "don't complain, do it"), |
| 2832 | OPT_INTEGER(0, "max-blocks", &max_blocks, | 2951 | OPT_INTEGER(0, "max-blocks", &max_blocks, |
| 2833 | "Maximum number of code blocks to dump with brstackinsn"), | 2952 | "Maximum number of code blocks to dump with brstackinsn"), |
| @@ -2865,8 +2984,8 @@ int cmd_script(int argc, const char **argv) | |||
| 2865 | argc = parse_options_subcommand(argc, argv, options, script_subcommands, script_usage, | 2984 | argc = parse_options_subcommand(argc, argv, options, script_subcommands, script_usage, |
| 2866 | PARSE_OPT_STOP_AT_NON_OPTION); | 2985 | PARSE_OPT_STOP_AT_NON_OPTION); |
| 2867 | 2986 | ||
| 2868 | file.path = input_name; | 2987 | data.file.path = input_name; |
| 2869 | file.force = symbol_conf.force; | 2988 | data.force = symbol_conf.force; |
| 2870 | 2989 | ||
| 2871 | if (argc > 1 && !strncmp(argv[0], "rec", strlen("rec"))) { | 2990 | if (argc > 1 && !strncmp(argv[0], "rec", strlen("rec"))) { |
| 2872 | rec_script_path = get_script_path(argv[1], RECORD_SUFFIX); | 2991 | rec_script_path = get_script_path(argv[1], RECORD_SUFFIX); |
| @@ -3033,7 +3152,7 @@ int cmd_script(int argc, const char **argv) | |||
| 3033 | if (!script_name) | 3152 | if (!script_name) |
| 3034 | setup_pager(); | 3153 | setup_pager(); |
| 3035 | 3154 | ||
| 3036 | session = perf_session__new(&file, false, &script.tool); | 3155 | session = perf_session__new(&data, false, &script.tool); |
| 3037 | if (session == NULL) | 3156 | if (session == NULL) |
| 3038 | return -1; | 3157 | return -1; |
| 3039 | 3158 | ||
| @@ -3089,7 +3208,7 @@ int cmd_script(int argc, const char **argv) | |||
| 3089 | goto out_delete; | 3208 | goto out_delete; |
| 3090 | } | 3209 | } |
| 3091 | 3210 | ||
| 3092 | input = open(file.path, O_RDONLY); /* input_name */ | 3211 | input = open(data.file.path, O_RDONLY); /* input_name */ |
| 3093 | if (input < 0) { | 3212 | if (input < 0) { |
| 3094 | err = -errno; | 3213 | err = -errno; |
| 3095 | perror("failed to open file"); | 3214 | perror("failed to open file"); |
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index dd525417880a..59af5a8419e2 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c | |||
| @@ -175,7 +175,7 @@ static int print_free_counters_hint; | |||
| 175 | 175 | ||
| 176 | struct perf_stat { | 176 | struct perf_stat { |
| 177 | bool record; | 177 | bool record; |
| 178 | struct perf_data_file file; | 178 | struct perf_data data; |
| 179 | struct perf_session *session; | 179 | struct perf_session *session; |
| 180 | u64 bytes_written; | 180 | u64 bytes_written; |
| 181 | struct perf_tool tool; | 181 | struct perf_tool tool; |
| @@ -253,7 +253,7 @@ static int create_perf_stat_counter(struct perf_evsel *evsel) | |||
| 253 | * by attr->sample_type != 0, and we can't run it on | 253 | * by attr->sample_type != 0, and we can't run it on |
| 254 | * stat sessions. | 254 | * stat sessions. |
| 255 | */ | 255 | */ |
| 256 | if (!(STAT_RECORD && perf_stat.file.is_pipe)) | 256 | if (!(STAT_RECORD && perf_stat.data.is_pipe)) |
| 257 | attr->sample_type = PERF_SAMPLE_IDENTIFIER; | 257 | attr->sample_type = PERF_SAMPLE_IDENTIFIER; |
| 258 | 258 | ||
| 259 | /* | 259 | /* |
| @@ -295,7 +295,7 @@ static int process_synthesized_event(struct perf_tool *tool __maybe_unused, | |||
| 295 | struct perf_sample *sample __maybe_unused, | 295 | struct perf_sample *sample __maybe_unused, |
| 296 | struct machine *machine __maybe_unused) | 296 | struct machine *machine __maybe_unused) |
| 297 | { | 297 | { |
| 298 | if (perf_data_file__write(&perf_stat.file, event, event->header.size) < 0) { | 298 | if (perf_data__write(&perf_stat.data, event, event->header.size) < 0) { |
| 299 | pr_err("failed to write perf data, error: %m\n"); | 299 | pr_err("failed to write perf data, error: %m\n"); |
| 300 | return -1; | 300 | return -1; |
| 301 | } | 301 | } |
| @@ -628,7 +628,7 @@ static int __run_perf_stat(int argc, const char **argv) | |||
| 628 | size_t l; | 628 | size_t l; |
| 629 | int status = 0; | 629 | int status = 0; |
| 630 | const bool forks = (argc > 0); | 630 | const bool forks = (argc > 0); |
| 631 | bool is_pipe = STAT_RECORD ? perf_stat.file.is_pipe : false; | 631 | bool is_pipe = STAT_RECORD ? perf_stat.data.is_pipe : false; |
| 632 | struct perf_evsel_config_term *err_term; | 632 | struct perf_evsel_config_term *err_term; |
| 633 | 633 | ||
| 634 | if (interval) { | 634 | if (interval) { |
| @@ -719,10 +719,10 @@ try_again: | |||
| 719 | } | 719 | } |
| 720 | 720 | ||
| 721 | if (STAT_RECORD) { | 721 | if (STAT_RECORD) { |
| 722 | int err, fd = perf_data_file__fd(&perf_stat.file); | 722 | int err, fd = perf_data__fd(&perf_stat.data); |
| 723 | 723 | ||
| 724 | if (is_pipe) { | 724 | if (is_pipe) { |
| 725 | err = perf_header__write_pipe(perf_data_file__fd(&perf_stat.file)); | 725 | err = perf_header__write_pipe(perf_data__fd(&perf_stat.data)); |
| 726 | } else { | 726 | } else { |
| 727 | err = perf_session__write_header(perf_stat.session, evsel_list, | 727 | err = perf_session__write_header(perf_stat.session, evsel_list, |
| 728 | fd, false); | 728 | fd, false); |
| @@ -845,7 +845,7 @@ static void print_noise(struct perf_evsel *evsel, double avg) | |||
| 845 | if (run_count == 1) | 845 | if (run_count == 1) |
| 846 | return; | 846 | return; |
| 847 | 847 | ||
| 848 | ps = evsel->priv; | 848 | ps = evsel->stats; |
| 849 | print_noise_pct(stddev_stats(&ps->res_stats[0]), avg); | 849 | print_noise_pct(stddev_stats(&ps->res_stats[0]), avg); |
| 850 | } | 850 | } |
| 851 | 851 | ||
| @@ -1267,8 +1267,7 @@ static void aggr_update_shadow(void) | |||
| 1267 | continue; | 1267 | continue; |
| 1268 | val += perf_counts(counter->counts, cpu, 0)->val; | 1268 | val += perf_counts(counter->counts, cpu, 0)->val; |
| 1269 | } | 1269 | } |
| 1270 | val = val * counter->scale; | 1270 | perf_stat__update_shadow_stats(counter, val, |
| 1271 | perf_stat__update_shadow_stats(counter, &val, | ||
| 1272 | first_shadow_cpu(counter, id)); | 1271 | first_shadow_cpu(counter, id)); |
| 1273 | } | 1272 | } |
| 1274 | } | 1273 | } |
| @@ -1432,7 +1431,7 @@ static void counter_aggr_cb(struct perf_evsel *counter, void *data, | |||
| 1432 | bool first __maybe_unused) | 1431 | bool first __maybe_unused) |
| 1433 | { | 1432 | { |
| 1434 | struct caggr_data *cd = data; | 1433 | struct caggr_data *cd = data; |
| 1435 | struct perf_stat_evsel *ps = counter->priv; | 1434 | struct perf_stat_evsel *ps = counter->stats; |
| 1436 | 1435 | ||
| 1437 | cd->avg += avg_stats(&ps->res_stats[0]); | 1436 | cd->avg += avg_stats(&ps->res_stats[0]); |
| 1438 | cd->avg_enabled += avg_stats(&ps->res_stats[1]); | 1437 | cd->avg_enabled += avg_stats(&ps->res_stats[1]); |
| @@ -1696,7 +1695,7 @@ static void print_counters(struct timespec *ts, int argc, const char **argv) | |||
| 1696 | char buf[64], *prefix = NULL; | 1695 | char buf[64], *prefix = NULL; |
| 1697 | 1696 | ||
| 1698 | /* Do not print anything if we record to the pipe. */ | 1697 | /* Do not print anything if we record to the pipe. */ |
| 1699 | if (STAT_RECORD && perf_stat.file.is_pipe) | 1698 | if (STAT_RECORD && perf_stat.data.is_pipe) |
| 1700 | return; | 1699 | return; |
| 1701 | 1700 | ||
| 1702 | if (interval) | 1701 | if (interval) |
| @@ -2406,20 +2405,20 @@ static void init_features(struct perf_session *session) | |||
| 2406 | static int __cmd_record(int argc, const char **argv) | 2405 | static int __cmd_record(int argc, const char **argv) |
| 2407 | { | 2406 | { |
| 2408 | struct perf_session *session; | 2407 | struct perf_session *session; |
| 2409 | struct perf_data_file *file = &perf_stat.file; | 2408 | struct perf_data *data = &perf_stat.data; |
| 2410 | 2409 | ||
| 2411 | argc = parse_options(argc, argv, stat_options, stat_record_usage, | 2410 | argc = parse_options(argc, argv, stat_options, stat_record_usage, |
| 2412 | PARSE_OPT_STOP_AT_NON_OPTION); | 2411 | PARSE_OPT_STOP_AT_NON_OPTION); |
| 2413 | 2412 | ||
| 2414 | if (output_name) | 2413 | if (output_name) |
| 2415 | file->path = output_name; | 2414 | data->file.path = output_name; |
| 2416 | 2415 | ||
| 2417 | if (run_count != 1 || forever) { | 2416 | if (run_count != 1 || forever) { |
| 2418 | pr_err("Cannot use -r option with perf stat record.\n"); | 2417 | pr_err("Cannot use -r option with perf stat record.\n"); |
| 2419 | return -1; | 2418 | return -1; |
| 2420 | } | 2419 | } |
| 2421 | 2420 | ||
| 2422 | session = perf_session__new(file, false, NULL); | 2421 | session = perf_session__new(data, false, NULL); |
| 2423 | if (session == NULL) { | 2422 | if (session == NULL) { |
| 2424 | pr_err("Perf session creation failed.\n"); | 2423 | pr_err("Perf session creation failed.\n"); |
| 2425 | return -1; | 2424 | return -1; |
| @@ -2477,7 +2476,7 @@ int process_stat_config_event(struct perf_tool *tool, | |||
| 2477 | if (st->aggr_mode != AGGR_UNSET) | 2476 | if (st->aggr_mode != AGGR_UNSET) |
| 2478 | stat_config.aggr_mode = st->aggr_mode; | 2477 | stat_config.aggr_mode = st->aggr_mode; |
| 2479 | 2478 | ||
| 2480 | if (perf_stat.file.is_pipe) | 2479 | if (perf_stat.data.is_pipe) |
| 2481 | perf_stat_init_aggr_mode(); | 2480 | perf_stat_init_aggr_mode(); |
| 2482 | else | 2481 | else |
| 2483 | perf_stat_init_aggr_mode_file(st); | 2482 | perf_stat_init_aggr_mode_file(st); |
| @@ -2585,10 +2584,10 @@ static int __cmd_report(int argc, const char **argv) | |||
| 2585 | input_name = "perf.data"; | 2584 | input_name = "perf.data"; |
| 2586 | } | 2585 | } |
| 2587 | 2586 | ||
| 2588 | perf_stat.file.path = input_name; | 2587 | perf_stat.data.file.path = input_name; |
| 2589 | perf_stat.file.mode = PERF_DATA_MODE_READ; | 2588 | perf_stat.data.mode = PERF_DATA_MODE_READ; |
| 2590 | 2589 | ||
| 2591 | session = perf_session__new(&perf_stat.file, false, &perf_stat.tool); | 2590 | session = perf_session__new(&perf_stat.data, false, &perf_stat.tool); |
| 2592 | if (session == NULL) | 2591 | if (session == NULL) |
| 2593 | return -1; | 2592 | return -1; |
| 2594 | 2593 | ||
| @@ -2859,7 +2858,7 @@ int cmd_stat(int argc, const char **argv) | |||
| 2859 | * records, but the need to suppress the kptr_restrict messages in older | 2858 | * records, but the need to suppress the kptr_restrict messages in older |
| 2860 | * tools remain -acme | 2859 | * tools remain -acme |
| 2861 | */ | 2860 | */ |
| 2862 | int fd = perf_data_file__fd(&perf_stat.file); | 2861 | int fd = perf_data__fd(&perf_stat.data); |
| 2863 | int err = perf_event__synthesize_kernel_mmap((void *)&perf_stat, | 2862 | int err = perf_event__synthesize_kernel_mmap((void *)&perf_stat, |
| 2864 | process_synthesized_event, | 2863 | process_synthesized_event, |
| 2865 | &perf_stat.session->machines.host); | 2864 | &perf_stat.session->machines.host); |
| @@ -2873,7 +2872,7 @@ int cmd_stat(int argc, const char **argv) | |||
| 2873 | pr_err("failed to write stat round event\n"); | 2872 | pr_err("failed to write stat round event\n"); |
| 2874 | } | 2873 | } |
| 2875 | 2874 | ||
| 2876 | if (!perf_stat.file.is_pipe) { | 2875 | if (!perf_stat.data.is_pipe) { |
| 2877 | perf_stat.session->header.data_size += perf_stat.bytes_written; | 2876 | perf_stat.session->header.data_size += perf_stat.bytes_written; |
| 2878 | perf_session__write_header(perf_stat.session, evsel_list, fd, true); | 2877 | perf_session__write_header(perf_stat.session, evsel_list, fd, true); |
| 2879 | } | 2878 | } |
diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c index 01de01ca14f2..813698a9b8c7 100644 --- a/tools/perf/builtin-timechart.c +++ b/tools/perf/builtin-timechart.c | |||
| @@ -1601,13 +1601,15 @@ static int __cmd_timechart(struct timechart *tchart, const char *output_name) | |||
| 1601 | { "syscalls:sys_exit_pselect6", process_exit_poll }, | 1601 | { "syscalls:sys_exit_pselect6", process_exit_poll }, |
| 1602 | { "syscalls:sys_exit_select", process_exit_poll }, | 1602 | { "syscalls:sys_exit_select", process_exit_poll }, |
| 1603 | }; | 1603 | }; |
| 1604 | struct perf_data_file file = { | 1604 | struct perf_data data = { |
| 1605 | .path = input_name, | 1605 | .file = { |
| 1606 | .mode = PERF_DATA_MODE_READ, | 1606 | .path = input_name, |
| 1607 | .force = tchart->force, | 1607 | }, |
| 1608 | .mode = PERF_DATA_MODE_READ, | ||
| 1609 | .force = tchart->force, | ||
| 1608 | }; | 1610 | }; |
| 1609 | 1611 | ||
| 1610 | struct perf_session *session = perf_session__new(&file, false, | 1612 | struct perf_session *session = perf_session__new(&data, false, |
| 1611 | &tchart->tool); | 1613 | &tchart->tool); |
| 1612 | int ret = -EINVAL; | 1614 | int ret = -EINVAL; |
| 1613 | 1615 | ||
| @@ -1617,7 +1619,7 @@ static int __cmd_timechart(struct timechart *tchart, const char *output_name) | |||
| 1617 | symbol__init(&session->header.env); | 1619 | symbol__init(&session->header.env); |
| 1618 | 1620 | ||
| 1619 | (void)perf_header__process_sections(&session->header, | 1621 | (void)perf_header__process_sections(&session->header, |
| 1620 | perf_data_file__fd(session->file), | 1622 | perf_data__fd(session->data), |
| 1621 | tchart, | 1623 | tchart, |
| 1622 | process_header); | 1624 | process_header); |
| 1623 | 1625 | ||
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 8b23982dd9f2..505b871fdc82 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c | |||
| @@ -578,7 +578,6 @@ static struct syscall_fmt { | |||
| 578 | } syscall_fmts[] = { | 578 | } syscall_fmts[] = { |
| 579 | { .name = "access", | 579 | { .name = "access", |
| 580 | .arg = { [1] = { .scnprintf = SCA_ACCMODE, /* mode */ }, }, }, | 580 | .arg = { [1] = { .scnprintf = SCA_ACCMODE, /* mode */ }, }, }, |
| 581 | { .name = "arch_prctl", .alias = "prctl", }, | ||
| 582 | { .name = "bpf", | 581 | { .name = "bpf", |
| 583 | .arg = { [0] = STRARRAY(cmd, bpf_cmd), }, }, | 582 | .arg = { [0] = STRARRAY(cmd, bpf_cmd), }, }, |
| 584 | { .name = "brk", .hexret = true, | 583 | { .name = "brk", .hexret = true, |
| @@ -634,6 +633,12 @@ static struct syscall_fmt { | |||
| 634 | #else | 633 | #else |
| 635 | [2] = { .scnprintf = SCA_HEX, /* arg */ }, }, }, | 634 | [2] = { .scnprintf = SCA_HEX, /* arg */ }, }, }, |
| 636 | #endif | 635 | #endif |
| 636 | { .name = "kcmp", .nr_args = 5, | ||
| 637 | .arg = { [0] = { .name = "pid1", .scnprintf = SCA_PID, }, | ||
| 638 | [1] = { .name = "pid2", .scnprintf = SCA_PID, }, | ||
| 639 | [2] = { .name = "type", .scnprintf = SCA_KCMP_TYPE, }, | ||
| 640 | [3] = { .name = "idx1", .scnprintf = SCA_KCMP_IDX, }, | ||
| 641 | [4] = { .name = "idx2", .scnprintf = SCA_KCMP_IDX, }, }, }, | ||
| 637 | { .name = "keyctl", | 642 | { .name = "keyctl", |
| 638 | .arg = { [0] = STRARRAY(option, keyctl_options), }, }, | 643 | .arg = { [0] = STRARRAY(option, keyctl_options), }, }, |
| 639 | { .name = "kill", | 644 | { .name = "kill", |
| @@ -703,6 +708,10 @@ static struct syscall_fmt { | |||
| 703 | [3] = { .scnprintf = SCA_INT, /* pkey */ }, }, }, | 708 | [3] = { .scnprintf = SCA_INT, /* pkey */ }, }, }, |
| 704 | { .name = "poll", .timeout = true, }, | 709 | { .name = "poll", .timeout = true, }, |
| 705 | { .name = "ppoll", .timeout = true, }, | 710 | { .name = "ppoll", .timeout = true, }, |
| 711 | { .name = "prctl", .alias = "arch_prctl", | ||
| 712 | .arg = { [0] = { .scnprintf = SCA_PRCTL_OPTION, /* option */ }, | ||
| 713 | [1] = { .scnprintf = SCA_PRCTL_ARG2, /* arg2 */ }, | ||
| 714 | [2] = { .scnprintf = SCA_PRCTL_ARG3, /* arg3 */ }, }, }, | ||
| 706 | { .name = "pread", .alias = "pread64", }, | 715 | { .name = "pread", .alias = "pread64", }, |
| 707 | { .name = "preadv", .alias = "pread", }, | 716 | { .name = "preadv", .alias = "pread", }, |
| 708 | { .name = "prlimit64", | 717 | { .name = "prlimit64", |
| @@ -985,6 +994,23 @@ size_t syscall_arg__scnprintf_fd(char *bf, size_t size, struct syscall_arg *arg) | |||
| 985 | return printed; | 994 | return printed; |
| 986 | } | 995 | } |
| 987 | 996 | ||
| 997 | size_t pid__scnprintf_fd(struct trace *trace, pid_t pid, int fd, char *bf, size_t size) | ||
| 998 | { | ||
| 999 | size_t printed = scnprintf(bf, size, "%d", fd); | ||
| 1000 | struct thread *thread = machine__find_thread(trace->host, pid, pid); | ||
| 1001 | |||
| 1002 | if (thread) { | ||
| 1003 | const char *path = thread__fd_path(thread, fd, trace); | ||
| 1004 | |||
| 1005 | if (path) | ||
| 1006 | printed += scnprintf(bf + printed, size - printed, "<%s>", path); | ||
| 1007 | |||
| 1008 | thread__put(thread); | ||
| 1009 | } | ||
| 1010 | |||
| 1011 | return printed; | ||
| 1012 | } | ||
| 1013 | |||
| 988 | static size_t syscall_arg__scnprintf_close_fd(char *bf, size_t size, | 1014 | static size_t syscall_arg__scnprintf_close_fd(char *bf, size_t size, |
| 989 | struct syscall_arg *arg) | 1015 | struct syscall_arg *arg) |
| 990 | { | 1016 | { |
| @@ -2529,10 +2555,12 @@ static int trace__replay(struct trace *trace) | |||
| 2529 | const struct perf_evsel_str_handler handlers[] = { | 2555 | const struct perf_evsel_str_handler handlers[] = { |
| 2530 | { "probe:vfs_getname", trace__vfs_getname, }, | 2556 | { "probe:vfs_getname", trace__vfs_getname, }, |
| 2531 | }; | 2557 | }; |
| 2532 | struct perf_data_file file = { | 2558 | struct perf_data data = { |
| 2533 | .path = input_name, | 2559 | .file = { |
| 2534 | .mode = PERF_DATA_MODE_READ, | 2560 | .path = input_name, |
| 2535 | .force = trace->force, | 2561 | }, |
| 2562 | .mode = PERF_DATA_MODE_READ, | ||
| 2563 | .force = trace->force, | ||
| 2536 | }; | 2564 | }; |
| 2537 | struct perf_session *session; | 2565 | struct perf_session *session; |
| 2538 | struct perf_evsel *evsel; | 2566 | struct perf_evsel *evsel; |
| @@ -2555,7 +2583,7 @@ static int trace__replay(struct trace *trace) | |||
| 2555 | /* add tid to output */ | 2583 | /* add tid to output */ |
| 2556 | trace->multiple_threads = true; | 2584 | trace->multiple_threads = true; |
| 2557 | 2585 | ||
| 2558 | session = perf_session__new(&file, false, &trace->tool); | 2586 | session = perf_session__new(&data, false, &trace->tool); |
| 2559 | if (session == NULL) | 2587 | if (session == NULL) |
| 2560 | return -1; | 2588 | return -1; |
| 2561 | 2589 | ||
diff --git a/tools/perf/check-headers.sh b/tools/perf/check-headers.sh index 322629423b49..a3a041b0d35e 100755 --- a/tools/perf/check-headers.sh +++ b/tools/perf/check-headers.sh | |||
| @@ -4,8 +4,10 @@ HEADERS=' | |||
| 4 | include/uapi/drm/drm.h | 4 | include/uapi/drm/drm.h |
| 5 | include/uapi/drm/i915_drm.h | 5 | include/uapi/drm/i915_drm.h |
| 6 | include/uapi/linux/fcntl.h | 6 | include/uapi/linux/fcntl.h |
| 7 | include/uapi/linux/kcmp.h | ||
| 7 | include/uapi/linux/kvm.h | 8 | include/uapi/linux/kvm.h |
| 8 | include/uapi/linux/perf_event.h | 9 | include/uapi/linux/perf_event.h |
| 10 | include/uapi/linux/prctl.h | ||
| 9 | include/uapi/linux/sched.h | 11 | include/uapi/linux/sched.h |
| 10 | include/uapi/linux/stat.h | 12 | include/uapi/linux/stat.h |
| 11 | include/uapi/linux/vhost.h | 13 | include/uapi/linux/vhost.h |
diff --git a/tools/perf/tests/topology.c b/tools/perf/tests/topology.c index 19b0561fd6f6..9bbfed51f1d6 100644 --- a/tools/perf/tests/topology.c +++ b/tools/perf/tests/topology.c | |||
| @@ -29,12 +29,14 @@ static int get_temp(char *path) | |||
| 29 | static int session_write_header(char *path) | 29 | static int session_write_header(char *path) |
| 30 | { | 30 | { |
| 31 | struct perf_session *session; | 31 | struct perf_session *session; |
| 32 | struct perf_data_file file = { | 32 | struct perf_data data = { |
| 33 | .path = path, | 33 | .file = { |
| 34 | .mode = PERF_DATA_MODE_WRITE, | 34 | .path = path, |
| 35 | }, | ||
| 36 | .mode = PERF_DATA_MODE_WRITE, | ||
| 35 | }; | 37 | }; |
| 36 | 38 | ||
| 37 | session = perf_session__new(&file, false, NULL); | 39 | session = perf_session__new(&data, false, NULL); |
| 38 | TEST_ASSERT_VAL("can't get session", session); | 40 | TEST_ASSERT_VAL("can't get session", session); |
| 39 | 41 | ||
| 40 | session->evlist = perf_evlist__new_default(); | 42 | session->evlist = perf_evlist__new_default(); |
| @@ -46,7 +48,7 @@ static int session_write_header(char *path) | |||
| 46 | session->header.data_size += DATA_SIZE; | 48 | session->header.data_size += DATA_SIZE; |
| 47 | 49 | ||
| 48 | TEST_ASSERT_VAL("failed to write header", | 50 | TEST_ASSERT_VAL("failed to write header", |
| 49 | !perf_session__write_header(session, session->evlist, file.fd, true)); | 51 | !perf_session__write_header(session, session->evlist, data.file.fd, true)); |
| 50 | 52 | ||
| 51 | perf_session__delete(session); | 53 | perf_session__delete(session); |
| 52 | 54 | ||
| @@ -56,13 +58,15 @@ static int session_write_header(char *path) | |||
| 56 | static int check_cpu_topology(char *path, struct cpu_map *map) | 58 | static int check_cpu_topology(char *path, struct cpu_map *map) |
| 57 | { | 59 | { |
| 58 | struct perf_session *session; | 60 | struct perf_session *session; |
| 59 | struct perf_data_file file = { | 61 | struct perf_data data = { |
| 60 | .path = path, | 62 | .file = { |
| 61 | .mode = PERF_DATA_MODE_READ, | 63 | .path = path, |
| 64 | }, | ||
| 65 | .mode = PERF_DATA_MODE_READ, | ||
| 62 | }; | 66 | }; |
| 63 | int i; | 67 | int i; |
| 64 | 68 | ||
| 65 | session = perf_session__new(&file, false, NULL); | 69 | session = perf_session__new(&data, false, NULL); |
| 66 | TEST_ASSERT_VAL("can't get session", session); | 70 | TEST_ASSERT_VAL("can't get session", session); |
| 67 | 71 | ||
| 68 | for (i = 0; i < session->header.env.nr_cpus_avail; i++) { | 72 | for (i = 0; i < session->header.env.nr_cpus_avail; i++) { |
diff --git a/tools/perf/trace/beauty/Build b/tools/perf/trace/beauty/Build index 175d633c6b49..066bbf0f4a74 100644 --- a/tools/perf/trace/beauty/Build +++ b/tools/perf/trace/beauty/Build | |||
| @@ -3,5 +3,7 @@ libperf-y += fcntl.o | |||
| 3 | ifeq ($(SRCARCH),$(filter $(SRCARCH),x86)) | 3 | ifeq ($(SRCARCH),$(filter $(SRCARCH),x86)) |
| 4 | libperf-y += ioctl.o | 4 | libperf-y += ioctl.o |
| 5 | endif | 5 | endif |
| 6 | libperf-y += kcmp.o | ||
| 6 | libperf-y += pkey_alloc.o | 7 | libperf-y += pkey_alloc.o |
| 8 | libperf-y += prctl.o | ||
| 7 | libperf-y += statx.o | 9 | libperf-y += statx.o |
diff --git a/tools/perf/trace/beauty/beauty.h b/tools/perf/trace/beauty/beauty.h index 4b58581a6053..3f067bdab84f 100644 --- a/tools/perf/trace/beauty/beauty.h +++ b/tools/perf/trace/beauty/beauty.h | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | 3 | ||
| 4 | #include <linux/kernel.h> | 4 | #include <linux/kernel.h> |
| 5 | #include <linux/types.h> | 5 | #include <linux/types.h> |
| 6 | #include <sys/types.h> | ||
| 6 | 7 | ||
| 7 | struct strarray { | 8 | struct strarray { |
| 8 | int offset; | 9 | int offset; |
| @@ -26,6 +27,8 @@ size_t strarray__scnprintf(struct strarray *sa, char *bf, size_t size, const cha | |||
| 26 | struct trace; | 27 | struct trace; |
| 27 | struct thread; | 28 | struct thread; |
| 28 | 29 | ||
| 30 | size_t pid__scnprintf_fd(struct trace *trace, pid_t pid, int fd, char *bf, size_t size); | ||
| 31 | |||
| 29 | /** | 32 | /** |
| 30 | * @val: value of syscall argument being formatted | 33 | * @val: value of syscall argument being formatted |
| 31 | * @args: All the args, use syscall_args__val(arg, nth) to access one | 34 | * @args: All the args, use syscall_args__val(arg, nth) to access one |
| @@ -78,12 +81,27 @@ size_t syscall_arg__scnprintf_fcntl_arg(char *bf, size_t size, struct syscall_ar | |||
| 78 | size_t syscall_arg__scnprintf_ioctl_cmd(char *bf, size_t size, struct syscall_arg *arg); | 81 | size_t syscall_arg__scnprintf_ioctl_cmd(char *bf, size_t size, struct syscall_arg *arg); |
| 79 | #define SCA_IOCTL_CMD syscall_arg__scnprintf_ioctl_cmd | 82 | #define SCA_IOCTL_CMD syscall_arg__scnprintf_ioctl_cmd |
| 80 | 83 | ||
| 84 | size_t syscall_arg__scnprintf_kcmp_type(char *bf, size_t size, struct syscall_arg *arg); | ||
| 85 | #define SCA_KCMP_TYPE syscall_arg__scnprintf_kcmp_type | ||
| 86 | |||
| 87 | size_t syscall_arg__scnprintf_kcmp_idx(char *bf, size_t size, struct syscall_arg *arg); | ||
| 88 | #define SCA_KCMP_IDX syscall_arg__scnprintf_kcmp_idx | ||
| 89 | |||
| 81 | size_t syscall_arg__scnprintf_pkey_alloc_access_rights(char *bf, size_t size, struct syscall_arg *arg); | 90 | size_t syscall_arg__scnprintf_pkey_alloc_access_rights(char *bf, size_t size, struct syscall_arg *arg); |
| 82 | #define SCA_PKEY_ALLOC_ACCESS_RIGHTS syscall_arg__scnprintf_pkey_alloc_access_rights | 91 | #define SCA_PKEY_ALLOC_ACCESS_RIGHTS syscall_arg__scnprintf_pkey_alloc_access_rights |
| 83 | 92 | ||
| 84 | size_t syscall_arg__scnprintf_open_flags(char *bf, size_t size, struct syscall_arg *arg); | 93 | size_t syscall_arg__scnprintf_open_flags(char *bf, size_t size, struct syscall_arg *arg); |
| 85 | #define SCA_OPEN_FLAGS syscall_arg__scnprintf_open_flags | 94 | #define SCA_OPEN_FLAGS syscall_arg__scnprintf_open_flags |
| 86 | 95 | ||
| 96 | size_t syscall_arg__scnprintf_prctl_option(char *bf, size_t size, struct syscall_arg *arg); | ||
| 97 | #define SCA_PRCTL_OPTION syscall_arg__scnprintf_prctl_option | ||
| 98 | |||
| 99 | size_t syscall_arg__scnprintf_prctl_arg2(char *bf, size_t size, struct syscall_arg *arg); | ||
| 100 | #define SCA_PRCTL_ARG2 syscall_arg__scnprintf_prctl_arg2 | ||
| 101 | |||
| 102 | size_t syscall_arg__scnprintf_prctl_arg3(char *bf, size_t size, struct syscall_arg *arg); | ||
| 103 | #define SCA_PRCTL_ARG3 syscall_arg__scnprintf_prctl_arg3 | ||
| 104 | |||
| 87 | size_t syscall_arg__scnprintf_statx_flags(char *bf, size_t size, struct syscall_arg *arg); | 105 | size_t syscall_arg__scnprintf_statx_flags(char *bf, size_t size, struct syscall_arg *arg); |
| 88 | #define SCA_STATX_FLAGS syscall_arg__scnprintf_statx_flags | 106 | #define SCA_STATX_FLAGS syscall_arg__scnprintf_statx_flags |
| 89 | 107 | ||
diff --git a/tools/perf/trace/beauty/kcmp.c b/tools/perf/trace/beauty/kcmp.c new file mode 100644 index 000000000000..f62040eb9d5c --- /dev/null +++ b/tools/perf/trace/beauty/kcmp.c | |||
| @@ -0,0 +1,44 @@ | |||
| 1 | /* | ||
| 2 | * trace/beauty/kcmp.c | ||
| 3 | * | ||
| 4 | * Copyright (C) 2017, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com> | ||
| 5 | * | ||
| 6 | * Released under the GPL v2. (and only v2, not any later version) | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include "trace/beauty/beauty.h" | ||
| 10 | #include <linux/kernel.h> | ||
| 11 | #include <sys/types.h> | ||
| 12 | #include <machine.h> | ||
| 13 | #include <uapi/linux/kcmp.h> | ||
| 14 | |||
| 15 | #include "trace/beauty/generated/kcmp_type_array.c" | ||
| 16 | |||
| 17 | size_t syscall_arg__scnprintf_kcmp_idx(char *bf, size_t size, struct syscall_arg *arg) | ||
| 18 | { | ||
| 19 | unsigned long fd = arg->val; | ||
| 20 | int type = syscall_arg__val(arg, 2); | ||
| 21 | pid_t pid; | ||
| 22 | |||
| 23 | if (type != KCMP_FILE) | ||
| 24 | return syscall_arg__scnprintf_long(bf, size, arg); | ||
| 25 | |||
| 26 | pid = syscall_arg__val(arg, arg->idx == 3 ? 0 : 1); /* idx1 -> pid1, idx2 -> pid2 */ | ||
| 27 | return pid__scnprintf_fd(arg->trace, pid, fd, bf, size); | ||
| 28 | } | ||
| 29 | |||
| 30 | static size_t kcmp__scnprintf_type(int type, char *bf, size_t size) | ||
| 31 | { | ||
| 32 | static DEFINE_STRARRAY(kcmp_types); | ||
| 33 | return strarray__scnprintf(&strarray__kcmp_types, bf, size, "%d", type); | ||
| 34 | } | ||
| 35 | |||
| 36 | size_t syscall_arg__scnprintf_kcmp_type(char *bf, size_t size, struct syscall_arg *arg) | ||
| 37 | { | ||
| 38 | unsigned long type = arg->val; | ||
| 39 | |||
| 40 | if (type != KCMP_FILE) | ||
| 41 | arg->mask |= (1 << 3) | (1 << 4); /* Ignore idx1 and idx2 */ | ||
| 42 | |||
| 43 | return kcmp__scnprintf_type(type, bf, size); | ||
| 44 | } | ||
diff --git a/tools/perf/trace/beauty/kcmp_type.sh b/tools/perf/trace/beauty/kcmp_type.sh new file mode 100755 index 000000000000..40d063b8c082 --- /dev/null +++ b/tools/perf/trace/beauty/kcmp_type.sh | |||
| @@ -0,0 +1,10 @@ | |||
| 1 | #!/bin/sh | ||
| 2 | |||
| 3 | header_dir=$1 | ||
| 4 | |||
| 5 | printf "static const char *kcmp_types[] = {\n" | ||
| 6 | regex='^[[:space:]]+(KCMP_(\w+)),' | ||
| 7 | egrep $regex ${header_dir}/kcmp.h | grep -v KCMP_TYPES, | \ | ||
| 8 | sed -r "s/$regex/\1 \2/g" | \ | ||
| 9 | xargs printf "\t[%s]\t= \"%s\",\n" | ||
| 10 | printf "};\n" | ||
diff --git a/tools/perf/trace/beauty/prctl.c b/tools/perf/trace/beauty/prctl.c new file mode 100644 index 000000000000..246130dad6c4 --- /dev/null +++ b/tools/perf/trace/beauty/prctl.c | |||
| @@ -0,0 +1,82 @@ | |||
| 1 | /* | ||
| 2 | * trace/beauty/prctl.c | ||
| 3 | * | ||
| 4 | * Copyright (C) 2017, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com> | ||
| 5 | * | ||
| 6 | * Released under the GPL v2. (and only v2, not any later version) | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include "trace/beauty/beauty.h" | ||
| 10 | #include <linux/kernel.h> | ||
| 11 | #include <uapi/linux/prctl.h> | ||
| 12 | |||
| 13 | #include "trace/beauty/generated/prctl_option_array.c" | ||
| 14 | |||
| 15 | static size_t prctl__scnprintf_option(int option, char *bf, size_t size) | ||
| 16 | { | ||
| 17 | static DEFINE_STRARRAY(prctl_options); | ||
| 18 | return strarray__scnprintf(&strarray__prctl_options, bf, size, "%d", option); | ||
| 19 | } | ||
| 20 | |||
| 21 | static size_t prctl__scnprintf_set_mm(int option, char *bf, size_t size) | ||
| 22 | { | ||
| 23 | static DEFINE_STRARRAY(prctl_set_mm_options); | ||
| 24 | return strarray__scnprintf(&strarray__prctl_set_mm_options, bf, size, "%d", option); | ||
| 25 | } | ||
| 26 | |||
| 27 | size_t syscall_arg__scnprintf_prctl_arg2(char *bf, size_t size, struct syscall_arg *arg) | ||
| 28 | { | ||
| 29 | int option = syscall_arg__val(arg, 0); | ||
| 30 | |||
| 31 | if (option == PR_SET_MM) | ||
| 32 | return prctl__scnprintf_set_mm(arg->val, bf, size); | ||
| 33 | /* | ||
| 34 | * We still don't grab the contents of pointers on entry or exit, | ||
| 35 | * so just print them as hex numbers | ||
| 36 | */ | ||
| 37 | if (option == PR_SET_NAME) | ||
| 38 | return syscall_arg__scnprintf_hex(bf, size, arg); | ||
| 39 | |||
| 40 | return syscall_arg__scnprintf_long(bf, size, arg); | ||
| 41 | } | ||
| 42 | |||
| 43 | size_t syscall_arg__scnprintf_prctl_arg3(char *bf, size_t size, struct syscall_arg *arg) | ||
| 44 | { | ||
| 45 | int option = syscall_arg__val(arg, 0); | ||
| 46 | |||
| 47 | if (option == PR_SET_MM) | ||
| 48 | return syscall_arg__scnprintf_hex(bf, size, arg); | ||
| 49 | |||
| 50 | return syscall_arg__scnprintf_long(bf, size, arg); | ||
| 51 | } | ||
| 52 | |||
| 53 | size_t syscall_arg__scnprintf_prctl_option(char *bf, size_t size, struct syscall_arg *arg) | ||
| 54 | { | ||
| 55 | unsigned long option = arg->val; | ||
| 56 | enum { | ||
| 57 | SPO_ARG2 = (1 << 1), | ||
| 58 | SPO_ARG3 = (1 << 2), | ||
| 59 | SPO_ARG4 = (1 << 3), | ||
| 60 | SPO_ARG5 = (1 << 4), | ||
| 61 | SPO_ARG6 = (1 << 5), | ||
| 62 | }; | ||
| 63 | const u8 all_but2 = SPO_ARG3 | SPO_ARG4 | SPO_ARG5 | SPO_ARG6; | ||
| 64 | const u8 all = SPO_ARG2 | all_but2; | ||
| 65 | const u8 masks[] = { | ||
| 66 | [PR_GET_DUMPABLE] = all, | ||
| 67 | [PR_SET_DUMPABLE] = all_but2, | ||
| 68 | [PR_SET_NAME] = all_but2, | ||
| 69 | [PR_GET_CHILD_SUBREAPER] = all_but2, | ||
| 70 | [PR_SET_CHILD_SUBREAPER] = all_but2, | ||
| 71 | [PR_GET_SECUREBITS] = all, | ||
| 72 | [PR_SET_SECUREBITS] = all_but2, | ||
| 73 | [PR_SET_MM] = SPO_ARG4 | SPO_ARG5 | SPO_ARG6, | ||
| 74 | [PR_GET_PDEATHSIG] = all, | ||
| 75 | [PR_SET_PDEATHSIG] = all_but2, | ||
| 76 | }; | ||
| 77 | |||
| 78 | if (option < ARRAY_SIZE(masks)) | ||
| 79 | arg->mask |= masks[option]; | ||
| 80 | |||
| 81 | return prctl__scnprintf_option(option, bf, size); | ||
| 82 | } | ||
diff --git a/tools/perf/trace/beauty/prctl_option.sh b/tools/perf/trace/beauty/prctl_option.sh new file mode 100755 index 000000000000..0be4138fbe71 --- /dev/null +++ b/tools/perf/trace/beauty/prctl_option.sh | |||
| @@ -0,0 +1,17 @@ | |||
| 1 | #!/bin/sh | ||
| 2 | |||
| 3 | header_dir=$1 | ||
| 4 | |||
| 5 | printf "static const char *prctl_options[] = {\n" | ||
| 6 | regex='^#define[[:space:]]+PR_([GS]ET\w+)[[:space:]]*([[:xdigit:]]+).*' | ||
| 7 | egrep $regex ${header_dir}/prctl.h | grep -v PR_SET_PTRACER | \ | ||
| 8 | sed -r "s/$regex/\2 \1/g" | \ | ||
| 9 | sort -n | xargs printf "\t[%s] = \"%s\",\n" | ||
| 10 | printf "};\n" | ||
| 11 | |||
| 12 | printf "static const char *prctl_set_mm_options[] = {\n" | ||
| 13 | regex='^#[[:space:]]+define[[:space:]]+PR_SET_MM_(\w+)[[:space:]]*([[:digit:]]+).*' | ||
| 14 | egrep $regex ${header_dir}/prctl.h | \ | ||
| 15 | sed -r "s/$regex/\2 \1/g" | \ | ||
| 16 | sort -n | xargs printf "\t[%s] = \"%s\",\n" | ||
| 17 | printf "};\n" | ||
diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c index 5547457566a7..a33491416400 100644 --- a/tools/perf/util/auxtrace.c +++ b/tools/perf/util/auxtrace.c | |||
| @@ -208,7 +208,7 @@ static int auxtrace_queues__grow(struct auxtrace_queues *queues, | |||
| 208 | 208 | ||
| 209 | static void *auxtrace_copy_data(u64 size, struct perf_session *session) | 209 | static void *auxtrace_copy_data(u64 size, struct perf_session *session) |
| 210 | { | 210 | { |
| 211 | int fd = perf_data_file__fd(session->file); | 211 | int fd = perf_data__fd(session->data); |
| 212 | void *p; | 212 | void *p; |
| 213 | ssize_t ret; | 213 | ssize_t ret; |
| 214 | 214 | ||
| @@ -305,7 +305,7 @@ static int auxtrace_queues__add_event_buffer(struct auxtrace_queues *queues, | |||
| 305 | if (session->one_mmap) { | 305 | if (session->one_mmap) { |
| 306 | buffer->data = buffer->data_offset - session->one_mmap_offset + | 306 | buffer->data = buffer->data_offset - session->one_mmap_offset + |
| 307 | session->one_mmap_addr; | 307 | session->one_mmap_addr; |
| 308 | } else if (perf_data_file__is_pipe(session->file)) { | 308 | } else if (perf_data__is_pipe(session->data)) { |
| 309 | buffer->data = auxtrace_copy_data(buffer->size, session); | 309 | buffer->data = auxtrace_copy_data(buffer->size, session); |
| 310 | if (!buffer->data) | 310 | if (!buffer->data) |
| 311 | return -ENOMEM; | 311 | return -ENOMEM; |
diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c index 3a3916934a92..837012147c7b 100644 --- a/tools/perf/util/callchain.c +++ b/tools/perf/util/callchain.c | |||
| @@ -1091,10 +1091,7 @@ int fill_callchain_info(struct addr_location *al, struct callchain_cursor_node * | |||
| 1091 | al->map = node->map; | 1091 | al->map = node->map; |
| 1092 | al->sym = node->sym; | 1092 | al->sym = node->sym; |
| 1093 | al->srcline = node->srcline; | 1093 | al->srcline = node->srcline; |
| 1094 | if (node->map) | 1094 | al->addr = node->ip; |
| 1095 | al->addr = node->map->map_ip(node->map, node->ip); | ||
| 1096 | else | ||
| 1097 | al->addr = node->ip; | ||
| 1098 | 1095 | ||
| 1099 | if (al->sym == NULL) { | 1096 | if (al->sym == NULL) { |
| 1100 | if (hide_unresolved) | 1097 | if (hide_unresolved) |
diff --git a/tools/perf/util/data-convert-bt.c b/tools/perf/util/data-convert-bt.c index 2346cecb8ea2..5744c12641a5 100644 --- a/tools/perf/util/data-convert-bt.c +++ b/tools/perf/util/data-convert-bt.c | |||
| @@ -1577,10 +1577,10 @@ int bt_convert__perf2ctf(const char *input, const char *path, | |||
| 1577 | struct perf_data_convert_opts *opts) | 1577 | struct perf_data_convert_opts *opts) |
| 1578 | { | 1578 | { |
| 1579 | struct perf_session *session; | 1579 | struct perf_session *session; |
| 1580 | struct perf_data_file file = { | 1580 | struct perf_data data = { |
| 1581 | .path = input, | 1581 | .file.path = input, |
| 1582 | .mode = PERF_DATA_MODE_READ, | 1582 | .mode = PERF_DATA_MODE_READ, |
| 1583 | .force = opts->force, | 1583 | .force = opts->force, |
| 1584 | }; | 1584 | }; |
| 1585 | struct convert c = { | 1585 | struct convert c = { |
| 1586 | .tool = { | 1586 | .tool = { |
| @@ -1619,7 +1619,7 @@ int bt_convert__perf2ctf(const char *input, const char *path, | |||
| 1619 | 1619 | ||
| 1620 | err = -1; | 1620 | err = -1; |
| 1621 | /* perf.data session */ | 1621 | /* perf.data session */ |
| 1622 | session = perf_session__new(&file, 0, &c.tool); | 1622 | session = perf_session__new(&data, 0, &c.tool); |
| 1623 | if (!session) | 1623 | if (!session) |
| 1624 | goto free_writer; | 1624 | goto free_writer; |
| 1625 | 1625 | ||
| @@ -1650,7 +1650,7 @@ int bt_convert__perf2ctf(const char *input, const char *path, | |||
| 1650 | 1650 | ||
| 1651 | fprintf(stderr, | 1651 | fprintf(stderr, |
| 1652 | "[ perf data convert: Converted '%s' into CTF data '%s' ]\n", | 1652 | "[ perf data convert: Converted '%s' into CTF data '%s' ]\n", |
| 1653 | file.path, path); | 1653 | data.file.path, path); |
| 1654 | 1654 | ||
| 1655 | fprintf(stderr, | 1655 | fprintf(stderr, |
| 1656 | "[ perf data convert: Converted and wrote %.3f MB (%" PRIu64 " samples", | 1656 | "[ perf data convert: Converted and wrote %.3f MB (%" PRIu64 " samples", |
diff --git a/tools/perf/util/data.c b/tools/perf/util/data.c index 1123b30e3033..f80a23d031d6 100644 --- a/tools/perf/util/data.c +++ b/tools/perf/util/data.c | |||
| @@ -21,56 +21,56 @@ | |||
| 21 | #endif | 21 | #endif |
| 22 | #endif | 22 | #endif |
| 23 | 23 | ||
| 24 | static bool check_pipe(struct perf_data_file *file) | 24 | static bool check_pipe(struct perf_data *data) |
| 25 | { | 25 | { |
| 26 | struct stat st; | 26 | struct stat st; |
| 27 | bool is_pipe = false; | 27 | bool is_pipe = false; |
| 28 | int fd = perf_data_file__is_read(file) ? | 28 | int fd = perf_data__is_read(data) ? |
| 29 | STDIN_FILENO : STDOUT_FILENO; | 29 | STDIN_FILENO : STDOUT_FILENO; |
| 30 | 30 | ||
| 31 | if (!file->path) { | 31 | if (!data->file.path) { |
| 32 | if (!fstat(fd, &st) && S_ISFIFO(st.st_mode)) | 32 | if (!fstat(fd, &st) && S_ISFIFO(st.st_mode)) |
| 33 | is_pipe = true; | 33 | is_pipe = true; |
| 34 | } else { | 34 | } else { |
| 35 | if (!strcmp(file->path, "-")) | 35 | if (!strcmp(data->file.path, "-")) |
| 36 | is_pipe = true; | 36 | is_pipe = true; |
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | if (is_pipe) | 39 | if (is_pipe) |
| 40 | file->fd = fd; | 40 | data->file.fd = fd; |
| 41 | 41 | ||
| 42 | return file->is_pipe = is_pipe; | 42 | return data->is_pipe = is_pipe; |
| 43 | } | 43 | } |
| 44 | 44 | ||
| 45 | static int check_backup(struct perf_data_file *file) | 45 | static int check_backup(struct perf_data *data) |
| 46 | { | 46 | { |
| 47 | struct stat st; | 47 | struct stat st; |
| 48 | 48 | ||
| 49 | if (!stat(file->path, &st) && st.st_size) { | 49 | if (!stat(data->file.path, &st) && st.st_size) { |
| 50 | /* TODO check errors properly */ | 50 | /* TODO check errors properly */ |
| 51 | char oldname[PATH_MAX]; | 51 | char oldname[PATH_MAX]; |
| 52 | snprintf(oldname, sizeof(oldname), "%s.old", | 52 | snprintf(oldname, sizeof(oldname), "%s.old", |
| 53 | file->path); | 53 | data->file.path); |
| 54 | unlink(oldname); | 54 | unlink(oldname); |
| 55 | rename(file->path, oldname); | 55 | rename(data->file.path, oldname); |
| 56 | } | 56 | } |
| 57 | 57 | ||
| 58 | return 0; | 58 | return 0; |
| 59 | } | 59 | } |
| 60 | 60 | ||
| 61 | static int open_file_read(struct perf_data_file *file) | 61 | static int open_file_read(struct perf_data *data) |
| 62 | { | 62 | { |
| 63 | struct stat st; | 63 | struct stat st; |
| 64 | int fd; | 64 | int fd; |
| 65 | char sbuf[STRERR_BUFSIZE]; | 65 | char sbuf[STRERR_BUFSIZE]; |
| 66 | 66 | ||
| 67 | fd = open(file->path, O_RDONLY); | 67 | fd = open(data->file.path, O_RDONLY); |
| 68 | if (fd < 0) { | 68 | if (fd < 0) { |
| 69 | int err = errno; | 69 | int err = errno; |
| 70 | 70 | ||
| 71 | pr_err("failed to open %s: %s", file->path, | 71 | pr_err("failed to open %s: %s", data->file.path, |
| 72 | str_error_r(err, sbuf, sizeof(sbuf))); | 72 | str_error_r(err, sbuf, sizeof(sbuf))); |
| 73 | if (err == ENOENT && !strcmp(file->path, "perf.data")) | 73 | if (err == ENOENT && !strcmp(data->file.path, "perf.data")) |
| 74 | pr_err(" (try 'perf record' first)"); | 74 | pr_err(" (try 'perf record' first)"); |
| 75 | pr_err("\n"); | 75 | pr_err("\n"); |
| 76 | return -err; | 76 | return -err; |
| @@ -79,19 +79,19 @@ static int open_file_read(struct perf_data_file *file) | |||
| 79 | if (fstat(fd, &st) < 0) | 79 | if (fstat(fd, &st) < 0) |
| 80 | goto out_close; | 80 | goto out_close; |
| 81 | 81 | ||
| 82 | if (!file->force && st.st_uid && (st.st_uid != geteuid())) { | 82 | if (!data->force && st.st_uid && (st.st_uid != geteuid())) { |
| 83 | pr_err("File %s not owned by current user or root (use -f to override)\n", | 83 | pr_err("File %s not owned by current user or root (use -f to override)\n", |
| 84 | file->path); | 84 | data->file.path); |
| 85 | goto out_close; | 85 | goto out_close; |
| 86 | } | 86 | } |
| 87 | 87 | ||
| 88 | if (!st.st_size) { | 88 | if (!st.st_size) { |
| 89 | pr_info("zero-sized file (%s), nothing to do!\n", | 89 | pr_info("zero-sized data (%s), nothing to do!\n", |
| 90 | file->path); | 90 | data->file.path); |
| 91 | goto out_close; | 91 | goto out_close; |
| 92 | } | 92 | } |
| 93 | 93 | ||
| 94 | file->size = st.st_size; | 94 | data->size = st.st_size; |
| 95 | return fd; | 95 | return fd; |
| 96 | 96 | ||
| 97 | out_close: | 97 | out_close: |
| @@ -99,49 +99,49 @@ static int open_file_read(struct perf_data_file *file) | |||
| 99 | return -1; | 99 | return -1; |
| 100 | } | 100 | } |
| 101 | 101 | ||
| 102 | static int open_file_write(struct perf_data_file *file) | 102 | static int open_file_write(struct perf_data *data) |
| 103 | { | 103 | { |
| 104 | int fd; | 104 | int fd; |
| 105 | char sbuf[STRERR_BUFSIZE]; | 105 | char sbuf[STRERR_BUFSIZE]; |
| 106 | 106 | ||
| 107 | if (check_backup(file)) | 107 | if (check_backup(data)) |
| 108 | return -1; | 108 | return -1; |
| 109 | 109 | ||
| 110 | fd = open(file->path, O_CREAT|O_RDWR|O_TRUNC|O_CLOEXEC, | 110 | fd = open(data->file.path, O_CREAT|O_RDWR|O_TRUNC|O_CLOEXEC, |
| 111 | S_IRUSR|S_IWUSR); | 111 | S_IRUSR|S_IWUSR); |
| 112 | 112 | ||
| 113 | if (fd < 0) | 113 | if (fd < 0) |
| 114 | pr_err("failed to open %s : %s\n", file->path, | 114 | pr_err("failed to open %s : %s\n", data->file.path, |
| 115 | str_error_r(errno, sbuf, sizeof(sbuf))); | 115 | str_error_r(errno, sbuf, sizeof(sbuf))); |
| 116 | 116 | ||
| 117 | return fd; | 117 | return fd; |
| 118 | } | 118 | } |
| 119 | 119 | ||
| 120 | static int open_file(struct perf_data_file *file) | 120 | static int open_file(struct perf_data *data) |
| 121 | { | 121 | { |
| 122 | int fd; | 122 | int fd; |
| 123 | 123 | ||
| 124 | fd = perf_data_file__is_read(file) ? | 124 | fd = perf_data__is_read(data) ? |
| 125 | open_file_read(file) : open_file_write(file); | 125 | open_file_read(data) : open_file_write(data); |
| 126 | 126 | ||
| 127 | file->fd = fd; | 127 | data->file.fd = fd; |
| 128 | return fd < 0 ? -1 : 0; | 128 | return fd < 0 ? -1 : 0; |
| 129 | } | 129 | } |
| 130 | 130 | ||
| 131 | int perf_data_file__open(struct perf_data_file *file) | 131 | int perf_data__open(struct perf_data *data) |
| 132 | { | 132 | { |
| 133 | if (check_pipe(file)) | 133 | if (check_pipe(data)) |
| 134 | return 0; | 134 | return 0; |
| 135 | 135 | ||
| 136 | if (!file->path) | 136 | if (!data->file.path) |
| 137 | file->path = "perf.data"; | 137 | data->file.path = "perf.data"; |
| 138 | 138 | ||
| 139 | return open_file(file); | 139 | return open_file(data); |
| 140 | } | 140 | } |
| 141 | 141 | ||
| 142 | void perf_data_file__close(struct perf_data_file *file) | 142 | void perf_data__close(struct perf_data *data) |
| 143 | { | 143 | { |
| 144 | close(file->fd); | 144 | close(data->file.fd); |
| 145 | } | 145 | } |
| 146 | 146 | ||
| 147 | ssize_t perf_data_file__write(struct perf_data_file *file, | 147 | ssize_t perf_data_file__write(struct perf_data_file *file, |
| @@ -150,42 +150,48 @@ ssize_t perf_data_file__write(struct perf_data_file *file, | |||
| 150 | return writen(file->fd, buf, size); | 150 | return writen(file->fd, buf, size); |
| 151 | } | 151 | } |
| 152 | 152 | ||
| 153 | int perf_data_file__switch(struct perf_data_file *file, | 153 | ssize_t perf_data__write(struct perf_data *data, |
| 154 | void *buf, size_t size) | ||
| 155 | { | ||
| 156 | return perf_data_file__write(&data->file, buf, size); | ||
| 157 | } | ||
| 158 | |||
| 159 | int perf_data__switch(struct perf_data *data, | ||
| 154 | const char *postfix, | 160 | const char *postfix, |
| 155 | size_t pos, bool at_exit) | 161 | size_t pos, bool at_exit) |
| 156 | { | 162 | { |
| 157 | char *new_filepath; | 163 | char *new_filepath; |
| 158 | int ret; | 164 | int ret; |
| 159 | 165 | ||
| 160 | if (check_pipe(file)) | 166 | if (check_pipe(data)) |
| 161 | return -EINVAL; | 167 | return -EINVAL; |
| 162 | if (perf_data_file__is_read(file)) | 168 | if (perf_data__is_read(data)) |
| 163 | return -EINVAL; | 169 | return -EINVAL; |
| 164 | 170 | ||
| 165 | if (asprintf(&new_filepath, "%s.%s", file->path, postfix) < 0) | 171 | if (asprintf(&new_filepath, "%s.%s", data->file.path, postfix) < 0) |
| 166 | return -ENOMEM; | 172 | return -ENOMEM; |
| 167 | 173 | ||
| 168 | /* | 174 | /* |
| 169 | * Only fire a warning, don't return error, continue fill | 175 | * Only fire a warning, don't return error, continue fill |
| 170 | * original file. | 176 | * original file. |
| 171 | */ | 177 | */ |
| 172 | if (rename(file->path, new_filepath)) | 178 | if (rename(data->file.path, new_filepath)) |
| 173 | pr_warning("Failed to rename %s to %s\n", file->path, new_filepath); | 179 | pr_warning("Failed to rename %s to %s\n", data->file.path, new_filepath); |
| 174 | 180 | ||
| 175 | if (!at_exit) { | 181 | if (!at_exit) { |
| 176 | close(file->fd); | 182 | close(data->file.fd); |
| 177 | ret = perf_data_file__open(file); | 183 | ret = perf_data__open(data); |
| 178 | if (ret < 0) | 184 | if (ret < 0) |
| 179 | goto out; | 185 | goto out; |
| 180 | 186 | ||
| 181 | if (lseek(file->fd, pos, SEEK_SET) == (off_t)-1) { | 187 | if (lseek(data->file.fd, pos, SEEK_SET) == (off_t)-1) { |
| 182 | ret = -errno; | 188 | ret = -errno; |
| 183 | pr_debug("Failed to lseek to %zu: %s", | 189 | pr_debug("Failed to lseek to %zu: %s", |
| 184 | pos, strerror(errno)); | 190 | pos, strerror(errno)); |
| 185 | goto out; | 191 | goto out; |
| 186 | } | 192 | } |
| 187 | } | 193 | } |
| 188 | ret = file->fd; | 194 | ret = data->file.fd; |
| 189 | out: | 195 | out: |
| 190 | free(new_filepath); | 196 | free(new_filepath); |
| 191 | return ret; | 197 | return ret; |
diff --git a/tools/perf/util/data.h b/tools/perf/util/data.h index ae510ce16cb1..000c43bbb7ac 100644 --- a/tools/perf/util/data.h +++ b/tools/perf/util/data.h | |||
| @@ -9,51 +9,57 @@ enum perf_data_mode { | |||
| 9 | }; | 9 | }; |
| 10 | 10 | ||
| 11 | struct perf_data_file { | 11 | struct perf_data_file { |
| 12 | const char *path; | 12 | const char *path; |
| 13 | int fd; | 13 | int fd; |
| 14 | }; | ||
| 15 | |||
| 16 | struct perf_data { | ||
| 17 | struct perf_data_file file; | ||
| 14 | bool is_pipe; | 18 | bool is_pipe; |
| 15 | bool force; | 19 | bool force; |
| 16 | unsigned long size; | 20 | unsigned long size; |
| 17 | enum perf_data_mode mode; | 21 | enum perf_data_mode mode; |
| 18 | }; | 22 | }; |
| 19 | 23 | ||
| 20 | static inline bool perf_data_file__is_read(struct perf_data_file *file) | 24 | static inline bool perf_data__is_read(struct perf_data *data) |
| 21 | { | 25 | { |
| 22 | return file->mode == PERF_DATA_MODE_READ; | 26 | return data->mode == PERF_DATA_MODE_READ; |
| 23 | } | 27 | } |
| 24 | 28 | ||
| 25 | static inline bool perf_data_file__is_write(struct perf_data_file *file) | 29 | static inline bool perf_data__is_write(struct perf_data *data) |
| 26 | { | 30 | { |
| 27 | return file->mode == PERF_DATA_MODE_WRITE; | 31 | return data->mode == PERF_DATA_MODE_WRITE; |
| 28 | } | 32 | } |
| 29 | 33 | ||
| 30 | static inline int perf_data_file__is_pipe(struct perf_data_file *file) | 34 | static inline int perf_data__is_pipe(struct perf_data *data) |
| 31 | { | 35 | { |
| 32 | return file->is_pipe; | 36 | return data->is_pipe; |
| 33 | } | 37 | } |
| 34 | 38 | ||
| 35 | static inline int perf_data_file__fd(struct perf_data_file *file) | 39 | static inline int perf_data__fd(struct perf_data *data) |
| 36 | { | 40 | { |
| 37 | return file->fd; | 41 | return data->file.fd; |
| 38 | } | 42 | } |
| 39 | 43 | ||
| 40 | static inline unsigned long perf_data_file__size(struct perf_data_file *file) | 44 | static inline unsigned long perf_data__size(struct perf_data *data) |
| 41 | { | 45 | { |
| 42 | return file->size; | 46 | return data->size; |
| 43 | } | 47 | } |
| 44 | 48 | ||
| 45 | int perf_data_file__open(struct perf_data_file *file); | 49 | int perf_data__open(struct perf_data *data); |
| 46 | void perf_data_file__close(struct perf_data_file *file); | 50 | void perf_data__close(struct perf_data *data); |
| 51 | ssize_t perf_data__write(struct perf_data *data, | ||
| 52 | void *buf, size_t size); | ||
| 47 | ssize_t perf_data_file__write(struct perf_data_file *file, | 53 | ssize_t perf_data_file__write(struct perf_data_file *file, |
| 48 | void *buf, size_t size); | 54 | void *buf, size_t size); |
| 49 | /* | 55 | /* |
| 50 | * If at_exit is set, only rename current perf.data to | 56 | * If at_exit is set, only rename current perf.data to |
| 51 | * perf.data.<postfix>, continue write on original file. | 57 | * perf.data.<postfix>, continue write on original data. |
| 52 | * Set at_exit when flushing the last output. | 58 | * Set at_exit when flushing the last output. |
| 53 | * | 59 | * |
| 54 | * Return value is fd of new output. | 60 | * Return value is fd of new output. |
| 55 | */ | 61 | */ |
| 56 | int perf_data_file__switch(struct perf_data_file *file, | 62 | int perf_data__switch(struct perf_data *data, |
| 57 | const char *postfix, | 63 | const char *postfix, |
| 58 | size_t pos, bool at_exit); | 64 | size_t pos, bool at_exit); |
| 59 | #endif /* __PERF_DATA_H */ | 65 | #endif /* __PERF_DATA_H */ |
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index db658785d828..64782b19089d 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h | |||
| @@ -68,6 +68,8 @@ struct perf_evsel_config_term { | |||
| 68 | } val; | 68 | } val; |
| 69 | }; | 69 | }; |
| 70 | 70 | ||
| 71 | struct perf_stat_evsel; | ||
| 72 | |||
| 71 | /** struct perf_evsel - event selector | 73 | /** struct perf_evsel - event selector |
| 72 | * | 74 | * |
| 73 | * @evlist - evlist this evsel is in, if it is in one. | 75 | * @evlist - evlist this evsel is in, if it is in one. |
| @@ -101,6 +103,7 @@ struct perf_evsel { | |||
| 101 | const char *unit; | 103 | const char *unit; |
| 102 | struct event_format *tp_format; | 104 | struct event_format *tp_format; |
| 103 | off_t id_offset; | 105 | off_t id_offset; |
| 106 | struct perf_stat_evsel *stats; | ||
| 104 | void *priv; | 107 | void *priv; |
| 105 | u64 db_id; | 108 | u64 db_id; |
| 106 | struct cgroup_sel *cgrp; | 109 | struct cgroup_sel *cgrp; |
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 605bbd5404fb..6e59dcca9df2 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c | |||
| @@ -1762,7 +1762,7 @@ process_event_desc(struct feat_fd *ff, void *data __maybe_unused) | |||
| 1762 | 1762 | ||
| 1763 | session = container_of(ff->ph, struct perf_session, header); | 1763 | session = container_of(ff->ph, struct perf_session, header); |
| 1764 | 1764 | ||
| 1765 | if (session->file->is_pipe) { | 1765 | if (session->data->is_pipe) { |
| 1766 | /* Save events for reading later by print_event_desc, | 1766 | /* Save events for reading later by print_event_desc, |
| 1767 | * since they can't be read again in pipe mode. */ | 1767 | * since they can't be read again in pipe mode. */ |
| 1768 | ff->events = events; | 1768 | ff->events = events; |
| @@ -1771,7 +1771,7 @@ process_event_desc(struct feat_fd *ff, void *data __maybe_unused) | |||
| 1771 | for (evsel = events; evsel->attr.size; evsel++) | 1771 | for (evsel = events; evsel->attr.size; evsel++) |
| 1772 | perf_evlist__set_event_name(session->evlist, evsel); | 1772 | perf_evlist__set_event_name(session->evlist, evsel); |
| 1773 | 1773 | ||
| 1774 | if (!session->file->is_pipe) | 1774 | if (!session->data->is_pipe) |
| 1775 | free_event_desc(events); | 1775 | free_event_desc(events); |
| 1776 | 1776 | ||
| 1777 | return 0; | 1777 | return 0; |
| @@ -2248,7 +2248,7 @@ int perf_header__fprintf_info(struct perf_session *session, FILE *fp, bool full) | |||
| 2248 | { | 2248 | { |
| 2249 | struct header_print_data hd; | 2249 | struct header_print_data hd; |
| 2250 | struct perf_header *header = &session->header; | 2250 | struct perf_header *header = &session->header; |
| 2251 | int fd = perf_data_file__fd(session->file); | 2251 | int fd = perf_data__fd(session->data); |
| 2252 | struct stat st; | 2252 | struct stat st; |
| 2253 | int ret, bit; | 2253 | int ret, bit; |
| 2254 | 2254 | ||
| @@ -2264,7 +2264,7 @@ int perf_header__fprintf_info(struct perf_session *session, FILE *fp, bool full) | |||
| 2264 | perf_header__process_sections(header, fd, &hd, | 2264 | perf_header__process_sections(header, fd, &hd, |
| 2265 | perf_file_section__fprintf_info); | 2265 | perf_file_section__fprintf_info); |
| 2266 | 2266 | ||
| 2267 | if (session->file->is_pipe) | 2267 | if (session->data->is_pipe) |
| 2268 | return 0; | 2268 | return 0; |
| 2269 | 2269 | ||
| 2270 | fprintf(fp, "# missing features: "); | 2270 | fprintf(fp, "# missing features: "); |
| @@ -2757,7 +2757,7 @@ static int perf_header__read_pipe(struct perf_session *session) | |||
| 2757 | struct perf_pipe_file_header f_header; | 2757 | struct perf_pipe_file_header f_header; |
| 2758 | 2758 | ||
| 2759 | if (perf_file_header__read_pipe(&f_header, header, | 2759 | if (perf_file_header__read_pipe(&f_header, header, |
| 2760 | perf_data_file__fd(session->file), | 2760 | perf_data__fd(session->data), |
| 2761 | session->repipe) < 0) { | 2761 | session->repipe) < 0) { |
| 2762 | pr_debug("incompatible file format\n"); | 2762 | pr_debug("incompatible file format\n"); |
| 2763 | return -EINVAL; | 2763 | return -EINVAL; |
| @@ -2860,13 +2860,13 @@ static int perf_evlist__prepare_tracepoint_events(struct perf_evlist *evlist, | |||
| 2860 | 2860 | ||
| 2861 | int perf_session__read_header(struct perf_session *session) | 2861 | int perf_session__read_header(struct perf_session *session) |
| 2862 | { | 2862 | { |
| 2863 | struct perf_data_file *file = session->file; | 2863 | struct perf_data *data = session->data; |
| 2864 | struct perf_header *header = &session->header; | 2864 | struct perf_header *header = &session->header; |
| 2865 | struct perf_file_header f_header; | 2865 | struct perf_file_header f_header; |
| 2866 | struct perf_file_attr f_attr; | 2866 | struct perf_file_attr f_attr; |
| 2867 | u64 f_id; | 2867 | u64 f_id; |
| 2868 | int nr_attrs, nr_ids, i, j; | 2868 | int nr_attrs, nr_ids, i, j; |
| 2869 | int fd = perf_data_file__fd(file); | 2869 | int fd = perf_data__fd(data); |
| 2870 | 2870 | ||
| 2871 | session->evlist = perf_evlist__new(); | 2871 | session->evlist = perf_evlist__new(); |
| 2872 | if (session->evlist == NULL) | 2872 | if (session->evlist == NULL) |
| @@ -2874,7 +2874,7 @@ int perf_session__read_header(struct perf_session *session) | |||
| 2874 | 2874 | ||
| 2875 | session->evlist->env = &header->env; | 2875 | session->evlist->env = &header->env; |
| 2876 | session->machines.host.env = &header->env; | 2876 | session->machines.host.env = &header->env; |
| 2877 | if (perf_data_file__is_pipe(file)) | 2877 | if (perf_data__is_pipe(data)) |
| 2878 | return perf_header__read_pipe(session); | 2878 | return perf_header__read_pipe(session); |
| 2879 | 2879 | ||
| 2880 | if (perf_file_header__read(&f_header, header, fd) < 0) | 2880 | if (perf_file_header__read(&f_header, header, fd) < 0) |
| @@ -2889,7 +2889,7 @@ int perf_session__read_header(struct perf_session *session) | |||
| 2889 | if (f_header.data.size == 0) { | 2889 | if (f_header.data.size == 0) { |
| 2890 | pr_warning("WARNING: The %s file's data size field is 0 which is unexpected.\n" | 2890 | pr_warning("WARNING: The %s file's data size field is 0 which is unexpected.\n" |
| 2891 | "Was the 'perf record' command properly terminated?\n", | 2891 | "Was the 'perf record' command properly terminated?\n", |
| 2892 | file->path); | 2892 | data->file.path); |
| 2893 | } | 2893 | } |
| 2894 | 2894 | ||
| 2895 | nr_attrs = f_header.attrs.size / f_header.attr_size; | 2895 | nr_attrs = f_header.attrs.size / f_header.attr_size; |
| @@ -3397,7 +3397,7 @@ int perf_event__process_tracing_data(struct perf_tool *tool __maybe_unused, | |||
| 3397 | struct perf_session *session) | 3397 | struct perf_session *session) |
| 3398 | { | 3398 | { |
| 3399 | ssize_t size_read, padding, size = event->tracing_data.size; | 3399 | ssize_t size_read, padding, size = event->tracing_data.size; |
| 3400 | int fd = perf_data_file__fd(session->file); | 3400 | int fd = perf_data__fd(session->data); |
| 3401 | off_t offset = lseek(fd, 0, SEEK_CUR); | 3401 | off_t offset = lseek(fd, 0, SEEK_CUR); |
| 3402 | char buf[BUFSIZ]; | 3402 | char buf[BUFSIZ]; |
| 3403 | 3403 | ||
diff --git a/tools/perf/util/intel-bts.c b/tools/perf/util/intel-bts.c index 218ee2bac9a5..5325e65f9711 100644 --- a/tools/perf/util/intel-bts.c +++ b/tools/perf/util/intel-bts.c | |||
| @@ -500,7 +500,7 @@ static int intel_bts_process_queue(struct intel_bts_queue *btsq, u64 *timestamp) | |||
| 500 | } | 500 | } |
| 501 | 501 | ||
| 502 | if (!buffer->data) { | 502 | if (!buffer->data) { |
| 503 | int fd = perf_data_file__fd(btsq->bts->session->file); | 503 | int fd = perf_data__fd(btsq->bts->session->data); |
| 504 | 504 | ||
| 505 | buffer->data = auxtrace_buffer__get_data(buffer, fd); | 505 | buffer->data = auxtrace_buffer__get_data(buffer, fd); |
| 506 | if (!buffer->data) { | 506 | if (!buffer->data) { |
| @@ -664,10 +664,10 @@ static int intel_bts_process_auxtrace_event(struct perf_session *session, | |||
| 664 | if (!bts->data_queued) { | 664 | if (!bts->data_queued) { |
| 665 | struct auxtrace_buffer *buffer; | 665 | struct auxtrace_buffer *buffer; |
| 666 | off_t data_offset; | 666 | off_t data_offset; |
| 667 | int fd = perf_data_file__fd(session->file); | 667 | int fd = perf_data__fd(session->data); |
| 668 | int err; | 668 | int err; |
| 669 | 669 | ||
| 670 | if (perf_data_file__is_pipe(session->file)) { | 670 | if (perf_data__is_pipe(session->data)) { |
| 671 | data_offset = 0; | 671 | data_offset = 0; |
| 672 | } else { | 672 | } else { |
| 673 | data_offset = lseek(fd, 0, SEEK_CUR); | 673 | data_offset = lseek(fd, 0, SEEK_CUR); |
diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c index b58f9fd1e2ee..23f9ba676df0 100644 --- a/tools/perf/util/intel-pt.c +++ b/tools/perf/util/intel-pt.c | |||
| @@ -271,7 +271,7 @@ next: | |||
| 271 | ptq->buffer = buffer; | 271 | ptq->buffer = buffer; |
| 272 | 272 | ||
| 273 | if (!buffer->data) { | 273 | if (!buffer->data) { |
| 274 | int fd = perf_data_file__fd(ptq->pt->session->file); | 274 | int fd = perf_data__fd(ptq->pt->session->data); |
| 275 | 275 | ||
| 276 | buffer->data = auxtrace_buffer__get_data(buffer, fd); | 276 | buffer->data = auxtrace_buffer__get_data(buffer, fd); |
| 277 | if (!buffer->data) | 277 | if (!buffer->data) |
| @@ -2084,10 +2084,10 @@ static int intel_pt_process_auxtrace_event(struct perf_session *session, | |||
| 2084 | if (!pt->data_queued) { | 2084 | if (!pt->data_queued) { |
| 2085 | struct auxtrace_buffer *buffer; | 2085 | struct auxtrace_buffer *buffer; |
| 2086 | off_t data_offset; | 2086 | off_t data_offset; |
| 2087 | int fd = perf_data_file__fd(session->file); | 2087 | int fd = perf_data__fd(session->data); |
| 2088 | int err; | 2088 | int err; |
| 2089 | 2089 | ||
| 2090 | if (perf_data_file__is_pipe(session->file)) { | 2090 | if (perf_data__is_pipe(session->data)) { |
| 2091 | data_offset = 0; | 2091 | data_offset = 0; |
| 2092 | } else { | 2092 | } else { |
| 2093 | data_offset = lseek(fd, 0, SEEK_CUR); | 2093 | data_offset = lseek(fd, 0, SEEK_CUR); |
diff --git a/tools/perf/util/jit.h b/tools/perf/util/jit.h index 3f42ee4d2a0b..961e7a8a0e17 100644 --- a/tools/perf/util/jit.h +++ b/tools/perf/util/jit.h | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | 3 | ||
| 4 | #include <data.h> | 4 | #include <data.h> |
| 5 | 5 | ||
| 6 | int jit_process(struct perf_session *session, struct perf_data_file *output, | 6 | int jit_process(struct perf_session *session, struct perf_data *output, |
| 7 | struct machine *machine, char *filename, pid_t pid, u64 *nbytes); | 7 | struct machine *machine, char *filename, pid_t pid, u64 *nbytes); |
| 8 | 8 | ||
| 9 | int jit_inject_record(const char *filename); | 9 | int jit_inject_record(const char *filename); |
diff --git a/tools/perf/util/jitdump.c b/tools/perf/util/jitdump.c index 9084930e1757..e7645098a323 100644 --- a/tools/perf/util/jitdump.c +++ b/tools/perf/util/jitdump.c | |||
| @@ -29,7 +29,7 @@ | |||
| 29 | #include "sane_ctype.h" | 29 | #include "sane_ctype.h" |
| 30 | 30 | ||
| 31 | struct jit_buf_desc { | 31 | struct jit_buf_desc { |
| 32 | struct perf_data_file *output; | 32 | struct perf_data *output; |
| 33 | struct perf_session *session; | 33 | struct perf_session *session; |
| 34 | struct machine *machine; | 34 | struct machine *machine; |
| 35 | union jr_entry *entry; | 35 | union jr_entry *entry; |
| @@ -60,8 +60,8 @@ struct debug_line_info { | |||
| 60 | 60 | ||
| 61 | struct jit_tool { | 61 | struct jit_tool { |
| 62 | struct perf_tool tool; | 62 | struct perf_tool tool; |
| 63 | struct perf_data_file output; | 63 | struct perf_data output; |
| 64 | struct perf_data_file input; | 64 | struct perf_data input; |
| 65 | u64 bytes_written; | 65 | u64 bytes_written; |
| 66 | }; | 66 | }; |
| 67 | 67 | ||
| @@ -356,7 +356,7 @@ jit_inject_event(struct jit_buf_desc *jd, union perf_event *event) | |||
| 356 | { | 356 | { |
| 357 | ssize_t size; | 357 | ssize_t size; |
| 358 | 358 | ||
| 359 | size = perf_data_file__write(jd->output, event, event->header.size); | 359 | size = perf_data__write(jd->output, event, event->header.size); |
| 360 | if (size < 0) | 360 | if (size < 0) |
| 361 | return -1; | 361 | return -1; |
| 362 | 362 | ||
| @@ -751,7 +751,7 @@ jit_detect(char *mmap_name, pid_t pid) | |||
| 751 | 751 | ||
| 752 | int | 752 | int |
| 753 | jit_process(struct perf_session *session, | 753 | jit_process(struct perf_session *session, |
| 754 | struct perf_data_file *output, | 754 | struct perf_data *output, |
| 755 | struct machine *machine, | 755 | struct machine *machine, |
| 756 | char *filename, | 756 | char *filename, |
| 757 | pid_t pid, | 757 | pid_t pid, |
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index b3fd62f7e4c9..c09b748ab599 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c | |||
| @@ -32,14 +32,14 @@ static int perf_session__deliver_event(struct perf_session *session, | |||
| 32 | 32 | ||
| 33 | static int perf_session__open(struct perf_session *session) | 33 | static int perf_session__open(struct perf_session *session) |
| 34 | { | 34 | { |
| 35 | struct perf_data_file *file = session->file; | 35 | struct perf_data *data = session->data; |
| 36 | 36 | ||
| 37 | if (perf_session__read_header(session) < 0) { | 37 | if (perf_session__read_header(session) < 0) { |
| 38 | pr_err("incompatible file format (rerun with -v to learn more)\n"); | 38 | pr_err("incompatible file format (rerun with -v to learn more)\n"); |
| 39 | return -1; | 39 | return -1; |
| 40 | } | 40 | } |
| 41 | 41 | ||
| 42 | if (perf_data_file__is_pipe(file)) | 42 | if (perf_data__is_pipe(data)) |
| 43 | return 0; | 43 | return 0; |
| 44 | 44 | ||
| 45 | if (perf_header__has_feat(&session->header, HEADER_STAT)) | 45 | if (perf_header__has_feat(&session->header, HEADER_STAT)) |
| @@ -120,7 +120,7 @@ static int ordered_events__deliver_event(struct ordered_events *oe, | |||
| 120 | session->tool, event->file_offset); | 120 | session->tool, event->file_offset); |
| 121 | } | 121 | } |
| 122 | 122 | ||
| 123 | struct perf_session *perf_session__new(struct perf_data_file *file, | 123 | struct perf_session *perf_session__new(struct perf_data *data, |
| 124 | bool repipe, struct perf_tool *tool) | 124 | bool repipe, struct perf_tool *tool) |
| 125 | { | 125 | { |
| 126 | struct perf_session *session = zalloc(sizeof(*session)); | 126 | struct perf_session *session = zalloc(sizeof(*session)); |
| @@ -134,13 +134,13 @@ struct perf_session *perf_session__new(struct perf_data_file *file, | |||
| 134 | machines__init(&session->machines); | 134 | machines__init(&session->machines); |
| 135 | ordered_events__init(&session->ordered_events, ordered_events__deliver_event); | 135 | ordered_events__init(&session->ordered_events, ordered_events__deliver_event); |
| 136 | 136 | ||
| 137 | if (file) { | 137 | if (data) { |
| 138 | if (perf_data_file__open(file)) | 138 | if (perf_data__open(data)) |
| 139 | goto out_delete; | 139 | goto out_delete; |
| 140 | 140 | ||
| 141 | session->file = file; | 141 | session->data = data; |
| 142 | 142 | ||
| 143 | if (perf_data_file__is_read(file)) { | 143 | if (perf_data__is_read(data)) { |
| 144 | if (perf_session__open(session) < 0) | 144 | if (perf_session__open(session) < 0) |
| 145 | goto out_close; | 145 | goto out_close; |
| 146 | 146 | ||
| @@ -148,7 +148,7 @@ struct perf_session *perf_session__new(struct perf_data_file *file, | |||
| 148 | * set session attributes that are present in perf.data | 148 | * set session attributes that are present in perf.data |
| 149 | * but not in pipe-mode. | 149 | * but not in pipe-mode. |
| 150 | */ | 150 | */ |
| 151 | if (!file->is_pipe) { | 151 | if (!data->is_pipe) { |
| 152 | perf_session__set_id_hdr_size(session); | 152 | perf_session__set_id_hdr_size(session); |
| 153 | perf_session__set_comm_exec(session); | 153 | perf_session__set_comm_exec(session); |
| 154 | } | 154 | } |
| @@ -157,7 +157,7 @@ struct perf_session *perf_session__new(struct perf_data_file *file, | |||
| 157 | session->machines.host.env = &perf_env; | 157 | session->machines.host.env = &perf_env; |
| 158 | } | 158 | } |
| 159 | 159 | ||
| 160 | if (!file || perf_data_file__is_write(file)) { | 160 | if (!data || perf_data__is_write(data)) { |
| 161 | /* | 161 | /* |
| 162 | * In O_RDONLY mode this will be performed when reading the | 162 | * In O_RDONLY mode this will be performed when reading the |
| 163 | * kernel MMAP event, in perf_event__process_mmap(). | 163 | * kernel MMAP event, in perf_event__process_mmap(). |
| @@ -170,7 +170,7 @@ struct perf_session *perf_session__new(struct perf_data_file *file, | |||
| 170 | * In pipe-mode, evlist is empty until PERF_RECORD_HEADER_ATTR is | 170 | * In pipe-mode, evlist is empty until PERF_RECORD_HEADER_ATTR is |
| 171 | * processed, so perf_evlist__sample_id_all is not meaningful here. | 171 | * processed, so perf_evlist__sample_id_all is not meaningful here. |
| 172 | */ | 172 | */ |
| 173 | if ((!file || !file->is_pipe) && tool && tool->ordering_requires_timestamps && | 173 | if ((!data || !data->is_pipe) && tool && tool->ordering_requires_timestamps && |
| 174 | tool->ordered_events && !perf_evlist__sample_id_all(session->evlist)) { | 174 | tool->ordered_events && !perf_evlist__sample_id_all(session->evlist)) { |
| 175 | dump_printf("WARNING: No sample_id_all support, falling back to unordered processing\n"); | 175 | dump_printf("WARNING: No sample_id_all support, falling back to unordered processing\n"); |
| 176 | tool->ordered_events = false; | 176 | tool->ordered_events = false; |
| @@ -179,7 +179,7 @@ struct perf_session *perf_session__new(struct perf_data_file *file, | |||
| 179 | return session; | 179 | return session; |
| 180 | 180 | ||
| 181 | out_close: | 181 | out_close: |
| 182 | perf_data_file__close(file); | 182 | perf_data__close(data); |
| 183 | out_delete: | 183 | out_delete: |
| 184 | perf_session__delete(session); | 184 | perf_session__delete(session); |
| 185 | out: | 185 | out: |
| @@ -201,8 +201,8 @@ void perf_session__delete(struct perf_session *session) | |||
| 201 | perf_session__delete_threads(session); | 201 | perf_session__delete_threads(session); |
| 202 | perf_env__exit(&session->header.env); | 202 | perf_env__exit(&session->header.env); |
| 203 | machines__exit(&session->machines); | 203 | machines__exit(&session->machines); |
| 204 | if (session->file) | 204 | if (session->data) |
| 205 | perf_data_file__close(session->file); | 205 | perf_data__close(session->data); |
| 206 | free(session); | 206 | free(session); |
| 207 | } | 207 | } |
| 208 | 208 | ||
| @@ -290,8 +290,8 @@ static s64 process_event_auxtrace_stub(struct perf_tool *tool __maybe_unused, | |||
| 290 | __maybe_unused) | 290 | __maybe_unused) |
| 291 | { | 291 | { |
| 292 | dump_printf(": unhandled!\n"); | 292 | dump_printf(": unhandled!\n"); |
| 293 | if (perf_data_file__is_pipe(session->file)) | 293 | if (perf_data__is_pipe(session->data)) |
| 294 | skipn(perf_data_file__fd(session->file), event->auxtrace.size); | 294 | skipn(perf_data__fd(session->data), event->auxtrace.size); |
| 295 | return event->auxtrace.size; | 295 | return event->auxtrace.size; |
| 296 | } | 296 | } |
| 297 | 297 | ||
| @@ -1349,7 +1349,7 @@ static s64 perf_session__process_user_event(struct perf_session *session, | |||
| 1349 | { | 1349 | { |
| 1350 | struct ordered_events *oe = &session->ordered_events; | 1350 | struct ordered_events *oe = &session->ordered_events; |
| 1351 | struct perf_tool *tool = session->tool; | 1351 | struct perf_tool *tool = session->tool; |
| 1352 | int fd = perf_data_file__fd(session->file); | 1352 | int fd = perf_data__fd(session->data); |
| 1353 | int err; | 1353 | int err; |
| 1354 | 1354 | ||
| 1355 | dump_event(session->evlist, event, file_offset, NULL); | 1355 | dump_event(session->evlist, event, file_offset, NULL); |
| @@ -1449,10 +1449,10 @@ int perf_session__peek_event(struct perf_session *session, off_t file_offset, | |||
| 1449 | goto out_parse_sample; | 1449 | goto out_parse_sample; |
| 1450 | } | 1450 | } |
| 1451 | 1451 | ||
| 1452 | if (perf_data_file__is_pipe(session->file)) | 1452 | if (perf_data__is_pipe(session->data)) |
| 1453 | return -1; | 1453 | return -1; |
| 1454 | 1454 | ||
| 1455 | fd = perf_data_file__fd(session->file); | 1455 | fd = perf_data__fd(session->data); |
| 1456 | hdr_sz = sizeof(struct perf_event_header); | 1456 | hdr_sz = sizeof(struct perf_event_header); |
| 1457 | 1457 | ||
| 1458 | if (buf_sz < hdr_sz) | 1458 | if (buf_sz < hdr_sz) |
| @@ -1687,7 +1687,7 @@ static int __perf_session__process_pipe_events(struct perf_session *session) | |||
| 1687 | { | 1687 | { |
| 1688 | struct ordered_events *oe = &session->ordered_events; | 1688 | struct ordered_events *oe = &session->ordered_events; |
| 1689 | struct perf_tool *tool = session->tool; | 1689 | struct perf_tool *tool = session->tool; |
| 1690 | int fd = perf_data_file__fd(session->file); | 1690 | int fd = perf_data__fd(session->data); |
| 1691 | union perf_event *event; | 1691 | union perf_event *event; |
| 1692 | uint32_t size, cur_size = 0; | 1692 | uint32_t size, cur_size = 0; |
| 1693 | void *buf = NULL; | 1693 | void *buf = NULL; |
| @@ -1828,7 +1828,7 @@ static int __perf_session__process_events(struct perf_session *session, | |||
| 1828 | { | 1828 | { |
| 1829 | struct ordered_events *oe = &session->ordered_events; | 1829 | struct ordered_events *oe = &session->ordered_events; |
| 1830 | struct perf_tool *tool = session->tool; | 1830 | struct perf_tool *tool = session->tool; |
| 1831 | int fd = perf_data_file__fd(session->file); | 1831 | int fd = perf_data__fd(session->data); |
| 1832 | u64 head, page_offset, file_offset, file_pos, size; | 1832 | u64 head, page_offset, file_offset, file_pos, size; |
| 1833 | int err, mmap_prot, mmap_flags, map_idx = 0; | 1833 | int err, mmap_prot, mmap_flags, map_idx = 0; |
| 1834 | size_t mmap_size; | 1834 | size_t mmap_size; |
| @@ -1945,13 +1945,13 @@ out_err: | |||
| 1945 | 1945 | ||
| 1946 | int perf_session__process_events(struct perf_session *session) | 1946 | int perf_session__process_events(struct perf_session *session) |
| 1947 | { | 1947 | { |
| 1948 | u64 size = perf_data_file__size(session->file); | 1948 | u64 size = perf_data__size(session->data); |
| 1949 | int err; | 1949 | int err; |
| 1950 | 1950 | ||
| 1951 | if (perf_session__register_idle_thread(session) < 0) | 1951 | if (perf_session__register_idle_thread(session) < 0) |
| 1952 | return -ENOMEM; | 1952 | return -ENOMEM; |
| 1953 | 1953 | ||
| 1954 | if (!perf_data_file__is_pipe(session->file)) | 1954 | if (!perf_data__is_pipe(session->data)) |
| 1955 | err = __perf_session__process_events(session, | 1955 | err = __perf_session__process_events(session, |
| 1956 | session->header.data_offset, | 1956 | session->header.data_offset, |
| 1957 | session->header.data_size, size); | 1957 | session->header.data_size, size); |
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index 47b5e7dbcb18..cc1c5ea53c39 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h | |||
| @@ -32,13 +32,13 @@ struct perf_session { | |||
| 32 | void *one_mmap_addr; | 32 | void *one_mmap_addr; |
| 33 | u64 one_mmap_offset; | 33 | u64 one_mmap_offset; |
| 34 | struct ordered_events ordered_events; | 34 | struct ordered_events ordered_events; |
| 35 | struct perf_data_file *file; | 35 | struct perf_data *data; |
| 36 | struct perf_tool *tool; | 36 | struct perf_tool *tool; |
| 37 | }; | 37 | }; |
| 38 | 38 | ||
| 39 | struct perf_tool; | 39 | struct perf_tool; |
| 40 | 40 | ||
| 41 | struct perf_session *perf_session__new(struct perf_data_file *file, | 41 | struct perf_session *perf_session__new(struct perf_data *data, |
| 42 | bool repipe, struct perf_tool *tool); | 42 | bool repipe, struct perf_tool *tool); |
| 43 | void perf_session__delete(struct perf_session *session); | 43 | void perf_session__delete(struct perf_session *session); |
| 44 | 44 | ||
diff --git a/tools/perf/util/srcline.c b/tools/perf/util/srcline.c index c143c3bc1ef8..ad1b46f1f2cf 100644 --- a/tools/perf/util/srcline.c +++ b/tools/perf/util/srcline.c | |||
| @@ -10,7 +10,7 @@ | |||
| 10 | #include "util/debug.h" | 10 | #include "util/debug.h" |
| 11 | #include "util/callchain.h" | 11 | #include "util/callchain.h" |
| 12 | #include "srcline.h" | 12 | #include "srcline.h" |
| 13 | 13 | #include "string2.h" | |
| 14 | #include "symbol.h" | 14 | #include "symbol.h" |
| 15 | 15 | ||
| 16 | bool srcline_full_filename; | 16 | bool srcline_full_filename; |
| @@ -77,6 +77,41 @@ static char *srcline_from_fileline(const char *file, unsigned int line) | |||
| 77 | return srcline; | 77 | return srcline; |
| 78 | } | 78 | } |
| 79 | 79 | ||
| 80 | static struct symbol *new_inline_sym(struct dso *dso, | ||
| 81 | struct symbol *base_sym, | ||
| 82 | const char *funcname) | ||
| 83 | { | ||
| 84 | struct symbol *inline_sym; | ||
| 85 | char *demangled = NULL; | ||
| 86 | |||
| 87 | if (dso) { | ||
| 88 | demangled = dso__demangle_sym(dso, 0, funcname); | ||
| 89 | if (demangled) | ||
| 90 | funcname = demangled; | ||
| 91 | } | ||
| 92 | |||
| 93 | if (base_sym && strcmp(funcname, base_sym->name) == 0) { | ||
| 94 | /* reuse the real, existing symbol */ | ||
| 95 | inline_sym = base_sym; | ||
| 96 | /* ensure that we don't alias an inlined symbol, which could | ||
| 97 | * lead to double frees in inline_node__delete | ||
| 98 | */ | ||
| 99 | assert(!base_sym->inlined); | ||
| 100 | } else { | ||
| 101 | /* create a fake symbol for the inline frame */ | ||
| 102 | inline_sym = symbol__new(base_sym ? base_sym->start : 0, | ||
| 103 | base_sym ? base_sym->end : 0, | ||
| 104 | base_sym ? base_sym->binding : 0, | ||
| 105 | funcname); | ||
| 106 | if (inline_sym) | ||
| 107 | inline_sym->inlined = 1; | ||
| 108 | } | ||
| 109 | |||
| 110 | free(demangled); | ||
| 111 | |||
| 112 | return inline_sym; | ||
| 113 | } | ||
| 114 | |||
| 80 | #ifdef HAVE_LIBBFD_SUPPORT | 115 | #ifdef HAVE_LIBBFD_SUPPORT |
| 81 | 116 | ||
| 82 | /* | 117 | /* |
| @@ -219,41 +254,6 @@ static void addr2line_cleanup(struct a2l_data *a2l) | |||
| 219 | 254 | ||
| 220 | #define MAX_INLINE_NEST 1024 | 255 | #define MAX_INLINE_NEST 1024 |
| 221 | 256 | ||
| 222 | static struct symbol *new_inline_sym(struct dso *dso, | ||
| 223 | struct symbol *base_sym, | ||
| 224 | const char *funcname) | ||
| 225 | { | ||
| 226 | struct symbol *inline_sym; | ||
| 227 | char *demangled = NULL; | ||
| 228 | |||
| 229 | if (dso) { | ||
| 230 | demangled = dso__demangle_sym(dso, 0, funcname); | ||
| 231 | if (demangled) | ||
| 232 | funcname = demangled; | ||
| 233 | } | ||
| 234 | |||
| 235 | if (base_sym && strcmp(funcname, base_sym->name) == 0) { | ||
| 236 | /* reuse the real, existing symbol */ | ||
| 237 | inline_sym = base_sym; | ||
| 238 | /* ensure that we don't alias an inlined symbol, which could | ||
| 239 | * lead to double frees in inline_node__delete | ||
| 240 | */ | ||
| 241 | assert(!base_sym->inlined); | ||
| 242 | } else { | ||
| 243 | /* create a fake symbol for the inline frame */ | ||
| 244 | inline_sym = symbol__new(base_sym ? base_sym->start : 0, | ||
| 245 | base_sym ? base_sym->end : 0, | ||
| 246 | base_sym ? base_sym->binding : 0, | ||
| 247 | funcname); | ||
| 248 | if (inline_sym) | ||
| 249 | inline_sym->inlined = 1; | ||
| 250 | } | ||
| 251 | |||
| 252 | free(demangled); | ||
| 253 | |||
| 254 | return inline_sym; | ||
| 255 | } | ||
| 256 | |||
| 257 | static int inline_list__append_dso_a2l(struct dso *dso, | 257 | static int inline_list__append_dso_a2l(struct dso *dso, |
| 258 | struct inline_node *node, | 258 | struct inline_node *node, |
| 259 | struct symbol *sym) | 259 | struct symbol *sym) |
| @@ -432,10 +432,11 @@ static struct inline_node *addr2inlines(const char *dso_name, u64 addr, | |||
| 432 | char cmd[PATH_MAX]; | 432 | char cmd[PATH_MAX]; |
| 433 | struct inline_node *node; | 433 | struct inline_node *node; |
| 434 | char *filename = NULL; | 434 | char *filename = NULL; |
| 435 | size_t len; | 435 | char *funcname = NULL; |
| 436 | size_t filelen, funclen; | ||
| 436 | unsigned int line_nr = 0; | 437 | unsigned int line_nr = 0; |
| 437 | 438 | ||
| 438 | scnprintf(cmd, sizeof(cmd), "addr2line -e %s -i %016"PRIx64, | 439 | scnprintf(cmd, sizeof(cmd), "addr2line -e %s -i -f %016"PRIx64, |
| 439 | dso_name, addr); | 440 | dso_name, addr); |
| 440 | 441 | ||
| 441 | fp = popen(cmd, "r"); | 442 | fp = popen(cmd, "r"); |
| @@ -453,23 +454,34 @@ static struct inline_node *addr2inlines(const char *dso_name, u64 addr, | |||
| 453 | INIT_LIST_HEAD(&node->val); | 454 | INIT_LIST_HEAD(&node->val); |
| 454 | node->addr = addr; | 455 | node->addr = addr; |
| 455 | 456 | ||
| 456 | while (getline(&filename, &len, fp) != -1) { | 457 | /* addr2line -f generates two lines for each inlined functions */ |
| 458 | while (getline(&funcname, &funclen, fp) != -1) { | ||
| 457 | char *srcline; | 459 | char *srcline; |
| 460 | struct symbol *inline_sym; | ||
| 461 | |||
| 462 | rtrim(funcname); | ||
| 458 | 463 | ||
| 459 | if (filename_split(filename, &line_nr) != 1) { | 464 | if (getline(&filename, &filelen, fp) == -1) |
| 460 | free(filename); | ||
| 461 | goto out; | 465 | goto out; |
| 462 | } | ||
| 463 | 466 | ||
| 464 | srcline = srcline_from_fileline(filename, line_nr); | 467 | if (filename_split(filename, &line_nr) != 1) |
| 465 | if (inline_list__append(sym, srcline, node) != 0) | ||
| 466 | goto out; | 468 | goto out; |
| 467 | 469 | ||
| 468 | filename = NULL; | 470 | srcline = srcline_from_fileline(filename, line_nr); |
| 471 | inline_sym = new_inline_sym(dso, sym, funcname); | ||
| 472 | |||
| 473 | if (inline_list__append(inline_sym, srcline, node) != 0) { | ||
| 474 | free(srcline); | ||
| 475 | if (inline_sym && inline_sym->inlined) | ||
| 476 | symbol__delete(inline_sym); | ||
| 477 | goto out; | ||
| 478 | } | ||
| 469 | } | 479 | } |
| 470 | 480 | ||
| 471 | out: | 481 | out: |
| 472 | pclose(fp); | 482 | pclose(fp); |
| 483 | free(filename); | ||
| 484 | free(funcname); | ||
| 473 | 485 | ||
| 474 | return node; | 486 | return node; |
| 475 | } | 487 | } |
diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c index a2c12d1ef32a..51ad03a799ec 100644 --- a/tools/perf/util/stat-shadow.c +++ b/tools/perf/util/stat-shadow.c | |||
| @@ -178,58 +178,60 @@ void perf_stat__reset_shadow_stats(void) | |||
| 178 | * more semantic information such as miss/hit ratios, | 178 | * more semantic information such as miss/hit ratios, |
| 179 | * instruction rates, etc: | 179 | * instruction rates, etc: |
| 180 | */ | 180 | */ |
| 181 | void perf_stat__update_shadow_stats(struct perf_evsel *counter, u64 *count, | 181 | void perf_stat__update_shadow_stats(struct perf_evsel *counter, u64 count, |
| 182 | int cpu) | 182 | int cpu) |
| 183 | { | 183 | { |
| 184 | int ctx = evsel_context(counter); | 184 | int ctx = evsel_context(counter); |
| 185 | 185 | ||
| 186 | count *= counter->scale; | ||
| 187 | |||
| 186 | if (perf_evsel__match(counter, SOFTWARE, SW_TASK_CLOCK) || | 188 | if (perf_evsel__match(counter, SOFTWARE, SW_TASK_CLOCK) || |
| 187 | perf_evsel__match(counter, SOFTWARE, SW_CPU_CLOCK)) | 189 | perf_evsel__match(counter, SOFTWARE, SW_CPU_CLOCK)) |
| 188 | update_stats(&runtime_nsecs_stats[cpu], count[0]); | 190 | update_stats(&runtime_nsecs_stats[cpu], count); |
| 189 | else if (perf_evsel__match(counter, HARDWARE, HW_CPU_CYCLES)) | 191 | else if (perf_evsel__match(counter, HARDWARE, HW_CPU_CYCLES)) |
| 190 | update_stats(&runtime_cycles_stats[ctx][cpu], count[0]); | 192 | update_stats(&runtime_cycles_stats[ctx][cpu], count); |
| 191 | else if (perf_stat_evsel__is(counter, CYCLES_IN_TX)) | 193 | else if (perf_stat_evsel__is(counter, CYCLES_IN_TX)) |
| 192 | update_stats(&runtime_cycles_in_tx_stats[ctx][cpu], count[0]); | 194 | update_stats(&runtime_cycles_in_tx_stats[ctx][cpu], count); |
| 193 | else if (perf_stat_evsel__is(counter, TRANSACTION_START)) | 195 | else if (perf_stat_evsel__is(counter, TRANSACTION_START)) |
| 194 | update_stats(&runtime_transaction_stats[ctx][cpu], count[0]); | 196 | update_stats(&runtime_transaction_stats[ctx][cpu], count); |
| 195 | else if (perf_stat_evsel__is(counter, ELISION_START)) | 197 | else if (perf_stat_evsel__is(counter, ELISION_START)) |
| 196 | update_stats(&runtime_elision_stats[ctx][cpu], count[0]); | 198 | update_stats(&runtime_elision_stats[ctx][cpu], count); |
| 197 | else if (perf_stat_evsel__is(counter, TOPDOWN_TOTAL_SLOTS)) | 199 | else if (perf_stat_evsel__is(counter, TOPDOWN_TOTAL_SLOTS)) |
| 198 | update_stats(&runtime_topdown_total_slots[ctx][cpu], count[0]); | 200 | update_stats(&runtime_topdown_total_slots[ctx][cpu], count); |
| 199 | else if (perf_stat_evsel__is(counter, TOPDOWN_SLOTS_ISSUED)) | 201 | else if (perf_stat_evsel__is(counter, TOPDOWN_SLOTS_ISSUED)) |
| 200 | update_stats(&runtime_topdown_slots_issued[ctx][cpu], count[0]); | 202 | update_stats(&runtime_topdown_slots_issued[ctx][cpu], count); |
| 201 | else if (perf_stat_evsel__is(counter, TOPDOWN_SLOTS_RETIRED)) | 203 | else if (perf_stat_evsel__is(counter, TOPDOWN_SLOTS_RETIRED)) |
| 202 | update_stats(&runtime_topdown_slots_retired[ctx][cpu], count[0]); | 204 | update_stats(&runtime_topdown_slots_retired[ctx][cpu], count); |
| 203 | else if (perf_stat_evsel__is(counter, TOPDOWN_FETCH_BUBBLES)) | 205 | else if (perf_stat_evsel__is(counter, TOPDOWN_FETCH_BUBBLES)) |
| 204 | update_stats(&runtime_topdown_fetch_bubbles[ctx][cpu],count[0]); | 206 | update_stats(&runtime_topdown_fetch_bubbles[ctx][cpu], count); |
| 205 | else if (perf_stat_evsel__is(counter, TOPDOWN_RECOVERY_BUBBLES)) | 207 | else if (perf_stat_evsel__is(counter, TOPDOWN_RECOVERY_BUBBLES)) |
| 206 | update_stats(&runtime_topdown_recovery_bubbles[ctx][cpu], count[0]); | 208 | update_stats(&runtime_topdown_recovery_bubbles[ctx][cpu], count); |
| 207 | else if (perf_evsel__match(counter, HARDWARE, HW_STALLED_CYCLES_FRONTEND)) | 209 | else if (perf_evsel__match(counter, HARDWARE, HW_STALLED_CYCLES_FRONTEND)) |
| 208 | update_stats(&runtime_stalled_cycles_front_stats[ctx][cpu], count[0]); | 210 | update_stats(&runtime_stalled_cycles_front_stats[ctx][cpu], count); |
| 209 | else if (perf_evsel__match(counter, HARDWARE, HW_STALLED_CYCLES_BACKEND)) | 211 | else if (perf_evsel__match(counter, HARDWARE, HW_STALLED_CYCLES_BACKEND)) |
| 210 | update_stats(&runtime_stalled_cycles_back_stats[ctx][cpu], count[0]); | 212 | update_stats(&runtime_stalled_cycles_back_stats[ctx][cpu], count); |
| 211 | else if (perf_evsel__match(counter, HARDWARE, HW_BRANCH_INSTRUCTIONS)) | 213 | else if (perf_evsel__match(counter, HARDWARE, HW_BRANCH_INSTRUCTIONS)) |
| 212 | update_stats(&runtime_branches_stats[ctx][cpu], count[0]); | 214 | update_stats(&runtime_branches_stats[ctx][cpu], count); |
| 213 | else if (perf_evsel__match(counter, HARDWARE, HW_CACHE_REFERENCES)) | 215 | else if (perf_evsel__match(counter, HARDWARE, HW_CACHE_REFERENCES)) |
| 214 | update_stats(&runtime_cacherefs_stats[ctx][cpu], count[0]); | 216 | update_stats(&runtime_cacherefs_stats[ctx][cpu], count); |
| 215 | else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_L1D)) | 217 | else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_L1D)) |
| 216 | update_stats(&runtime_l1_dcache_stats[ctx][cpu], count[0]); | 218 | update_stats(&runtime_l1_dcache_stats[ctx][cpu], count); |
| 217 | else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_L1I)) | 219 | else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_L1I)) |
| 218 | update_stats(&runtime_ll_cache_stats[ctx][cpu], count[0]); | 220 | update_stats(&runtime_ll_cache_stats[ctx][cpu], count); |
| 219 | else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_LL)) | 221 | else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_LL)) |
| 220 | update_stats(&runtime_ll_cache_stats[ctx][cpu], count[0]); | 222 | update_stats(&runtime_ll_cache_stats[ctx][cpu], count); |
| 221 | else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_DTLB)) | 223 | else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_DTLB)) |
| 222 | update_stats(&runtime_dtlb_cache_stats[ctx][cpu], count[0]); | 224 | update_stats(&runtime_dtlb_cache_stats[ctx][cpu], count); |
| 223 | else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_ITLB)) | 225 | else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_ITLB)) |
| 224 | update_stats(&runtime_itlb_cache_stats[ctx][cpu], count[0]); | 226 | update_stats(&runtime_itlb_cache_stats[ctx][cpu], count); |
| 225 | else if (perf_stat_evsel__is(counter, SMI_NUM)) | 227 | else if (perf_stat_evsel__is(counter, SMI_NUM)) |
| 226 | update_stats(&runtime_smi_num_stats[ctx][cpu], count[0]); | 228 | update_stats(&runtime_smi_num_stats[ctx][cpu], count); |
| 227 | else if (perf_stat_evsel__is(counter, APERF)) | 229 | else if (perf_stat_evsel__is(counter, APERF)) |
| 228 | update_stats(&runtime_aperf_stats[ctx][cpu], count[0]); | 230 | update_stats(&runtime_aperf_stats[ctx][cpu], count); |
| 229 | 231 | ||
| 230 | if (counter->collect_stat) { | 232 | if (counter->collect_stat) { |
| 231 | struct saved_value *v = saved_value_lookup(counter, cpu, true); | 233 | struct saved_value *v = saved_value_lookup(counter, cpu, true); |
| 232 | update_stats(&v->stats, count[0]); | 234 | update_stats(&v->stats, count); |
| 233 | } | 235 | } |
| 234 | } | 236 | } |
| 235 | 237 | ||
diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c index 35e9848734d6..203f5d8d11d1 100644 --- a/tools/perf/util/stat.c +++ b/tools/perf/util/stat.c | |||
| @@ -69,7 +69,7 @@ double rel_stddev_stats(double stddev, double avg) | |||
| 69 | bool __perf_evsel_stat__is(struct perf_evsel *evsel, | 69 | bool __perf_evsel_stat__is(struct perf_evsel *evsel, |
| 70 | enum perf_stat_evsel_id id) | 70 | enum perf_stat_evsel_id id) |
| 71 | { | 71 | { |
| 72 | struct perf_stat_evsel *ps = evsel->priv; | 72 | struct perf_stat_evsel *ps = evsel->stats; |
| 73 | 73 | ||
| 74 | return ps->id == id; | 74 | return ps->id == id; |
| 75 | } | 75 | } |
| @@ -93,7 +93,7 @@ static const char *id_str[PERF_STAT_EVSEL_ID__MAX] = { | |||
| 93 | 93 | ||
| 94 | void perf_stat_evsel_id_init(struct perf_evsel *evsel) | 94 | void perf_stat_evsel_id_init(struct perf_evsel *evsel) |
| 95 | { | 95 | { |
| 96 | struct perf_stat_evsel *ps = evsel->priv; | 96 | struct perf_stat_evsel *ps = evsel->stats; |
| 97 | int i; | 97 | int i; |
| 98 | 98 | ||
| 99 | /* ps->id is 0 hence PERF_STAT_EVSEL_ID__NONE by default */ | 99 | /* ps->id is 0 hence PERF_STAT_EVSEL_ID__NONE by default */ |
| @@ -109,7 +109,7 @@ void perf_stat_evsel_id_init(struct perf_evsel *evsel) | |||
| 109 | static void perf_evsel__reset_stat_priv(struct perf_evsel *evsel) | 109 | static void perf_evsel__reset_stat_priv(struct perf_evsel *evsel) |
| 110 | { | 110 | { |
| 111 | int i; | 111 | int i; |
| 112 | struct perf_stat_evsel *ps = evsel->priv; | 112 | struct perf_stat_evsel *ps = evsel->stats; |
| 113 | 113 | ||
| 114 | for (i = 0; i < 3; i++) | 114 | for (i = 0; i < 3; i++) |
| 115 | init_stats(&ps->res_stats[i]); | 115 | init_stats(&ps->res_stats[i]); |
| @@ -119,8 +119,8 @@ static void perf_evsel__reset_stat_priv(struct perf_evsel *evsel) | |||
| 119 | 119 | ||
| 120 | static int perf_evsel__alloc_stat_priv(struct perf_evsel *evsel) | 120 | static int perf_evsel__alloc_stat_priv(struct perf_evsel *evsel) |
| 121 | { | 121 | { |
| 122 | evsel->priv = zalloc(sizeof(struct perf_stat_evsel)); | 122 | evsel->stats = zalloc(sizeof(struct perf_stat_evsel)); |
| 123 | if (evsel->priv == NULL) | 123 | if (evsel->stats == NULL) |
| 124 | return -ENOMEM; | 124 | return -ENOMEM; |
| 125 | perf_evsel__reset_stat_priv(evsel); | 125 | perf_evsel__reset_stat_priv(evsel); |
| 126 | return 0; | 126 | return 0; |
| @@ -128,11 +128,11 @@ static int perf_evsel__alloc_stat_priv(struct perf_evsel *evsel) | |||
| 128 | 128 | ||
| 129 | static void perf_evsel__free_stat_priv(struct perf_evsel *evsel) | 129 | static void perf_evsel__free_stat_priv(struct perf_evsel *evsel) |
| 130 | { | 130 | { |
| 131 | struct perf_stat_evsel *ps = evsel->priv; | 131 | struct perf_stat_evsel *ps = evsel->stats; |
| 132 | 132 | ||
| 133 | if (ps) | 133 | if (ps) |
| 134 | free(ps->group_data); | 134 | free(ps->group_data); |
| 135 | zfree(&evsel->priv); | 135 | zfree(&evsel->stats); |
| 136 | } | 136 | } |
| 137 | 137 | ||
| 138 | static int perf_evsel__alloc_prev_raw_counts(struct perf_evsel *evsel, | 138 | static int perf_evsel__alloc_prev_raw_counts(struct perf_evsel *evsel, |
| @@ -277,7 +277,9 @@ process_counter_values(struct perf_stat_config *config, struct perf_evsel *evsel | |||
| 277 | perf_evsel__compute_deltas(evsel, cpu, thread, count); | 277 | perf_evsel__compute_deltas(evsel, cpu, thread, count); |
| 278 | perf_counts_values__scale(count, config->scale, NULL); | 278 | perf_counts_values__scale(count, config->scale, NULL); |
| 279 | if (config->aggr_mode == AGGR_NONE) | 279 | if (config->aggr_mode == AGGR_NONE) |
| 280 | perf_stat__update_shadow_stats(evsel, count->values, cpu); | 280 | perf_stat__update_shadow_stats(evsel, count->val, cpu); |
| 281 | if (config->aggr_mode == AGGR_THREAD) | ||
| 282 | perf_stat__update_shadow_stats(evsel, count->val, 0); | ||
| 281 | break; | 283 | break; |
| 282 | case AGGR_GLOBAL: | 284 | case AGGR_GLOBAL: |
| 283 | aggr->val += count->val; | 285 | aggr->val += count->val; |
| @@ -318,9 +320,8 @@ int perf_stat_process_counter(struct perf_stat_config *config, | |||
| 318 | struct perf_evsel *counter) | 320 | struct perf_evsel *counter) |
| 319 | { | 321 | { |
| 320 | struct perf_counts_values *aggr = &counter->counts->aggr; | 322 | struct perf_counts_values *aggr = &counter->counts->aggr; |
| 321 | struct perf_stat_evsel *ps = counter->priv; | 323 | struct perf_stat_evsel *ps = counter->stats; |
| 322 | u64 *count = counter->counts->aggr.values; | 324 | u64 *count = counter->counts->aggr.values; |
| 323 | u64 val; | ||
| 324 | int i, ret; | 325 | int i, ret; |
| 325 | 326 | ||
| 326 | aggr->val = aggr->ena = aggr->run = 0; | 327 | aggr->val = aggr->ena = aggr->run = 0; |
| @@ -360,8 +361,7 @@ int perf_stat_process_counter(struct perf_stat_config *config, | |||
| 360 | /* | 361 | /* |
| 361 | * Save the full runtime - to allow normalization during printout: | 362 | * Save the full runtime - to allow normalization during printout: |
| 362 | */ | 363 | */ |
| 363 | val = counter->scale * *count; | 364 | perf_stat__update_shadow_stats(counter, *count, 0); |
| 364 | perf_stat__update_shadow_stats(counter, &val, 0); | ||
| 365 | 365 | ||
| 366 | return 0; | 366 | return 0; |
| 367 | } | 367 | } |
diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h index 47915df346fb..490b78aa7230 100644 --- a/tools/perf/util/stat.h +++ b/tools/perf/util/stat.h | |||
| @@ -82,7 +82,7 @@ typedef void (*new_line_t )(void *ctx); | |||
| 82 | 82 | ||
| 83 | void perf_stat__init_shadow_stats(void); | 83 | void perf_stat__init_shadow_stats(void); |
| 84 | void perf_stat__reset_shadow_stats(void); | 84 | void perf_stat__reset_shadow_stats(void); |
| 85 | void perf_stat__update_shadow_stats(struct perf_evsel *counter, u64 *count, | 85 | void perf_stat__update_shadow_stats(struct perf_evsel *counter, u64 count, |
| 86 | int cpu); | 86 | int cpu); |
| 87 | struct perf_stat_output_ctx { | 87 | struct perf_stat_output_ctx { |
| 88 | void *ctx; | 88 | void *ctx; |
