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

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'perf-tools-2020-08-14' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux

Pull more perf tools updates from Arnaldo Carvalho de Melo:
"Fixes:
- Fixes for 'perf bench numa'.

- Always memset source before memcpy in 'perf bench mem'.

- Quote CC and CXX for their arguments to fix build in environments
using those variables to pass more than just the compiler names.

- Fix module symbol processing, addressing regression detected via
"perf test".

- Allow multiple probes in record+script_probe_vfs_getname.sh 'perf
test' entry.

Improvements:
- Add script to autogenerate socket family name id->string table from
copy of kernel header, used so far in 'perf trace'.

- 'perf ftrace' improvements to provide similar options for this
utility so that one can go from 'perf record', 'perf trace', etc to
'perf ftrace' just by changing the name of the subcommand.

- Prefer new "sched:sched_waking" trace event when it exists in 'perf
sched' post processing.

- Update POWER9 metrics to utilize other metrics.

- Fall back to querying debuginfod if debuginfo not found locally.

Miscellaneous:
- Sync various kvm headers with kernel sources"

* tag 'perf-tools-2020-08-14' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux: (40 commits)
perf ftrace: Make option description initials all capital letters
perf build-ids: Fall back to debuginfod query if debuginfo not found
perf bench numa: Remove dead code in parse_nodes_opt()
perf stat: Update POWER9 metrics to utilize other metrics
perf ftrace: Add change log
perf: ftrace: Add set_tracing_options() to set all trace options
perf ftrace: Add option --tid to filter by thread id
perf ftrace: Add option -D/--delay to delay tracing
perf: ftrace: Allow set graph depth by '--graph-opts'
perf ftrace: Add support for trace option tracing_thresh
perf ftrace: Add option 'verbose' to show more info for graph tracer
perf ftrace: Add support for tracing option 'irq-info'
perf ftrace: Add support for trace option funcgraph-irqs
perf ftrace: Add support for trace option sleep-time
perf ftrace: Add support for tracing option 'func_stack_trace'
perf tools: Add general function to parse sublevel options
perf ftrace: Add option '--inherit' to trace children processes
perf ftrace: Show trace column header
perf ftrace: Add option '-m/--buffer-size' to set per-cpu buffer size
perf ftrace: Factor out function write_tracing_file_int()
...

+1254 -248
+1
MAINTAINERS
··· 13566 13566 F: include/linux/perf_event.h 13567 13567 F: include/uapi/linux/perf_event.h 13568 13568 F: kernel/events/* 13569 + F: tools/lib/perf/ 13569 13570 F: tools/perf/ 13570 13571 13571 13572 PERFORMANCE EVENTS SUBSYSTEM ARM64 PMU EVENTS
+5 -2
tools/arch/s390/include/uapi/asm/kvm.h
··· 231 231 #define KVM_SYNC_GSCB (1UL << 9) 232 232 #define KVM_SYNC_BPBC (1UL << 10) 233 233 #define KVM_SYNC_ETOKEN (1UL << 11) 234 + #define KVM_SYNC_DIAG318 (1UL << 12) 234 235 235 236 #define KVM_SYNC_S390_VALID_FIELDS \ 236 237 (KVM_SYNC_PREFIX | KVM_SYNC_GPRS | KVM_SYNC_ACRS | KVM_SYNC_CRS | \ 237 238 KVM_SYNC_ARCH0 | KVM_SYNC_PFAULT | KVM_SYNC_VRS | KVM_SYNC_RICCB | \ 238 - KVM_SYNC_FPRS | KVM_SYNC_GSCB | KVM_SYNC_BPBC | KVM_SYNC_ETOKEN) 239 + KVM_SYNC_FPRS | KVM_SYNC_GSCB | KVM_SYNC_BPBC | KVM_SYNC_ETOKEN | \ 240 + KVM_SYNC_DIAG318) 239 241 240 242 /* length and alignment of the sdnx as a power of two */ 241 243 #define SDNXC 8 ··· 266 264 __u8 reserved2 : 7; 267 265 __u8 padding1[51]; /* riccb needs to be 64byte aligned */ 268 266 __u8 riccb[64]; /* runtime instrumentation controls block */ 269 - __u8 padding2[192]; /* sdnx needs to be 256byte aligned */ 267 + __u64 diag318; /* diagnose 0x318 info */ 268 + __u8 padding2[184]; /* sdnx needs to be 256byte aligned */ 270 269 union { 271 270 __u8 sdnx[SDNXL]; /* state description annex */ 272 271 struct {
+3 -2
tools/build/Makefile.feature
··· 8 8 9 9 feature_check = $(eval $(feature_check_code)) 10 10 define feature_check_code 11 - feature-$(1) := $(shell $(MAKE) OUTPUT=$(OUTPUT_FEATURES) CC=$(CC) CXX=$(CXX) CFLAGS="$(EXTRA_CFLAGS) $(FEATURE_CHECK_CFLAGS-$(1))" CXXFLAGS="$(EXTRA_CXXFLAGS) $(FEATURE_CHECK_CXXFLAGS-$(1))" LDFLAGS="$(LDFLAGS) $(FEATURE_CHECK_LDFLAGS-$(1))" -C $(feature_dir) $(OUTPUT_FEATURES)test-$1.bin >/dev/null 2>/dev/null && echo 1 || echo 0) 11 + feature-$(1) := $(shell $(MAKE) OUTPUT=$(OUTPUT_FEATURES) CC="$(CC)" CXX="$(CXX)" CFLAGS="$(EXTRA_CFLAGS) $(FEATURE_CHECK_CFLAGS-$(1))" CXXFLAGS="$(EXTRA_CXXFLAGS) $(FEATURE_CHECK_CXXFLAGS-$(1))" LDFLAGS="$(LDFLAGS) $(FEATURE_CHECK_LDFLAGS-$(1))" -C $(feature_dir) $(OUTPUT_FEATURES)test-$1.bin >/dev/null 2>/dev/null && echo 1 || echo 0) 12 12 endef 13 13 14 14 feature_set = $(eval $(feature_set_code)) ··· 98 98 llvm-version \ 99 99 clang \ 100 100 libbpf \ 101 - libpfm4 101 + libpfm4 \ 102 + libdebuginfod 102 103 103 104 FEATURE_TESTS ?= $(FEATURE_TESTS_BASIC) 104 105
+4
tools/build/feature/Makefile
··· 26 26 test-libelf-gelf_getnote.bin \ 27 27 test-libelf-getshdrstrndx.bin \ 28 28 test-libelf-mmap.bin \ 29 + test-libdebuginfod.bin \ 29 30 test-libnuma.bin \ 30 31 test-numa_num_possible_cpus.bin \ 31 32 test-libperl.bin \ ··· 157 156 158 157 $(OUTPUT)test-libelf-getshdrstrndx.bin: 159 158 $(BUILD) -lelf 159 + 160 + $(OUTPUT)test-libdebuginfod.bin: 161 + $(BUILD) -ldebuginfod 160 162 161 163 $(OUTPUT)test-libnuma.bin: 162 164 $(BUILD) -lnuma
+8
tools/build/feature/test-libdebuginfod.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + #include <elfutils/debuginfod.h> 3 + 4 + int main(void) 5 + { 6 + debuginfod_client* c = debuginfod_begin(); 7 + return (long)c; 8 + }
+4
tools/include/uapi/linux/kvm.h
··· 289 289 /* KVM_EXIT_FAIL_ENTRY */ 290 290 struct { 291 291 __u64 hardware_entry_failure_reason; 292 + __u32 cpu; 292 293 } fail_entry; 293 294 /* KVM_EXIT_EXCEPTION */ 294 295 struct { ··· 1032 1031 #define KVM_CAP_PPC_SECURE_GUEST 181 1033 1032 #define KVM_CAP_HALT_POLL 182 1034 1033 #define KVM_CAP_ASYNC_PF_INT 183 1034 + #define KVM_CAP_LAST_CPU 184 1035 + #define KVM_CAP_SMALLER_MAXPHYADDR 185 1036 + #define KVM_CAP_S390_DIAG318 186 1035 1037 1036 1038 #ifdef KVM_CAP_IRQ_ROUTING 1037 1039
+2
tools/include/uapi/linux/vhost.h
··· 91 91 92 92 /* Use message type V2 */ 93 93 #define VHOST_BACKEND_F_IOTLB_MSG_V2 0x1 94 + /* IOTLB can accept batching hints */ 95 + #define VHOST_BACKEND_F_IOTLB_BATCH 0x2 94 96 95 97 #define VHOST_SET_BACKEND_FEATURES _IOW(VHOST_VIRTIO, 0x25, __u64) 96 98 #define VHOST_GET_BACKEND_FEATURES _IOR(VHOST_VIRTIO, 0x26, __u64)
+8 -6
tools/lib/perf/Documentation/libperf-counting.txt
··· 7 7 8 8 DESCRIPTION 9 9 ----------- 10 - The counting interface provides API to meassure and get count for specific perf events. 10 + The counting interface provides API to measure and get count for specific perf events. 11 11 12 12 The following test tries to explain count on `counting.c` example. 13 13 14 14 It is by no means complete guide to counting, but shows libperf basic API for counting. 15 15 16 - The `counting.c` comes with libbperf package and can be compiled and run like: 16 + The `counting.c` comes with libperf package and can be compiled and run like: 17 17 18 18 [source,bash] 19 19 -- ··· 26 26 It requires root access, because of the `PERF_COUNT_SW_CPU_CLOCK` event, 27 27 which is available only for root. 28 28 29 - The `counting.c` example monitors two events on the current process and displays their count, in a nutshel it: 29 + The `counting.c` example monitors two events on the current process and displays 30 + their count, in a nutshell it: 30 31 31 32 * creates events 32 33 * adds them to the event list ··· 153 152 -- 154 153 155 154 Both events are created as disabled (note the `disabled = 1` assignment above), 156 - so we need to enable the whole list explicitely (both events). 155 + so we need to enable the whole list explicitly (both events). 157 156 158 157 From this moment events are counting and we can do our workload. 159 158 ··· 168 167 79 perf_evlist__disable(evlist); 169 168 -- 170 169 171 - Now we need to get the counts from events, following code iterates throught the events list and read counts: 170 + Now we need to get the counts from events, following code iterates through the 171 + events list and read counts: 172 172 173 173 [source,c] 174 174 -- ··· 180 178 85 } 181 179 -- 182 180 183 - And finaly cleanup. 181 + And finally cleanup. 184 182 185 183 We close the whole events list (both events) and remove it together with the threads map: 186 184
+7 -6
tools/lib/perf/Documentation/libperf-sampling.txt
··· 8 8 9 9 DESCRIPTION 10 10 ----------- 11 - The sampling interface provides API to meassure and get count for specific perf events. 11 + The sampling interface provides API to measure and get count for specific perf events. 12 12 13 13 The following test tries to explain count on `sampling.c` example. 14 14 15 15 It is by no means complete guide to sampling, but shows libperf basic API for sampling. 16 16 17 - The `sampling.c` comes with libbperf package and can be compiled and run like: 17 + The `sampling.c` comes with libperf package and can be compiled and run like: 18 18 19 19 [source,bash] 20 20 -- ··· 33 33 34 34 It requires root access, because it uses hardware cycles event. 35 35 36 - The `sampling.c` example profiles/samples all CPUs with hardware cycles, in a nutshel it: 36 + The `sampling.c` example profiles/samples all CPUs with hardware cycles, in a 37 + nutshell it: 37 38 38 39 - creates events 39 40 - adds them to the event list ··· 91 90 36 }; 92 91 -- 93 92 94 - Next step is to prepare cpus map. 93 + Next step is to prepare CPUs map. 95 94 96 95 In this case we will monitor all the available CPUs: 97 96 ··· 153 152 -- 154 153 155 154 The event is created as disabled (note the `disabled = 1` assignment above), 156 - so we need to enable the events list explicitely. 155 + so we need to enable the events list explicitly. 157 156 158 157 From this moment the cycles event is sampling. 159 158 ··· 213 212 106 cpu, pid, tid, ip, period); 214 213 -- 215 214 216 - And finaly cleanup. 215 + And finally cleanup. 217 216 218 217 We close the whole events list (both events) and remove it together with the threads map: 219 218
+2 -2
tools/lib/perf/Documentation/libperf.txt
··· 29 29 void libperf_init(libperf_print_fn_t fn); 30 30 -- 31 31 32 - *API to handle cpu maps:* 32 + *API to handle CPU maps:* 33 33 34 34 [source,c] 35 35 -- ··· 217 217 218 218 [horizontal] 219 219 220 - struct perf_cpu_map:: Provides a cpu list abstraction. 220 + struct perf_cpu_map:: Provides a CPU list abstraction. 221 221 222 222 struct perf_thread_map:: Provides a thread list abstraction. 223 223
+3 -2
tools/perf/Documentation/perf-config.txt
··· 614 614 615 615 ftrace.*:: 616 616 ftrace.tracer:: 617 - Can be used to select the default tracer. Possible values are 618 - 'function' and 'function_graph'. 617 + Can be used to select the default tracer when neither -G nor 618 + -F option is not specified. Possible values are 'function' and 619 + 'function_graph'. 619 620 620 621 llvm.*:: 621 622 llvm.clang-path::
+53 -22
tools/perf/Documentation/perf-ftrace.txt
··· 24 24 25 25 -t:: 26 26 --tracer=:: 27 - Tracer to use: function_graph or function. 27 + Tracer to use when neither -G nor -F option is not 28 + specified: function_graph or function. 28 29 29 30 -v:: 30 31 --verbose=:: 31 32 Verbosity level. 32 33 34 + -F:: 35 + --funcs:: 36 + List all available functions to trace. 37 + 33 38 -p:: 34 39 --pid=:: 35 40 Trace on existing process id (comma separated list). 41 + 42 + --tid=:: 43 + Trace on existing thread id (comma separated list). 44 + 45 + -D:: 46 + --delay:: 47 + Time (ms) to wait before starting tracing after program start. 36 48 37 49 -a:: 38 50 --all-cpus:: ··· 60 48 Ranges of CPUs are specified with -: 0-2. 61 49 Default is to trace on all online CPUs. 62 50 51 + -m:: 52 + --buffer-size:: 53 + Set the size of per-cpu tracing buffer, <size> is expected to 54 + be a number with appended unit character - B/K/M/G. 55 + 56 + --inherit:: 57 + Trace children processes spawned by our target. 58 + 63 59 -T:: 64 60 --trace-funcs=:: 65 - Only trace functions given by the argument. Multiple functions 66 - can be given by using this option more than once. The function 67 - argument also can be a glob pattern. It will be passed to 68 - 'set_ftrace_filter' in tracefs. 61 + Select function tracer and set function filter on the given 62 + function (or a glob pattern). Multiple functions can be given 63 + by using this option more than once. The function argument also 64 + can be a glob pattern. It will be passed to 'set_ftrace_filter' 65 + in tracefs. 69 66 70 67 -N:: 71 68 --notrace-funcs=:: 72 - Do not trace functions given by the argument. Like -T option, 73 - this can be used more than once to specify multiple functions 74 - (or glob patterns). It will be passed to 'set_ftrace_notrace' 75 - in tracefs. 69 + Select function tracer and do not trace functions given by the 70 + argument. Like -T option, this can be used more than once to 71 + specify multiple functions (or glob patterns). It will be 72 + passed to 'set_ftrace_notrace' in tracefs. 73 + 74 + --func-opts:: 75 + List of options allowed to set: 76 + call-graph - Display kernel stack trace for function tracer. 77 + irq-info - Display irq context info for function tracer. 76 78 77 79 -G:: 78 80 --graph-funcs=:: 79 - Set graph filter on the given function (or a glob pattern). 80 - This is useful for the function_graph tracer only and enables 81 - tracing for functions executed from the given function. 82 - This can be used more than once to specify multiple functions. 83 - It will be passed to 'set_graph_function' in tracefs. 81 + Select function_graph tracer and set graph filter on the given 82 + function (or a glob pattern). This is useful to trace for 83 + functions executed from the given function. This can be used more 84 + than once to specify multiple functions. It will be passed to 85 + 'set_graph_function' in tracefs. 84 86 85 87 -g:: 86 88 --nograph-funcs=:: 87 - Set graph notrace filter on the given function (or a glob pattern). 88 - Like -G option, this is useful for the function_graph tracer only 89 - and disables tracing for function executed from the given function. 90 - This can be used more than once to specify multiple functions. 91 - It will be passed to 'set_graph_notrace' in tracefs. 89 + Select function_graph tracer and set graph notrace filter on the 90 + given function (or a glob pattern). Like -G option, this is useful 91 + for the function_graph tracer only and disables tracing for function 92 + executed from the given function. This can be used more than once to 93 + specify multiple functions. It will be passed to 'set_graph_notrace' 94 + in tracefs. 92 95 93 - -D:: 94 - --graph-depth=:: 95 - Set max depth for function graph tracer to follow 96 + --graph-opts:: 97 + List of options allowed to set: 98 + nosleep-time - Measure on-CPU time only for function_graph tracer. 99 + noirqs - Ignore functions that happen inside interrupt. 100 + verbose - Show process names, PIDs, timestamps, etc. 101 + thresh=<n> - Setup trace duration threshold in microseconds. 102 + depth=<n> - Set max depth for function graph tracer to follow. 96 103 97 104 SEE ALSO 98 105 --------
+8
tools/perf/Makefile.config
··· 501 501 CFLAGS += -DHAVE_ELF_GETSHDRSTRNDX_SUPPORT 502 502 endif 503 503 504 + ifndef NO_LIBDEBUGINFOD 505 + $(call feature_check,libdebuginfod) 506 + ifeq ($(feature-libdebuginfod), 1) 507 + CFLAGS += -DHAVE_DEBUGINFOD_SUPPORT 508 + EXTLIBS += -ldebuginfod 509 + endif 510 + endif 511 + 504 512 ifndef NO_DWARF 505 513 ifeq ($(origin PERF_HAVE_DWARF_REGS), undefined) 506 514 msg := $(warning DWARF register mappings have not been defined for architecture $(SRCARCH), DWARF support disabled);
+11
tools/perf/Makefile.perf
··· 124 124 # 125 125 # Define LIBPFM4 to enable libpfm4 events extension. 126 126 # 127 + # Define NO_LIBDEBUGINFOD if you do not want support debuginfod 128 + # 127 129 128 130 # As per kernel Makefile, avoid funny character set dependencies 129 131 unexport LC_ALL ··· 420 418 421 419 SHELL = $(SHELL_PATH) 422 420 421 + beauty_linux_dir := $(srctree)/tools/perf/trace/beauty/include/linux/ 423 422 linux_uapi_dir := $(srctree)/tools/include/uapi/linux 424 423 asm_generic_uapi_dir := $(srctree)/tools/include/uapi/asm-generic 425 424 arch_asm_uapi_dir := $(srctree)/tools/arch/$(SRCARCH)/include/uapi/asm/ ··· 503 500 504 501 $(socket_ipproto_array): $(linux_uapi_dir)/in.h $(socket_ipproto_tbl) 505 502 $(Q)$(SHELL) '$(socket_ipproto_tbl)' $(linux_uapi_dir) > $@ 503 + 504 + socket_arrays := $(beauty_outdir)/socket_arrays.c 505 + socket_tbl := $(srctree)/tools/perf/trace/beauty/socket.sh 506 + 507 + $(socket_arrays): $(beauty_linux_dir)/socket.h $(socket_tbl) 508 + $(Q)$(SHELL) '$(socket_tbl)' $(beauty_linux_dir) > $@ 506 509 507 510 vhost_virtio_ioctl_array := $(beauty_ioctl_outdir)/vhost_virtio_ioctl_array.c 508 511 vhost_virtio_hdr_dir := $(srctree)/tools/include/uapi/linux ··· 706 697 $(kcmp_type_array) \ 707 698 $(kvm_ioctl_array) \ 708 699 $(socket_ipproto_array) \ 700 + $(socket_arrays) \ 709 701 $(vhost_virtio_ioctl_array) \ 710 702 $(madvise_behavior_array) \ 711 703 $(mmap_flags_array) \ ··· 1016 1006 $(OUTPUT)$(kvm_ioctl_array) \ 1017 1007 $(OUTPUT)$(kcmp_type_array) \ 1018 1008 $(OUTPUT)$(socket_ipproto_array) \ 1009 + $(OUTPUT)$(socket_arrays) \ 1019 1010 $(OUTPUT)$(vhost_virtio_ioctl_array) \ 1020 1011 $(OUTPUT)$(perf_ioctl_array) \ 1021 1012 $(OUTPUT)$(prctl_option_array) \
+2 -2
tools/perf/bench/find-bit-bench.c
··· 17 17 18 18 static const struct option options[] = { 19 19 OPT_UINTEGER('i', "outer-iterations", &outer_iterations, 20 - "Number of outerer iterations used"), 20 + "Number of outer iterations used"), 21 21 OPT_UINTEGER('j', "inner-iterations", &inner_iterations, 22 - "Number of outerer iterations used"), 22 + "Number of inner iterations used"), 23 23 OPT_END() 24 24 }; 25 25
+11 -10
tools/perf/bench/mem-functions.c
··· 223 223 return 0; 224 224 } 225 225 226 - static u64 do_memcpy_cycles(const struct function *r, size_t size, void *src, void *dst) 226 + static void memcpy_prefault(memcpy_t fn, size_t size, void *src, void *dst) 227 227 { 228 - u64 cycle_start = 0ULL, cycle_end = 0ULL; 229 - memcpy_t fn = r->fn.memcpy; 230 - int i; 231 - 232 228 /* Make sure to always prefault zero pages even if MMAP_THRESH is crossed: */ 233 229 memset(src, 0, size); 234 230 ··· 233 237 * to not measure page fault overhead: 234 238 */ 235 239 fn(dst, src, size); 240 + } 241 + 242 + static u64 do_memcpy_cycles(const struct function *r, size_t size, void *src, void *dst) 243 + { 244 + u64 cycle_start = 0ULL, cycle_end = 0ULL; 245 + memcpy_t fn = r->fn.memcpy; 246 + int i; 247 + 248 + memcpy_prefault(fn, size, src, dst); 236 249 237 250 cycle_start = get_cycles(); 238 251 for (i = 0; i < nr_loops; ++i) ··· 257 252 memcpy_t fn = r->fn.memcpy; 258 253 int i; 259 254 260 - /* 261 - * We prefault the freshly allocated memory range here, 262 - * to not measure page fault overhead: 263 - */ 264 - fn(dst, src, size); 255 + memcpy_prefault(fn, size, src, dst); 265 256 266 257 BUG_ON(gettimeofday(&tv_start, NULL)); 267 258 for (i = 0; i < nr_loops; ++i)
+39 -38
tools/perf/bench/numa.c
··· 247 247 */ 248 248 static bool node_has_cpus(int node) 249 249 { 250 - struct bitmask *cpu = numa_allocate_cpumask(); 251 - unsigned int i; 250 + struct bitmask *cpumask = numa_allocate_cpumask(); 251 + bool ret = false; /* fall back to nocpus */ 252 + int cpu; 252 253 253 - if (cpu && !numa_node_to_cpus(node, cpu)) { 254 - for (i = 0; i < cpu->size; i++) { 255 - if (numa_bitmask_isbitset(cpu, i)) 256 - return true; 254 + BUG_ON(!cpumask); 255 + if (!numa_node_to_cpus(node, cpumask)) { 256 + for (cpu = 0; cpu < (int)cpumask->size; cpu++) { 257 + if (numa_bitmask_isbitset(cpumask, cpu)) { 258 + ret = true; 259 + break; 260 + } 257 261 } 258 262 } 263 + numa_free_cpumask(cpumask); 259 264 260 - return false; /* lets fall back to nocpus safely */ 265 + return ret; 261 266 } 262 267 263 268 static cpu_set_t bind_to_cpu(int target_cpu) ··· 293 288 294 289 static cpu_set_t bind_to_node(int target_node) 295 290 { 296 - int cpus_per_node = g->p.nr_cpus / nr_numa_nodes(); 297 291 cpu_set_t orig_mask, mask; 298 292 int cpu; 299 293 int ret; 300 - 301 - BUG_ON(cpus_per_node * nr_numa_nodes() != g->p.nr_cpus); 302 - BUG_ON(!cpus_per_node); 303 294 304 295 ret = sched_getaffinity(0, sizeof(orig_mask), &orig_mask); 305 296 BUG_ON(ret); ··· 306 305 for (cpu = 0; cpu < g->p.nr_cpus; cpu++) 307 306 CPU_SET(cpu, &mask); 308 307 } else { 309 - int cpu_start = (target_node + 0) * cpus_per_node; 310 - int cpu_stop = (target_node + 1) * cpus_per_node; 308 + struct bitmask *cpumask = numa_allocate_cpumask(); 311 309 312 - BUG_ON(cpu_stop > g->p.nr_cpus); 313 - 314 - for (cpu = cpu_start; cpu < cpu_stop; cpu++) 315 - CPU_SET(cpu, &mask); 310 + BUG_ON(!cpumask); 311 + if (!numa_node_to_cpus(target_node, cpumask)) { 312 + for (cpu = 0; cpu < (int)cpumask->size; cpu++) { 313 + if (numa_bitmask_isbitset(cpumask, cpu)) 314 + CPU_SET(cpu, &mask); 315 + } 316 + } 317 + numa_free_cpumask(cpumask); 316 318 } 317 319 318 320 ret = sched_setaffinity(0, sizeof(mask), &mask); ··· 733 729 return -1; 734 730 735 731 return parse_node_list(arg); 736 - 737 - return 0; 738 732 } 739 733 740 734 #define BIT(x) (1ul << x) ··· 815 813 } 816 814 } 817 815 } else if (!g->p.data_backwards || (nr + loop) & 1) { 816 + /* Process data forwards: */ 818 817 819 818 d0 = data + off; 820 819 d = data + off + 1; 821 820 d1 = data + words; 822 821 823 - /* Process data forwards: */ 824 822 for (;;) { 825 823 if (unlikely(d >= d1)) 826 824 d = data; ··· 838 836 d = data + off - 1; 839 837 d1 = data + words; 840 838 841 - /* Process data forwards: */ 842 839 for (;;) { 843 840 if (unlikely(d < data)) 844 841 d = data + words-1; ··· 1734 1733 */ 1735 1734 static const char *tests[][MAX_ARGS] = { 1736 1735 /* Basic single-stream NUMA bandwidth measurements: */ 1737 - { "RAM-bw-local,", "mem", "-p", "1", "-t", "1", "-P", "1024", 1736 + { "RAM-bw-local,", "mem", "-p", "1", "-t", "1", "-P", "1024", 1738 1737 "-C" , "0", "-M", "0", OPT_BW_RAM }, 1739 1738 { "RAM-bw-local-NOTHP,", 1740 1739 "mem", "-p", "1", "-t", "1", "-P", "1024", 1741 1740 "-C" , "0", "-M", "0", OPT_BW_RAM_NOTHP }, 1742 - { "RAM-bw-remote,", "mem", "-p", "1", "-t", "1", "-P", "1024", 1741 + { "RAM-bw-remote,", "mem", "-p", "1", "-t", "1", "-P", "1024", 1743 1742 "-C" , "0", "-M", "1", OPT_BW_RAM }, 1744 1743 1745 1744 /* 2-stream NUMA bandwidth measurements: */ ··· 1756 1755 { " 1x3-convergence,", "mem", "-p", "1", "-t", "3", "-P", "512", OPT_CONV }, 1757 1756 { " 1x4-convergence,", "mem", "-p", "1", "-t", "4", "-P", "512", OPT_CONV }, 1758 1757 { " 1x6-convergence,", "mem", "-p", "1", "-t", "6", "-P", "1020", OPT_CONV }, 1759 - { " 2x3-convergence,", "mem", "-p", "3", "-t", "3", "-P", "1020", OPT_CONV }, 1758 + { " 2x3-convergence,", "mem", "-p", "2", "-t", "3", "-P", "1020", OPT_CONV }, 1760 1759 { " 3x3-convergence,", "mem", "-p", "3", "-t", "3", "-P", "1020", OPT_CONV }, 1761 1760 { " 4x4-convergence,", "mem", "-p", "4", "-t", "4", "-P", "512", OPT_CONV }, 1762 1761 { " 4x4-convergence-NOTHP,", ··· 1781 1780 "mem", "-p", "8", "-t", "1", "-P", " 512", OPT_BW_NOTHP }, 1782 1781 { "16x1-bw-process,", "mem", "-p", "16", "-t", "1", "-P", "256", OPT_BW }, 1783 1782 1784 - { " 4x1-bw-thread,", "mem", "-p", "1", "-t", "4", "-T", "256", OPT_BW }, 1785 - { " 8x1-bw-thread,", "mem", "-p", "1", "-t", "8", "-T", "256", OPT_BW }, 1786 - { "16x1-bw-thread,", "mem", "-p", "1", "-t", "16", "-T", "128", OPT_BW }, 1787 - { "32x1-bw-thread,", "mem", "-p", "1", "-t", "32", "-T", "64", OPT_BW }, 1783 + { " 1x4-bw-thread,", "mem", "-p", "1", "-t", "4", "-T", "256", OPT_BW }, 1784 + { " 1x8-bw-thread,", "mem", "-p", "1", "-t", "8", "-T", "256", OPT_BW }, 1785 + { "1x16-bw-thread,", "mem", "-p", "1", "-t", "16", "-T", "128", OPT_BW }, 1786 + { "1x32-bw-thread,", "mem", "-p", "1", "-t", "32", "-T", "64", OPT_BW }, 1788 1787 1789 - { " 2x3-bw-thread,", "mem", "-p", "2", "-t", "3", "-P", "512", OPT_BW }, 1790 - { " 4x4-bw-thread,", "mem", "-p", "4", "-t", "4", "-P", "512", OPT_BW }, 1791 - { " 4x6-bw-thread,", "mem", "-p", "4", "-t", "6", "-P", "512", OPT_BW }, 1792 - { " 4x8-bw-thread,", "mem", "-p", "4", "-t", "8", "-P", "512", OPT_BW }, 1793 - { " 4x8-bw-thread-NOTHP,", 1788 + { " 2x3-bw-process,", "mem", "-p", "2", "-t", "3", "-P", "512", OPT_BW }, 1789 + { " 4x4-bw-process,", "mem", "-p", "4", "-t", "4", "-P", "512", OPT_BW }, 1790 + { " 4x6-bw-process,", "mem", "-p", "4", "-t", "6", "-P", "512", OPT_BW }, 1791 + { " 4x8-bw-process,", "mem", "-p", "4", "-t", "8", "-P", "512", OPT_BW }, 1792 + { " 4x8-bw-process-NOTHP,", 1794 1793 "mem", "-p", "4", "-t", "8", "-P", "512", OPT_BW_NOTHP }, 1795 - { " 3x3-bw-thread,", "mem", "-p", "3", "-t", "3", "-P", "512", OPT_BW }, 1796 - { " 5x5-bw-thread,", "mem", "-p", "5", "-t", "5", "-P", "512", OPT_BW }, 1794 + { " 3x3-bw-process,", "mem", "-p", "3", "-t", "3", "-P", "512", OPT_BW }, 1795 + { " 5x5-bw-process,", "mem", "-p", "5", "-t", "5", "-P", "512", OPT_BW }, 1797 1796 1798 - { "2x16-bw-thread,", "mem", "-p", "2", "-t", "16", "-P", "512", OPT_BW }, 1799 - { "1x32-bw-thread,", "mem", "-p", "1", "-t", "32", "-P", "2048", OPT_BW }, 1797 + { "2x16-bw-process,", "mem", "-p", "2", "-t", "16", "-P", "512", OPT_BW }, 1798 + { "1x32-bw-process,", "mem", "-p", "1", "-t", "32", "-P", "2048", OPT_BW }, 1800 1799 1801 - { "numa02-bw,", "mem", "-p", "1", "-t", "32", "-T", "32", OPT_BW }, 1800 + { "numa02-bw,", "mem", "-p", "1", "-t", "32", "-T", "32", OPT_BW }, 1802 1801 { "numa02-bw-NOTHP,", "mem", "-p", "1", "-t", "32", "-T", "32", OPT_BW_NOTHP }, 1803 1802 { "numa01-bw-thread,", "mem", "-p", "2", "-t", "16", "-T", "192", OPT_BW }, 1804 1803 { "numa01-bw-thread-NOTHP,",
+402 -36
tools/perf/builtin-ftrace.c
··· 3 3 * builtin-ftrace.c 4 4 * 5 5 * Copyright (c) 2013 LG Electronics, Namhyung Kim <namhyung@kernel.org> 6 + * Copyright (c) 2020 Changbin Du <changbin.du@gmail.com>, significant enhancement. 6 7 */ 7 8 8 9 #include "builtin.h" ··· 27 26 #include "thread_map.h" 28 27 #include "util/cap.h" 29 28 #include "util/config.h" 29 + #include "util/units.h" 30 + #include "util/parse-sublevel-options.h" 30 31 31 32 #define DEFAULT_TRACER "function_graph" 32 33 ··· 36 33 struct evlist *evlist; 37 34 struct target target; 38 35 const char *tracer; 36 + bool list_avail_functions; 39 37 struct list_head filters; 40 38 struct list_head notrace; 41 39 struct list_head graph_funcs; 42 40 struct list_head nograph_funcs; 43 41 int graph_depth; 42 + unsigned long percpu_buffer_size; 43 + bool inherit; 44 + int func_stack_trace; 45 + int func_irq_info; 46 + int graph_nosleep_time; 47 + int graph_noirqs; 48 + int graph_verbose; 49 + int graph_thresh; 50 + unsigned int initial_delay; 44 51 }; 45 52 46 53 struct filter_entry { ··· 141 128 return __write_tracing_file(name, val, true); 142 129 } 143 130 131 + static int read_tracing_file_to_stdout(const char *name) 132 + { 133 + char buf[4096]; 134 + char *file; 135 + int fd; 136 + int ret = -1; 137 + 138 + file = get_tracing_file(name); 139 + if (!file) { 140 + pr_debug("cannot get tracing file: %s\n", name); 141 + return -1; 142 + } 143 + 144 + fd = open(file, O_RDONLY); 145 + if (fd < 0) { 146 + pr_debug("cannot open tracing file: %s: %s\n", 147 + name, str_error_r(errno, buf, sizeof(buf))); 148 + goto out; 149 + } 150 + 151 + /* read contents to stdout */ 152 + while (true) { 153 + int n = read(fd, buf, sizeof(buf)); 154 + if (n == 0) 155 + break; 156 + else if (n < 0) 157 + goto out_close; 158 + 159 + if (fwrite(buf, n, 1, stdout) != 1) 160 + goto out_close; 161 + } 162 + ret = 0; 163 + 164 + out_close: 165 + close(fd); 166 + out: 167 + put_tracing_file(file); 168 + return ret; 169 + } 170 + 171 + static int write_tracing_file_int(const char *name, int value) 172 + { 173 + char buf[16]; 174 + 175 + snprintf(buf, sizeof(buf), "%d", value); 176 + if (write_tracing_file(name, buf) < 0) 177 + return -1; 178 + 179 + return 0; 180 + } 181 + 182 + static int write_tracing_option_file(const char *name, const char *val) 183 + { 184 + char *file; 185 + int ret; 186 + 187 + if (asprintf(&file, "options/%s", name) < 0) 188 + return -1; 189 + 190 + ret = __write_tracing_file(file, val, false); 191 + free(file); 192 + return ret; 193 + } 194 + 144 195 static int reset_tracing_cpu(void); 145 196 static void reset_tracing_filters(void); 197 + 198 + static void reset_tracing_options(struct perf_ftrace *ftrace __maybe_unused) 199 + { 200 + write_tracing_option_file("function-fork", "0"); 201 + write_tracing_option_file("func_stack_trace", "0"); 202 + write_tracing_option_file("sleep-time", "1"); 203 + write_tracing_option_file("funcgraph-irqs", "1"); 204 + write_tracing_option_file("funcgraph-proc", "0"); 205 + write_tracing_option_file("funcgraph-abstime", "0"); 206 + write_tracing_option_file("latency-format", "0"); 207 + write_tracing_option_file("irq-info", "0"); 208 + } 146 209 147 210 static int reset_tracing_files(struct perf_ftrace *ftrace __maybe_unused) 148 211 { ··· 237 148 if (write_tracing_file("max_graph_depth", "0") < 0) 238 149 return -1; 239 150 151 + if (write_tracing_file("tracing_thresh", "0") < 0) 152 + return -1; 153 + 240 154 reset_tracing_filters(); 155 + reset_tracing_options(ftrace); 241 156 return 0; 242 157 } 243 158 ··· 295 202 return 0; 296 203 297 204 return set_tracing_cpumask(cpumap); 205 + } 206 + 207 + static int set_tracing_func_stack_trace(struct perf_ftrace *ftrace) 208 + { 209 + if (!ftrace->func_stack_trace) 210 + return 0; 211 + 212 + if (write_tracing_option_file("func_stack_trace", "1") < 0) 213 + return -1; 214 + 215 + return 0; 216 + } 217 + 218 + static int set_tracing_func_irqinfo(struct perf_ftrace *ftrace) 219 + { 220 + if (!ftrace->func_irq_info) 221 + return 0; 222 + 223 + if (write_tracing_option_file("irq-info", "1") < 0) 224 + return -1; 225 + 226 + return 0; 298 227 } 299 228 300 229 static int reset_tracing_cpu(void) ··· 373 258 374 259 static int set_tracing_depth(struct perf_ftrace *ftrace) 375 260 { 376 - char buf[16]; 377 - 378 261 if (ftrace->graph_depth == 0) 379 262 return 0; 380 263 ··· 381 268 return -1; 382 269 } 383 270 384 - snprintf(buf, sizeof(buf), "%d", ftrace->graph_depth); 385 - 386 - if (write_tracing_file("max_graph_depth", buf) < 0) 271 + if (write_tracing_file_int("max_graph_depth", ftrace->graph_depth) < 0) 387 272 return -1; 273 + 274 + return 0; 275 + } 276 + 277 + static int set_tracing_percpu_buffer_size(struct perf_ftrace *ftrace) 278 + { 279 + int ret; 280 + 281 + if (ftrace->percpu_buffer_size == 0) 282 + return 0; 283 + 284 + ret = write_tracing_file_int("buffer_size_kb", 285 + ftrace->percpu_buffer_size / 1024); 286 + if (ret < 0) 287 + return ret; 288 + 289 + return 0; 290 + } 291 + 292 + static int set_tracing_trace_inherit(struct perf_ftrace *ftrace) 293 + { 294 + if (!ftrace->inherit) 295 + return 0; 296 + 297 + if (write_tracing_option_file("function-fork", "1") < 0) 298 + return -1; 299 + 300 + return 0; 301 + } 302 + 303 + static int set_tracing_sleep_time(struct perf_ftrace *ftrace) 304 + { 305 + if (!ftrace->graph_nosleep_time) 306 + return 0; 307 + 308 + if (write_tracing_option_file("sleep-time", "0") < 0) 309 + return -1; 310 + 311 + return 0; 312 + } 313 + 314 + static int set_tracing_funcgraph_irqs(struct perf_ftrace *ftrace) 315 + { 316 + if (!ftrace->graph_noirqs) 317 + return 0; 318 + 319 + if (write_tracing_option_file("funcgraph-irqs", "0") < 0) 320 + return -1; 321 + 322 + return 0; 323 + } 324 + 325 + static int set_tracing_funcgraph_verbose(struct perf_ftrace *ftrace) 326 + { 327 + if (!ftrace->graph_verbose) 328 + return 0; 329 + 330 + if (write_tracing_option_file("funcgraph-proc", "1") < 0) 331 + return -1; 332 + 333 + if (write_tracing_option_file("funcgraph-abstime", "1") < 0) 334 + return -1; 335 + 336 + if (write_tracing_option_file("latency-format", "1") < 0) 337 + return -1; 338 + 339 + return 0; 340 + } 341 + 342 + static int set_tracing_thresh(struct perf_ftrace *ftrace) 343 + { 344 + int ret; 345 + 346 + if (ftrace->graph_thresh == 0) 347 + return 0; 348 + 349 + ret = write_tracing_file_int("tracing_thresh", ftrace->graph_thresh); 350 + if (ret < 0) 351 + return ret; 352 + 353 + return 0; 354 + } 355 + 356 + static int set_tracing_options(struct perf_ftrace *ftrace) 357 + { 358 + if (set_tracing_pid(ftrace) < 0) { 359 + pr_err("failed to set ftrace pid\n"); 360 + return -1; 361 + } 362 + 363 + if (set_tracing_cpu(ftrace) < 0) { 364 + pr_err("failed to set tracing cpumask\n"); 365 + return -1; 366 + } 367 + 368 + if (set_tracing_func_stack_trace(ftrace) < 0) { 369 + pr_err("failed to set tracing option func_stack_trace\n"); 370 + return -1; 371 + } 372 + 373 + if (set_tracing_func_irqinfo(ftrace) < 0) { 374 + pr_err("failed to set tracing option irq-info\n"); 375 + return -1; 376 + } 377 + 378 + if (set_tracing_filters(ftrace) < 0) { 379 + pr_err("failed to set tracing filters\n"); 380 + return -1; 381 + } 382 + 383 + if (set_tracing_depth(ftrace) < 0) { 384 + pr_err("failed to set graph depth\n"); 385 + return -1; 386 + } 387 + 388 + if (set_tracing_percpu_buffer_size(ftrace) < 0) { 389 + pr_err("failed to set tracing per-cpu buffer size\n"); 390 + return -1; 391 + } 392 + 393 + if (set_tracing_trace_inherit(ftrace) < 0) { 394 + pr_err("failed to set tracing option function-fork\n"); 395 + return -1; 396 + } 397 + 398 + if (set_tracing_sleep_time(ftrace) < 0) { 399 + pr_err("failed to set tracing option sleep-time\n"); 400 + return -1; 401 + } 402 + 403 + if (set_tracing_funcgraph_irqs(ftrace) < 0) { 404 + pr_err("failed to set tracing option funcgraph-irqs\n"); 405 + return -1; 406 + } 407 + 408 + if (set_tracing_funcgraph_verbose(ftrace) < 0) { 409 + pr_err("failed to set tracing option funcgraph-proc/funcgraph-abstime\n"); 410 + return -1; 411 + } 412 + 413 + if (set_tracing_thresh(ftrace) < 0) { 414 + pr_err("failed to set tracing thresh\n"); 415 + return -1; 416 + } 388 417 389 418 return 0; 390 419 } ··· 557 302 signal(SIGCHLD, sig_handler); 558 303 signal(SIGPIPE, sig_handler); 559 304 305 + if (ftrace->list_avail_functions) 306 + return read_tracing_file_to_stdout("available_filter_functions"); 307 + 560 308 if (reset_tracing_files(ftrace) < 0) { 561 309 pr_err("failed to reset ftrace\n"); 562 310 goto out; ··· 575 317 goto out; 576 318 } 577 319 578 - if (set_tracing_pid(ftrace) < 0) { 579 - pr_err("failed to set ftrace pid\n"); 320 + if (set_tracing_options(ftrace) < 0) 580 321 goto out_reset; 581 - } 582 - 583 - if (set_tracing_cpu(ftrace) < 0) { 584 - pr_err("failed to set tracing cpumask\n"); 585 - goto out_reset; 586 - } 587 - 588 - if (set_tracing_filters(ftrace) < 0) { 589 - pr_err("failed to set tracing filters\n"); 590 - goto out_reset; 591 - } 592 - 593 - if (set_tracing_depth(ftrace) < 0) { 594 - pr_err("failed to set graph depth\n"); 595 - goto out_reset; 596 - } 597 322 598 323 if (write_tracing_file("current_tracer", ftrace->tracer) < 0) { 599 324 pr_err("failed to set current_tracer to %s\n", ftrace->tracer); ··· 603 362 fcntl(trace_fd, F_SETFL, O_NONBLOCK); 604 363 pollfd.fd = trace_fd; 605 364 606 - if (write_tracing_file("tracing_on", "1") < 0) { 607 - pr_err("can't enable tracing\n"); 608 - goto out_close_fd; 365 + /* display column headers */ 366 + read_tracing_file_to_stdout("trace"); 367 + 368 + if (!ftrace->initial_delay) { 369 + if (write_tracing_file("tracing_on", "1") < 0) { 370 + pr_err("can't enable tracing\n"); 371 + goto out_close_fd; 372 + } 609 373 } 610 374 611 375 perf_evlist__start_workload(ftrace->evlist); 376 + 377 + if (ftrace->initial_delay) { 378 + usleep(ftrace->initial_delay * 1000); 379 + if (write_tracing_file("tracing_on", "1") < 0) { 380 + pr_err("can't enable tracing\n"); 381 + goto out_close_fd; 382 + } 383 + } 612 384 613 385 while (!done) { 614 386 if (poll(&pollfd, 1, -1) < 0) ··· 709 455 } 710 456 } 711 457 458 + static int parse_buffer_size(const struct option *opt, 459 + const char *str, int unset) 460 + { 461 + unsigned long *s = (unsigned long *)opt->value; 462 + static struct parse_tag tags_size[] = { 463 + { .tag = 'B', .mult = 1 }, 464 + { .tag = 'K', .mult = 1 << 10 }, 465 + { .tag = 'M', .mult = 1 << 20 }, 466 + { .tag = 'G', .mult = 1 << 30 }, 467 + { .tag = 0 }, 468 + }; 469 + unsigned long val; 470 + 471 + if (unset) { 472 + *s = 0; 473 + return 0; 474 + } 475 + 476 + val = parse_tag_value(str, tags_size); 477 + if (val != (unsigned long) -1) { 478 + if (val < 1024) { 479 + pr_err("buffer size too small, must larger than 1KB."); 480 + return -1; 481 + } 482 + *s = val; 483 + return 0; 484 + } 485 + 486 + return -1; 487 + } 488 + 489 + static int parse_func_tracer_opts(const struct option *opt, 490 + const char *str, int unset) 491 + { 492 + int ret; 493 + struct perf_ftrace *ftrace = (struct perf_ftrace *) opt->value; 494 + struct sublevel_option func_tracer_opts[] = { 495 + { .name = "call-graph", .value_ptr = &ftrace->func_stack_trace }, 496 + { .name = "irq-info", .value_ptr = &ftrace->func_irq_info }, 497 + { .name = NULL, } 498 + }; 499 + 500 + if (unset) 501 + return 0; 502 + 503 + ret = perf_parse_sublevel_options(str, func_tracer_opts); 504 + if (ret) 505 + return ret; 506 + 507 + return 0; 508 + } 509 + 510 + static int parse_graph_tracer_opts(const struct option *opt, 511 + const char *str, int unset) 512 + { 513 + int ret; 514 + struct perf_ftrace *ftrace = (struct perf_ftrace *) opt->value; 515 + struct sublevel_option graph_tracer_opts[] = { 516 + { .name = "nosleep-time", .value_ptr = &ftrace->graph_nosleep_time }, 517 + { .name = "noirqs", .value_ptr = &ftrace->graph_noirqs }, 518 + { .name = "verbose", .value_ptr = &ftrace->graph_verbose }, 519 + { .name = "thresh", .value_ptr = &ftrace->graph_thresh }, 520 + { .name = "depth", .value_ptr = &ftrace->graph_depth }, 521 + { .name = NULL, } 522 + }; 523 + 524 + if (unset) 525 + return 0; 526 + 527 + ret = perf_parse_sublevel_options(str, graph_tracer_opts); 528 + if (ret) 529 + return ret; 530 + 531 + return 0; 532 + } 533 + 534 + static void select_tracer(struct perf_ftrace *ftrace) 535 + { 536 + bool graph = !list_empty(&ftrace->graph_funcs) || 537 + !list_empty(&ftrace->nograph_funcs); 538 + bool func = !list_empty(&ftrace->filters) || 539 + !list_empty(&ftrace->notrace); 540 + 541 + /* The function_graph has priority over function tracer. */ 542 + if (graph) 543 + ftrace->tracer = "function_graph"; 544 + else if (func) 545 + ftrace->tracer = "function"; 546 + /* Otherwise, the default tracer is used. */ 547 + 548 + pr_debug("%s tracer is used\n", ftrace->tracer); 549 + } 550 + 712 551 int cmd_ftrace(int argc, const char **argv) 713 552 { 714 553 int ret; ··· 816 469 }; 817 470 const struct option ftrace_options[] = { 818 471 OPT_STRING('t', "tracer", &ftrace.tracer, "tracer", 819 - "tracer to use: function_graph(default) or function"), 472 + "Tracer to use: function_graph(default) or function"), 473 + OPT_BOOLEAN('F', "funcs", &ftrace.list_avail_functions, 474 + "Show available functions to filter"), 820 475 OPT_STRING('p', "pid", &ftrace.target.pid, "pid", 821 - "trace on existing process id"), 476 + "Trace on existing process id"), 477 + /* TODO: Add short option -t after -t/--tracer can be removed. */ 478 + OPT_STRING(0, "tid", &ftrace.target.tid, "tid", 479 + "Trace on existing thread id (exclusive to --pid)"), 822 480 OPT_INCR('v', "verbose", &verbose, 823 - "be more verbose"), 481 + "Be more verbose"), 824 482 OPT_BOOLEAN('a', "all-cpus", &ftrace.target.system_wide, 825 - "system-wide collection from all CPUs"), 483 + "System-wide collection from all CPUs"), 826 484 OPT_STRING('C', "cpu", &ftrace.target.cpu_list, "cpu", 827 - "list of cpus to monitor"), 485 + "List of cpus to monitor"), 828 486 OPT_CALLBACK('T', "trace-funcs", &ftrace.filters, "func", 829 - "trace given functions only", parse_filter_func), 487 + "Trace given functions using function tracer", 488 + parse_filter_func), 830 489 OPT_CALLBACK('N', "notrace-funcs", &ftrace.notrace, "func", 831 - "do not trace given functions", parse_filter_func), 490 + "Do not trace given functions", parse_filter_func), 491 + OPT_CALLBACK(0, "func-opts", &ftrace, "options", 492 + "Function tracer options, available options: call-graph,irq-info", 493 + parse_func_tracer_opts), 832 494 OPT_CALLBACK('G', "graph-funcs", &ftrace.graph_funcs, "func", 833 - "Set graph filter on given functions", parse_filter_func), 495 + "Trace given functions using function_graph tracer", 496 + parse_filter_func), 834 497 OPT_CALLBACK('g', "nograph-funcs", &ftrace.nograph_funcs, "func", 835 498 "Set nograph filter on given functions", parse_filter_func), 836 - OPT_INTEGER('D', "graph-depth", &ftrace.graph_depth, 837 - "Max depth for function graph tracer"), 499 + OPT_CALLBACK(0, "graph-opts", &ftrace, "options", 500 + "Graph tracer options, available options: nosleep-time,noirqs,verbose,thresh=<n>,depth=<n>", 501 + parse_graph_tracer_opts), 502 + OPT_CALLBACK('m', "buffer-size", &ftrace.percpu_buffer_size, "size", 503 + "Size of per cpu buffer, needs to use a B, K, M or G suffix.", parse_buffer_size), 504 + OPT_BOOLEAN(0, "inherit", &ftrace.inherit, 505 + "Trace children processes"), 506 + OPT_UINTEGER('D', "delay", &ftrace.initial_delay, 507 + "Number of milliseconds to wait before starting tracing after program start"), 838 508 OPT_END() 839 509 }; 840 510 ··· 868 504 PARSE_OPT_STOP_AT_NON_OPTION); 869 505 if (!argc && target__none(&ftrace.target)) 870 506 ftrace.target.system_wide = true; 507 + 508 + select_tracer(&ftrace); 871 509 872 510 ret = target__validate(&ftrace.target); 873 511 if (ret) {
+29 -3
tools/perf/builtin-sched.c
··· 2398 2398 printf("\n"); 2399 2399 } 2400 2400 2401 + static int timehist_sched_wakeup_ignore(struct perf_tool *tool __maybe_unused, 2402 + union perf_event *event __maybe_unused, 2403 + struct evsel *evsel __maybe_unused, 2404 + struct perf_sample *sample __maybe_unused, 2405 + struct machine *machine __maybe_unused) 2406 + { 2407 + return 0; 2408 + } 2409 + 2401 2410 static int timehist_sched_wakeup_event(struct perf_tool *tool, 2402 2411 union perf_event *event __maybe_unused, 2403 2412 struct evsel *evsel, ··· 2967 2958 2968 2959 static int perf_sched__timehist(struct perf_sched *sched) 2969 2960 { 2970 - const struct evsel_str_handler handlers[] = { 2961 + struct evsel_str_handler handlers[] = { 2971 2962 { "sched:sched_switch", timehist_sched_switch_event, }, 2972 2963 { "sched:sched_wakeup", timehist_sched_wakeup_event, }, 2964 + { "sched:sched_waking", timehist_sched_wakeup_event, }, 2973 2965 { "sched:sched_wakeup_new", timehist_sched_wakeup_event, }, 2974 2966 }; 2975 2967 const struct evsel_str_handler migrate_handlers[] = { ··· 3027 3017 goto out; 3028 3018 3029 3019 setup_pager(); 3020 + 3021 + /* prefer sched_waking if it is captured */ 3022 + if (perf_evlist__find_tracepoint_by_name(session->evlist, 3023 + "sched:sched_waking")) 3024 + handlers[1].handler = timehist_sched_wakeup_ignore; 3030 3025 3031 3026 /* setup per-evsel handlers */ 3032 3027 if (perf_session__set_tracepoints_handlers(session, handlers)) ··· 3345 3330 "-e", "sched:sched_stat_iowait", 3346 3331 "-e", "sched:sched_stat_runtime", 3347 3332 "-e", "sched:sched_process_fork", 3348 - "-e", "sched:sched_wakeup", 3349 3333 "-e", "sched:sched_wakeup_new", 3350 3334 "-e", "sched:sched_migrate_task", 3351 3335 }; 3336 + struct tep_event *waking_event; 3352 3337 3353 - rec_argc = ARRAY_SIZE(record_args) + argc - 1; 3338 + /* 3339 + * +2 for either "-e", "sched:sched_wakeup" or 3340 + * "-e", "sched:sched_waking" 3341 + */ 3342 + rec_argc = ARRAY_SIZE(record_args) + 2 + argc - 1; 3354 3343 rec_argv = calloc(rec_argc + 1, sizeof(char *)); 3355 3344 3356 3345 if (rec_argv == NULL) ··· 3362 3343 3363 3344 for (i = 0; i < ARRAY_SIZE(record_args); i++) 3364 3345 rec_argv[i] = strdup(record_args[i]); 3346 + 3347 + rec_argv[i++] = "-e"; 3348 + waking_event = trace_event__tp_format("sched", "sched_waking"); 3349 + if (!IS_ERR(waking_event)) 3350 + rec_argv[i++] = strdup("sched:sched_waking"); 3351 + else 3352 + rec_argv[i++] = strdup("sched:sched_wakeup"); 3365 3353 3366 3354 for (j = 1; j < (unsigned int)argc; j++, i++) 3367 3355 rec_argv[i] = argv[j];
+3
tools/perf/check-headers.sh
··· 128 128 # diff non-symmetric files 129 129 check_2 tools/perf/arch/x86/entry/syscalls/syscall_64.tbl arch/x86/entry/syscalls/syscall_64.tbl 130 130 131 + # These will require a beauty_check when we get some more like that 132 + check_2 tools/perf/trace/beauty/include/linux/socket.h include/linux/socket.h 133 + 131 134 # check duplicated library files 132 135 check_2 tools/perf/util/hashmap.h tools/lib/bpf/hashmap.h 133 136 check_2 tools/perf/util/hashmap.c tools/lib/bpf/hashmap.c
+24 -24
tools/perf/pmu-events/arch/powerpc/power9/metrics.json
··· 60 60 }, 61 61 { 62 62 "BriefDescription": "Stalls due to short latency decimal floating ops.", 63 - "MetricExpr": "(PM_CMPLU_STALL_DFU - PM_CMPLU_STALL_DFLONG)/PM_RUN_INST_CMPL", 63 + "MetricExpr": "dfu_stall_cpi - dflong_stall_cpi", 64 64 "MetricGroup": "cpi_breakdown", 65 65 "MetricName": "dfu_other_stall_cpi" 66 66 }, ··· 72 72 }, 73 73 { 74 74 "BriefDescription": "Completion stall by Dcache miss which resolved off node memory/cache", 75 - "MetricExpr": "(PM_CMPLU_STALL_DMISS_L3MISS - PM_CMPLU_STALL_DMISS_L21_L31 - PM_CMPLU_STALL_DMISS_LMEM - PM_CMPLU_STALL_DMISS_REMOTE)/PM_RUN_INST_CMPL", 75 + "MetricExpr": "dmiss_non_local_stall_cpi - dmiss_remote_stall_cpi", 76 76 "MetricGroup": "cpi_breakdown", 77 77 "MetricName": "dmiss_distant_stall_cpi" 78 78 }, ··· 90 90 }, 91 91 { 92 92 "BriefDescription": "Completion stall due to cache miss that resolves in the L2 or L3 without conflict", 93 - "MetricExpr": "(PM_CMPLU_STALL_DMISS_L2L3 - PM_CMPLU_STALL_DMISS_L2L3_CONFLICT)/PM_RUN_INST_CMPL", 93 + "MetricExpr": "dmiss_l2l3_stall_cpi - dmiss_l2l3_conflict_stall_cpi", 94 94 "MetricGroup": "cpi_breakdown", 95 95 "MetricName": "dmiss_l2l3_noconflict_stall_cpi" 96 96 }, ··· 114 114 }, 115 115 { 116 116 "BriefDescription": "Completion stall by Dcache miss which resolved outside of local memory", 117 - "MetricExpr": "(PM_CMPLU_STALL_DMISS_L3MISS - PM_CMPLU_STALL_DMISS_L21_L31 - PM_CMPLU_STALL_DMISS_LMEM)/PM_RUN_INST_CMPL", 117 + "MetricExpr": "dmiss_l3miss_stall_cpi - dmiss_l21_l31_stall_cpi - dmiss_lmem_stall_cpi", 118 118 "MetricGroup": "cpi_breakdown", 119 119 "MetricName": "dmiss_non_local_stall_cpi" 120 120 }, ··· 126 126 }, 127 127 { 128 128 "BriefDescription": "Stalls due to short latency double precision ops.", 129 - "MetricExpr": "(PM_CMPLU_STALL_DP - PM_CMPLU_STALL_DPLONG)/PM_RUN_INST_CMPL", 129 + "MetricExpr": "dp_stall_cpi - dplong_stall_cpi", 130 130 "MetricGroup": "cpi_breakdown", 131 131 "MetricName": "dp_other_stall_cpi" 132 132 }, ··· 155 155 "MetricName": "emq_full_stall_cpi" 156 156 }, 157 157 { 158 - "MetricExpr": "(PM_CMPLU_STALL_ERAT_MISS + PM_CMPLU_STALL_EMQ_FULL)/PM_RUN_INST_CMPL", 158 + "MetricExpr": "erat_miss_stall_cpi + emq_full_stall_cpi", 159 159 "MetricGroup": "cpi_breakdown", 160 160 "MetricName": "emq_stall_cpi" 161 161 }, ··· 173 173 }, 174 174 { 175 175 "BriefDescription": "Completion stall due to execution units for other reasons.", 176 - "MetricExpr": "(PM_CMPLU_STALL_EXEC_UNIT - PM_CMPLU_STALL_FXU - PM_CMPLU_STALL_DP - PM_CMPLU_STALL_DFU - PM_CMPLU_STALL_PM - PM_CMPLU_STALL_CRYPTO - PM_CMPLU_STALL_VFXU - PM_CMPLU_STALL_VDP)/PM_RUN_INST_CMPL", 176 + "MetricExpr": "exec_unit_stall_cpi - scalar_stall_cpi - vector_stall_cpi", 177 177 "MetricGroup": "cpi_breakdown", 178 178 "MetricName": "exec_unit_other_stall_cpi" 179 179 }, ··· 197 197 }, 198 198 { 199 199 "BriefDescription": "Stalls due to short latency integer ops", 200 - "MetricExpr": "(PM_CMPLU_STALL_FXU - PM_CMPLU_STALL_FXLONG)/PM_RUN_INST_CMPL", 200 + "MetricExpr": "fxu_stall_cpi - fxlong_stall_cpi", 201 201 "MetricGroup": "cpi_breakdown", 202 202 "MetricName": "fxu_other_stall_cpi" 203 203 }, ··· 221 221 }, 222 222 { 223 223 "BriefDescription": "Instruction Completion Table other stalls", 224 - "MetricExpr": "(PM_ICT_NOSLOT_CYC - PM_ICT_NOSLOT_IC_MISS - PM_ICT_NOSLOT_BR_MPRED_ICMISS - PM_ICT_NOSLOT_BR_MPRED - PM_ICT_NOSLOT_DISP_HELD)/PM_RUN_INST_CMPL", 224 + "MetricExpr": "nothing_dispatched_cpi - ict_noslot_ic_miss_cpi - ict_noslot_br_mpred_icmiss_cpi - ict_noslot_br_mpred_cpi - ict_noslot_disp_held_cpi", 225 225 "MetricGroup": "cpi_breakdown", 226 226 "MetricName": "ict_noslot_cyc_other_cpi" 227 227 }, ··· 245 245 }, 246 246 { 247 247 "BriefDescription": "ICT_NOSLOT_DISP_HELD_OTHER_CPI", 248 - "MetricExpr": "(PM_ICT_NOSLOT_DISP_HELD - PM_ICT_NOSLOT_DISP_HELD_HB_FULL - PM_ICT_NOSLOT_DISP_HELD_SYNC - PM_ICT_NOSLOT_DISP_HELD_TBEGIN - PM_ICT_NOSLOT_DISP_HELD_ISSQ)/PM_RUN_INST_CMPL", 248 + "MetricExpr": "ict_noslot_disp_held_cpi - ict_noslot_disp_held_hb_full_cpi - ict_noslot_disp_held_sync_cpi - ict_noslot_disp_held_tbegin_cpi - ict_noslot_disp_held_issq_cpi", 249 249 "MetricGroup": "cpi_breakdown", 250 250 "MetricName": "ict_noslot_disp_held_other_cpi" 251 251 }, ··· 263 263 }, 264 264 { 265 265 "BriefDescription": "ICT_NOSLOT_IC_L2_CPI", 266 - "MetricExpr": "(PM_ICT_NOSLOT_IC_MISS - PM_ICT_NOSLOT_IC_L3 - PM_ICT_NOSLOT_IC_L3MISS)/PM_RUN_INST_CMPL", 266 + "MetricExpr": "ict_noslot_ic_miss_cpi - ict_noslot_ic_l3_cpi - ict_noslot_ic_l3miss_cpi", 267 267 "MetricGroup": "cpi_breakdown", 268 268 "MetricName": "ict_noslot_ic_l2_cpi" 269 269 }, ··· 286 286 "MetricName": "ict_noslot_ic_miss_cpi" 287 287 }, 288 288 { 289 - "MetricExpr": "(PM_NTC_ISSUE_HELD_DARQ_FULL + PM_NTC_ISSUE_HELD_ARB + PM_NTC_ISSUE_HELD_OTHER)/PM_RUN_INST_CMPL", 289 + "MetricExpr": "ntc_issue_held_darq_full_cpi + ntc_issue_held_arb_cpi + ntc_issue_held_other_cpi", 290 290 "MetricGroup": "cpi_breakdown", 291 291 "MetricName": "issue_hold_cpi" 292 292 }, ··· 327 327 "MetricName": "lrq_other_stall_cpi" 328 328 }, 329 329 { 330 - "MetricExpr": "(PM_CMPLU_STALL_LMQ_FULL + PM_CMPLU_STALL_ST_FWD + PM_CMPLU_STALL_LHS + PM_CMPLU_STALL_LSU_MFSPR + PM_CMPLU_STALL_LARX + PM_CMPLU_STALL_LRQ_OTHER)/PM_RUN_INST_CMPL", 330 + "MetricExpr": "lmq_full_stall_cpi + st_fwd_stall_cpi + lhs_stall_cpi + lsu_mfspr_stall_cpi + larx_stall_cpi + lrq_other_stall_cpi", 331 331 "MetricGroup": "cpi_breakdown", 332 332 "MetricName": "lrq_stall_cpi" 333 333 }, ··· 338 338 "MetricName": "lsaq_arb_stall_cpi" 339 339 }, 340 340 { 341 - "MetricExpr": "(PM_CMPLU_STALL_LRQ_FULL + PM_CMPLU_STALL_SRQ_FULL + PM_CMPLU_STALL_LSAQ_ARB)/PM_RUN_INST_CMPL", 341 + "MetricExpr": "lrq_full_stall_cpi + srq_full_stall_cpi + lsaq_arb_stall_cpi", 342 342 "MetricGroup": "cpi_breakdown", 343 343 "MetricName": "lsaq_stall_cpi" 344 344 }, ··· 362 362 }, 363 363 { 364 364 "BriefDescription": "Completion LSU stall for other reasons", 365 - "MetricExpr": "(PM_CMPLU_STALL_LSU - PM_CMPLU_STALL_LSU_FIN - PM_CMPLU_STALL_STORE_FINISH - PM_CMPLU_STALL_STORE_DATA - PM_CMPLU_STALL_EIEIO - PM_CMPLU_STALL_STCX - PM_CMPLU_STALL_SLB - PM_CMPLU_STALL_TEND - PM_CMPLU_STALL_PASTE - PM_CMPLU_STALL_TLBIE - PM_CMPLU_STALL_STORE_PIPE_ARB - PM_CMPLU_STALL_STORE_FIN_ARB - PM_CMPLU_STALL_LOAD_FINISH + PM_CMPLU_STALL_DCACHE_MISS - PM_CMPLU_STALL_LMQ_FULL - PM_CMPLU_STALL_ST_FWD - PM_CMPLU_STALL_LHS - PM_CMPLU_STALL_LSU_MFSPR - PM_CMPLU_STALL_LARX - PM_CMPLU_STALL_LRQ_OTHER + PM_CMPLU_STALL_ERAT_MISS + PM_CMPLU_STALL_EMQ_FULL - PM_CMPLU_STALL_LRQ_FULL - PM_CMPLU_STALL_SRQ_FULL - PM_CMPLU_STALL_LSAQ_ARB) / PM_RUN_INST_CMPL", 365 + "MetricExpr": "lsu_stall_cpi - lsu_fin_stall_cpi - store_finish_stall_cpi - srq_stall_cpi - load_finish_stall_cpi + lsu_stall_dcache_miss_cpi - lrq_stall_cpi + emq_stall_cpi - lsaq_stall_cpi", 366 366 "MetricGroup": "cpi_breakdown", 367 367 "MetricName": "lsu_other_stall_cpi" 368 368 }, ··· 434 434 }, 435 435 { 436 436 "BriefDescription": "Cycles unaccounted for.", 437 - "MetricExpr": "(PM_RUN_CYC - PM_1PLUS_PPC_CMPL - PM_CMPLU_STALL_THRD - PM_CMPLU_STALL - PM_ICT_NOSLOT_CYC)/PM_RUN_INST_CMPL", 437 + "MetricExpr": "run_cpi - completion_cpi - thread_block_stall_cpi - stall_cpi - nothing_dispatched_cpi", 438 438 "MetricGroup": "cpi_breakdown", 439 439 "MetricName": "other_cpi" 440 440 }, 441 441 { 442 442 "BriefDescription": "Completion stall for other reasons", 443 - "MetricExpr": "(PM_CMPLU_STALL - PM_CMPLU_STALL_NTC_DISP_FIN - PM_CMPLU_STALL_NTC_FLUSH - PM_CMPLU_STALL_LSU - PM_CMPLU_STALL_EXEC_UNIT - PM_CMPLU_STALL_BRU)/PM_RUN_INST_CMPL", 443 + "MetricExpr": "stall_cpi - ntc_disp_fin_stall_cpi - ntc_flush_stall_cpi - lsu_stall_cpi - exec_unit_stall_cpi - bru_stall_cpi", 444 444 "MetricGroup": "cpi_breakdown", 445 445 "MetricName": "other_stall_cpi" 446 446 }, ··· 469 469 "MetricName": "run_cyc_cpi" 470 470 }, 471 471 { 472 - "MetricExpr": "(PM_CMPLU_STALL_FXU + PM_CMPLU_STALL_DP + PM_CMPLU_STALL_DFU + PM_CMPLU_STALL_PM + PM_CMPLU_STALL_CRYPTO)/PM_RUN_INST_CMPL", 472 + "MetricExpr": "fxu_stall_cpi + dp_stall_cpi + dfu_stall_cpi + pm_stall_cpi + crypto_stall_cpi", 473 473 "MetricGroup": "cpi_breakdown", 474 474 "MetricName": "scalar_stall_cpi" 475 475 }, ··· 492 492 "MetricName": "srq_full_stall_cpi" 493 493 }, 494 494 { 495 - "MetricExpr": "(PM_CMPLU_STALL_STORE_DATA + PM_CMPLU_STALL_EIEIO + PM_CMPLU_STALL_STCX + PM_CMPLU_STALL_SLB + PM_CMPLU_STALL_TEND + PM_CMPLU_STALL_PASTE + PM_CMPLU_STALL_TLBIE + PM_CMPLU_STALL_STORE_PIPE_ARB + PM_CMPLU_STALL_STORE_FIN_ARB)/PM_RUN_INST_CMPL", 495 + "MetricExpr": "store_data_stall_cpi + eieio_stall_cpi + stcx_stall_cpi + slb_stall_cpi + tend_stall_cpi + paste_stall_cpi + tlbie_stall_cpi + store_pipe_arb_stall_cpi + store_fin_arb_stall_cpi", 496 496 "MetricGroup": "cpi_breakdown", 497 497 "MetricName": "srq_stall_cpi" 498 498 }, ··· 558 558 }, 559 559 { 560 560 "BriefDescription": "Vector stalls due to small latency double precision ops", 561 - "MetricExpr": "(PM_CMPLU_STALL_VDP - PM_CMPLU_STALL_VDPLONG)/PM_RUN_INST_CMPL", 561 + "MetricExpr": "vdp_stall_cpi - vdplong_stall_cpi", 562 562 "MetricGroup": "cpi_breakdown", 563 563 "MetricName": "vdp_other_stall_cpi" 564 564 }, ··· 575 575 "MetricName": "vdplong_stall_cpi" 576 576 }, 577 577 { 578 - "MetricExpr": "(PM_CMPLU_STALL_VFXU + PM_CMPLU_STALL_VDP)/PM_RUN_INST_CMPL", 578 + "MetricExpr": "vfxu_stall_cpi + vdp_stall_cpi", 579 579 "MetricGroup": "cpi_breakdown", 580 580 "MetricName": "vector_stall_cpi" 581 581 }, ··· 587 587 }, 588 588 { 589 589 "BriefDescription": "Vector stalls due to small latency integer ops", 590 - "MetricExpr": "(PM_CMPLU_STALL_VFXU - PM_CMPLU_STALL_VFXLONG)/PM_RUN_INST_CMPL", 590 + "MetricExpr": "vfxu_stall_cpi - vfxlong_stall_cpi", 591 591 "MetricGroup": "cpi_breakdown", 592 592 "MetricName": "vfxu_other_stall_cpi" 593 593 }, ··· 1844 1844 }, 1845 1845 { 1846 1846 "BriefDescription": "% of DL1 reloads from Private L3, other core per Inst", 1847 - "MetricExpr": "(PM_DATA_FROM_L31_MOD + PM_DATA_FROM_L31_SHR) * 100 / PM_RUN_INST_CMPL", 1847 + "MetricExpr": "dl1_reload_from_l31_mod_rate_percent + dl1_reload_from_l31_shr_rate_percent", 1848 1848 "MetricName": "dl1_reload_from_l31_rate_percent" 1849 1849 }, 1850 1850 { ··· 1979 1979 }, 1980 1980 { 1981 1981 "BriefDescription": "Completion stall because a different thread was using the completion pipe", 1982 - "MetricExpr": "(PM_CMPLU_STALL_THRD - PM_CMPLU_STALL_EXCEPTION - PM_CMPLU_STALL_ANY_SYNC - PM_CMPLU_STALL_SYNC_PMU_INT - PM_CMPLU_STALL_SPEC_FINISH - PM_CMPLU_STALL_FLUSH_ANY_THREAD - PM_CMPLU_STALL_LSU_FLUSH_NEXT - PM_CMPLU_STALL_NESTED_TBEGIN - PM_CMPLU_STALL_NESTED_TEND - PM_CMPLU_STALL_MTFPSCR)/PM_RUN_INST_CMPL", 1982 + "MetricExpr": "thread_block_stall_cpi - exception_stall_cpi - any_sync_stall_cpi - sync_pmu_int_stall_cpi - spec_finish_stall_cpi - flush_any_thread_stall_cpi - lsu_flush_next_stall_cpi - nested_tbegin_stall_cpi - nested_tend_stall_cpi - mtfpscr_stall_cpi", 1983 1983 "MetricName": "other_thread_cmpl_stall" 1984 1984 }, 1985 1985 {
+2 -2
tools/perf/tests/shell/record+script_probe_vfs_getname.sh
··· 20 20 21 21 record_open_file() { 22 22 echo "Recording open file:" 23 - perf record -o ${perfdata} -e probe:vfs_getname touch $file 23 + perf record -o ${perfdata} -e probe:vfs_getname\* touch $file 24 24 } 25 25 26 26 perf_script_filenames() { 27 27 echo "Looking at perf.data file for vfs_getname records for the file we touched:" 28 28 perf script -i ${perfdata} | \ 29 - egrep " +touch +[0-9]+ +\[[0-9]+\] +[0-9]+\.[0-9]+: +probe:vfs_getname: +\([[:xdigit:]]+\) +pathname=\"${file}\"" 29 + egrep " +touch +[0-9]+ +\[[0-9]+\] +[0-9]+\.[0-9]+: +probe:vfs_getname[_0-9]*: +\([[:xdigit:]]+\) +pathname=\"${file}\"" 30 30 } 31 31 32 32 add_probe_vfs_getname || skip_if_no_debuginfo
+442
tools/perf/trace/beauty/include/linux/socket.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + #ifndef _LINUX_SOCKET_H 3 + #define _LINUX_SOCKET_H 4 + 5 + 6 + #include <asm/socket.h> /* arch-dependent defines */ 7 + #include <linux/sockios.h> /* the SIOCxxx I/O controls */ 8 + #include <linux/uio.h> /* iovec support */ 9 + #include <linux/types.h> /* pid_t */ 10 + #include <linux/compiler.h> /* __user */ 11 + #include <uapi/linux/socket.h> 12 + 13 + struct file; 14 + struct pid; 15 + struct cred; 16 + struct socket; 17 + 18 + #define __sockaddr_check_size(size) \ 19 + BUILD_BUG_ON(((size) > sizeof(struct __kernel_sockaddr_storage))) 20 + 21 + #ifdef CONFIG_PROC_FS 22 + struct seq_file; 23 + extern void socket_seq_show(struct seq_file *seq); 24 + #endif 25 + 26 + typedef __kernel_sa_family_t sa_family_t; 27 + 28 + /* 29 + * 1003.1g requires sa_family_t and that sa_data is char. 30 + */ 31 + 32 + struct sockaddr { 33 + sa_family_t sa_family; /* address family, AF_xxx */ 34 + char sa_data[14]; /* 14 bytes of protocol address */ 35 + }; 36 + 37 + struct linger { 38 + int l_onoff; /* Linger active */ 39 + int l_linger; /* How long to linger for */ 40 + }; 41 + 42 + #define sockaddr_storage __kernel_sockaddr_storage 43 + 44 + /* 45 + * As we do 4.4BSD message passing we use a 4.4BSD message passing 46 + * system, not 4.3. Thus msg_accrights(len) are now missing. They 47 + * belong in an obscure libc emulation or the bin. 48 + */ 49 + 50 + struct msghdr { 51 + void *msg_name; /* ptr to socket address structure */ 52 + int msg_namelen; /* size of socket address structure */ 53 + struct iov_iter msg_iter; /* data */ 54 + 55 + /* 56 + * Ancillary data. msg_control_user is the user buffer used for the 57 + * recv* side when msg_control_is_user is set, msg_control is the kernel 58 + * buffer used for all other cases. 59 + */ 60 + union { 61 + void *msg_control; 62 + void __user *msg_control_user; 63 + }; 64 + bool msg_control_is_user : 1; 65 + __kernel_size_t msg_controllen; /* ancillary data buffer length */ 66 + unsigned int msg_flags; /* flags on received message */ 67 + struct kiocb *msg_iocb; /* ptr to iocb for async requests */ 68 + }; 69 + 70 + struct user_msghdr { 71 + void __user *msg_name; /* ptr to socket address structure */ 72 + int msg_namelen; /* size of socket address structure */ 73 + struct iovec __user *msg_iov; /* scatter/gather array */ 74 + __kernel_size_t msg_iovlen; /* # elements in msg_iov */ 75 + void __user *msg_control; /* ancillary data */ 76 + __kernel_size_t msg_controllen; /* ancillary data buffer length */ 77 + unsigned int msg_flags; /* flags on received message */ 78 + }; 79 + 80 + /* For recvmmsg/sendmmsg */ 81 + struct mmsghdr { 82 + struct user_msghdr msg_hdr; 83 + unsigned int msg_len; 84 + }; 85 + 86 + /* 87 + * POSIX 1003.1g - ancillary data object information 88 + * Ancillary data consits of a sequence of pairs of 89 + * (cmsghdr, cmsg_data[]) 90 + */ 91 + 92 + struct cmsghdr { 93 + __kernel_size_t cmsg_len; /* data byte count, including hdr */ 94 + int cmsg_level; /* originating protocol */ 95 + int cmsg_type; /* protocol-specific type */ 96 + }; 97 + 98 + /* 99 + * Ancillary data object information MACROS 100 + * Table 5-14 of POSIX 1003.1g 101 + */ 102 + 103 + #define __CMSG_NXTHDR(ctl, len, cmsg) __cmsg_nxthdr((ctl),(len),(cmsg)) 104 + #define CMSG_NXTHDR(mhdr, cmsg) cmsg_nxthdr((mhdr), (cmsg)) 105 + 106 + #define CMSG_ALIGN(len) ( ((len)+sizeof(long)-1) & ~(sizeof(long)-1) ) 107 + 108 + #define CMSG_DATA(cmsg) \ 109 + ((void *)(cmsg) + sizeof(struct cmsghdr)) 110 + #define CMSG_USER_DATA(cmsg) \ 111 + ((void __user *)(cmsg) + sizeof(struct cmsghdr)) 112 + #define CMSG_SPACE(len) (sizeof(struct cmsghdr) + CMSG_ALIGN(len)) 113 + #define CMSG_LEN(len) (sizeof(struct cmsghdr) + (len)) 114 + 115 + #define __CMSG_FIRSTHDR(ctl,len) ((len) >= sizeof(struct cmsghdr) ? \ 116 + (struct cmsghdr *)(ctl) : \ 117 + (struct cmsghdr *)NULL) 118 + #define CMSG_FIRSTHDR(msg) __CMSG_FIRSTHDR((msg)->msg_control, (msg)->msg_controllen) 119 + #define CMSG_OK(mhdr, cmsg) ((cmsg)->cmsg_len >= sizeof(struct cmsghdr) && \ 120 + (cmsg)->cmsg_len <= (unsigned long) \ 121 + ((mhdr)->msg_controllen - \ 122 + ((char *)(cmsg) - (char *)(mhdr)->msg_control))) 123 + #define for_each_cmsghdr(cmsg, msg) \ 124 + for (cmsg = CMSG_FIRSTHDR(msg); \ 125 + cmsg; \ 126 + cmsg = CMSG_NXTHDR(msg, cmsg)) 127 + 128 + /* 129 + * Get the next cmsg header 130 + * 131 + * PLEASE, do not touch this function. If you think, that it is 132 + * incorrect, grep kernel sources and think about consequences 133 + * before trying to improve it. 134 + * 135 + * Now it always returns valid, not truncated ancillary object 136 + * HEADER. But caller still MUST check, that cmsg->cmsg_len is 137 + * inside range, given by msg->msg_controllen before using 138 + * ancillary object DATA. --ANK (980731) 139 + */ 140 + 141 + static inline struct cmsghdr * __cmsg_nxthdr(void *__ctl, __kernel_size_t __size, 142 + struct cmsghdr *__cmsg) 143 + { 144 + struct cmsghdr * __ptr; 145 + 146 + __ptr = (struct cmsghdr*)(((unsigned char *) __cmsg) + CMSG_ALIGN(__cmsg->cmsg_len)); 147 + if ((unsigned long)((char*)(__ptr+1) - (char *) __ctl) > __size) 148 + return (struct cmsghdr *)0; 149 + 150 + return __ptr; 151 + } 152 + 153 + static inline struct cmsghdr * cmsg_nxthdr (struct msghdr *__msg, struct cmsghdr *__cmsg) 154 + { 155 + return __cmsg_nxthdr(__msg->msg_control, __msg->msg_controllen, __cmsg); 156 + } 157 + 158 + static inline size_t msg_data_left(struct msghdr *msg) 159 + { 160 + return iov_iter_count(&msg->msg_iter); 161 + } 162 + 163 + /* "Socket"-level control message types: */ 164 + 165 + #define SCM_RIGHTS 0x01 /* rw: access rights (array of int) */ 166 + #define SCM_CREDENTIALS 0x02 /* rw: struct ucred */ 167 + #define SCM_SECURITY 0x03 /* rw: security label */ 168 + 169 + struct ucred { 170 + __u32 pid; 171 + __u32 uid; 172 + __u32 gid; 173 + }; 174 + 175 + /* Supported address families. */ 176 + #define AF_UNSPEC 0 177 + #define AF_UNIX 1 /* Unix domain sockets */ 178 + #define AF_LOCAL 1 /* POSIX name for AF_UNIX */ 179 + #define AF_INET 2 /* Internet IP Protocol */ 180 + #define AF_AX25 3 /* Amateur Radio AX.25 */ 181 + #define AF_IPX 4 /* Novell IPX */ 182 + #define AF_APPLETALK 5 /* AppleTalk DDP */ 183 + #define AF_NETROM 6 /* Amateur Radio NET/ROM */ 184 + #define AF_BRIDGE 7 /* Multiprotocol bridge */ 185 + #define AF_ATMPVC 8 /* ATM PVCs */ 186 + #define AF_X25 9 /* Reserved for X.25 project */ 187 + #define AF_INET6 10 /* IP version 6 */ 188 + #define AF_ROSE 11 /* Amateur Radio X.25 PLP */ 189 + #define AF_DECnet 12 /* Reserved for DECnet project */ 190 + #define AF_NETBEUI 13 /* Reserved for 802.2LLC project*/ 191 + #define AF_SECURITY 14 /* Security callback pseudo AF */ 192 + #define AF_KEY 15 /* PF_KEY key management API */ 193 + #define AF_NETLINK 16 194 + #define AF_ROUTE AF_NETLINK /* Alias to emulate 4.4BSD */ 195 + #define AF_PACKET 17 /* Packet family */ 196 + #define AF_ASH 18 /* Ash */ 197 + #define AF_ECONET 19 /* Acorn Econet */ 198 + #define AF_ATMSVC 20 /* ATM SVCs */ 199 + #define AF_RDS 21 /* RDS sockets */ 200 + #define AF_SNA 22 /* Linux SNA Project (nutters!) */ 201 + #define AF_IRDA 23 /* IRDA sockets */ 202 + #define AF_PPPOX 24 /* PPPoX sockets */ 203 + #define AF_WANPIPE 25 /* Wanpipe API Sockets */ 204 + #define AF_LLC 26 /* Linux LLC */ 205 + #define AF_IB 27 /* Native InfiniBand address */ 206 + #define AF_MPLS 28 /* MPLS */ 207 + #define AF_CAN 29 /* Controller Area Network */ 208 + #define AF_TIPC 30 /* TIPC sockets */ 209 + #define AF_BLUETOOTH 31 /* Bluetooth sockets */ 210 + #define AF_IUCV 32 /* IUCV sockets */ 211 + #define AF_RXRPC 33 /* RxRPC sockets */ 212 + #define AF_ISDN 34 /* mISDN sockets */ 213 + #define AF_PHONET 35 /* Phonet sockets */ 214 + #define AF_IEEE802154 36 /* IEEE802154 sockets */ 215 + #define AF_CAIF 37 /* CAIF sockets */ 216 + #define AF_ALG 38 /* Algorithm sockets */ 217 + #define AF_NFC 39 /* NFC sockets */ 218 + #define AF_VSOCK 40 /* vSockets */ 219 + #define AF_KCM 41 /* Kernel Connection Multiplexor*/ 220 + #define AF_QIPCRTR 42 /* Qualcomm IPC Router */ 221 + #define AF_SMC 43 /* smc sockets: reserve number for 222 + * PF_SMC protocol family that 223 + * reuses AF_INET address family 224 + */ 225 + #define AF_XDP 44 /* XDP sockets */ 226 + 227 + #define AF_MAX 45 /* For now.. */ 228 + 229 + /* Protocol families, same as address families. */ 230 + #define PF_UNSPEC AF_UNSPEC 231 + #define PF_UNIX AF_UNIX 232 + #define PF_LOCAL AF_LOCAL 233 + #define PF_INET AF_INET 234 + #define PF_AX25 AF_AX25 235 + #define PF_IPX AF_IPX 236 + #define PF_APPLETALK AF_APPLETALK 237 + #define PF_NETROM AF_NETROM 238 + #define PF_BRIDGE AF_BRIDGE 239 + #define PF_ATMPVC AF_ATMPVC 240 + #define PF_X25 AF_X25 241 + #define PF_INET6 AF_INET6 242 + #define PF_ROSE AF_ROSE 243 + #define PF_DECnet AF_DECnet 244 + #define PF_NETBEUI AF_NETBEUI 245 + #define PF_SECURITY AF_SECURITY 246 + #define PF_KEY AF_KEY 247 + #define PF_NETLINK AF_NETLINK 248 + #define PF_ROUTE AF_ROUTE 249 + #define PF_PACKET AF_PACKET 250 + #define PF_ASH AF_ASH 251 + #define PF_ECONET AF_ECONET 252 + #define PF_ATMSVC AF_ATMSVC 253 + #define PF_RDS AF_RDS 254 + #define PF_SNA AF_SNA 255 + #define PF_IRDA AF_IRDA 256 + #define PF_PPPOX AF_PPPOX 257 + #define PF_WANPIPE AF_WANPIPE 258 + #define PF_LLC AF_LLC 259 + #define PF_IB AF_IB 260 + #define PF_MPLS AF_MPLS 261 + #define PF_CAN AF_CAN 262 + #define PF_TIPC AF_TIPC 263 + #define PF_BLUETOOTH AF_BLUETOOTH 264 + #define PF_IUCV AF_IUCV 265 + #define PF_RXRPC AF_RXRPC 266 + #define PF_ISDN AF_ISDN 267 + #define PF_PHONET AF_PHONET 268 + #define PF_IEEE802154 AF_IEEE802154 269 + #define PF_CAIF AF_CAIF 270 + #define PF_ALG AF_ALG 271 + #define PF_NFC AF_NFC 272 + #define PF_VSOCK AF_VSOCK 273 + #define PF_KCM AF_KCM 274 + #define PF_QIPCRTR AF_QIPCRTR 275 + #define PF_SMC AF_SMC 276 + #define PF_XDP AF_XDP 277 + #define PF_MAX AF_MAX 278 + 279 + /* Maximum queue length specifiable by listen. */ 280 + #define SOMAXCONN 4096 281 + 282 + /* Flags we can use with send/ and recv. 283 + Added those for 1003.1g not all are supported yet 284 + */ 285 + 286 + #define MSG_OOB 1 287 + #define MSG_PEEK 2 288 + #define MSG_DONTROUTE 4 289 + #define MSG_TRYHARD 4 /* Synonym for MSG_DONTROUTE for DECnet */ 290 + #define MSG_CTRUNC 8 291 + #define MSG_PROBE 0x10 /* Do not send. Only probe path f.e. for MTU */ 292 + #define MSG_TRUNC 0x20 293 + #define MSG_DONTWAIT 0x40 /* Nonblocking io */ 294 + #define MSG_EOR 0x80 /* End of record */ 295 + #define MSG_WAITALL 0x100 /* Wait for a full request */ 296 + #define MSG_FIN 0x200 297 + #define MSG_SYN 0x400 298 + #define MSG_CONFIRM 0x800 /* Confirm path validity */ 299 + #define MSG_RST 0x1000 300 + #define MSG_ERRQUEUE 0x2000 /* Fetch message from error queue */ 301 + #define MSG_NOSIGNAL 0x4000 /* Do not generate SIGPIPE */ 302 + #define MSG_MORE 0x8000 /* Sender will send more */ 303 + #define MSG_WAITFORONE 0x10000 /* recvmmsg(): block until 1+ packets avail */ 304 + #define MSG_SENDPAGE_NOPOLICY 0x10000 /* sendpage() internal : do no apply policy */ 305 + #define MSG_SENDPAGE_NOTLAST 0x20000 /* sendpage() internal : not the last page */ 306 + #define MSG_BATCH 0x40000 /* sendmmsg(): more messages coming */ 307 + #define MSG_EOF MSG_FIN 308 + #define MSG_NO_SHARED_FRAGS 0x80000 /* sendpage() internal : page frags are not shared */ 309 + #define MSG_SENDPAGE_DECRYPTED 0x100000 /* sendpage() internal : page may carry 310 + * plain text and require encryption 311 + */ 312 + 313 + #define MSG_ZEROCOPY 0x4000000 /* Use user data in kernel path */ 314 + #define MSG_FASTOPEN 0x20000000 /* Send data in TCP SYN */ 315 + #define MSG_CMSG_CLOEXEC 0x40000000 /* Set close_on_exec for file 316 + descriptor received through 317 + SCM_RIGHTS */ 318 + #if defined(CONFIG_COMPAT) 319 + #define MSG_CMSG_COMPAT 0x80000000 /* This message needs 32 bit fixups */ 320 + #else 321 + #define MSG_CMSG_COMPAT 0 /* We never have 32 bit fixups */ 322 + #endif 323 + 324 + 325 + /* Setsockoptions(2) level. Thanks to BSD these must match IPPROTO_xxx */ 326 + #define SOL_IP 0 327 + /* #define SOL_ICMP 1 No-no-no! Due to Linux :-) we cannot use SOL_ICMP=1 */ 328 + #define SOL_TCP 6 329 + #define SOL_UDP 17 330 + #define SOL_IPV6 41 331 + #define SOL_ICMPV6 58 332 + #define SOL_SCTP 132 333 + #define SOL_UDPLITE 136 /* UDP-Lite (RFC 3828) */ 334 + #define SOL_RAW 255 335 + #define SOL_IPX 256 336 + #define SOL_AX25 257 337 + #define SOL_ATALK 258 338 + #define SOL_NETROM 259 339 + #define SOL_ROSE 260 340 + #define SOL_DECNET 261 341 + #define SOL_X25 262 342 + #define SOL_PACKET 263 343 + #define SOL_ATM 264 /* ATM layer (cell level) */ 344 + #define SOL_AAL 265 /* ATM Adaption Layer (packet level) */ 345 + #define SOL_IRDA 266 346 + #define SOL_NETBEUI 267 347 + #define SOL_LLC 268 348 + #define SOL_DCCP 269 349 + #define SOL_NETLINK 270 350 + #define SOL_TIPC 271 351 + #define SOL_RXRPC 272 352 + #define SOL_PPPOL2TP 273 353 + #define SOL_BLUETOOTH 274 354 + #define SOL_PNPIPE 275 355 + #define SOL_RDS 276 356 + #define SOL_IUCV 277 357 + #define SOL_CAIF 278 358 + #define SOL_ALG 279 359 + #define SOL_NFC 280 360 + #define SOL_KCM 281 361 + #define SOL_TLS 282 362 + #define SOL_XDP 283 363 + 364 + /* IPX options */ 365 + #define IPX_TYPE 1 366 + 367 + extern int move_addr_to_kernel(void __user *uaddr, int ulen, struct sockaddr_storage *kaddr); 368 + extern int put_cmsg(struct msghdr*, int level, int type, int len, void *data); 369 + 370 + struct timespec64; 371 + struct __kernel_timespec; 372 + struct old_timespec32; 373 + 374 + struct scm_timestamping_internal { 375 + struct timespec64 ts[3]; 376 + }; 377 + 378 + extern void put_cmsg_scm_timestamping64(struct msghdr *msg, struct scm_timestamping_internal *tss); 379 + extern void put_cmsg_scm_timestamping(struct msghdr *msg, struct scm_timestamping_internal *tss); 380 + 381 + /* The __sys_...msg variants allow MSG_CMSG_COMPAT iff 382 + * forbid_cmsg_compat==false 383 + */ 384 + extern long __sys_recvmsg(int fd, struct user_msghdr __user *msg, 385 + unsigned int flags, bool forbid_cmsg_compat); 386 + extern long __sys_sendmsg(int fd, struct user_msghdr __user *msg, 387 + unsigned int flags, bool forbid_cmsg_compat); 388 + extern int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, 389 + unsigned int vlen, unsigned int flags, 390 + struct __kernel_timespec __user *timeout, 391 + struct old_timespec32 __user *timeout32); 392 + extern int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, 393 + unsigned int vlen, unsigned int flags, 394 + bool forbid_cmsg_compat); 395 + extern long __sys_sendmsg_sock(struct socket *sock, struct msghdr *msg, 396 + unsigned int flags); 397 + extern long __sys_recvmsg_sock(struct socket *sock, struct msghdr *msg, 398 + struct user_msghdr __user *umsg, 399 + struct sockaddr __user *uaddr, 400 + unsigned int flags); 401 + extern int sendmsg_copy_msghdr(struct msghdr *msg, 402 + struct user_msghdr __user *umsg, unsigned flags, 403 + struct iovec **iov); 404 + extern int recvmsg_copy_msghdr(struct msghdr *msg, 405 + struct user_msghdr __user *umsg, unsigned flags, 406 + struct sockaddr __user **uaddr, 407 + struct iovec **iov); 408 + extern int __copy_msghdr_from_user(struct msghdr *kmsg, 409 + struct user_msghdr __user *umsg, 410 + struct sockaddr __user **save_addr, 411 + struct iovec __user **uiov, size_t *nsegs); 412 + 413 + /* helpers which do the actual work for syscalls */ 414 + extern int __sys_recvfrom(int fd, void __user *ubuf, size_t size, 415 + unsigned int flags, struct sockaddr __user *addr, 416 + int __user *addr_len); 417 + extern int __sys_sendto(int fd, void __user *buff, size_t len, 418 + unsigned int flags, struct sockaddr __user *addr, 419 + int addr_len); 420 + extern int __sys_accept4_file(struct file *file, unsigned file_flags, 421 + struct sockaddr __user *upeer_sockaddr, 422 + int __user *upeer_addrlen, int flags, 423 + unsigned long nofile); 424 + extern int __sys_accept4(int fd, struct sockaddr __user *upeer_sockaddr, 425 + int __user *upeer_addrlen, int flags); 426 + extern int __sys_socket(int family, int type, int protocol); 427 + extern int __sys_bind(int fd, struct sockaddr __user *umyaddr, int addrlen); 428 + extern int __sys_connect_file(struct file *file, struct sockaddr_storage *addr, 429 + int addrlen, int file_flags); 430 + extern int __sys_connect(int fd, struct sockaddr __user *uservaddr, 431 + int addrlen); 432 + extern int __sys_listen(int fd, int backlog); 433 + extern int __sys_getsockname(int fd, struct sockaddr __user *usockaddr, 434 + int __user *usockaddr_len); 435 + extern int __sys_getpeername(int fd, struct sockaddr __user *usockaddr, 436 + int __user *usockaddr_len); 437 + extern int __sys_socketpair(int family, int type, int protocol, 438 + int __user *usockvec); 439 + extern int __sys_shutdown(int fd, int how); 440 + 441 + extern struct ns_common *get_net_ns(struct ns_common *ns); 442 + #endif /* _LINUX_SOCKET_H */
+1 -8
tools/perf/trace/beauty/sockaddr.c
··· 7 7 #include <sys/un.h> 8 8 #include <arpa/inet.h> 9 9 10 - static const char *socket_families[] = { 11 - "UNSPEC", "LOCAL", "INET", "AX25", "IPX", "APPLETALK", "NETROM", 12 - "BRIDGE", "ATMPVC", "X25", "INET6", "ROSE", "DECnet", "NETBEUI", 13 - "SECURITY", "KEY", "NETLINK", "PACKET", "ASH", "ECONET", "ATMSVC", 14 - "RDS", "SNA", "IRDA", "PPPOX", "WANPIPE", "LLC", "IB", "CAN", "TIPC", 15 - "BLUETOOTH", "IUCV", "RXRPC", "ISDN", "PHONET", "IEEE802154", "CAIF", 16 - "ALG", "NFC", "VSOCK", 17 - }; 10 + #include "trace/beauty/generated/socket_arrays.c" 18 11 DEFINE_STRARRAY(socket_families, "PF_"); 19 12 20 13 static size_t af_inet__scnprintf(struct sockaddr *sa, char *bf, size_t size)
+24
tools/perf/trace/beauty/socket.sh
··· 1 + #!/bin/sh 2 + # SPDX-License-Identifier: LGPL-2.1 3 + 4 + # This one uses a copy from the kernel sources headers that is in a 5 + # place used just for these tools/perf/beauty/ usage, we shouldn't not 6 + # put it in tools/include/linux otherwise they would be used in the 7 + # normal compiler building process and would drag needless stuff from the 8 + # kernel. 9 + 10 + # When what these scripts need is already in tools/include/ then use it, 11 + # otherwise grab and check the copy from the kernel sources just for these 12 + # string table building scripts. 13 + 14 + [ $# -eq 1 ] && header_dir=$1 || header_dir=tools/perf/trace/beauty/include/linux/ 15 + 16 + printf "static const char *socket_families[] = {\n" 17 + # #define AF_LOCAL 1 /* POSIX name for AF_UNIX */ 18 + regex='^#define[[:space:]]+AF_(\w+)[[:space:]]+([[:digit:]]+).*' 19 + 20 + egrep $regex ${header_dir}/socket.h | \ 21 + sed -r "s/$regex/\2 \1/g" | \ 22 + xargs printf "\t[%s] = \"%s\",\n" | \ 23 + egrep -v "\"(UNIX|MAX)\"" 24 + printf "};\n"
+1
tools/perf/util/Build
··· 117 117 perf-y += parse-branch-options.o 118 118 perf-y += dump-insn.o 119 119 perf-y += parse-regs-options.o 120 + perf-y += parse-sublevel-options.o 120 121 perf-y += term.o 121 122 perf-y += help-unknown-cmd.o 122 123 perf-y += mem-events.o
+19
tools/perf/util/build-id.c
··· 31 31 #include "probe-file.h" 32 32 #include "strlist.h" 33 33 34 + #ifdef HAVE_DEBUGINFOD_SUPPORT 35 + #include <elfutils/debuginfod.h> 36 + #endif 37 + 34 38 #include <linux/ctype.h> 35 39 #include <linux/zalloc.h> 36 40 ··· 640 636 if (realname && access(realname, R_OK)) 641 637 zfree(&realname); 642 638 nsinfo__mountns_exit(&nsc); 639 + 640 + #ifdef HAVE_DEBUGINFOD_SUPPORT 641 + if (realname == NULL) { 642 + debuginfod_client* c = debuginfod_begin(); 643 + if (c != NULL) { 644 + int fd = debuginfod_find_debuginfo(c, 645 + (const unsigned char*)sbuild_id, 0, 646 + &realname); 647 + if (fd >= 0) 648 + close(fd); /* retaining reference by realname */ 649 + debuginfod_end(c); 650 + } 651 + } 652 + #endif 653 + 643 654 out: 644 655 free(debugfile); 645 656 return realname;
+17 -44
tools/perf/util/debug.c
··· 20 20 #include "target.h" 21 21 #include "ui/helpline.h" 22 22 #include "ui/ui.h" 23 + #include "util/parse-sublevel-options.h" 23 24 24 25 #include <linux/ctype.h> 25 26 ··· 174 173 trace_event_printer, event); 175 174 } 176 175 177 - static struct debug_variable { 178 - const char *name; 179 - int *ptr; 180 - } debug_variables[] = { 181 - { .name = "verbose", .ptr = &verbose }, 182 - { .name = "ordered-events", .ptr = &debug_ordered_events}, 183 - { .name = "stderr", .ptr = &redirect_to_stderr}, 184 - { .name = "data-convert", .ptr = &debug_data_convert }, 185 - { .name = "perf-event-open", .ptr = &debug_peo_args }, 176 + static struct sublevel_option debug_opts[] = { 177 + { .name = "verbose", .value_ptr = &verbose }, 178 + { .name = "ordered-events", .value_ptr = &debug_ordered_events}, 179 + { .name = "stderr", .value_ptr = &redirect_to_stderr}, 180 + { .name = "data-convert", .value_ptr = &debug_data_convert }, 181 + { .name = "perf-event-open", .value_ptr = &debug_peo_args }, 186 182 { .name = NULL, } 187 183 }; 188 184 189 185 int perf_debug_option(const char *str) 190 186 { 191 - struct debug_variable *var = &debug_variables[0]; 192 - char *vstr, *s = strdup(str); 193 - int v = 1; 187 + int ret; 194 188 195 - vstr = strchr(s, '='); 196 - if (vstr) 197 - *vstr++ = 0; 189 + ret = perf_parse_sublevel_options(str, debug_opts); 190 + if (ret) 191 + return ret; 198 192 199 - while (var->name) { 200 - if (!strcmp(s, var->name)) 201 - break; 202 - var++; 203 - } 193 + /* Allow only verbose value in range (0, 10), otherwise set 0. */ 194 + verbose = (verbose < 0) || (verbose > 10) ? 0 : verbose; 204 195 205 - if (!var->name) { 206 - pr_err("Unknown debug variable name '%s'\n", s); 207 - free(s); 208 - return -1; 209 - } 210 - 211 - if (vstr) { 212 - v = atoi(vstr); 213 - /* 214 - * Allow only values in range (0, 10), 215 - * otherwise set 0. 216 - */ 217 - v = (v < 0) || (v > 10) ? 0 : v; 218 - } 219 - 220 - if (quiet) 221 - v = -1; 222 - 223 - *var->ptr = v; 224 - free(s); 225 196 return 0; 226 197 } 227 198 228 199 int perf_quiet_option(void) 229 200 { 230 - struct debug_variable *var = &debug_variables[0]; 201 + struct sublevel_option *opt = &debug_opts[0]; 231 202 232 203 /* disable all debug messages */ 233 - while (var->name) { 234 - *var->ptr = -1; 235 - var++; 204 + while (opt->name) { 205 + *opt->value_ptr = -1; 206 + opt++; 236 207 } 237 208 238 209 return 0;
+1 -1
tools/perf/util/dso.c
··· 1265 1265 dso->has_build_id = 0; 1266 1266 dso->has_srcline = 1; 1267 1267 dso->a2l_fails = 1; 1268 - dso->kernel = DSO_TYPE_USER; 1268 + dso->kernel = DSO_SPACE__USER; 1269 1269 dso->needs_swap = DSO_SWAP__UNSET; 1270 1270 dso->comp = COMP_ID__NONE; 1271 1271 RB_CLEAR_NODE(&dso->rb_node);
+5 -5
tools/perf/util/dso.h
··· 46 46 DSO_BINARY_TYPE__NOT_FOUND, 47 47 }; 48 48 49 - enum dso_kernel_type { 50 - DSO_TYPE_USER = 0, 51 - DSO_TYPE_KERNEL, 52 - DSO_TYPE_GUEST_KERNEL 49 + enum dso_space_type { 50 + DSO_SPACE__USER = 0, 51 + DSO_SPACE__KERNEL, 52 + DSO_SPACE__KERNEL_GUEST 53 53 }; 54 54 55 55 enum dso_swap_type { ··· 160 160 void *a2l; 161 161 char *symsrc_filename; 162 162 unsigned int a2l_fails; 163 - enum dso_kernel_type kernel; 163 + enum dso_space_type kernel; 164 164 enum dso_swap_type needs_swap; 165 165 enum dso_binary_type symtab_type; 166 166 enum dso_binary_type binary_type;
+6 -7
tools/perf/util/header.c
··· 2056 2056 struct machine *machine; 2057 2057 u16 cpumode; 2058 2058 struct dso *dso; 2059 - enum dso_kernel_type dso_type; 2059 + enum dso_space_type dso_space; 2060 2060 2061 2061 machine = perf_session__findnew_machine(session, bev->pid); 2062 2062 if (!machine) ··· 2066 2066 2067 2067 switch (cpumode) { 2068 2068 case PERF_RECORD_MISC_KERNEL: 2069 - dso_type = DSO_TYPE_KERNEL; 2069 + dso_space = DSO_SPACE__KERNEL; 2070 2070 break; 2071 2071 case PERF_RECORD_MISC_GUEST_KERNEL: 2072 - dso_type = DSO_TYPE_GUEST_KERNEL; 2072 + dso_space = DSO_SPACE__KERNEL_GUEST; 2073 2073 break; 2074 2074 case PERF_RECORD_MISC_USER: 2075 2075 case PERF_RECORD_MISC_GUEST_USER: 2076 - dso_type = DSO_TYPE_USER; 2076 + dso_space = DSO_SPACE__USER; 2077 2077 break; 2078 2078 default: 2079 2079 goto out; ··· 2085 2085 2086 2086 dso__set_build_id(dso, &bev->build_id); 2087 2087 2088 - if (dso_type != DSO_TYPE_USER) { 2088 + if (dso_space != DSO_SPACE__USER) { 2089 2089 struct kmod_path m = { .name = NULL, }; 2090 2090 2091 2091 if (!kmod_path__parse_name(&m, filename) && m.kmod) 2092 2092 dso__set_module_info(dso, &m, machine); 2093 - else 2094 - dso->kernel = dso_type; 2095 2093 2094 + dso->kernel = dso_space; 2096 2095 free(m.name); 2097 2096 } 2098 2097
+8 -8
tools/perf/util/machine.c
··· 703 703 704 704 dso__set_module_info(dso, m, machine); 705 705 dso__set_long_name(dso, strdup(filename), true); 706 - dso->kernel = DSO_TYPE_KERNEL; 706 + dso->kernel = DSO_SPACE__KERNEL; 707 707 } 708 708 709 709 dso__get(dso); ··· 753 753 struct dso *dso = dso__new(event->ksymbol.name); 754 754 755 755 if (dso) { 756 - dso->kernel = DSO_TYPE_KERNEL; 756 + dso->kernel = DSO_SPACE__KERNEL; 757 757 map = map__new2(0, dso); 758 758 } 759 759 ··· 971 971 vmlinux_name = symbol_conf.vmlinux_name; 972 972 973 973 kernel = machine__findnew_kernel(machine, vmlinux_name, 974 - "[kernel]", DSO_TYPE_KERNEL); 974 + "[kernel]", DSO_SPACE__KERNEL); 975 975 } else { 976 976 if (symbol_conf.default_guest_vmlinux_name) 977 977 vmlinux_name = symbol_conf.default_guest_vmlinux_name; 978 978 979 979 kernel = machine__findnew_kernel(machine, vmlinux_name, 980 980 "[guest.kernel]", 981 - DSO_TYPE_GUEST_KERNEL); 981 + DSO_SPACE__KERNEL_GUEST); 982 982 } 983 983 984 984 if (kernel != NULL && (!kernel->has_build_id)) ··· 1606 1606 union perf_event *event) 1607 1607 { 1608 1608 struct map *map; 1609 - enum dso_kernel_type kernel_type; 1609 + enum dso_space_type dso_space; 1610 1610 bool is_kernel_mmap; 1611 1611 1612 1612 /* If we have maps from kcore then we do not need or want any others */ ··· 1614 1614 return 0; 1615 1615 1616 1616 if (machine__is_host(machine)) 1617 - kernel_type = DSO_TYPE_KERNEL; 1617 + dso_space = DSO_SPACE__KERNEL; 1618 1618 else 1619 - kernel_type = DSO_TYPE_GUEST_KERNEL; 1619 + dso_space = DSO_SPACE__KERNEL_GUEST; 1620 1620 1621 1621 is_kernel_mmap = memcmp(event->mmap.filename, 1622 1622 machine->mmap_name, ··· 1676 1676 if (kernel == NULL) 1677 1677 goto out_problem; 1678 1678 1679 - kernel->kernel = kernel_type; 1679 + kernel->kernel = dso_space; 1680 1680 if (__machine__create_kernel_maps(machine, kernel) < 0) { 1681 1681 dso__put(kernel); 1682 1682 goto out_problem;
+2 -2
tools/perf/util/map.c
··· 486 486 * kernel modules also have DSO_TYPE_USER in dso->kernel, 487 487 * but all kernel modules are ET_REL, so won't get here. 488 488 */ 489 - if (map->dso->kernel == DSO_TYPE_USER) 489 + if (map->dso->kernel == DSO_SPACE__USER) 490 490 return rip + map->dso->text_offset; 491 491 492 492 return map->unmap_ip(map, rip) - map->reloc; ··· 516 516 * kernel modules also have DSO_TYPE_USER in dso->kernel, 517 517 * but all kernel modules are ET_REL, so won't get here. 518 518 */ 519 - if (map->dso->kernel == DSO_TYPE_USER) 519 + if (map->dso->kernel == DSO_SPACE__USER) 520 520 return map->unmap_ip(map, ip - map->dso->text_offset); 521 521 522 522 return ip + map->reloc;
+70
tools/perf/util/parse-sublevel-options.c
··· 1 + #include <stdlib.h> 2 + #include <stdint.h> 3 + #include <string.h> 4 + #include <stdio.h> 5 + 6 + #include "util/debug.h" 7 + #include "util/parse-sublevel-options.h" 8 + 9 + static int parse_one_sublevel_option(const char *str, 10 + struct sublevel_option *opts) 11 + { 12 + struct sublevel_option *opt = opts; 13 + char *vstr, *s = strdup(str); 14 + int v = 1; 15 + 16 + if (!s) { 17 + pr_err("no memory\n"); 18 + return -1; 19 + } 20 + 21 + vstr = strchr(s, '='); 22 + if (vstr) 23 + *vstr++ = 0; 24 + 25 + while (opt->name) { 26 + if (!strcmp(s, opt->name)) 27 + break; 28 + opt++; 29 + } 30 + 31 + if (!opt->name) { 32 + pr_err("Unknown option name '%s'\n", s); 33 + free(s); 34 + return -1; 35 + } 36 + 37 + if (vstr) 38 + v = atoi(vstr); 39 + 40 + *opt->value_ptr = v; 41 + free(s); 42 + return 0; 43 + } 44 + 45 + /* parse options like --foo a=<n>,b,c... */ 46 + int perf_parse_sublevel_options(const char *str, struct sublevel_option *opts) 47 + { 48 + char *s = strdup(str); 49 + char *p = NULL; 50 + int ret; 51 + 52 + if (!s) { 53 + pr_err("no memory\n"); 54 + return -1; 55 + } 56 + 57 + p = strtok(s, ","); 58 + while (p) { 59 + ret = parse_one_sublevel_option(p, opts); 60 + if (ret) { 61 + free(s); 62 + return ret; 63 + } 64 + 65 + p = strtok(NULL, ","); 66 + } 67 + 68 + free(s); 69 + return 0; 70 + }
+11
tools/perf/util/parse-sublevel-options.h
··· 1 + #ifndef _PERF_PARSE_SUBLEVEL_OPTIONS_H 2 + #define _PERF_PARSE_SUBLEVEL_OPTIONS_H 3 + 4 + struct sublevel_option { 5 + const char *name; 6 + int *value_ptr; 7 + }; 8 + 9 + int perf_parse_sublevel_options(const char *str, struct sublevel_option *opts); 10 + 11 + #endif
+4 -4
tools/perf/util/symbol-elf.c
··· 789 789 if (ss->opdshdr.sh_type != SHT_PROGBITS) 790 790 ss->opdsec = NULL; 791 791 792 - if (dso->kernel == DSO_TYPE_USER) 792 + if (dso->kernel == DSO_SPACE__USER) 793 793 ss->adjust_symbols = true; 794 794 else 795 795 ss->adjust_symbols = elf__needs_adjust_symbols(ehdr); ··· 872 872 * kallsyms and identity maps. Overwrite it to 873 873 * map to the kernel dso. 874 874 */ 875 - if (*remap_kernel && dso->kernel) { 875 + if (*remap_kernel && dso->kernel && !kmodule) { 876 876 *remap_kernel = false; 877 877 map->start = shdr->sh_addr + ref_reloc(kmap); 878 878 map->end = map->start + shdr->sh_size; ··· 1068 1068 * Initial kernel and module mappings do not map to the dso. 1069 1069 * Flag the fixups. 1070 1070 */ 1071 - if (dso->kernel || kmodule) { 1071 + if (dso->kernel) { 1072 1072 remap_kernel = true; 1073 1073 adjust_kernel_syms = dso->adjust_symbols; 1074 1074 } ··· 1130 1130 (sym.st_value & 1)) 1131 1131 --sym.st_value; 1132 1132 1133 - if (dso->kernel || kmodule) { 1133 + if (dso->kernel) { 1134 1134 if (dso__process_kernel_symbol(dso, map, &sym, &shdr, kmaps, kmap, &curr_dso, &curr_map, 1135 1135 section_name, adjust_kernel_syms, kmodule, &remap_kernel)) 1136 1136 goto out_elf_end;
+12 -12
tools/perf/util/symbol.c
··· 808 808 809 809 if (strcmp(curr_map->dso->short_name, module)) { 810 810 if (curr_map != initial_map && 811 - dso->kernel == DSO_TYPE_GUEST_KERNEL && 811 + dso->kernel == DSO_SPACE__KERNEL_GUEST && 812 812 machine__is_default_guest(machine)) { 813 813 /* 814 814 * We assume all symbols of a module are ··· 865 865 goto add_symbol; 866 866 } 867 867 868 - if (dso->kernel == DSO_TYPE_GUEST_KERNEL) 868 + if (dso->kernel == DSO_SPACE__KERNEL_GUEST) 869 869 snprintf(dso_name, sizeof(dso_name), 870 870 "[guest.kernel].%d", 871 871 kernel_range++); ··· 909 909 } 910 910 911 911 if (curr_map != initial_map && 912 - dso->kernel == DSO_TYPE_GUEST_KERNEL && 912 + dso->kernel == DSO_SPACE__KERNEL_GUEST && 913 913 machine__is_default_guest(kmaps->machine)) { 914 914 dso__set_loaded(curr_map->dso); 915 915 } ··· 1387 1387 * Set the data type and long name so that kcore can be read via 1388 1388 * dso__data_read_addr(). 1389 1389 */ 1390 - if (dso->kernel == DSO_TYPE_GUEST_KERNEL) 1390 + if (dso->kernel == DSO_SPACE__KERNEL_GUEST) 1391 1391 dso->binary_type = DSO_BINARY_TYPE__GUEST_KCORE; 1392 1392 else 1393 1393 dso->binary_type = DSO_BINARY_TYPE__KCORE; ··· 1451 1451 symbols__fixup_end(&dso->symbols); 1452 1452 symbols__fixup_duplicate(&dso->symbols); 1453 1453 1454 - if (dso->kernel == DSO_TYPE_GUEST_KERNEL) 1454 + if (dso->kernel == DSO_SPACE__KERNEL_GUEST) 1455 1455 dso->symtab_type = DSO_BINARY_TYPE__GUEST_KALLSYMS; 1456 1456 else 1457 1457 dso->symtab_type = DSO_BINARY_TYPE__KALLSYMS; ··· 1537 1537 case DSO_BINARY_TYPE__MIXEDUP_UBUNTU_DEBUGINFO: 1538 1538 case DSO_BINARY_TYPE__BUILDID_DEBUGINFO: 1539 1539 case DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO: 1540 - return !kmod && dso->kernel == DSO_TYPE_USER; 1540 + return !kmod && dso->kernel == DSO_SPACE__USER; 1541 1541 1542 1542 case DSO_BINARY_TYPE__KALLSYMS: 1543 1543 case DSO_BINARY_TYPE__VMLINUX: 1544 1544 case DSO_BINARY_TYPE__KCORE: 1545 - return dso->kernel == DSO_TYPE_KERNEL; 1545 + return dso->kernel == DSO_SPACE__KERNEL; 1546 1546 1547 1547 case DSO_BINARY_TYPE__GUEST_KALLSYMS: 1548 1548 case DSO_BINARY_TYPE__GUEST_VMLINUX: 1549 1549 case DSO_BINARY_TYPE__GUEST_KCORE: 1550 - return dso->kernel == DSO_TYPE_GUEST_KERNEL; 1550 + return dso->kernel == DSO_SPACE__KERNEL_GUEST; 1551 1551 1552 1552 case DSO_BINARY_TYPE__GUEST_KMODULE: 1553 1553 case DSO_BINARY_TYPE__GUEST_KMODULE_COMP: ··· 1650 1650 dso->symtab_type == DSO_BINARY_TYPE__GUEST_KMODULE_COMP; 1651 1651 1652 1652 if (dso->kernel && !kmod) { 1653 - if (dso->kernel == DSO_TYPE_KERNEL) 1653 + if (dso->kernel == DSO_SPACE__KERNEL) 1654 1654 ret = dso__load_kernel_sym(dso, map); 1655 - else if (dso->kernel == DSO_TYPE_GUEST_KERNEL) 1655 + else if (dso->kernel == DSO_SPACE__KERNEL_GUEST) 1656 1656 ret = dso__load_guest_kernel_sym(dso, map); 1657 1657 1658 1658 machine = map__kmaps(map)->machine; ··· 1882 1882 else 1883 1883 symbol__join_symfs(symfs_vmlinux, vmlinux); 1884 1884 1885 - if (dso->kernel == DSO_TYPE_GUEST_KERNEL) 1885 + if (dso->kernel == DSO_SPACE__KERNEL_GUEST) 1886 1886 symtab_type = DSO_BINARY_TYPE__GUEST_VMLINUX; 1887 1887 else 1888 1888 symtab_type = DSO_BINARY_TYPE__VMLINUX; ··· 1894 1894 symsrc__destroy(&ss); 1895 1895 1896 1896 if (err > 0) { 1897 - if (dso->kernel == DSO_TYPE_GUEST_KERNEL) 1897 + if (dso->kernel == DSO_SPACE__KERNEL_GUEST) 1898 1898 dso->binary_type = DSO_BINARY_TYPE__GUEST_VMLINUX; 1899 1899 else 1900 1900 dso->binary_type = DSO_BINARY_TYPE__VMLINUX;