Commit 713eee84 authored by Linus Torvalds's avatar Linus Torvalds

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()
  ...
parents 50f6c7db 492e4edb
...@@ -13566,6 +13566,7 @@ F: arch/*/kernel/perf_event*.c ...@@ -13566,6 +13566,7 @@ F: arch/*/kernel/perf_event*.c
F: include/linux/perf_event.h F: include/linux/perf_event.h
F: include/uapi/linux/perf_event.h F: include/uapi/linux/perf_event.h
F: kernel/events/* F: kernel/events/*
F: tools/lib/perf/
F: tools/perf/ F: tools/perf/
PERFORMANCE EVENTS SUBSYSTEM ARM64 PMU EVENTS PERFORMANCE EVENTS SUBSYSTEM ARM64 PMU EVENTS
......
...@@ -231,11 +231,13 @@ struct kvm_guest_debug_arch { ...@@ -231,11 +231,13 @@ struct kvm_guest_debug_arch {
#define KVM_SYNC_GSCB (1UL << 9) #define KVM_SYNC_GSCB (1UL << 9)
#define KVM_SYNC_BPBC (1UL << 10) #define KVM_SYNC_BPBC (1UL << 10)
#define KVM_SYNC_ETOKEN (1UL << 11) #define KVM_SYNC_ETOKEN (1UL << 11)
#define KVM_SYNC_DIAG318 (1UL << 12)
#define KVM_SYNC_S390_VALID_FIELDS \ #define KVM_SYNC_S390_VALID_FIELDS \
(KVM_SYNC_PREFIX | KVM_SYNC_GPRS | KVM_SYNC_ACRS | KVM_SYNC_CRS | \ (KVM_SYNC_PREFIX | KVM_SYNC_GPRS | KVM_SYNC_ACRS | KVM_SYNC_CRS | \
KVM_SYNC_ARCH0 | KVM_SYNC_PFAULT | KVM_SYNC_VRS | KVM_SYNC_RICCB | \ KVM_SYNC_ARCH0 | KVM_SYNC_PFAULT | KVM_SYNC_VRS | KVM_SYNC_RICCB | \
KVM_SYNC_FPRS | KVM_SYNC_GSCB | KVM_SYNC_BPBC | KVM_SYNC_ETOKEN) KVM_SYNC_FPRS | KVM_SYNC_GSCB | KVM_SYNC_BPBC | KVM_SYNC_ETOKEN | \
KVM_SYNC_DIAG318)
/* length and alignment of the sdnx as a power of two */ /* length and alignment of the sdnx as a power of two */
#define SDNXC 8 #define SDNXC 8
...@@ -264,7 +266,8 @@ struct kvm_sync_regs { ...@@ -264,7 +266,8 @@ struct kvm_sync_regs {
__u8 reserved2 : 7; __u8 reserved2 : 7;
__u8 padding1[51]; /* riccb needs to be 64byte aligned */ __u8 padding1[51]; /* riccb needs to be 64byte aligned */
__u8 riccb[64]; /* runtime instrumentation controls block */ __u8 riccb[64]; /* runtime instrumentation controls block */
__u8 padding2[192]; /* sdnx needs to be 256byte aligned */ __u64 diag318; /* diagnose 0x318 info */
__u8 padding2[184]; /* sdnx needs to be 256byte aligned */
union { union {
__u8 sdnx[SDNXL]; /* state description annex */ __u8 sdnx[SDNXL]; /* state description annex */
struct { struct {
......
...@@ -8,7 +8,7 @@ endif ...@@ -8,7 +8,7 @@ endif
feature_check = $(eval $(feature_check_code)) feature_check = $(eval $(feature_check_code))
define feature_check_code define feature_check_code
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) 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)
endef endef
feature_set = $(eval $(feature_set_code)) feature_set = $(eval $(feature_set_code))
...@@ -98,7 +98,8 @@ FEATURE_TESTS_EXTRA := \ ...@@ -98,7 +98,8 @@ FEATURE_TESTS_EXTRA := \
llvm-version \ llvm-version \
clang \ clang \
libbpf \ libbpf \
libpfm4 libpfm4 \
libdebuginfod
FEATURE_TESTS ?= $(FEATURE_TESTS_BASIC) FEATURE_TESTS ?= $(FEATURE_TESTS_BASIC)
......
...@@ -26,6 +26,7 @@ FILES= \ ...@@ -26,6 +26,7 @@ FILES= \
test-libelf-gelf_getnote.bin \ test-libelf-gelf_getnote.bin \
test-libelf-getshdrstrndx.bin \ test-libelf-getshdrstrndx.bin \
test-libelf-mmap.bin \ test-libelf-mmap.bin \
test-libdebuginfod.bin \
test-libnuma.bin \ test-libnuma.bin \
test-numa_num_possible_cpus.bin \ test-numa_num_possible_cpus.bin \
test-libperl.bin \ test-libperl.bin \
...@@ -157,6 +158,9 @@ $(OUTPUT)test-libelf-gelf_getnote.bin: ...@@ -157,6 +158,9 @@ $(OUTPUT)test-libelf-gelf_getnote.bin:
$(OUTPUT)test-libelf-getshdrstrndx.bin: $(OUTPUT)test-libelf-getshdrstrndx.bin:
$(BUILD) -lelf $(BUILD) -lelf
$(OUTPUT)test-libdebuginfod.bin:
$(BUILD) -ldebuginfod
$(OUTPUT)test-libnuma.bin: $(OUTPUT)test-libnuma.bin:
$(BUILD) -lnuma $(BUILD) -lnuma
......
// SPDX-License-Identifier: GPL-2.0
#include <elfutils/debuginfod.h>
int main(void)
{
debuginfod_client* c = debuginfod_begin();
return (long)c;
}
...@@ -289,6 +289,7 @@ struct kvm_run { ...@@ -289,6 +289,7 @@ struct kvm_run {
/* KVM_EXIT_FAIL_ENTRY */ /* KVM_EXIT_FAIL_ENTRY */
struct { struct {
__u64 hardware_entry_failure_reason; __u64 hardware_entry_failure_reason;
__u32 cpu;
} fail_entry; } fail_entry;
/* KVM_EXIT_EXCEPTION */ /* KVM_EXIT_EXCEPTION */
struct { struct {
...@@ -1031,6 +1032,9 @@ struct kvm_ppc_resize_hpt { ...@@ -1031,6 +1032,9 @@ struct kvm_ppc_resize_hpt {
#define KVM_CAP_PPC_SECURE_GUEST 181 #define KVM_CAP_PPC_SECURE_GUEST 181
#define KVM_CAP_HALT_POLL 182 #define KVM_CAP_HALT_POLL 182
#define KVM_CAP_ASYNC_PF_INT 183 #define KVM_CAP_ASYNC_PF_INT 183
#define KVM_CAP_LAST_CPU 184
#define KVM_CAP_SMALLER_MAXPHYADDR 185
#define KVM_CAP_S390_DIAG318 186
#ifdef KVM_CAP_IRQ_ROUTING #ifdef KVM_CAP_IRQ_ROUTING
......
...@@ -91,6 +91,8 @@ ...@@ -91,6 +91,8 @@
/* Use message type V2 */ /* Use message type V2 */
#define VHOST_BACKEND_F_IOTLB_MSG_V2 0x1 #define VHOST_BACKEND_F_IOTLB_MSG_V2 0x1
/* IOTLB can accept batching hints */
#define VHOST_BACKEND_F_IOTLB_BATCH 0x2
#define VHOST_SET_BACKEND_FEATURES _IOW(VHOST_VIRTIO, 0x25, __u64) #define VHOST_SET_BACKEND_FEATURES _IOW(VHOST_VIRTIO, 0x25, __u64)
#define VHOST_GET_BACKEND_FEATURES _IOR(VHOST_VIRTIO, 0x26, __u64) #define VHOST_GET_BACKEND_FEATURES _IOR(VHOST_VIRTIO, 0x26, __u64)
......
...@@ -7,13 +7,13 @@ libperf-counting - counting interface ...@@ -7,13 +7,13 @@ libperf-counting - counting interface
DESCRIPTION DESCRIPTION
----------- -----------
The counting interface provides API to meassure and get count for specific perf events. The counting interface provides API to measure and get count for specific perf events.
The following test tries to explain count on `counting.c` example. The following test tries to explain count on `counting.c` example.
It is by no means complete guide to counting, but shows libperf basic API for counting. It is by no means complete guide to counting, but shows libperf basic API for counting.
The `counting.c` comes with libbperf package and can be compiled and run like: The `counting.c` comes with libperf package and can be compiled and run like:
[source,bash] [source,bash]
-- --
...@@ -26,7 +26,8 @@ count 176242, enabled 176242, run 176242 ...@@ -26,7 +26,8 @@ count 176242, enabled 176242, run 176242
It requires root access, because of the `PERF_COUNT_SW_CPU_CLOCK` event, It requires root access, because of the `PERF_COUNT_SW_CPU_CLOCK` event,
which is available only for root. which is available only for root.
The `counting.c` example monitors two events on the current process and displays their count, in a nutshel it: The `counting.c` example monitors two events on the current process and displays
their count, in a nutshell it:
* creates events * creates events
* adds them to the event list * adds them to the event list
...@@ -152,7 +153,7 @@ Configure event list with the thread map and open events: ...@@ -152,7 +153,7 @@ Configure event list with the thread map and open events:
-- --
Both events are created as disabled (note the `disabled = 1` assignment above), Both events are created as disabled (note the `disabled = 1` assignment above),
so we need to enable the whole list explicitely (both events). so we need to enable the whole list explicitly (both events).
From this moment events are counting and we can do our workload. From this moment events are counting and we can do our workload.
...@@ -167,7 +168,8 @@ When we are done we disable the events list. ...@@ -167,7 +168,8 @@ When we are done we disable the events list.
79 perf_evlist__disable(evlist); 79 perf_evlist__disable(evlist);
-- --
Now we need to get the counts from events, following code iterates throught the events list and read counts: Now we need to get the counts from events, following code iterates through the
events list and read counts:
[source,c] [source,c]
-- --
...@@ -178,7 +180,7 @@ Now we need to get the counts from events, following code iterates throught the ...@@ -178,7 +180,7 @@ Now we need to get the counts from events, following code iterates throught the
85 } 85 }
-- --
And finaly cleanup. And finally cleanup.
We close the whole events list (both events) and remove it together with the threads map: We close the whole events list (both events) and remove it together with the threads map:
......
...@@ -8,13 +8,13 @@ libperf-sampling - sampling interface ...@@ -8,13 +8,13 @@ libperf-sampling - sampling interface
DESCRIPTION DESCRIPTION
----------- -----------
The sampling interface provides API to meassure and get count for specific perf events. The sampling interface provides API to measure and get count for specific perf events.
The following test tries to explain count on `sampling.c` example. The following test tries to explain count on `sampling.c` example.
It is by no means complete guide to sampling, but shows libperf basic API for sampling. It is by no means complete guide to sampling, but shows libperf basic API for sampling.
The `sampling.c` comes with libbperf package and can be compiled and run like: The `sampling.c` comes with libperf package and can be compiled and run like:
[source,bash] [source,bash]
-- --
...@@ -33,7 +33,8 @@ cpu 0, pid 4465, tid 4470, ip 7f84fe0ebebf, period 176 ...@@ -33,7 +33,8 @@ cpu 0, pid 4465, tid 4470, ip 7f84fe0ebebf, period 176
It requires root access, because it uses hardware cycles event. It requires root access, because it uses hardware cycles event.
The `sampling.c` example profiles/samples all CPUs with hardware cycles, in a nutshel it: The `sampling.c` example profiles/samples all CPUs with hardware cycles, in a
nutshell it:
- creates events - creates events
- adds them to the event list - adds them to the event list
...@@ -90,7 +91,7 @@ Once the setup is complete we start by defining cycles event using the `struct p ...@@ -90,7 +91,7 @@ Once the setup is complete we start by defining cycles event using the `struct p
36 }; 36 };
-- --
Next step is to prepare cpus map. Next step is to prepare CPUs map.
In this case we will monitor all the available CPUs: In this case we will monitor all the available CPUs:
...@@ -152,7 +153,7 @@ Once the events list is open, we can create memory maps AKA perf ring buffers: ...@@ -152,7 +153,7 @@ Once the events list is open, we can create memory maps AKA perf ring buffers:
-- --
The event is created as disabled (note the `disabled = 1` assignment above), The event is created as disabled (note the `disabled = 1` assignment above),
so we need to enable the events list explicitely. so we need to enable the events list explicitly.
From this moment the cycles event is sampling. From this moment the cycles event is sampling.
...@@ -212,7 +213,7 @@ Each sample needs to get parsed: ...@@ -212,7 +213,7 @@ Each sample needs to get parsed:
106 cpu, pid, tid, ip, period); 106 cpu, pid, tid, ip, period);
-- --
And finaly cleanup. And finally cleanup.
We close the whole events list (both events) and remove it together with the threads map: We close the whole events list (both events) and remove it together with the threads map:
......
...@@ -29,7 +29,7 @@ SYNOPSIS ...@@ -29,7 +29,7 @@ SYNOPSIS
void libperf_init(libperf_print_fn_t fn); void libperf_init(libperf_print_fn_t fn);
-- --
*API to handle cpu maps:* *API to handle CPU maps:*
[source,c] [source,c]
-- --
...@@ -217,7 +217,7 @@ Following objects are key to the libperf interface: ...@@ -217,7 +217,7 @@ Following objects are key to the libperf interface:
[horizontal] [horizontal]
struct perf_cpu_map:: Provides a cpu list abstraction. struct perf_cpu_map:: Provides a CPU list abstraction.
struct perf_thread_map:: Provides a thread list abstraction. struct perf_thread_map:: Provides a thread list abstraction.
......
...@@ -614,8 +614,9 @@ trace.*:: ...@@ -614,8 +614,9 @@ trace.*::
ftrace.*:: ftrace.*::
ftrace.tracer:: ftrace.tracer::
Can be used to select the default tracer. Possible values are Can be used to select the default tracer when neither -G nor
'function' and 'function_graph'. -F option is not specified. Possible values are 'function' and
'function_graph'.
llvm.*:: llvm.*::
llvm.clang-path:: llvm.clang-path::
......
...@@ -24,16 +24,28 @@ OPTIONS ...@@ -24,16 +24,28 @@ OPTIONS
-t:: -t::
--tracer=:: --tracer=::
Tracer to use: function_graph or function. Tracer to use when neither -G nor -F option is not
specified: function_graph or function.
-v:: -v::
--verbose=:: --verbose=::
Verbosity level. Verbosity level.
-F::
--funcs::
List all available functions to trace.
-p:: -p::
--pid=:: --pid=::
Trace on existing process id (comma separated list). Trace on existing process id (comma separated list).
--tid=::
Trace on existing thread id (comma separated list).
-D::
--delay::
Time (ms) to wait before starting tracing after program start.
-a:: -a::
--all-cpus:: --all-cpus::
Force system-wide collection. Scripts run without a <command> Force system-wide collection. Scripts run without a <command>
...@@ -48,39 +60,58 @@ OPTIONS ...@@ -48,39 +60,58 @@ OPTIONS
Ranges of CPUs are specified with -: 0-2. Ranges of CPUs are specified with -: 0-2.
Default is to trace on all online CPUs. Default is to trace on all online CPUs.
-m::
--buffer-size::
Set the size of per-cpu tracing buffer, <size> is expected to
be a number with appended unit character - B/K/M/G.
--inherit::
Trace children processes spawned by our target.
-T:: -T::
--trace-funcs=:: --trace-funcs=::
Only trace functions given by the argument. Multiple functions Select function tracer and set function filter on the given
can be given by using this option more than once. The function function (or a glob pattern). Multiple functions can be given
argument also can be a glob pattern. It will be passed to by using this option more than once. The function argument also
'set_ftrace_filter' in tracefs. can be a glob pattern. It will be passed to 'set_ftrace_filter'
in tracefs.
-N:: -N::
--notrace-funcs=:: --notrace-funcs=::
Do not trace functions given by the argument. Like -T option, Select function tracer and do not trace functions given by the
this can be used more than once to specify multiple functions argument. Like -T option, this can be used more than once to
(or glob patterns). It will be passed to 'set_ftrace_notrace' specify multiple functions (or glob patterns). It will be
in tracefs. passed to 'set_ftrace_notrace' in tracefs.
--func-opts::
List of options allowed to set:
call-graph - Display kernel stack trace for function tracer.
irq-info - Display irq context info for function tracer.
-G:: -G::
--graph-funcs=:: --graph-funcs=::
Set graph filter on the given function (or a glob pattern). Select function_graph tracer and set graph filter on the given
This is useful for the function_graph tracer only and enables function (or a glob pattern). This is useful to trace for
tracing for functions executed from the given function. functions executed from the given function. This can be used more
This can be used more than once to specify multiple functions. than once to specify multiple functions. It will be passed to
It will be passed to 'set_graph_function' in tracefs. 'set_graph_function' in tracefs.
-g:: -g::
--nograph-funcs=:: --nograph-funcs=::
Set graph notrace filter on the given function (or a glob pattern). Select function_graph tracer and set graph notrace filter on the
Like -G option, this is useful for the function_graph tracer only given function (or a glob pattern). Like -G option, this is useful
and disables tracing for function executed from the given function. for the function_graph tracer only and disables tracing for function
This can be used more than once to specify multiple functions. executed from the given function. This can be used more than once to
It will be passed to 'set_graph_notrace' in tracefs. specify multiple functions. It will be passed to 'set_graph_notrace'
in tracefs.
-D:: --graph-opts::
--graph-depth=:: List of options allowed to set:
Set max depth for function graph tracer to follow nosleep-time - Measure on-CPU time only for function_graph tracer.
noirqs - Ignore functions that happen inside interrupt.
verbose - Show process names, PIDs, timestamps, etc.
thresh=<n> - Setup trace duration threshold in microseconds.
depth=<n> - Set max depth for function graph tracer to follow.
SEE ALSO SEE ALSO
-------- --------
......
...@@ -501,6 +501,14 @@ ifndef NO_LIBELF ...@@ -501,6 +501,14 @@ ifndef NO_LIBELF
CFLAGS += -DHAVE_ELF_GETSHDRSTRNDX_SUPPORT CFLAGS += -DHAVE_ELF_GETSHDRSTRNDX_SUPPORT
endif endif
ifndef NO_LIBDEBUGINFOD
$(call feature_check,libdebuginfod)
ifeq ($(feature-libdebuginfod), 1)
CFLAGS += -DHAVE_DEBUGINFOD_SUPPORT
EXTLIBS += -ldebuginfod
endif
endif
ifndef NO_DWARF ifndef NO_DWARF
ifeq ($(origin PERF_HAVE_DWARF_REGS), undefined) ifeq ($(origin PERF_HAVE_DWARF_REGS), undefined)
msg := $(warning DWARF register mappings have not been defined for architecture $(SRCARCH), DWARF support disabled); msg := $(warning DWARF register mappings have not been defined for architecture $(SRCARCH), DWARF support disabled);
......
...@@ -124,6 +124,8 @@ include ../scripts/utilities.mak ...@@ -124,6 +124,8 @@ include ../scripts/utilities.mak
# #
# Define LIBPFM4 to enable libpfm4 events extension. # Define LIBPFM4 to enable libpfm4 events extension.
# #
# Define NO_LIBDEBUGINFOD if you do not want support debuginfod
#
# As per kernel Makefile, avoid funny character set dependencies # As per kernel Makefile, avoid funny character set dependencies
unexport LC_ALL unexport LC_ALL
...@@ -418,6 +420,7 @@ export INSTALL SHELL_PATH ...@@ -418,6 +420,7 @@ export INSTALL SHELL_PATH
SHELL = $(SHELL_PATH) SHELL = $(SHELL_PATH)
beauty_linux_dir := $(srctree)/tools/perf/trace/beauty/include/linux/
linux_uapi_dir := $(srctree)/tools/include/uapi/linux linux_uapi_dir := $(srctree)/tools/include/uapi/linux
asm_generic_uapi_dir := $(srctree)/tools/include/uapi/asm-generic asm_generic_uapi_dir := $(srctree)/tools/include/uapi/asm-generic
arch_asm_uapi_dir := $(srctree)/tools/arch/$(SRCARCH)/include/uapi/asm/ arch_asm_uapi_dir := $(srctree)/tools/arch/$(SRCARCH)/include/uapi/asm/
...@@ -501,6 +504,12 @@ socket_ipproto_tbl := $(srctree)/tools/perf/trace/beauty/socket_ipproto.sh ...@@ -501,6 +504,12 @@ socket_ipproto_tbl := $(srctree)/tools/perf/trace/beauty/socket_ipproto.sh
$(socket_ipproto_array): $(linux_uapi_dir)/in.h $(socket_ipproto_tbl) $(socket_ipproto_array): $(linux_uapi_dir)/in.h $(socket_ipproto_tbl)
$(Q)$(SHELL) '$(socket_ipproto_tbl)' $(linux_uapi_dir) > $@ $(Q)$(SHELL) '$(socket_ipproto_tbl)' $(linux_uapi_dir) > $@
socket_arrays := $(beauty_outdir)/socket_arrays.c
socket_tbl := $(srctree)/tools/perf/trace/beauty/socket.sh
$(socket_arrays): $(beauty_linux_dir)/socket.h $(socket_tbl)
$(Q)$(SHELL) '$(socket_tbl)' $(beauty_linux_dir) > $@
vhost_virtio_ioctl_array := $(beauty_ioctl_outdir)/vhost_virtio_ioctl_array.c vhost_virtio_ioctl_array := $(beauty_ioctl_outdir)/vhost_virtio_ioctl_array.c
vhost_virtio_hdr_dir := $(srctree)/tools/include/uapi/linux vhost_virtio_hdr_dir := $(srctree)/tools/include/uapi/linux
vhost_virtio_ioctl_tbl := $(srctree)/tools/perf/trace/beauty/vhost_virtio_ioctl.sh vhost_virtio_ioctl_tbl := $(srctree)/tools/perf/trace/beauty/vhost_virtio_ioctl.sh
...@@ -697,6 +706,7 @@ prepare: $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h archheaders $(drm_ioc ...@@ -697,6 +706,7 @@ prepare: $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h archheaders $(drm_ioc
$(kcmp_type_array) \ $(kcmp_type_array) \
$(kvm_ioctl_array) \ $(kvm_ioctl_array) \
$(socket_ipproto_array) \ $(socket_ipproto_array) \
$(socket_arrays) \
$(vhost_virtio_ioctl_array) \ $(vhost_virtio_ioctl_array) \
$(madvise_behavior_array) \ $(madvise_behavior_array) \
$(mmap_flags_array) \ $(mmap_flags_array) \
...@@ -1006,6 +1016,7 @@ clean:: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clea ...@@ -1006,6 +1016,7 @@ clean:: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clea
$(OUTPUT)$(kvm_ioctl_array) \ $(OUTPUT)$(kvm_ioctl_array) \
$(OUTPUT)$(kcmp_type_array) \ $(OUTPUT)$(kcmp_type_array) \
$(OUTPUT)$(socket_ipproto_array) \ $(OUTPUT)$(socket_ipproto_array) \
$(OUTPUT)$(socket_arrays) \
$(OUTPUT)$(vhost_virtio_ioctl_array) \ $(OUTPUT)$(vhost_virtio_ioctl_array) \
$(OUTPUT)$(perf_ioctl_array) \ $(OUTPUT)$(perf_ioctl_array) \
$(OUTPUT)$(prctl_option_array) \ $(OUTPUT)$(prctl_option_array) \
......
...@@ -17,9 +17,9 @@ static unsigned int inner_iterations = 100000; ...@@ -17,9 +17,9 @@ static unsigned int inner_iterations = 100000;
static const struct option options[] = { static const struct option options[] = {
OPT_UINTEGER('i', "outer-iterations", &outer_iterations, OPT_UINTEGER('i', "outer-iterations", &outer_iterations,
"Number of outerer iterations used"), "Number of outer iterations used"),
OPT_UINTEGER('j', "inner-iterations", &inner_iterations, OPT_UINTEGER('j', "inner-iterations", &inner_iterations,
"Number of outerer iterations used"), "Number of inner iterations used"),
OPT_END() OPT_END()
}; };
......
...@@ -223,12 +223,8 @@ static int bench_mem_common(int argc, const char **argv, struct bench_mem_info * ...@@ -223,12 +223,8 @@ static int bench_mem_common(int argc, const char **argv, struct bench_mem_info *
return 0; return 0;
} }
static u64 do_memcpy_cycles(const struct function *r, size_t size, void *src, void *dst) static void memcpy_prefault(memcpy_t fn, size_t size, void *src, void *dst)
{ {
u64 cycle_start = 0ULL, cycle_end = 0ULL;
memcpy_t fn = r->fn.memcpy;
int i;
/* Make sure to always prefault zero pages even if MMAP_THRESH is crossed: */ /* Make sure to always prefault zero pages even if MMAP_THRESH is crossed: */
memset(src, 0, size); memset(src, 0, size);
...@@ -237,6 +233,15 @@ static u64 do_memcpy_cycles(const struct function *r, size_t size, void *src, vo ...@@ -237,6 +233,15 @@ static u64 do_memcpy_cycles(const struct function *r, size_t size, void *src, vo
* to not measure page fault overhead: * to not measure page fault overhead:
*/ */
fn(dst, src, size); fn(dst, src, size);
}
static u64 do_memcpy_cycles(const struct function *r, size_t size, void *src, void *dst)
{
u64 cycle_start = 0ULL, cycle_end = 0ULL;
memcpy_t fn = r->fn.memcpy;
int i;
memcpy_prefault(fn, size, src, dst);
cycle_start = get_cycles(); cycle_start = get_cycles();
for (i = 0; i < nr_loops; ++i) for (i = 0; i < nr_loops; ++i)
...@@ -252,11 +257,7 @@ static double do_memcpy_gettimeofday(const struct function *r, size_t size, void ...@@ -252,11 +257,7 @@ static double do_memcpy_gettimeofday(const struct function *r, size_t size, void
memcpy_t fn = r->fn.memcpy; memcpy_t fn = r->fn.memcpy;
int i; int i;
/* memcpy_prefault(fn, size, src, dst);
* We prefault the freshly allocated memory range here,
* to not measure page fault overhead:
*/
fn(dst, src, size);
BUG_ON(gettimeofday(&tv_start, NULL)); BUG_ON(gettimeofday(&tv_start, NULL));
for (i = 0; i < nr_loops; ++i) for (i = 0; i < nr_loops; ++i)
......
...@@ -247,17 +247,22 @@ static int is_node_present(int node) ...@@ -247,17 +247,22 @@ static int is_node_present(int node)
*/ */
static bool node_has_cpus(int node) static bool node_has_cpus(int node)
{ {
struct bitmask *cpu = numa_allocate_cpumask(); struct bitmask *cpumask = numa_allocate_cpumask();
unsigned int i; bool ret = false; /* fall back to nocpus */
int cpu;
if (cpu && !numa_node_to_cpus(node, cpu)) { BUG_ON(!cpumask);
for (i = 0; i < cpu->size; i++) { if (!numa_node_to_cpus(node, cpumask)) {
if (numa_bitmask_isbitset(cpu, i)) for (cpu = 0; cpu < (int)cpumask->size; cpu++) {
return true; if (numa_bitmask_isbitset(cpumask, cpu)) {
ret = true;
break;
}
} }
} }
numa_free_cpumask(cpumask);
return false; /* lets fall back to nocpus safely */ return ret;
} }
static cpu_set_t bind_to_cpu(int target_cpu) static cpu_set_t bind_to_cpu(int target_cpu)
...@@ -288,14 +293,10 @@ static cpu_set_t bind_to_cpu(int target_cpu) ...@@ -288,14 +293,10 @@ static cpu_set_t bind_to_cpu(int target_cpu)
static cpu_set_t bind_to_node(int target_node) static cpu_set_t bind_to_node(int target_node)
{ {
int cpus_per_node = g->p.nr_cpus / nr_numa_nodes();
cpu_set_t orig_mask, mask; cpu_set_t orig_mask, mask;
int cpu; int cpu;
int ret; int ret;
BUG_ON(cpus_per_node * nr_numa_nodes() != g->p.nr_cpus);
BUG_ON(!cpus_per_node);
ret = sched_getaffinity(0, sizeof(orig_mask), &orig_mask); ret = sched_getaffinity(0, sizeof(orig_mask), &orig_mask);
BUG_ON(ret); BUG_ON(ret);
...@@ -305,13 +306,16 @@ static cpu_set_t bind_to_node(int target_node) ...@@ -305,13 +306,16 @@ static cpu_set_t bind_to_node(int target_node)
for (cpu = 0; cpu < g->p.nr_cpus; cpu++) for (cpu = 0; cpu < g->p.nr_cpus; cpu++)
CPU_SET(cpu, &mask); CPU_SET(cpu, &mask);
} else { } else {
int cpu_start = (target_node + 0) * cpus_per_node; struct bitmask *cpumask = numa_allocate_cpumask();
int cpu_stop = (target_node + 1) * cpus_per_node;
BUG_ON(cpu_stop > g->p.nr_cpus); BUG_ON(!cpumask);
if (!numa_node_to_cpus(target_node, cpumask)) {
for (cpu = cpu_start; cpu < cpu_stop; cpu++) for (cpu = 0; cpu < (int)cpumask->size; cpu++) {
CPU_SET(cpu, &mask); if (numa_bitmask_isbitset(cpumask, cpu))
CPU_SET(cpu, &mask);
}
}
numa_free_cpumask(cpumask);
} }
ret = sched_setaffinity(0, sizeof(mask), &mask); ret = sched_setaffinity(0, sizeof(mask), &mask);
...@@ -729,8 +733,6 @@ static int parse_nodes_opt(const struct option *opt __maybe_unused, ...@@ -729,8 +733,6 @@ static int parse_nodes_opt(const struct option *opt __maybe_unused,
return -1; return -1;
return parse_node_list(arg); return parse_node_list(arg);
return 0;
} }
#define BIT(x) (1ul << x) #define BIT(x) (1ul << x)
...@@ -813,12 +815,12 @@ static u64 do_work(u8 *__data, long bytes, int nr, int nr_max, int loop, u64 val ...@@ -813,12 +815,12 @@ static u64 do_work(u8 *__data, long bytes, int nr, int nr_max, int loop, u64 val
} }
} }
} else if (!g->p.data_backwards || (nr + loop) & 1) { } else if (!g->p.data_backwards || (nr + loop) & 1) {
/* Process data forwards: */
d0 = data + off; d0 = data + off;
d = data + off + 1; d = data + off + 1;
d1 = data + words; d1 = data + words;
/* Process data forwards: */
for (;;) { for (;;) {
if (unlikely(d >= d1)) if (unlikely(d >= d1))
d = data; d = data;
...@@ -836,7 +838,6 @@ static u64 do_work(u8 *__data, long bytes, int nr, int nr_max, int loop, u64 val ...@@ -836,7 +838,6 @@ static u64 do_work(u8 *__data, long bytes, int nr, int nr_max, int loop, u64 val
d = data + off - 1; d = data + off - 1;
d1 = data + words; d1 = data + words;
/* Process data forwards: */
for (;;) { for (;;) {
if (unlikely(d < data)) if (unlikely(d < data))
d = data + words-1; d = data + words-1;
...@@ -1733,12 +1734,12 @@ static int run_bench_numa(const char *name, const char **argv) ...@@ -1733,12 +1734,12 @@ static int run_bench_numa(const char *name, const char **argv)
*/ */
static const char *tests[][MAX_ARGS] = { static const char *tests[][MAX_ARGS] = {
/* Basic single-stream NUMA bandwidth measurements: */ /* Basic single-stream NUMA bandwidth measurements: */
{ "RAM-bw-local,", "mem", "-p", "1", "-t", "1", "-P", "1024", { "RAM-bw-local,", "mem", "-p", "1", "-t", "1", "-P", "1024",
"-C" , "0", "-M", "0", OPT_BW_RAM }, "-C" , "0", "-M", "0", OPT_BW_RAM },
{ "RAM-bw-local-NOTHP,", { "RAM-bw-local-NOTHP,",
"mem", "-p", "1", "-t", "1", "-P", "1024", "mem", "-p", "1", "-t", "1", "-P", "1024",
"-C" , "0", "-M", "0", OPT_BW_RAM_NOTHP }, "-C" , "0", "-M", "0", OPT_BW_RAM_NOTHP },
{ "RAM-bw-remote,", "mem", "-p", "1", "-t", "1", "-P", "1024", { "RAM-bw-remote,", "mem", "-p", "1", "-t", "1", "-P", "1024",
"-C" , "0", "-M", "1", OPT_BW_RAM }, "-C" , "0", "-M", "1", OPT_BW_RAM },
/* 2-stream NUMA bandwidth measurements: */ /* 2-stream NUMA bandwidth measurements: */
...@@ -1755,7 +1756,7 @@ static const char *tests[][MAX_ARGS] = { ...@@ -1755,7 +1756,7 @@ static const char *tests[][MAX_ARGS] = {
{ " 1x3-convergence,", "mem", "-p", "1", "-t", "3", "-P", "512", OPT_CONV }, { " 1x3-convergence,", "mem", "-p", "1", "-t", "3", "-P", "512", OPT_CONV },
{ " 1x4-convergence,", "mem", "-p", "1", "-t", "4", "-P", "512", OPT_CONV }, { " 1x4-convergence,", "mem", "-p", "1", "-t", "4", "-P", "512", OPT_CONV },
{ " 1x6-convergence,", "mem", "-p", "1", "-t", "6", "-P", "1020", OPT_CONV }, { " 1x6-convergence,", "mem", "-p", "1", "-t", "6", "-P", "1020", OPT_CONV },
{ " 2x3-convergence,", "mem", "-p", "3", "-t", "3", "-P", "1020", OPT_CONV }, { " 2x3-convergence,", "mem", "-p", "2", "-t", "3", "-P", "1020", OPT_CONV },
{ " 3x3-convergence,", "mem", "-p", "3", "-t", "3", "-P", "1020", OPT_CONV }, { " 3x3-convergence,", "mem", "-p", "3", "-t", "3", "-P", "1020", OPT_CONV },
{ " 4x4-convergence,", "mem", "-p", "4", "-t", "4", "-P", "512", OPT_CONV }, { " 4x4-convergence,", "mem", "-p", "4", "-t", "4", "-P", "512", OPT_CONV },
{ " 4x4-convergence-NOTHP,", { " 4x4-convergence-NOTHP,",
...@@ -1780,24 +1781,24 @@ static const char *tests[][MAX_ARGS] = { ...@@ -1780,24 +1781,24 @@ static const char *tests[][MAX_ARGS] = {
"mem", "-p", "8", "-t", "1", "-P", " 512", OPT_BW_NOTHP }, "mem", "-p", "8", "-t", "1", "-P", " 512", OPT_BW_NOTHP },
{ "16x1-bw-process,", "mem", "-p", "16", "-t", "1", "-P", "256", OPT_BW }, { "16x1-bw-process,", "mem", "-p", "16", "-t", "1", "-P", "256", OPT_BW },
{ " 4x1-bw-thread,", "mem", "-p", "1", "-t", "4", "-T", "256", OPT_BW }, { " 1x4-bw-thread,", "mem", "-p", "1", "-t", "4", "-T", "256", OPT_BW },
{ " 8x1-bw-thread,", "mem", "-p", "1", "-t", "8", "-T", "256", OPT_BW }, { " 1x8-bw-thread,", "mem", "-p", "1", "-t", "8", "-T", "256", OPT_BW },
{ "16x1-bw-thread,", "mem", "-p", "1", "-t", "16", "-T", "128", OPT_BW }, { "1x16-bw-thread,", "mem", "-p", "1", "-t", "16", "-T", "128", OPT_BW },
{ "32x1-bw-thread,", "mem", "-p", "1", "-t", "32", "-T", "64", OPT_BW }, { "1x32-bw-thread,", "mem", "-p", "1", "-t", "32", "-T", "64", OPT_BW },
{ " 2x3-bw-thread,", "mem", "-p", "2", "-t", "3", "-P", "512", OPT_BW }, { " 2x3-bw-process,", "mem", "-p", "2", "-t", "3", "-P", "512", OPT_BW },
{ " 4x4-bw-thread,", "mem", "-p", "4", "-t", "4", "-P", "512", OPT_BW }, { " 4x4-bw-process,", "mem", "-p", "4", "-t", "4", "-P", "512", OPT_BW },
{ " 4x6-bw-thread,", "mem", "-p", "4", "-t", "6", "-P", "512", OPT_BW }, { " 4x6-bw-process,", "mem", "-p", "4", "-t", "6", "-P", "512", OPT_BW },
{ " 4x8-bw-thread,", "mem", "-p", "4", "-t", "8", "-P", "512", OPT_BW }, { " 4x8-bw-process,", "mem", "-p", "4", "-t", "8", "-P", "512", OPT_BW },
{ " 4x8-bw-thread-NOTHP,", { " 4x8-bw-process-NOTHP,",
"mem", "-p", "4", "-t", "8", "-P", "512", OPT_BW_NOTHP }, "mem", "-p", "4", "-t", "8", "-P", "512", OPT_BW_NOTHP },
{ " 3x3-bw-thread,", "mem", "-p", "3", "-t", "3", "-P", "512", OPT_BW }, { " 3x3-bw-process,", "mem", "-p", "3", "-t", "3", "-P", "512", OPT_BW },
{ " 5x5-bw-thread,", "mem", "-p", "5", "-t", "5", "-P", "512", OPT_BW }, { " 5x5-bw-process,", "mem", "-p", "5", "-t", "5", "-P", "512", OPT_BW },
{ "2x16-bw-thread,", "mem", "-p", "2", "-t", "16", "-P", "512", OPT_BW }, { "2x16-bw-process,", "mem", "-p", "2", "-t", "16", "-P", "512", OPT_BW },
{ "1x32-bw-thread,", "mem", "-p", "1", "-t", "32", "-P", "2048", OPT_BW }, { "1x32-bw-process,", "mem", "-p", "1", "-t", "32", "-P", "2048", OPT_BW },
{ "numa02-bw,", "mem", "-p", "1", "-t", "32", "-T", "32", OPT_BW }, { "numa02-bw,", "mem", "-p", "1", "-t", "32", "-T", "32", OPT_BW },
{ "numa02-bw-NOTHP,", "mem", "-p", "1", "-t", "32", "-T", "32", OPT_BW_NOTHP }, { "numa02-bw-NOTHP,", "mem", "-p", "1", "-t", "32", "-T", "32", OPT_BW_NOTHP },
{ "numa01-bw-thread,", "mem", "-p", "2", "-t", "16", "-T", "192", OPT_BW }, { "numa01-bw-thread,", "mem", "-p", "2", "-t", "16", "-T", "192", OPT_BW },
{ "numa01-bw-thread-NOTHP,", { "numa01-bw-thread-NOTHP,",
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
* builtin-ftrace.c * builtin-ftrace.c
* *
* Copyright (c) 2013 LG Electronics, Namhyung Kim <namhyung@kernel.org> * Copyright (c) 2013 LG Electronics, Namhyung Kim <namhyung@kernel.org>
* Copyright (c) 2020 Changbin Du <changbin.du@gmail.com>, significant enhancement.
*/ */
#include "builtin.h" #include "builtin.h"
...@@ -26,6 +27,8 @@ ...@@ -26,6 +27,8 @@
#include "thread_map.h" #include "thread_map.h"
#include "util/cap.h" #include "util/cap.h"
#include "util/config.h" #include "util/config.h"
#include "util/units.h"
#include "util/parse-sublevel-options.h"
#define DEFAULT_TRACER "function_graph" #define DEFAULT_TRACER "function_graph"
...@@ -33,11 +36,21 @@ struct perf_ftrace { ...@@ -33,11 +36,21 @@ struct perf_ftrace {
struct evlist *evlist; struct evlist *evlist;
struct target target; struct target target;
const char *tracer; const char *tracer;
bool list_avail_functions;
struct list_head filters; struct list_head filters;
struct list_head notrace; struct list_head notrace;
struct list_head graph_funcs; struct list_head graph_funcs;
struct list_head nograph_funcs; struct list_head nograph_funcs;
int graph_depth; int graph_depth;
unsigned long percpu_buffer_size;
bool inherit;
int func_stack_trace;
int func_irq_info;
int graph_nosleep_time;
int graph_noirqs;
int graph_verbose;
int graph_thresh;
unsigned int initial_delay;
}; };
struct filter_entry { struct filter_entry {
...@@ -128,9 +141,85 @@ static int append_tracing_file(const char *name, const char *val) ...@@ -128,9 +141,85 @@ static int append_tracing_file(const char *name, const char *val)
return __write_tracing_file(name, val, true); return __write_tracing_file(name, val, true);
} }
static int read_tracing_file_to_stdout(const char *name)
{
char buf[4096];
char *file;
int fd;
int ret = -1;
file = get_tracing_file(name);
if (!file) {
pr_debug("cannot get tracing file: %s\n", name);
return -1;
}
fd = open(file, O_RDONLY);
if (fd < 0) {
pr_debug("cannot open tracing file: %s: %s\n",
name, str_error_r(errno, buf, sizeof(buf)));
goto out;
}
/* read contents to stdout */
while (true) {
int n = read(fd, buf, sizeof(buf));
if (n == 0)
break;
else if (n < 0)
goto out_close;
if (fwrite(buf, n, 1, stdout) != 1)
goto out_close;
}
ret = 0;
out_close:
close(fd);
out:
put_tracing_file(file);
return ret;
}
static int write_tracing_file_int(const char *name, int value)
{
char buf[16];
snprintf(buf, sizeof(buf), "%d", value);
if (write_tracing_file(name, buf) < 0)
return -1;
return 0;
}
static int write_tracing_option_file(const char *name, const char *val)
{
char *file;
int ret;
if (asprintf(&file, "options/%s", name) < 0)
return -1;
ret = __write_tracing_file(file, val, false);
free(file);
return ret;
}
static int reset_tracing_cpu(void); static int reset_tracing_cpu(void);
static void reset_tracing_filters(void); static void reset_tracing_filters(void);
static void reset_tracing_options(struct perf_ftrace *ftrace __maybe_unused)
{
write_tracing_option_file("function-fork", "0");
write_tracing_option_file("func_stack_trace", "0");
write_tracing_option_file("sleep-time", "1");
write_tracing_option_file("funcgraph-irqs", "1");
write_tracing_option_file("funcgraph-proc", "0");
write_tracing_option_file("funcgraph-abstime", "0");
write_tracing_option_file("latency-format", "0");
write_tracing_option_file("irq-info", "0");
}
static int reset_tracing_files(struct perf_ftrace *ftrace __maybe_unused) static int reset_tracing_files(struct perf_ftrace *ftrace __maybe_unused)
{ {
if (write_tracing_file("tracing_on", "0") < 0) if (write_tracing_file("tracing_on", "0") < 0)
...@@ -148,7 +237,11 @@ static int reset_tracing_files(struct perf_ftrace *ftrace __maybe_unused) ...@@ -148,7 +237,11 @@ static int reset_tracing_files(struct perf_ftrace *ftrace __maybe_unused)
if (write_tracing_file("max_graph_depth", "0") < 0) if (write_tracing_file("max_graph_depth", "0") < 0)
return -1; return -1;
if (write_tracing_file("tracing_thresh", "0") < 0)
return -1;
reset_tracing_filters(); reset_tracing_filters();
reset_tracing_options(ftrace);
return 0; return 0;
} }
...@@ -204,6 +297,28 @@ static int set_tracing_cpu(struct perf_ftrace *ftrace) ...@@ -204,6 +297,28 @@ static int set_tracing_cpu(struct perf_ftrace *ftrace)
return set_tracing_cpumask(cpumap); return set_tracing_cpumask(cpumap);
} }
static int set_tracing_func_stack_trace(struct perf_ftrace *ftrace)
{
if (!ftrace->func_stack_trace)
return 0;
if (write_tracing_option_file("func_stack_trace", "1") < 0)
return -1;
return 0;
}
static int set_tracing_func_irqinfo(struct perf_ftrace *ftrace)
{
if (!ftrace->func_irq_info)
return 0;
if (write_tracing_option_file("irq-info", "1") < 0)
return -1;
return 0;
}
static int reset_tracing_cpu(void) static int reset_tracing_cpu(void)
{ {
struct perf_cpu_map *cpumap = perf_cpu_map__new(NULL); struct perf_cpu_map *cpumap = perf_cpu_map__new(NULL);
...@@ -258,8 +373,6 @@ static void reset_tracing_filters(void) ...@@ -258,8 +373,6 @@ static void reset_tracing_filters(void)
static int set_tracing_depth(struct perf_ftrace *ftrace) static int set_tracing_depth(struct perf_ftrace *ftrace)
{ {
char buf[16];
if (ftrace->graph_depth == 0) if (ftrace->graph_depth == 0)
return 0; return 0;
...@@ -268,10 +381,152 @@ static int set_tracing_depth(struct perf_ftrace *ftrace) ...@@ -268,10 +381,152 @@ static int set_tracing_depth(struct perf_ftrace *ftrace)
return -1; return -1;
} }
snprintf(buf, sizeof(buf), "%d", ftrace->graph_depth); if (write_tracing_file_int("max_graph_depth", ftrace->graph_depth) < 0)
return -1;
return 0;
}
static int set_tracing_percpu_buffer_size(struct perf_ftrace *ftrace)
{
int ret;
if (ftrace->percpu_buffer_size == 0)
return 0;
ret = write_tracing_file_int("buffer_size_kb",
ftrace->percpu_buffer_size / 1024);
if (ret < 0)
return ret;
return 0;
}
static int set_tracing_trace_inherit(struct perf_ftrace *ftrace)
{
if (!ftrace->inherit)
return 0;
if (write_tracing_option_file("function-fork", "1") < 0)
return -1;
return 0;
}
static int set_tracing_sleep_time(struct perf_ftrace *ftrace)
{
if (!ftrace->graph_nosleep_time)
return 0;
if (write_tracing_option_file("sleep-time", "0") < 0)
return -1;
return 0;
}
static int set_tracing_funcgraph_irqs(struct perf_ftrace *ftrace)
{
if (!ftrace->graph_noirqs)
return 0;
if (write_tracing_option_file("funcgraph-irqs", "0") < 0)
return -1;
return 0;
}
static int set_tracing_funcgraph_verbose(struct perf_ftrace *ftrace)
{
if (!ftrace->graph_verbose)
return 0;
if (write_tracing_option_file("funcgraph-proc", "1") < 0)
return -1;
if (write_tracing_option_file("funcgraph-abstime", "1") < 0)
return -1;
if (write_tracing_option_file("latency-format", "1") < 0)
return -1;
return 0;
}
static int set_tracing_thresh(struct perf_ftrace *ftrace)
{
int ret;
if (ftrace->graph_thresh == 0)
return 0;
ret = write_tracing_file_int("tracing_thresh", ftrace->graph_thresh);
if (ret < 0)
return ret;
return 0;
}
static int set_tracing_options(struct perf_ftrace *ftrace)
{
if (set_tracing_pid(ftrace) < 0) {
pr_err("failed to set ftrace pid\n");
return -1;
}
if (set_tracing_cpu(ftrace) < 0) {
pr_err("failed to set tracing cpumask\n");
return -1;
}
if (set_tracing_func_stack_trace(ftrace) < 0) {
pr_err("failed to set tracing option func_stack_trace\n");
return -1;
}
if (set_tracing_func_irqinfo(ftrace) < 0) {
pr_err("failed to set tracing option irq-info\n");
return -1;
}
if (set_tracing_filters(ftrace) < 0) {
pr_err("failed to set tracing filters\n");
return -1;
}
if (set_tracing_depth(ftrace) < 0) {
pr_err("failed to set graph depth\n");
return -1;
}
if (set_tracing_percpu_buffer_size(ftrace) < 0) {
pr_err("failed to set tracing per-cpu buffer size\n");
return -1;
}
if (set_tracing_trace_inherit(ftrace) < 0) {
pr_err("failed to set tracing option function-fork\n");
return -1;
}
if (set_tracing_sleep_time(ftrace) < 0) {
pr_err("failed to set tracing option sleep-time\n");
return -1;
}
if (set_tracing_funcgraph_irqs(ftrace) < 0) {
pr_err("failed to set tracing option funcgraph-irqs\n");
return -1;
}
if (write_tracing_file("max_graph_depth", buf) < 0) if (set_tracing_funcgraph_verbose(ftrace) < 0) {
pr_err("failed to set tracing option funcgraph-proc/funcgraph-abstime\n");
return -1; return -1;
}
if (set_tracing_thresh(ftrace) < 0) {
pr_err("failed to set tracing thresh\n");
return -1;
}
return 0; return 0;
} }
...@@ -302,6 +557,9 @@ static int __cmd_ftrace(struct perf_ftrace *ftrace, int argc, const char **argv) ...@@ -302,6 +557,9 @@ static int __cmd_ftrace(struct perf_ftrace *ftrace, int argc, const char **argv)
signal(SIGCHLD, sig_handler); signal(SIGCHLD, sig_handler);
signal(SIGPIPE, sig_handler); signal(SIGPIPE, sig_handler);
if (ftrace->list_avail_functions)
return read_tracing_file_to_stdout("available_filter_functions");
if (reset_tracing_files(ftrace) < 0) { if (reset_tracing_files(ftrace) < 0) {
pr_err("failed to reset ftrace\n"); pr_err("failed to reset ftrace\n");
goto out; goto out;
...@@ -317,25 +575,8 @@ static int __cmd_ftrace(struct perf_ftrace *ftrace, int argc, const char **argv) ...@@ -317,25 +575,8 @@ static int __cmd_ftrace(struct perf_ftrace *ftrace, int argc, const char **argv)
goto out; goto out;
} }
if (set_tracing_pid(ftrace) < 0) { if (set_tracing_options(ftrace) < 0)
pr_err("failed to set ftrace pid\n");
goto out_reset; goto out_reset;
}
if (set_tracing_cpu(ftrace) < 0) {
pr_err("failed to set tracing cpumask\n");
goto out_reset;
}
if (set_tracing_filters(ftrace) < 0) {
pr_err("failed to set tracing filters\n");
goto out_reset;
}
if (set_tracing_depth(ftrace) < 0) {
pr_err("failed to set graph depth\n");
goto out_reset;
}
if (write_tracing_file("current_tracer", ftrace->tracer) < 0) { if (write_tracing_file("current_tracer", ftrace->tracer) < 0) {
pr_err("failed to set current_tracer to %s\n", ftrace->tracer); pr_err("failed to set current_tracer to %s\n", ftrace->tracer);
...@@ -362,13 +603,26 @@ static int __cmd_ftrace(struct perf_ftrace *ftrace, int argc, const char **argv) ...@@ -362,13 +603,26 @@ static int __cmd_ftrace(struct perf_ftrace *ftrace, int argc, const char **argv)
fcntl(trace_fd, F_SETFL, O_NONBLOCK); fcntl(trace_fd, F_SETFL, O_NONBLOCK);
pollfd.fd = trace_fd; pollfd.fd = trace_fd;
if (write_tracing_file("tracing_on", "1") < 0) { /* display column headers */
pr_err("can't enable tracing\n"); read_tracing_file_to_stdout("trace");
goto out_close_fd;
if (!ftrace->initial_delay) {
if (write_tracing_file("tracing_on", "1") < 0) {
pr_err("can't enable tracing\n");
goto out_close_fd;
}
} }
perf_evlist__start_workload(ftrace->evlist); perf_evlist__start_workload(ftrace->evlist);
if (ftrace->initial_delay) {
usleep(ftrace->initial_delay * 1000);
if (write_tracing_file("tracing_on", "1") < 0) {
pr_err("can't enable tracing\n");
goto out_close_fd;
}
}
while (!done) { while (!done) {
if (poll(&pollfd, 1, -1) < 0) if (poll(&pollfd, 1, -1) < 0)
break; break;
...@@ -455,6 +709,99 @@ static void delete_filter_func(struct list_head *head) ...@@ -455,6 +709,99 @@ static void delete_filter_func(struct list_head *head)
} }
} }
static int parse_buffer_size(const struct option *opt,
const char *str, int unset)
{
unsigned long *s = (unsigned long *)opt->value;
static struct parse_tag tags_size[] = {
{ .tag = 'B', .mult = 1 },
{ .tag = 'K', .mult = 1 << 10 },
{ .tag = 'M', .mult = 1 << 20 },
{ .tag = 'G', .mult = 1 << 30 },
{ .tag = 0 },
};
unsigned long val;
if (unset) {
*s = 0;
return 0;
}
val = parse_tag_value(str, tags_size);
if (val != (unsigned long) -1) {
if (val < 1024) {
pr_err("buffer size too small, must larger than 1KB.");
return -1;
}
*s = val;
return 0;
}
return -1;
}
static int parse_func_tracer_opts(const struct option *opt,
const char *str, int unset)
{
int ret;
struct perf_ftrace *ftrace = (struct perf_ftrace *) opt->value;
struct sublevel_option func_tracer_opts[] = {
{ .name = "call-graph", .value_ptr = &ftrace->func_stack_trace },
{ .name = "irq-info", .value_ptr = &ftrace->func_irq_info },
{ .name = NULL, }
};
if (unset)
return 0;
ret = perf_parse_sublevel_options(str, func_tracer_opts);
if (ret)
return ret;
return 0;
}
static int parse_graph_tracer_opts(const struct option *opt,
const char *str, int unset)
{
int ret;
struct perf_ftrace *ftrace = (struct perf_ftrace *) opt->value;
struct sublevel_option graph_tracer_opts[] = {
{ .name = "nosleep-time", .value_ptr = &ftrace->graph_nosleep_time },
{ .name = "noirqs", .value_ptr = &ftrace->graph_noirqs },
{ .name = "verbose", .value_ptr = &ftrace->graph_verbose },
{ .name = "thresh", .value_ptr = &ftrace->graph_thresh },
{ .name = "depth", .value_ptr = &ftrace->graph_depth },
{ .name = NULL, }
};
if (unset)
return 0;
ret = perf_parse_sublevel_options(str, graph_tracer_opts);
if (ret)
return ret;
return 0;
}
static void select_tracer(struct perf_ftrace *ftrace)
{
bool graph = !list_empty(&ftrace->graph_funcs) ||
!list_empty(&ftrace->nograph_funcs);
bool func = !list_empty(&ftrace->filters) ||
!list_empty(&ftrace->notrace);
/* The function_graph has priority over function tracer. */
if (graph)
ftrace->tracer = "function_graph";
else if (func)
ftrace->tracer = "function";
/* Otherwise, the default tracer is used. */
pr_debug("%s tracer is used\n", ftrace->tracer);
}
int cmd_ftrace(int argc, const char **argv) int cmd_ftrace(int argc, const char **argv)
{ {
int ret; int ret;
...@@ -469,25 +816,42 @@ int cmd_ftrace(int argc, const char **argv) ...@@ -469,25 +816,42 @@ int cmd_ftrace(int argc, const char **argv)
}; };
const struct option ftrace_options[] = { const struct option ftrace_options[] = {
OPT_STRING('t', "tracer", &ftrace.tracer, "tracer", OPT_STRING('t', "tracer", &ftrace.tracer, "tracer",
"tracer to use: function_graph(default) or function"), "Tracer to use: function_graph(default) or function"),
OPT_BOOLEAN('F', "funcs", &ftrace.list_avail_functions,
"Show available functions to filter"),
OPT_STRING('p', "pid", &ftrace.target.pid, "pid", OPT_STRING('p', "pid", &ftrace.target.pid, "pid",
"trace on existing process id"), "Trace on existing process id"),
/* TODO: Add short option -t after -t/--tracer can be removed. */
OPT_STRING(0, "tid", &ftrace.target.tid, "tid",
"Trace on existing thread id (exclusive to --pid)"),
OPT_INCR('v', "verbose", &verbose, OPT_INCR('v', "verbose", &verbose,
"be more verbose"), "Be more verbose"),
OPT_BOOLEAN('a', "all-cpus", &ftrace.target.system_wide, OPT_BOOLEAN('a', "all-cpus", &ftrace.target.system_wide,
"system-wide collection from all CPUs"), "System-wide collection from all CPUs"),
OPT_STRING('C', "cpu", &ftrace.target.cpu_list, "cpu", OPT_STRING('C', "cpu", &ftrace.target.cpu_list, "cpu",
"list of cpus to monitor"), "List of cpus to monitor"),
OPT_CALLBACK('T', "trace-funcs", &ftrace.filters, "func", OPT_CALLBACK('T', "trace-funcs", &ftrace.filters, "func",
"trace given functions only", parse_filter_func), "Trace given functions using function tracer",
parse_filter_func),
OPT_CALLBACK('N', "notrace-funcs", &ftrace.notrace, "func", OPT_CALLBACK('N', "notrace-funcs", &ftrace.notrace, "func",
"do not trace given functions", parse_filter_func), "Do not trace given functions", parse_filter_func),
OPT_CALLBACK(0, "func-opts", &ftrace, "options",
"Function tracer options, available options: call-graph,irq-info",
parse_func_tracer_opts),
OPT_CALLBACK('G', "graph-funcs", &ftrace.graph_funcs, "func", OPT_CALLBACK('G', "graph-funcs", &ftrace.graph_funcs, "func",
"Set graph filter on given functions", parse_filter_func), "Trace given functions using function_graph tracer",
parse_filter_func),
OPT_CALLBACK('g', "nograph-funcs", &ftrace.nograph_funcs, "func", OPT_CALLBACK('g', "nograph-funcs", &ftrace.nograph_funcs, "func",
"Set nograph filter on given functions", parse_filter_func), "Set nograph filter on given functions", parse_filter_func),
OPT_INTEGER('D', "graph-depth", &ftrace.graph_depth, OPT_CALLBACK(0, "graph-opts", &ftrace, "options",
"Max depth for function graph tracer"), "Graph tracer options, available options: nosleep-time,noirqs,verbose,thresh=<n>,depth=<n>",
parse_graph_tracer_opts),
OPT_CALLBACK('m', "buffer-size", &ftrace.percpu_buffer_size, "size",
"Size of per cpu buffer, needs to use a B, K, M or G suffix.", parse_buffer_size),
OPT_BOOLEAN(0, "inherit", &ftrace.inherit,
"Trace children processes"),
OPT_UINTEGER('D', "delay", &ftrace.initial_delay,
"Number of milliseconds to wait before starting tracing after program start"),
OPT_END() OPT_END()
}; };
...@@ -505,6 +869,8 @@ int cmd_ftrace(int argc, const char **argv) ...@@ -505,6 +869,8 @@ int cmd_ftrace(int argc, const char **argv)
if (!argc && target__none(&ftrace.target)) if (!argc && target__none(&ftrace.target))
ftrace.target.system_wide = true; ftrace.target.system_wide = true;
select_tracer(&ftrace);
ret = target__validate(&ftrace.target); ret = target__validate(&ftrace.target);
if (ret) { if (ret) {
char errbuf[512]; char errbuf[512];
......
...@@ -2398,6 +2398,15 @@ static void timehist_print_wakeup_event(struct perf_sched *sched, ...@@ -2398,6 +2398,15 @@ static void timehist_print_wakeup_event(struct perf_sched *sched,
printf("\n"); printf("\n");
} }
static int timehist_sched_wakeup_ignore(struct perf_tool *tool __maybe_unused,
union perf_event *event __maybe_unused,
struct evsel *evsel __maybe_unused,
struct perf_sample *sample __maybe_unused,
struct machine *machine __maybe_unused)
{
return 0;
}
static int timehist_sched_wakeup_event(struct perf_tool *tool, static int timehist_sched_wakeup_event(struct perf_tool *tool,
union perf_event *event __maybe_unused, union perf_event *event __maybe_unused,
struct evsel *evsel, struct evsel *evsel,
...@@ -2958,9 +2967,10 @@ static int timehist_check_attr(struct perf_sched *sched, ...@@ -2958,9 +2967,10 @@ static int timehist_check_attr(struct perf_sched *sched,
static int perf_sched__timehist(struct perf_sched *sched) static int perf_sched__timehist(struct perf_sched *sched)
{ {
const struct evsel_str_handler handlers[] = { struct evsel_str_handler handlers[] = {
{ "sched:sched_switch", timehist_sched_switch_event, }, { "sched:sched_switch", timehist_sched_switch_event, },
{ "sched:sched_wakeup", timehist_sched_wakeup_event, }, { "sched:sched_wakeup", timehist_sched_wakeup_event, },
{ "sched:sched_waking", timehist_sched_wakeup_event, },
{ "sched:sched_wakeup_new", timehist_sched_wakeup_event, }, { "sched:sched_wakeup_new", timehist_sched_wakeup_event, },
}; };
const struct evsel_str_handler migrate_handlers[] = { const struct evsel_str_handler migrate_handlers[] = {
...@@ -3018,6 +3028,11 @@ static int perf_sched__timehist(struct perf_sched *sched) ...@@ -3018,6 +3028,11 @@ static int perf_sched__timehist(struct perf_sched *sched)
setup_pager(); setup_pager();
/* prefer sched_waking if it is captured */
if (perf_evlist__find_tracepoint_by_name(session->evlist,
"sched:sched_waking"))
handlers[1].handler = timehist_sched_wakeup_ignore;
/* setup per-evsel handlers */ /* setup per-evsel handlers */
if (perf_session__set_tracepoints_handlers(session, handlers)) if (perf_session__set_tracepoints_handlers(session, handlers))
goto out; goto out;
...@@ -3330,12 +3345,16 @@ static int __cmd_record(int argc, const char **argv) ...@@ -3330,12 +3345,16 @@ static int __cmd_record(int argc, const char **argv)
"-e", "sched:sched_stat_iowait", "-e", "sched:sched_stat_iowait",
"-e", "sched:sched_stat_runtime", "-e", "sched:sched_stat_runtime",
"-e", "sched:sched_process_fork", "-e", "sched:sched_process_fork",
"-e", "sched:sched_wakeup",
"-e", "sched:sched_wakeup_new", "-e", "sched:sched_wakeup_new",
"-e", "sched:sched_migrate_task", "-e", "sched:sched_migrate_task",
}; };
struct tep_event *waking_event;
rec_argc = ARRAY_SIZE(record_args) + argc - 1; /*
* +2 for either "-e", "sched:sched_wakeup" or
* "-e", "sched:sched_waking"
*/
rec_argc = ARRAY_SIZE(record_args) + 2 + argc - 1;
rec_argv = calloc(rec_argc + 1, sizeof(char *)); rec_argv = calloc(rec_argc + 1, sizeof(char *));
if (rec_argv == NULL) if (rec_argv == NULL)
...@@ -3344,6 +3363,13 @@ static int __cmd_record(int argc, const char **argv) ...@@ -3344,6 +3363,13 @@ static int __cmd_record(int argc, const char **argv)
for (i = 0; i < ARRAY_SIZE(record_args); i++) for (i = 0; i < ARRAY_SIZE(record_args); i++)
rec_argv[i] = strdup(record_args[i]); rec_argv[i] = strdup(record_args[i]);
rec_argv[i++] = "-e";
waking_event = trace_event__tp_format("sched", "sched_waking");
if (!IS_ERR(waking_event))
rec_argv[i++] = strdup("sched:sched_waking");
else
rec_argv[i++] = strdup("sched:sched_wakeup");
for (j = 1; j < (unsigned int)argc; j++, i++) for (j = 1; j < (unsigned int)argc; j++, i++)
rec_argv[i] = argv[j]; rec_argv[i] = argv[j];
......
...@@ -128,6 +128,9 @@ check arch/x86/lib/insn.c '-I "^#include [\"<]\(../include/\)*asm/in ...@@ -128,6 +128,9 @@ check arch/x86/lib/insn.c '-I "^#include [\"<]\(../include/\)*asm/in
# diff non-symmetric files # diff non-symmetric files
check_2 tools/perf/arch/x86/entry/syscalls/syscall_64.tbl arch/x86/entry/syscalls/syscall_64.tbl check_2 tools/perf/arch/x86/entry/syscalls/syscall_64.tbl arch/x86/entry/syscalls/syscall_64.tbl
# These will require a beauty_check when we get some more like that
check_2 tools/perf/trace/beauty/include/linux/socket.h include/linux/socket.h
# check duplicated library files # check duplicated library files
check_2 tools/perf/util/hashmap.h tools/lib/bpf/hashmap.h check_2 tools/perf/util/hashmap.h tools/lib/bpf/hashmap.h
check_2 tools/perf/util/hashmap.c tools/lib/bpf/hashmap.c check_2 tools/perf/util/hashmap.c tools/lib/bpf/hashmap.c
......
...@@ -60,7 +60,7 @@ ...@@ -60,7 +60,7 @@
}, },
{ {
"BriefDescription": "Stalls due to short latency decimal floating ops.", "BriefDescription": "Stalls due to short latency decimal floating ops.",
"MetricExpr": "(PM_CMPLU_STALL_DFU - PM_CMPLU_STALL_DFLONG)/PM_RUN_INST_CMPL", "MetricExpr": "dfu_stall_cpi - dflong_stall_cpi",
"MetricGroup": "cpi_breakdown", "MetricGroup": "cpi_breakdown",
"MetricName": "dfu_other_stall_cpi" "MetricName": "dfu_other_stall_cpi"
}, },
...@@ -72,7 +72,7 @@ ...@@ -72,7 +72,7 @@
}, },
{ {
"BriefDescription": "Completion stall by Dcache miss which resolved off node memory/cache", "BriefDescription": "Completion stall by Dcache miss which resolved off node memory/cache",
"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", "MetricExpr": "dmiss_non_local_stall_cpi - dmiss_remote_stall_cpi",
"MetricGroup": "cpi_breakdown", "MetricGroup": "cpi_breakdown",
"MetricName": "dmiss_distant_stall_cpi" "MetricName": "dmiss_distant_stall_cpi"
}, },
...@@ -90,7 +90,7 @@ ...@@ -90,7 +90,7 @@
}, },
{ {
"BriefDescription": "Completion stall due to cache miss that resolves in the L2 or L3 without conflict", "BriefDescription": "Completion stall due to cache miss that resolves in the L2 or L3 without conflict",
"MetricExpr": "(PM_CMPLU_STALL_DMISS_L2L3 - PM_CMPLU_STALL_DMISS_L2L3_CONFLICT)/PM_RUN_INST_CMPL", "MetricExpr": "dmiss_l2l3_stall_cpi - dmiss_l2l3_conflict_stall_cpi",
"MetricGroup": "cpi_breakdown", "MetricGroup": "cpi_breakdown",
"MetricName": "dmiss_l2l3_noconflict_stall_cpi" "MetricName": "dmiss_l2l3_noconflict_stall_cpi"
}, },
...@@ -114,7 +114,7 @@ ...@@ -114,7 +114,7 @@
}, },
{ {
"BriefDescription": "Completion stall by Dcache miss which resolved outside of local memory", "BriefDescription": "Completion stall by Dcache miss which resolved outside of local memory",
"MetricExpr": "(PM_CMPLU_STALL_DMISS_L3MISS - PM_CMPLU_STALL_DMISS_L21_L31 - PM_CMPLU_STALL_DMISS_LMEM)/PM_RUN_INST_CMPL", "MetricExpr": "dmiss_l3miss_stall_cpi - dmiss_l21_l31_stall_cpi - dmiss_lmem_stall_cpi",
"MetricGroup": "cpi_breakdown", "MetricGroup": "cpi_breakdown",
"MetricName": "dmiss_non_local_stall_cpi" "MetricName": "dmiss_non_local_stall_cpi"
}, },
...@@ -126,7 +126,7 @@ ...@@ -126,7 +126,7 @@
}, },
{ {
"BriefDescription": "Stalls due to short latency double precision ops.", "BriefDescription": "Stalls due to short latency double precision ops.",
"MetricExpr": "(PM_CMPLU_STALL_DP - PM_CMPLU_STALL_DPLONG)/PM_RUN_INST_CMPL", "MetricExpr": "dp_stall_cpi - dplong_stall_cpi",
"MetricGroup": "cpi_breakdown", "MetricGroup": "cpi_breakdown",
"MetricName": "dp_other_stall_cpi" "MetricName": "dp_other_stall_cpi"
}, },
...@@ -155,7 +155,7 @@ ...@@ -155,7 +155,7 @@
"MetricName": "emq_full_stall_cpi" "MetricName": "emq_full_stall_cpi"
}, },
{ {
"MetricExpr": "(PM_CMPLU_STALL_ERAT_MISS + PM_CMPLU_STALL_EMQ_FULL)/PM_RUN_INST_CMPL", "MetricExpr": "erat_miss_stall_cpi + emq_full_stall_cpi",
"MetricGroup": "cpi_breakdown", "MetricGroup": "cpi_breakdown",
"MetricName": "emq_stall_cpi" "MetricName": "emq_stall_cpi"
}, },
...@@ -173,7 +173,7 @@ ...@@ -173,7 +173,7 @@
}, },
{ {
"BriefDescription": "Completion stall due to execution units for other reasons.", "BriefDescription": "Completion stall due to execution units for other reasons.",
"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", "MetricExpr": "exec_unit_stall_cpi - scalar_stall_cpi - vector_stall_cpi",
"MetricGroup": "cpi_breakdown", "MetricGroup": "cpi_breakdown",
"MetricName": "exec_unit_other_stall_cpi" "MetricName": "exec_unit_other_stall_cpi"
}, },
...@@ -197,7 +197,7 @@ ...@@ -197,7 +197,7 @@
}, },
{ {
"BriefDescription": "Stalls due to short latency integer ops", "BriefDescription": "Stalls due to short latency integer ops",
"MetricExpr": "(PM_CMPLU_STALL_FXU - PM_CMPLU_STALL_FXLONG)/PM_RUN_INST_CMPL", "MetricExpr": "fxu_stall_cpi - fxlong_stall_cpi",
"MetricGroup": "cpi_breakdown", "MetricGroup": "cpi_breakdown",
"MetricName": "fxu_other_stall_cpi" "MetricName": "fxu_other_stall_cpi"
}, },
...@@ -221,7 +221,7 @@ ...@@ -221,7 +221,7 @@
}, },
{ {
"BriefDescription": "Instruction Completion Table other stalls", "BriefDescription": "Instruction Completion Table other stalls",
"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", "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",
"MetricGroup": "cpi_breakdown", "MetricGroup": "cpi_breakdown",
"MetricName": "ict_noslot_cyc_other_cpi" "MetricName": "ict_noslot_cyc_other_cpi"
}, },
...@@ -245,7 +245,7 @@ ...@@ -245,7 +245,7 @@
}, },
{ {
"BriefDescription": "ICT_NOSLOT_DISP_HELD_OTHER_CPI", "BriefDescription": "ICT_NOSLOT_DISP_HELD_OTHER_CPI",
"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", "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",
"MetricGroup": "cpi_breakdown", "MetricGroup": "cpi_breakdown",
"MetricName": "ict_noslot_disp_held_other_cpi" "MetricName": "ict_noslot_disp_held_other_cpi"
}, },
...@@ -263,7 +263,7 @@ ...@@ -263,7 +263,7 @@
}, },
{ {
"BriefDescription": "ICT_NOSLOT_IC_L2_CPI", "BriefDescription": "ICT_NOSLOT_IC_L2_CPI",
"MetricExpr": "(PM_ICT_NOSLOT_IC_MISS - PM_ICT_NOSLOT_IC_L3 - PM_ICT_NOSLOT_IC_L3MISS)/PM_RUN_INST_CMPL", "MetricExpr": "ict_noslot_ic_miss_cpi - ict_noslot_ic_l3_cpi - ict_noslot_ic_l3miss_cpi",
"MetricGroup": "cpi_breakdown", "MetricGroup": "cpi_breakdown",
"MetricName": "ict_noslot_ic_l2_cpi" "MetricName": "ict_noslot_ic_l2_cpi"
}, },
...@@ -286,7 +286,7 @@ ...@@ -286,7 +286,7 @@
"MetricName": "ict_noslot_ic_miss_cpi" "MetricName": "ict_noslot_ic_miss_cpi"
}, },
{ {
"MetricExpr": "(PM_NTC_ISSUE_HELD_DARQ_FULL + PM_NTC_ISSUE_HELD_ARB + PM_NTC_ISSUE_HELD_OTHER)/PM_RUN_INST_CMPL", "MetricExpr": "ntc_issue_held_darq_full_cpi + ntc_issue_held_arb_cpi + ntc_issue_held_other_cpi",
"MetricGroup": "cpi_breakdown", "MetricGroup": "cpi_breakdown",
"MetricName": "issue_hold_cpi" "MetricName": "issue_hold_cpi"
}, },
...@@ -327,7 +327,7 @@ ...@@ -327,7 +327,7 @@
"MetricName": "lrq_other_stall_cpi" "MetricName": "lrq_other_stall_cpi"
}, },
{ {
"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", "MetricExpr": "lmq_full_stall_cpi + st_fwd_stall_cpi + lhs_stall_cpi + lsu_mfspr_stall_cpi + larx_stall_cpi + lrq_other_stall_cpi",
"MetricGroup": "cpi_breakdown", "MetricGroup": "cpi_breakdown",
"MetricName": "lrq_stall_cpi" "MetricName": "lrq_stall_cpi"
}, },
...@@ -338,7 +338,7 @@ ...@@ -338,7 +338,7 @@
"MetricName": "lsaq_arb_stall_cpi" "MetricName": "lsaq_arb_stall_cpi"
}, },
{ {
"MetricExpr": "(PM_CMPLU_STALL_LRQ_FULL + PM_CMPLU_STALL_SRQ_FULL + PM_CMPLU_STALL_LSAQ_ARB)/PM_RUN_INST_CMPL", "MetricExpr": "lrq_full_stall_cpi + srq_full_stall_cpi + lsaq_arb_stall_cpi",
"MetricGroup": "cpi_breakdown", "MetricGroup": "cpi_breakdown",
"MetricName": "lsaq_stall_cpi" "MetricName": "lsaq_stall_cpi"
}, },
...@@ -362,7 +362,7 @@ ...@@ -362,7 +362,7 @@
}, },
{ {
"BriefDescription": "Completion LSU stall for other reasons", "BriefDescription": "Completion LSU stall for other reasons",
"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", "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",
"MetricGroup": "cpi_breakdown", "MetricGroup": "cpi_breakdown",
"MetricName": "lsu_other_stall_cpi" "MetricName": "lsu_other_stall_cpi"
}, },
...@@ -434,13 +434,13 @@ ...@@ -434,13 +434,13 @@
}, },
{ {
"BriefDescription": "Cycles unaccounted for.", "BriefDescription": "Cycles unaccounted for.",
"MetricExpr": "(PM_RUN_CYC - PM_1PLUS_PPC_CMPL - PM_CMPLU_STALL_THRD - PM_CMPLU_STALL - PM_ICT_NOSLOT_CYC)/PM_RUN_INST_CMPL", "MetricExpr": "run_cpi - completion_cpi - thread_block_stall_cpi - stall_cpi - nothing_dispatched_cpi",
"MetricGroup": "cpi_breakdown", "MetricGroup": "cpi_breakdown",
"MetricName": "other_cpi" "MetricName": "other_cpi"
}, },
{ {
"BriefDescription": "Completion stall for other reasons", "BriefDescription": "Completion stall for other reasons",
"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", "MetricExpr": "stall_cpi - ntc_disp_fin_stall_cpi - ntc_flush_stall_cpi - lsu_stall_cpi - exec_unit_stall_cpi - bru_stall_cpi",
"MetricGroup": "cpi_breakdown", "MetricGroup": "cpi_breakdown",
"MetricName": "other_stall_cpi" "MetricName": "other_stall_cpi"
}, },
...@@ -469,7 +469,7 @@ ...@@ -469,7 +469,7 @@
"MetricName": "run_cyc_cpi" "MetricName": "run_cyc_cpi"
}, },
{ {
"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", "MetricExpr": "fxu_stall_cpi + dp_stall_cpi + dfu_stall_cpi + pm_stall_cpi + crypto_stall_cpi",
"MetricGroup": "cpi_breakdown", "MetricGroup": "cpi_breakdown",
"MetricName": "scalar_stall_cpi" "MetricName": "scalar_stall_cpi"
}, },
...@@ -492,7 +492,7 @@ ...@@ -492,7 +492,7 @@
"MetricName": "srq_full_stall_cpi" "MetricName": "srq_full_stall_cpi"
}, },
{ {
"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", "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",
"MetricGroup": "cpi_breakdown", "MetricGroup": "cpi_breakdown",
"MetricName": "srq_stall_cpi" "MetricName": "srq_stall_cpi"
}, },
...@@ -558,7 +558,7 @@ ...@@ -558,7 +558,7 @@
}, },
{ {
"BriefDescription": "Vector stalls due to small latency double precision ops", "BriefDescription": "Vector stalls due to small latency double precision ops",
"MetricExpr": "(PM_CMPLU_STALL_VDP - PM_CMPLU_STALL_VDPLONG)/PM_RUN_INST_CMPL", "MetricExpr": "vdp_stall_cpi - vdplong_stall_cpi",
"MetricGroup": "cpi_breakdown", "MetricGroup": "cpi_breakdown",
"MetricName": "vdp_other_stall_cpi" "MetricName": "vdp_other_stall_cpi"
}, },
...@@ -575,7 +575,7 @@ ...@@ -575,7 +575,7 @@
"MetricName": "vdplong_stall_cpi" "MetricName": "vdplong_stall_cpi"
}, },
{ {
"MetricExpr": "(PM_CMPLU_STALL_VFXU + PM_CMPLU_STALL_VDP)/PM_RUN_INST_CMPL", "MetricExpr": "vfxu_stall_cpi + vdp_stall_cpi",
"MetricGroup": "cpi_breakdown", "MetricGroup": "cpi_breakdown",
"MetricName": "vector_stall_cpi" "MetricName": "vector_stall_cpi"
}, },
...@@ -587,7 +587,7 @@ ...@@ -587,7 +587,7 @@
}, },
{ {
"BriefDescription": "Vector stalls due to small latency integer ops", "BriefDescription": "Vector stalls due to small latency integer ops",
"MetricExpr": "(PM_CMPLU_STALL_VFXU - PM_CMPLU_STALL_VFXLONG)/PM_RUN_INST_CMPL", "MetricExpr": "vfxu_stall_cpi - vfxlong_stall_cpi",
"MetricGroup": "cpi_breakdown", "MetricGroup": "cpi_breakdown",
"MetricName": "vfxu_other_stall_cpi" "MetricName": "vfxu_other_stall_cpi"
}, },
...@@ -1844,7 +1844,7 @@ ...@@ -1844,7 +1844,7 @@
}, },
{ {
"BriefDescription": "% of DL1 reloads from Private L3, other core per Inst", "BriefDescription": "% of DL1 reloads from Private L3, other core per Inst",
"MetricExpr": "(PM_DATA_FROM_L31_MOD + PM_DATA_FROM_L31_SHR) * 100 / PM_RUN_INST_CMPL", "MetricExpr": "dl1_reload_from_l31_mod_rate_percent + dl1_reload_from_l31_shr_rate_percent",
"MetricName": "dl1_reload_from_l31_rate_percent" "MetricName": "dl1_reload_from_l31_rate_percent"
}, },
{ {
...@@ -1979,7 +1979,7 @@ ...@@ -1979,7 +1979,7 @@
}, },
{ {
"BriefDescription": "Completion stall because a different thread was using the completion pipe", "BriefDescription": "Completion stall because a different thread was using the completion pipe",
"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", "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",
"MetricName": "other_thread_cmpl_stall" "MetricName": "other_thread_cmpl_stall"
}, },
{ {
......
...@@ -20,13 +20,13 @@ file=$(mktemp /tmp/temporary_file.XXXXX) ...@@ -20,13 +20,13 @@ file=$(mktemp /tmp/temporary_file.XXXXX)
record_open_file() { record_open_file() {
echo "Recording open file:" echo "Recording open file:"
perf record -o ${perfdata} -e probe:vfs_getname touch $file perf record -o ${perfdata} -e probe:vfs_getname\* touch $file
} }
perf_script_filenames() { perf_script_filenames() {
echo "Looking at perf.data file for vfs_getname records for the file we touched:" echo "Looking at perf.data file for vfs_getname records for the file we touched:"
perf script -i ${perfdata} | \ perf script -i ${perfdata} | \
egrep " +touch +[0-9]+ +\[[0-9]+\] +[0-9]+\.[0-9]+: +probe:vfs_getname: +\([[:xdigit:]]+\) +pathname=\"${file}\"" egrep " +touch +[0-9]+ +\[[0-9]+\] +[0-9]+\.[0-9]+: +probe:vfs_getname[_0-9]*: +\([[:xdigit:]]+\) +pathname=\"${file}\""
} }
add_probe_vfs_getname || skip_if_no_debuginfo add_probe_vfs_getname || skip_if_no_debuginfo
......
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _LINUX_SOCKET_H
#define _LINUX_SOCKET_H
#include <asm/socket.h> /* arch-dependent defines */
#include <linux/sockios.h> /* the SIOCxxx I/O controls */
#include <linux/uio.h> /* iovec support */
#include <linux/types.h> /* pid_t */
#include <linux/compiler.h> /* __user */
#include <uapi/linux/socket.h>
struct file;
struct pid;
struct cred;
struct socket;
#define __sockaddr_check_size(size) \
BUILD_BUG_ON(((size) > sizeof(struct __kernel_sockaddr_storage)))
#ifdef CONFIG_PROC_FS
struct seq_file;
extern void socket_seq_show(struct seq_file *seq);
#endif
typedef __kernel_sa_family_t sa_family_t;
/*
* 1003.1g requires sa_family_t and that sa_data is char.
*/
struct sockaddr {
sa_family_t sa_family; /* address family, AF_xxx */
char sa_data[14]; /* 14 bytes of protocol address */
};
struct linger {
int l_onoff; /* Linger active */
int l_linger; /* How long to linger for */
};
#define sockaddr_storage __kernel_sockaddr_storage
/*
* As we do 4.4BSD message passing we use a 4.4BSD message passing
* system, not 4.3. Thus msg_accrights(len) are now missing. They
* belong in an obscure libc emulation or the bin.
*/
struct msghdr {
void *msg_name; /* ptr to socket address structure */
int msg_namelen; /* size of socket address structure */
struct iov_iter msg_iter; /* data */
/*
* Ancillary data. msg_control_user is the user buffer used for the
* recv* side when msg_control_is_user is set, msg_control is the kernel
* buffer used for all other cases.
*/
union {
void *msg_control;
void __user *msg_control_user;
};
bool msg_control_is_user : 1;
__kernel_size_t msg_controllen; /* ancillary data buffer length */
unsigned int msg_flags; /* flags on received message */
struct kiocb *msg_iocb; /* ptr to iocb for async requests */
};
struct user_msghdr {
void __user *msg_name; /* ptr to socket address structure */
int msg_namelen; /* size of socket address structure */
struct iovec __user *msg_iov; /* scatter/gather array */
__kernel_size_t msg_iovlen; /* # elements in msg_iov */
void __user *msg_control; /* ancillary data */
__kernel_size_t msg_controllen; /* ancillary data buffer length */
unsigned int msg_flags; /* flags on received message */
};
/* For recvmmsg/sendmmsg */
struct mmsghdr {
struct user_msghdr msg_hdr;
unsigned int msg_len;
};
/*
* POSIX 1003.1g - ancillary data object information
* Ancillary data consits of a sequence of pairs of
* (cmsghdr, cmsg_data[])
*/
struct cmsghdr {
__kernel_size_t cmsg_len; /* data byte count, including hdr */
int cmsg_level; /* originating protocol */
int cmsg_type; /* protocol-specific type */
};
/*
* Ancillary data object information MACROS
* Table 5-14 of POSIX 1003.1g
*/
#define __CMSG_NXTHDR(ctl, len, cmsg) __cmsg_nxthdr((ctl),(len),(cmsg))
#define CMSG_NXTHDR(mhdr, cmsg) cmsg_nxthdr((mhdr), (cmsg))
#define CMSG_ALIGN(len) ( ((len)+sizeof(long)-1) & ~(sizeof(long)-1) )
#define CMSG_DATA(cmsg) \
((void *)(cmsg) + sizeof(struct cmsghdr))
#define CMSG_USER_DATA(cmsg) \
((void __user *)(cmsg) + sizeof(struct cmsghdr))
#define CMSG_SPACE(len) (sizeof(struct cmsghdr) + CMSG_ALIGN(len))
#define CMSG_LEN(len) (sizeof(struct cmsghdr) + (len))
#define __CMSG_FIRSTHDR(ctl,len) ((len) >= sizeof(struct cmsghdr) ? \
(struct cmsghdr *)(ctl) : \
(struct cmsghdr *)NULL)
#define CMSG_FIRSTHDR(msg) __CMSG_FIRSTHDR((msg)->msg_control, (msg)->msg_controllen)
#define CMSG_OK(mhdr, cmsg) ((cmsg)->cmsg_len >= sizeof(struct cmsghdr) && \
(cmsg)->cmsg_len <= (unsigned long) \
((mhdr)->msg_controllen - \
((char *)(cmsg) - (char *)(mhdr)->msg_control)))
#define for_each_cmsghdr(cmsg, msg) \
for (cmsg = CMSG_FIRSTHDR(msg); \
cmsg; \
cmsg = CMSG_NXTHDR(msg, cmsg))
/*
* Get the next cmsg header
*
* PLEASE, do not touch this function. If you think, that it is
* incorrect, grep kernel sources and think about consequences
* before trying to improve it.
*
* Now it always returns valid, not truncated ancillary object
* HEADER. But caller still MUST check, that cmsg->cmsg_len is
* inside range, given by msg->msg_controllen before using
* ancillary object DATA. --ANK (980731)
*/
static inline struct cmsghdr * __cmsg_nxthdr(void *__ctl, __kernel_size_t __size,
struct cmsghdr *__cmsg)
{
struct cmsghdr * __ptr;
__ptr = (struct cmsghdr*)(((unsigned char *) __cmsg) + CMSG_ALIGN(__cmsg->cmsg_len));
if ((unsigned long)((char*)(__ptr+1) - (char *) __ctl) > __size)
return (struct cmsghdr *)0;
return __ptr;
}
static inline struct cmsghdr * cmsg_nxthdr (struct msghdr *__msg, struct cmsghdr *__cmsg)
{
return __cmsg_nxthdr(__msg->msg_control, __msg->msg_controllen, __cmsg);
}
static inline size_t msg_data_left(struct msghdr *msg)
{
return iov_iter_count(&msg->msg_iter);
}
/* "Socket"-level control message types: */
#define SCM_RIGHTS 0x01 /* rw: access rights (array of int) */
#define SCM_CREDENTIALS 0x02 /* rw: struct ucred */
#define SCM_SECURITY 0x03 /* rw: security label */
struct ucred {
__u32 pid;
__u32 uid;
__u32 gid;
};
/* Supported address families. */
#define AF_UNSPEC 0
#define AF_UNIX 1 /* Unix domain sockets */
#define AF_LOCAL 1 /* POSIX name for AF_UNIX */
#define AF_INET 2 /* Internet IP Protocol */
#define AF_AX25 3 /* Amateur Radio AX.25 */
#define AF_IPX 4 /* Novell IPX */
#define AF_APPLETALK 5 /* AppleTalk DDP */
#define AF_NETROM 6 /* Amateur Radio NET/ROM */
#define AF_BRIDGE 7 /* Multiprotocol bridge */
#define AF_ATMPVC 8 /* ATM PVCs */
#define AF_X25 9 /* Reserved for X.25 project */
#define AF_INET6 10 /* IP version 6 */
#define AF_ROSE 11 /* Amateur Radio X.25 PLP */
#define AF_DECnet 12 /* Reserved for DECnet project */
#define AF_NETBEUI 13 /* Reserved for 802.2LLC project*/
#define AF_SECURITY 14 /* Security callback pseudo AF */
#define AF_KEY 15 /* PF_KEY key management API */
#define AF_NETLINK 16
#define AF_ROUTE AF_NETLINK /* Alias to emulate 4.4BSD */
#define AF_PACKET 17 /* Packet family */
#define AF_ASH 18 /* Ash */
#define AF_ECONET 19 /* Acorn Econet */
#define AF_ATMSVC 20 /* ATM SVCs */
#define AF_RDS 21 /* RDS sockets */
#define AF_SNA 22 /* Linux SNA Project (nutters!) */
#define AF_IRDA 23 /* IRDA sockets */
#define AF_PPPOX 24 /* PPPoX sockets */
#define AF_WANPIPE 25 /* Wanpipe API Sockets */
#define AF_LLC 26 /* Linux LLC */
#define AF_IB 27 /* Native InfiniBand address */
#define AF_MPLS 28 /* MPLS */
#define AF_CAN 29 /* Controller Area Network */
#define AF_TIPC 30 /* TIPC sockets */
#define AF_BLUETOOTH 31 /* Bluetooth sockets */
#define AF_IUCV 32 /* IUCV sockets */
#define AF_RXRPC 33 /* RxRPC sockets */
#define AF_ISDN 34 /* mISDN sockets */
#define AF_PHONET 35 /* Phonet sockets */
#define AF_IEEE802154 36 /* IEEE802154 sockets */
#define AF_CAIF 37 /* CAIF sockets */
#define AF_ALG 38 /* Algorithm sockets */
#define AF_NFC 39 /* NFC sockets */
#define AF_VSOCK 40 /* vSockets */
#define AF_KCM 41 /* Kernel Connection Multiplexor*/
#define AF_QIPCRTR 42 /* Qualcomm IPC Router */
#define AF_SMC 43 /* smc sockets: reserve number for
* PF_SMC protocol family that
* reuses AF_INET address family
*/
#define AF_XDP 44 /* XDP sockets */
#define AF_MAX 45 /* For now.. */
/* Protocol families, same as address families. */
#define PF_UNSPEC AF_UNSPEC
#define PF_UNIX AF_UNIX
#define PF_LOCAL AF_LOCAL
#define PF_INET AF_INET
#define PF_AX25 AF_AX25
#define PF_IPX AF_IPX
#define PF_APPLETALK AF_APPLETALK
#define PF_NETROM AF_NETROM
#define PF_BRIDGE AF_BRIDGE
#define PF_ATMPVC AF_ATMPVC
#define PF_X25 AF_X25
#define PF_INET6 AF_INET6
#define PF_ROSE AF_ROSE
#define PF_DECnet AF_DECnet
#define PF_NETBEUI AF_NETBEUI
#define PF_SECURITY AF_SECURITY
#define PF_KEY AF_KEY
#define PF_NETLINK AF_NETLINK
#define PF_ROUTE AF_ROUTE
#define PF_PACKET AF_PACKET
#define PF_ASH AF_ASH
#define PF_ECONET AF_ECONET
#define PF_ATMSVC AF_ATMSVC
#define PF_RDS AF_RDS
#define PF_SNA AF_SNA
#define PF_IRDA AF_IRDA
#define PF_PPPOX AF_PPPOX
#define PF_WANPIPE AF_WANPIPE
#define PF_LLC AF_LLC
#define PF_IB AF_IB
#define PF_MPLS AF_MPLS
#define PF_CAN AF_CAN
#define PF_TIPC AF_TIPC
#define PF_BLUETOOTH AF_BLUETOOTH
#define PF_IUCV AF_IUCV
#define PF_RXRPC AF_RXRPC
#define PF_ISDN AF_ISDN
#define PF_PHONET AF_PHONET
#define PF_IEEE802154 AF_IEEE802154
#define PF_CAIF AF_CAIF
#define PF_ALG AF_ALG
#define PF_NFC AF_NFC
#define PF_VSOCK AF_VSOCK
#define PF_KCM AF_KCM
#define PF_QIPCRTR AF_QIPCRTR
#define PF_SMC AF_SMC
#define PF_XDP AF_XDP
#define PF_MAX AF_MAX
/* Maximum queue length specifiable by listen. */
#define SOMAXCONN 4096
/* Flags we can use with send/ and recv.
Added those for 1003.1g not all are supported yet
*/
#define MSG_OOB 1
#define MSG_PEEK 2
#define MSG_DONTROUTE 4
#define MSG_TRYHARD 4 /* Synonym for MSG_DONTROUTE for DECnet */
#define MSG_CTRUNC 8
#define MSG_PROBE 0x10 /* Do not send. Only probe path f.e. for MTU */
#define MSG_TRUNC 0x20
#define MSG_DONTWAIT 0x40 /* Nonblocking io */
#define MSG_EOR 0x80 /* End of record */
#define MSG_WAITALL 0x100 /* Wait for a full request */
#define MSG_FIN 0x200
#define MSG_SYN 0x400
#define MSG_CONFIRM 0x800 /* Confirm path validity */
#define MSG_RST 0x1000
#define MSG_ERRQUEUE 0x2000 /* Fetch message from error queue */
#define MSG_NOSIGNAL 0x4000 /* Do not generate SIGPIPE */
#define MSG_MORE 0x8000 /* Sender will send more */
#define MSG_WAITFORONE 0x10000 /* recvmmsg(): block until 1+ packets avail */
#define MSG_SENDPAGE_NOPOLICY 0x10000 /* sendpage() internal : do no apply policy */
#define MSG_SENDPAGE_NOTLAST 0x20000 /* sendpage() internal : not the last page */
#define MSG_BATCH 0x40000 /* sendmmsg(): more messages coming */
#define MSG_EOF MSG_FIN
#define MSG_NO_SHARED_FRAGS 0x80000 /* sendpage() internal : page frags are not shared */
#define MSG_SENDPAGE_DECRYPTED 0x100000 /* sendpage() internal : page may carry
* plain text and require encryption
*/
#define MSG_ZEROCOPY 0x4000000 /* Use user data in kernel path */
#define MSG_FASTOPEN 0x20000000 /* Send data in TCP SYN */
#define MSG_CMSG_CLOEXEC 0x40000000 /* Set close_on_exec for file
descriptor received through
SCM_RIGHTS */
#if defined(CONFIG_COMPAT)
#define MSG_CMSG_COMPAT 0x80000000 /* This message needs 32 bit fixups */
#else
#define MSG_CMSG_COMPAT 0 /* We never have 32 bit fixups */
#endif
/* Setsockoptions(2) level. Thanks to BSD these must match IPPROTO_xxx */
#define SOL_IP 0
/* #define SOL_ICMP 1 No-no-no! Due to Linux :-) we cannot use SOL_ICMP=1 */
#define SOL_TCP 6
#define SOL_UDP 17
#define SOL_IPV6 41
#define SOL_ICMPV6 58
#define SOL_SCTP 132
#define SOL_UDPLITE 136 /* UDP-Lite (RFC 3828) */
#define SOL_RAW 255
#define SOL_IPX 256
#define SOL_AX25 257
#define SOL_ATALK 258
#define SOL_NETROM 259
#define SOL_ROSE 260
#define SOL_DECNET 261
#define SOL_X25 262
#define SOL_PACKET 263
#define SOL_ATM 264 /* ATM layer (cell level) */
#define SOL_AAL 265 /* ATM Adaption Layer (packet level) */
#define SOL_IRDA 266
#define SOL_NETBEUI 267
#define SOL_LLC 268
#define SOL_DCCP 269
#define SOL_NETLINK 270
#define SOL_TIPC 271
#define SOL_RXRPC 272
#define SOL_PPPOL2TP 273
#define SOL_BLUETOOTH 274
#define SOL_PNPIPE 275
#define SOL_RDS 276
#define SOL_IUCV 277
#define SOL_CAIF 278
#define SOL_ALG 279
#define SOL_NFC 280
#define SOL_KCM 281
#define SOL_TLS 282
#define SOL_XDP 283
/* IPX options */
#define IPX_TYPE 1
extern int move_addr_to_kernel(void __user *uaddr, int ulen, struct sockaddr_storage *kaddr);
extern int put_cmsg(struct msghdr*, int level, int type, int len, void *data);
struct timespec64;
struct __kernel_timespec;
struct old_timespec32;
struct scm_timestamping_internal {
struct timespec64 ts[3];
};
extern void put_cmsg_scm_timestamping64(struct msghdr *msg, struct scm_timestamping_internal *tss);
extern void put_cmsg_scm_timestamping(struct msghdr *msg, struct scm_timestamping_internal *tss);
/* The __sys_...msg variants allow MSG_CMSG_COMPAT iff
* forbid_cmsg_compat==false
*/
extern long __sys_recvmsg(int fd, struct user_msghdr __user *msg,
unsigned int flags, bool forbid_cmsg_compat);
extern long __sys_sendmsg(int fd, struct user_msghdr __user *msg,
unsigned int flags, bool forbid_cmsg_compat);
extern int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg,
unsigned int vlen, unsigned int flags,
struct __kernel_timespec __user *timeout,
struct old_timespec32 __user *timeout32);
extern int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg,
unsigned int vlen, unsigned int flags,
bool forbid_cmsg_compat);
extern long __sys_sendmsg_sock(struct socket *sock, struct msghdr *msg,
unsigned int flags);
extern long __sys_recvmsg_sock(struct socket *sock, struct msghdr *msg,
struct user_msghdr __user *umsg,
struct sockaddr __user *uaddr,
unsigned int flags);
extern int sendmsg_copy_msghdr(struct msghdr *msg,
struct user_msghdr __user *umsg, unsigned flags,
struct iovec **iov);
extern int recvmsg_copy_msghdr(struct msghdr *msg,
struct user_msghdr __user *umsg, unsigned flags,
struct sockaddr __user **uaddr,
struct iovec **iov);
extern int __copy_msghdr_from_user(struct msghdr *kmsg,
struct user_msghdr __user *umsg,
struct sockaddr __user **save_addr,
struct iovec __user **uiov, size_t *nsegs);
/* helpers which do the actual work for syscalls */
extern int __sys_recvfrom(int fd, void __user *ubuf, size_t size,
unsigned int flags, struct sockaddr __user *addr,
int __user *addr_len);
extern int __sys_sendto(int fd, void __user *buff, size_t len,
unsigned int flags, struct sockaddr __user *addr,
int addr_len);
extern int __sys_accept4_file(struct file *file, unsigned file_flags,
struct sockaddr __user *upeer_sockaddr,
int __user *upeer_addrlen, int flags,
unsigned long nofile);
extern int __sys_accept4(int fd, struct sockaddr __user *upeer_sockaddr,
int __user *upeer_addrlen, int flags);
extern int __sys_socket(int family, int type, int protocol);
extern int __sys_bind(int fd, struct sockaddr __user *umyaddr, int addrlen);
extern int __sys_connect_file(struct file *file, struct sockaddr_storage *addr,
int addrlen, int file_flags);
extern int __sys_connect(int fd, struct sockaddr __user *uservaddr,
int addrlen);
extern int __sys_listen(int fd, int backlog);
extern int __sys_getsockname(int fd, struct sockaddr __user *usockaddr,
int __user *usockaddr_len);
extern int __sys_getpeername(int fd, struct sockaddr __user *usockaddr,
int __user *usockaddr_len);
extern int __sys_socketpair(int family, int type, int protocol,
int __user *usockvec);
extern int __sys_shutdown(int fd, int how);
extern struct ns_common *get_net_ns(struct ns_common *ns);
#endif /* _LINUX_SOCKET_H */
...@@ -7,14 +7,7 @@ ...@@ -7,14 +7,7 @@
#include <sys/un.h> #include <sys/un.h>
#include <arpa/inet.h> #include <arpa/inet.h>
static const char *socket_families[] = { #include "trace/beauty/generated/socket_arrays.c"
"UNSPEC", "LOCAL", "INET", "AX25", "IPX", "APPLETALK", "NETROM",
"BRIDGE", "ATMPVC", "X25", "INET6", "ROSE", "DECnet", "NETBEUI",
"SECURITY", "KEY", "NETLINK", "PACKET", "ASH", "ECONET", "ATMSVC",
"RDS", "SNA", "IRDA", "PPPOX", "WANPIPE", "LLC", "IB", "CAN", "TIPC",
"BLUETOOTH", "IUCV", "RXRPC", "ISDN", "PHONET", "IEEE802154", "CAIF",
"ALG", "NFC", "VSOCK",
};
DEFINE_STRARRAY(socket_families, "PF_"); DEFINE_STRARRAY(socket_families, "PF_");
static size_t af_inet__scnprintf(struct sockaddr *sa, char *bf, size_t size) static size_t af_inet__scnprintf(struct sockaddr *sa, char *bf, size_t size)
......
#!/bin/sh
# SPDX-License-Identifier: LGPL-2.1
# This one uses a copy from the kernel sources headers that is in a
# place used just for these tools/perf/beauty/ usage, we shouldn't not
# put it in tools/include/linux otherwise they would be used in the
# normal compiler building process and would drag needless stuff from the
# kernel.
# When what these scripts need is already in tools/include/ then use it,
# otherwise grab and check the copy from the kernel sources just for these
# string table building scripts.
[ $# -eq 1 ] && header_dir=$1 || header_dir=tools/perf/trace/beauty/include/linux/
printf "static const char *socket_families[] = {\n"
# #define AF_LOCAL 1 /* POSIX name for AF_UNIX */
regex='^#define[[:space:]]+AF_(\w+)[[:space:]]+([[:digit:]]+).*'
egrep $regex ${header_dir}/socket.h | \
sed -r "s/$regex/\2 \1/g" | \
xargs printf "\t[%s] = \"%s\",\n" | \
egrep -v "\"(UNIX|MAX)\""
printf "};\n"
...@@ -117,6 +117,7 @@ endif ...@@ -117,6 +117,7 @@ endif
perf-y += parse-branch-options.o perf-y += parse-branch-options.o
perf-y += dump-insn.o perf-y += dump-insn.o
perf-y += parse-regs-options.o perf-y += parse-regs-options.o
perf-y += parse-sublevel-options.o
perf-y += term.o perf-y += term.o
perf-y += help-unknown-cmd.o perf-y += help-unknown-cmd.o
perf-y += mem-events.o perf-y += mem-events.o
......
...@@ -31,6 +31,10 @@ ...@@ -31,6 +31,10 @@
#include "probe-file.h" #include "probe-file.h"
#include "strlist.h" #include "strlist.h"
#ifdef HAVE_DEBUGINFOD_SUPPORT
#include <elfutils/debuginfod.h>
#endif
#include <linux/ctype.h> #include <linux/ctype.h>
#include <linux/zalloc.h> #include <linux/zalloc.h>
...@@ -636,6 +640,21 @@ static char *build_id_cache__find_debug(const char *sbuild_id, ...@@ -636,6 +640,21 @@ static char *build_id_cache__find_debug(const char *sbuild_id,
if (realname && access(realname, R_OK)) if (realname && access(realname, R_OK))
zfree(&realname); zfree(&realname);
nsinfo__mountns_exit(&nsc); nsinfo__mountns_exit(&nsc);
#ifdef HAVE_DEBUGINFOD_SUPPORT
if (realname == NULL) {
debuginfod_client* c = debuginfod_begin();
if (c != NULL) {
int fd = debuginfod_find_debuginfo(c,
(const unsigned char*)sbuild_id, 0,
&realname);
if (fd >= 0)
close(fd); /* retaining reference by realname */
debuginfod_end(c);
}
}
#endif
out: out:
free(debugfile); free(debugfile);
return realname; return realname;
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "target.h" #include "target.h"
#include "ui/helpline.h" #include "ui/helpline.h"
#include "ui/ui.h" #include "ui/ui.h"
#include "util/parse-sublevel-options.h"
#include <linux/ctype.h> #include <linux/ctype.h>
...@@ -173,65 +174,37 @@ void trace_event(union perf_event *event) ...@@ -173,65 +174,37 @@ void trace_event(union perf_event *event)
trace_event_printer, event); trace_event_printer, event);
} }
static struct debug_variable { static struct sublevel_option debug_opts[] = {
const char *name; { .name = "verbose", .value_ptr = &verbose },
int *ptr; { .name = "ordered-events", .value_ptr = &debug_ordered_events},
} debug_variables[] = { { .name = "stderr", .value_ptr = &redirect_to_stderr},
{ .name = "verbose", .ptr = &verbose }, { .name = "data-convert", .value_ptr = &debug_data_convert },
{ .name = "ordered-events", .ptr = &debug_ordered_events}, { .name = "perf-event-open", .value_ptr = &debug_peo_args },
{ .name = "stderr", .ptr = &redirect_to_stderr},
{ .name = "data-convert", .ptr = &debug_data_convert },
{ .name = "perf-event-open", .ptr = &debug_peo_args },
{ .name = NULL, } { .name = NULL, }
}; };
int perf_debug_option(const char *str) int perf_debug_option(const char *str)
{ {
struct debug_variable *var = &debug_variables[0]; int ret;
char *vstr, *s = strdup(str);
int v = 1;
vstr = strchr(s, '=');
if (vstr)
*vstr++ = 0;
while (var->name) {
if (!strcmp(s, var->name))
break;
var++;
}
if (!var->name) {
pr_err("Unknown debug variable name '%s'\n", s);
free(s);
return -1;
}
if (vstr) { ret = perf_parse_sublevel_options(str, debug_opts);
v = atoi(vstr); if (ret)
/* return ret;
* Allow only values in range (0, 10),
* otherwise set 0.
*/
v = (v < 0) || (v > 10) ? 0 : v;
}
if (quiet) /* Allow only verbose value in range (0, 10), otherwise set 0. */
v = -1; verbose = (verbose < 0) || (verbose > 10) ? 0 : verbose;
*var->ptr = v;
free(s);
return 0; return 0;
} }
int perf_quiet_option(void) int perf_quiet_option(void)
{ {
struct debug_variable *var = &debug_variables[0]; struct sublevel_option *opt = &debug_opts[0];
/* disable all debug messages */ /* disable all debug messages */
while (var->name) { while (opt->name) {
*var->ptr = -1; *opt->value_ptr = -1;
var++; opt++;
} }
return 0; return 0;
......
...@@ -1265,7 +1265,7 @@ struct dso *dso__new_id(const char *name, struct dso_id *id) ...@@ -1265,7 +1265,7 @@ struct dso *dso__new_id(const char *name, struct dso_id *id)
dso->has_build_id = 0; dso->has_build_id = 0;
dso->has_srcline = 1; dso->has_srcline = 1;
dso->a2l_fails = 1; dso->a2l_fails = 1;
dso->kernel = DSO_TYPE_USER; dso->kernel = DSO_SPACE__USER;
dso->needs_swap = DSO_SWAP__UNSET; dso->needs_swap = DSO_SWAP__UNSET;
dso->comp = COMP_ID__NONE; dso->comp = COMP_ID__NONE;
RB_CLEAR_NODE(&dso->rb_node); RB_CLEAR_NODE(&dso->rb_node);
......
...@@ -46,10 +46,10 @@ enum dso_binary_type { ...@@ -46,10 +46,10 @@ enum dso_binary_type {
DSO_BINARY_TYPE__NOT_FOUND, DSO_BINARY_TYPE__NOT_FOUND,
}; };
enum dso_kernel_type { enum dso_space_type {
DSO_TYPE_USER = 0, DSO_SPACE__USER = 0,
DSO_TYPE_KERNEL, DSO_SPACE__KERNEL,
DSO_TYPE_GUEST_KERNEL DSO_SPACE__KERNEL_GUEST
}; };
enum dso_swap_type { enum dso_swap_type {
...@@ -160,7 +160,7 @@ struct dso { ...@@ -160,7 +160,7 @@ struct dso {
void *a2l; void *a2l;
char *symsrc_filename; char *symsrc_filename;
unsigned int a2l_fails; unsigned int a2l_fails;
enum dso_kernel_type kernel; enum dso_space_type kernel;
enum dso_swap_type needs_swap; enum dso_swap_type needs_swap;
enum dso_binary_type symtab_type; enum dso_binary_type symtab_type;
enum dso_binary_type binary_type; enum dso_binary_type binary_type;
......
...@@ -2056,7 +2056,7 @@ static int __event_process_build_id(struct perf_record_header_build_id *bev, ...@@ -2056,7 +2056,7 @@ static int __event_process_build_id(struct perf_record_header_build_id *bev,
struct machine *machine; struct machine *machine;
u16 cpumode; u16 cpumode;
struct dso *dso; struct dso *dso;
enum dso_kernel_type dso_type; enum dso_space_type dso_space;
machine = perf_session__findnew_machine(session, bev->pid); machine = perf_session__findnew_machine(session, bev->pid);
if (!machine) if (!machine)
...@@ -2066,14 +2066,14 @@ static int __event_process_build_id(struct perf_record_header_build_id *bev, ...@@ -2066,14 +2066,14 @@ static int __event_process_build_id(struct perf_record_header_build_id *bev,
switch (cpumode) { switch (cpumode) {
case PERF_RECORD_MISC_KERNEL: case PERF_RECORD_MISC_KERNEL:
dso_type = DSO_TYPE_KERNEL; dso_space = DSO_SPACE__KERNEL;
break; break;
case PERF_RECORD_MISC_GUEST_KERNEL: case PERF_RECORD_MISC_GUEST_KERNEL:
dso_type = DSO_TYPE_GUEST_KERNEL; dso_space = DSO_SPACE__KERNEL_GUEST;
break; break;
case PERF_RECORD_MISC_USER: case PERF_RECORD_MISC_USER:
case PERF_RECORD_MISC_GUEST_USER: case PERF_RECORD_MISC_GUEST_USER:
dso_type = DSO_TYPE_USER; dso_space = DSO_SPACE__USER;
break; break;
default: default:
goto out; goto out;
...@@ -2085,14 +2085,13 @@ static int __event_process_build_id(struct perf_record_header_build_id *bev, ...@@ -2085,14 +2085,13 @@ static int __event_process_build_id(struct perf_record_header_build_id *bev,
dso__set_build_id(dso, &bev->build_id); dso__set_build_id(dso, &bev->build_id);
if (dso_type != DSO_TYPE_USER) { if (dso_space != DSO_SPACE__USER) {
struct kmod_path m = { .name = NULL, }; struct kmod_path m = { .name = NULL, };
if (!kmod_path__parse_name(&m, filename) && m.kmod) if (!kmod_path__parse_name(&m, filename) && m.kmod)
dso__set_module_info(dso, &m, machine); dso__set_module_info(dso, &m, machine);
else
dso->kernel = dso_type;
dso->kernel = dso_space;
free(m.name); free(m.name);
} }
......
...@@ -703,7 +703,7 @@ static struct dso *machine__findnew_module_dso(struct machine *machine, ...@@ -703,7 +703,7 @@ static struct dso *machine__findnew_module_dso(struct machine *machine,
dso__set_module_info(dso, m, machine); dso__set_module_info(dso, m, machine);
dso__set_long_name(dso, strdup(filename), true); dso__set_long_name(dso, strdup(filename), true);
dso->kernel = DSO_TYPE_KERNEL; dso->kernel = DSO_SPACE__KERNEL;
} }
dso__get(dso); dso__get(dso);
...@@ -753,7 +753,7 @@ static int machine__process_ksymbol_register(struct machine *machine, ...@@ -753,7 +753,7 @@ static int machine__process_ksymbol_register(struct machine *machine,
struct dso *dso = dso__new(event->ksymbol.name); struct dso *dso = dso__new(event->ksymbol.name);
if (dso) { if (dso) {
dso->kernel = DSO_TYPE_KERNEL; dso->kernel = DSO_SPACE__KERNEL;
map = map__new2(0, dso); map = map__new2(0, dso);
} }
...@@ -971,14 +971,14 @@ static struct dso *machine__get_kernel(struct machine *machine) ...@@ -971,14 +971,14 @@ static struct dso *machine__get_kernel(struct machine *machine)
vmlinux_name = symbol_conf.vmlinux_name; vmlinux_name = symbol_conf.vmlinux_name;
kernel = machine__findnew_kernel(machine, vmlinux_name, kernel = machine__findnew_kernel(machine, vmlinux_name,
"[kernel]", DSO_TYPE_KERNEL); "[kernel]", DSO_SPACE__KERNEL);
} else { } else {
if (symbol_conf.default_guest_vmlinux_name) if (symbol_conf.default_guest_vmlinux_name)
vmlinux_name = symbol_conf.default_guest_vmlinux_name; vmlinux_name = symbol_conf.default_guest_vmlinux_name;
kernel = machine__findnew_kernel(machine, vmlinux_name, kernel = machine__findnew_kernel(machine, vmlinux_name,
"[guest.kernel]", "[guest.kernel]",
DSO_TYPE_GUEST_KERNEL); DSO_SPACE__KERNEL_GUEST);
} }
if (kernel != NULL && (!kernel->has_build_id)) if (kernel != NULL && (!kernel->has_build_id))
...@@ -1606,7 +1606,7 @@ static int machine__process_kernel_mmap_event(struct machine *machine, ...@@ -1606,7 +1606,7 @@ static int machine__process_kernel_mmap_event(struct machine *machine,
union perf_event *event) union perf_event *event)
{ {
struct map *map; struct map *map;
enum dso_kernel_type kernel_type; enum dso_space_type dso_space;
bool is_kernel_mmap; bool is_kernel_mmap;
/* If we have maps from kcore then we do not need or want any others */ /* If we have maps from kcore then we do not need or want any others */
...@@ -1614,9 +1614,9 @@ static int machine__process_kernel_mmap_event(struct machine *machine, ...@@ -1614,9 +1614,9 @@ static int machine__process_kernel_mmap_event(struct machine *machine,
return 0; return 0;
if (machine__is_host(machine)) if (machine__is_host(machine))
kernel_type = DSO_TYPE_KERNEL; dso_space = DSO_SPACE__KERNEL;
else else
kernel_type = DSO_TYPE_GUEST_KERNEL; dso_space = DSO_SPACE__KERNEL_GUEST;
is_kernel_mmap = memcmp(event->mmap.filename, is_kernel_mmap = memcmp(event->mmap.filename,
machine->mmap_name, machine->mmap_name,
...@@ -1676,7 +1676,7 @@ static int machine__process_kernel_mmap_event(struct machine *machine, ...@@ -1676,7 +1676,7 @@ static int machine__process_kernel_mmap_event(struct machine *machine,
if (kernel == NULL) if (kernel == NULL)
goto out_problem; goto out_problem;
kernel->kernel = kernel_type; kernel->kernel = dso_space;
if (__machine__create_kernel_maps(machine, kernel) < 0) { if (__machine__create_kernel_maps(machine, kernel) < 0) {
dso__put(kernel); dso__put(kernel);
goto out_problem; goto out_problem;
......
...@@ -486,7 +486,7 @@ u64 map__rip_2objdump(struct map *map, u64 rip) ...@@ -486,7 +486,7 @@ u64 map__rip_2objdump(struct map *map, u64 rip)
* kernel modules also have DSO_TYPE_USER in dso->kernel, * kernel modules also have DSO_TYPE_USER in dso->kernel,
* but all kernel modules are ET_REL, so won't get here. * but all kernel modules are ET_REL, so won't get here.
*/ */
if (map->dso->kernel == DSO_TYPE_USER) if (map->dso->kernel == DSO_SPACE__USER)
return rip + map->dso->text_offset; return rip + map->dso->text_offset;
return map->unmap_ip(map, rip) - map->reloc; return map->unmap_ip(map, rip) - map->reloc;
...@@ -516,7 +516,7 @@ u64 map__objdump_2mem(struct map *map, u64 ip) ...@@ -516,7 +516,7 @@ u64 map__objdump_2mem(struct map *map, u64 ip)
* kernel modules also have DSO_TYPE_USER in dso->kernel, * kernel modules also have DSO_TYPE_USER in dso->kernel,
* but all kernel modules are ET_REL, so won't get here. * but all kernel modules are ET_REL, so won't get here.
*/ */
if (map->dso->kernel == DSO_TYPE_USER) if (map->dso->kernel == DSO_SPACE__USER)
return map->unmap_ip(map, ip - map->dso->text_offset); return map->unmap_ip(map, ip - map->dso->text_offset);
return ip + map->reloc; return ip + map->reloc;
......
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include "util/debug.h"
#include "util/parse-sublevel-options.h"
static int parse_one_sublevel_option(const char *str,
struct sublevel_option *opts)
{
struct sublevel_option *opt = opts;
char *vstr, *s = strdup(str);
int v = 1;
if (!s) {
pr_err("no memory\n");
return -1;
}
vstr = strchr(s, '=');
if (vstr)
*vstr++ = 0;
while (opt->name) {
if (!strcmp(s, opt->name))
break;
opt++;
}
if (!opt->name) {
pr_err("Unknown option name '%s'\n", s);
free(s);
return -1;
}
if (vstr)
v = atoi(vstr);
*opt->value_ptr = v;
free(s);
return 0;
}
/* parse options like --foo a=<n>,b,c... */
int perf_parse_sublevel_options(const char *str, struct sublevel_option *opts)
{
char *s = strdup(str);
char *p = NULL;
int ret;
if (!s) {
pr_err("no memory\n");
return -1;
}
p = strtok(s, ",");
while (p) {
ret = parse_one_sublevel_option(p, opts);
if (ret) {
free(s);
return ret;
}
p = strtok(NULL, ",");
}
free(s);
return 0;
}
#ifndef _PERF_PARSE_SUBLEVEL_OPTIONS_H
#define _PERF_PARSE_SUBLEVEL_OPTIONS_H
struct sublevel_option {
const char *name;
int *value_ptr;
};
int perf_parse_sublevel_options(const char *str, struct sublevel_option *opts);
#endif
\ No newline at end of file
...@@ -789,7 +789,7 @@ int symsrc__init(struct symsrc *ss, struct dso *dso, const char *name, ...@@ -789,7 +789,7 @@ int symsrc__init(struct symsrc *ss, struct dso *dso, const char *name,
if (ss->opdshdr.sh_type != SHT_PROGBITS) if (ss->opdshdr.sh_type != SHT_PROGBITS)
ss->opdsec = NULL; ss->opdsec = NULL;
if (dso->kernel == DSO_TYPE_USER) if (dso->kernel == DSO_SPACE__USER)
ss->adjust_symbols = true; ss->adjust_symbols = true;
else else
ss->adjust_symbols = elf__needs_adjust_symbols(ehdr); ss->adjust_symbols = elf__needs_adjust_symbols(ehdr);
...@@ -872,7 +872,7 @@ static int dso__process_kernel_symbol(struct dso *dso, struct map *map, ...@@ -872,7 +872,7 @@ static int dso__process_kernel_symbol(struct dso *dso, struct map *map,
* kallsyms and identity maps. Overwrite it to * kallsyms and identity maps. Overwrite it to
* map to the kernel dso. * map to the kernel dso.
*/ */
if (*remap_kernel && dso->kernel) { if (*remap_kernel && dso->kernel && !kmodule) {
*remap_kernel = false; *remap_kernel = false;
map->start = shdr->sh_addr + ref_reloc(kmap); map->start = shdr->sh_addr + ref_reloc(kmap);
map->end = map->start + shdr->sh_size; map->end = map->start + shdr->sh_size;
...@@ -1068,7 +1068,7 @@ int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss, ...@@ -1068,7 +1068,7 @@ int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss,
* Initial kernel and module mappings do not map to the dso. * Initial kernel and module mappings do not map to the dso.
* Flag the fixups. * Flag the fixups.
*/ */
if (dso->kernel || kmodule) { if (dso->kernel) {
remap_kernel = true; remap_kernel = true;
adjust_kernel_syms = dso->adjust_symbols; adjust_kernel_syms = dso->adjust_symbols;
} }
...@@ -1130,7 +1130,7 @@ int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss, ...@@ -1130,7 +1130,7 @@ int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss,
(sym.st_value & 1)) (sym.st_value & 1))
--sym.st_value; --sym.st_value;
if (dso->kernel || kmodule) { if (dso->kernel) {
if (dso__process_kernel_symbol(dso, map, &sym, &shdr, kmaps, kmap, &curr_dso, &curr_map, if (dso__process_kernel_symbol(dso, map, &sym, &shdr, kmaps, kmap, &curr_dso, &curr_map,
section_name, adjust_kernel_syms, kmodule, &remap_kernel)) section_name, adjust_kernel_syms, kmodule, &remap_kernel))
goto out_elf_end; goto out_elf_end;
......
...@@ -808,7 +808,7 @@ static int maps__split_kallsyms(struct maps *kmaps, struct dso *dso, u64 delta, ...@@ -808,7 +808,7 @@ static int maps__split_kallsyms(struct maps *kmaps, struct dso *dso, u64 delta,
if (strcmp(curr_map->dso->short_name, module)) { if (strcmp(curr_map->dso->short_name, module)) {
if (curr_map != initial_map && if (curr_map != initial_map &&
dso->kernel == DSO_TYPE_GUEST_KERNEL && dso->kernel == DSO_SPACE__KERNEL_GUEST &&
machine__is_default_guest(machine)) { machine__is_default_guest(machine)) {
/* /*
* We assume all symbols of a module are * We assume all symbols of a module are
...@@ -865,7 +865,7 @@ static int maps__split_kallsyms(struct maps *kmaps, struct dso *dso, u64 delta, ...@@ -865,7 +865,7 @@ static int maps__split_kallsyms(struct maps *kmaps, struct dso *dso, u64 delta,
goto add_symbol; goto add_symbol;
} }
if (dso->kernel == DSO_TYPE_GUEST_KERNEL) if (dso->kernel == DSO_SPACE__KERNEL_GUEST)
snprintf(dso_name, sizeof(dso_name), snprintf(dso_name, sizeof(dso_name),
"[guest.kernel].%d", "[guest.kernel].%d",
kernel_range++); kernel_range++);
...@@ -909,7 +909,7 @@ static int maps__split_kallsyms(struct maps *kmaps, struct dso *dso, u64 delta, ...@@ -909,7 +909,7 @@ static int maps__split_kallsyms(struct maps *kmaps, struct dso *dso, u64 delta,
} }
if (curr_map != initial_map && if (curr_map != initial_map &&
dso->kernel == DSO_TYPE_GUEST_KERNEL && dso->kernel == DSO_SPACE__KERNEL_GUEST &&
machine__is_default_guest(kmaps->machine)) { machine__is_default_guest(kmaps->machine)) {
dso__set_loaded(curr_map->dso); dso__set_loaded(curr_map->dso);
} }
...@@ -1387,7 +1387,7 @@ static int dso__load_kcore(struct dso *dso, struct map *map, ...@@ -1387,7 +1387,7 @@ static int dso__load_kcore(struct dso *dso, struct map *map,
* Set the data type and long name so that kcore can be read via * Set the data type and long name so that kcore can be read via
* dso__data_read_addr(). * dso__data_read_addr().
*/ */
if (dso->kernel == DSO_TYPE_GUEST_KERNEL) if (dso->kernel == DSO_SPACE__KERNEL_GUEST)
dso->binary_type = DSO_BINARY_TYPE__GUEST_KCORE; dso->binary_type = DSO_BINARY_TYPE__GUEST_KCORE;
else else
dso->binary_type = DSO_BINARY_TYPE__KCORE; dso->binary_type = DSO_BINARY_TYPE__KCORE;
...@@ -1451,7 +1451,7 @@ int __dso__load_kallsyms(struct dso *dso, const char *filename, ...@@ -1451,7 +1451,7 @@ int __dso__load_kallsyms(struct dso *dso, const char *filename,
symbols__fixup_end(&dso->symbols); symbols__fixup_end(&dso->symbols);
symbols__fixup_duplicate(&dso->symbols); symbols__fixup_duplicate(&dso->symbols);
if (dso->kernel == DSO_TYPE_GUEST_KERNEL) if (dso->kernel == DSO_SPACE__KERNEL_GUEST)
dso->symtab_type = DSO_BINARY_TYPE__GUEST_KALLSYMS; dso->symtab_type = DSO_BINARY_TYPE__GUEST_KALLSYMS;
else else
dso->symtab_type = DSO_BINARY_TYPE__KALLSYMS; dso->symtab_type = DSO_BINARY_TYPE__KALLSYMS;
...@@ -1537,17 +1537,17 @@ static bool dso__is_compatible_symtab_type(struct dso *dso, bool kmod, ...@@ -1537,17 +1537,17 @@ static bool dso__is_compatible_symtab_type(struct dso *dso, bool kmod,
case DSO_BINARY_TYPE__MIXEDUP_UBUNTU_DEBUGINFO: case DSO_BINARY_TYPE__MIXEDUP_UBUNTU_DEBUGINFO:
case DSO_BINARY_TYPE__BUILDID_DEBUGINFO: case DSO_BINARY_TYPE__BUILDID_DEBUGINFO:
case DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO: case DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO:
return !kmod && dso->kernel == DSO_TYPE_USER; return !kmod && dso->kernel == DSO_SPACE__USER;
case DSO_BINARY_TYPE__KALLSYMS: case DSO_BINARY_TYPE__KALLSYMS:
case DSO_BINARY_TYPE__VMLINUX: case DSO_BINARY_TYPE__VMLINUX:
case DSO_BINARY_TYPE__KCORE: case DSO_BINARY_TYPE__KCORE:
return dso->kernel == DSO_TYPE_KERNEL; return dso->kernel == DSO_SPACE__KERNEL;
case DSO_BINARY_TYPE__GUEST_KALLSYMS: case DSO_BINARY_TYPE__GUEST_KALLSYMS:
case DSO_BINARY_TYPE__GUEST_VMLINUX: case DSO_BINARY_TYPE__GUEST_VMLINUX:
case DSO_BINARY_TYPE__GUEST_KCORE: case DSO_BINARY_TYPE__GUEST_KCORE:
return dso->kernel == DSO_TYPE_GUEST_KERNEL; return dso->kernel == DSO_SPACE__KERNEL_GUEST;
case DSO_BINARY_TYPE__GUEST_KMODULE: case DSO_BINARY_TYPE__GUEST_KMODULE:
case DSO_BINARY_TYPE__GUEST_KMODULE_COMP: case DSO_BINARY_TYPE__GUEST_KMODULE_COMP:
...@@ -1650,9 +1650,9 @@ int dso__load(struct dso *dso, struct map *map) ...@@ -1650,9 +1650,9 @@ int dso__load(struct dso *dso, struct map *map)
dso->symtab_type == DSO_BINARY_TYPE__GUEST_KMODULE_COMP; dso->symtab_type == DSO_BINARY_TYPE__GUEST_KMODULE_COMP;
if (dso->kernel && !kmod) { if (dso->kernel && !kmod) {
if (dso->kernel == DSO_TYPE_KERNEL) if (dso->kernel == DSO_SPACE__KERNEL)
ret = dso__load_kernel_sym(dso, map); ret = dso__load_kernel_sym(dso, map);
else if (dso->kernel == DSO_TYPE_GUEST_KERNEL) else if (dso->kernel == DSO_SPACE__KERNEL_GUEST)
ret = dso__load_guest_kernel_sym(dso, map); ret = dso__load_guest_kernel_sym(dso, map);
machine = map__kmaps(map)->machine; machine = map__kmaps(map)->machine;
...@@ -1882,7 +1882,7 @@ int dso__load_vmlinux(struct dso *dso, struct map *map, ...@@ -1882,7 +1882,7 @@ int dso__load_vmlinux(struct dso *dso, struct map *map,
else else
symbol__join_symfs(symfs_vmlinux, vmlinux); symbol__join_symfs(symfs_vmlinux, vmlinux);
if (dso->kernel == DSO_TYPE_GUEST_KERNEL) if (dso->kernel == DSO_SPACE__KERNEL_GUEST)
symtab_type = DSO_BINARY_TYPE__GUEST_VMLINUX; symtab_type = DSO_BINARY_TYPE__GUEST_VMLINUX;
else else
symtab_type = DSO_BINARY_TYPE__VMLINUX; symtab_type = DSO_BINARY_TYPE__VMLINUX;
...@@ -1894,7 +1894,7 @@ int dso__load_vmlinux(struct dso *dso, struct map *map, ...@@ -1894,7 +1894,7 @@ int dso__load_vmlinux(struct dso *dso, struct map *map,
symsrc__destroy(&ss); symsrc__destroy(&ss);
if (err > 0) { if (err > 0) {
if (dso->kernel == DSO_TYPE_GUEST_KERNEL) if (dso->kernel == DSO_SPACE__KERNEL_GUEST)
dso->binary_type = DSO_BINARY_TYPE__GUEST_VMLINUX; dso->binary_type = DSO_BINARY_TYPE__GUEST_VMLINUX;
else else
dso->binary_type = DSO_BINARY_TYPE__VMLINUX; dso->binary_type = DSO_BINARY_TYPE__VMLINUX;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment