diff options
Diffstat (limited to '')
-rw-r--r-- | tools/lib/perf/Build (renamed from tools/perf/lib/Build) | 0 | ||||
-rw-r--r-- | tools/lib/perf/Makefile (renamed from tools/perf/lib/Makefile) | 7 | ||||
-rw-r--r-- | tools/lib/perf/core.c (renamed from tools/perf/lib/core.c) | 0 | ||||
-rw-r--r-- | tools/lib/perf/cpumap.c (renamed from tools/perf/lib/cpumap.c) | 0 | ||||
-rw-r--r-- | tools/lib/perf/evlist.c (renamed from tools/perf/lib/evlist.c) | 3 | ||||
-rw-r--r-- | tools/lib/perf/evsel.c (renamed from tools/perf/lib/evsel.c) | 0 | ||||
-rw-r--r-- | tools/lib/perf/include/internal/cpumap.h (renamed from tools/perf/lib/include/internal/cpumap.h) | 0 | ||||
-rw-r--r-- | tools/lib/perf/include/internal/evlist.h (renamed from tools/perf/lib/include/internal/evlist.h) | 0 | ||||
-rw-r--r-- | tools/lib/perf/include/internal/evsel.h (renamed from tools/perf/lib/include/internal/evsel.h) | 0 | ||||
-rw-r--r-- | tools/lib/perf/include/internal/lib.h (renamed from tools/perf/lib/include/internal/lib.h) | 0 | ||||
-rw-r--r-- | tools/lib/perf/include/internal/mmap.h (renamed from tools/perf/lib/include/internal/mmap.h) | 0 | ||||
-rw-r--r-- | tools/lib/perf/include/internal/tests.h (renamed from tools/perf/lib/include/internal/tests.h) | 0 | ||||
-rw-r--r-- | tools/lib/perf/include/internal/threadmap.h (renamed from tools/perf/lib/include/internal/threadmap.h) | 0 | ||||
-rw-r--r-- | tools/lib/perf/include/internal/xyarray.h (renamed from tools/perf/lib/include/internal/xyarray.h) | 0 | ||||
-rw-r--r-- | tools/lib/perf/include/perf/core.h (renamed from tools/perf/lib/include/perf/core.h) | 0 | ||||
-rw-r--r-- | tools/lib/perf/include/perf/cpumap.h (renamed from tools/perf/lib/include/perf/cpumap.h) | 0 | ||||
-rw-r--r-- | tools/lib/perf/include/perf/event.h (renamed from tools/perf/lib/include/perf/event.h) | 0 | ||||
-rw-r--r-- | tools/lib/perf/include/perf/evlist.h (renamed from tools/perf/lib/include/perf/evlist.h) | 0 | ||||
-rw-r--r-- | tools/lib/perf/include/perf/evsel.h (renamed from tools/perf/lib/include/perf/evsel.h) | 0 | ||||
-rw-r--r-- | tools/lib/perf/include/perf/mmap.h (renamed from tools/perf/lib/include/perf/mmap.h) | 0 | ||||
-rw-r--r-- | tools/lib/perf/include/perf/threadmap.h (renamed from tools/perf/lib/include/perf/threadmap.h) | 0 | ||||
-rw-r--r-- | tools/lib/perf/internal.h (renamed from tools/perf/lib/internal.h) | 0 | ||||
-rw-r--r-- | tools/lib/perf/lib.c (renamed from tools/perf/lib/lib.c) | 0 | ||||
-rw-r--r-- | tools/lib/perf/libperf.map (renamed from tools/perf/lib/libperf.map) | 0 | ||||
-rw-r--r-- | tools/lib/perf/libperf.pc.template (renamed from tools/perf/lib/libperf.pc.template) | 0 | ||||
-rw-r--r-- | tools/lib/perf/mmap.c (renamed from tools/perf/lib/mmap.c) | 0 | ||||
-rw-r--r-- | tools/lib/perf/tests/Makefile (renamed from tools/perf/lib/tests/Makefile) | 2 | ||||
-rw-r--r-- | tools/lib/perf/tests/test-cpumap.c (renamed from tools/perf/lib/tests/test-cpumap.c) | 0 | ||||
-rw-r--r-- | tools/lib/perf/tests/test-evlist.c (renamed from tools/perf/lib/tests/test-evlist.c) | 0 | ||||
-rw-r--r-- | tools/lib/perf/tests/test-evsel.c (renamed from tools/perf/lib/tests/test-evsel.c) | 0 | ||||
-rw-r--r-- | tools/lib/perf/tests/test-threadmap.c (renamed from tools/perf/lib/tests/test-threadmap.c) | 0 | ||||
-rw-r--r-- | tools/lib/perf/threadmap.c (renamed from tools/perf/lib/threadmap.c) | 0 | ||||
-rw-r--r-- | tools/lib/perf/xyarray.c (renamed from tools/perf/lib/xyarray.c) | 0 | ||||
-rw-r--r-- | tools/perf/Documentation/perf-annotate.txt | 6 | ||||
-rw-r--r-- | tools/perf/Documentation/perf-report.txt | 6 | ||||
-rw-r--r-- | tools/perf/Documentation/perf-sched.txt | 4 | ||||
-rw-r--r-- | tools/perf/Documentation/perf-top.txt | 6 | ||||
-rw-r--r-- | tools/perf/MANIFEST | 1 | ||||
-rw-r--r-- | tools/perf/Makefile.config | 2 | ||||
-rw-r--r-- | tools/perf/Makefile.perf | 2 | ||||
-rw-r--r-- | tools/perf/builtin-annotate.c | 7 | ||||
-rw-r--r-- | tools/perf/builtin-c2c.c | 14 | ||||
-rw-r--r-- | tools/perf/builtin-record.c | 28 | ||||
-rw-r--r-- | tools/perf/builtin-report.c | 16 | ||||
-rw-r--r-- | tools/perf/builtin-sched.c | 13 | ||||
-rw-r--r-- | tools/perf/builtin-top.c | 7 | ||||
-rw-r--r-- | tools/perf/examples/bpf/5sec.c | 8 | ||||
-rw-r--r-- | tools/perf/examples/bpf/empty.c | 2 | ||||
-rw-r--r-- | tools/perf/examples/bpf/sys_enter_openat.c | 2 | ||||
-rw-r--r-- | tools/perf/include/bpf/pid_filter.h | 2 | ||||
-rw-r--r-- | tools/perf/include/bpf/stdio.h | 2 | ||||
-rw-r--r-- | tools/perf/include/bpf/unistd.h | 2 | ||||
-rw-r--r-- | tools/perf/lib/Documentation/Makefile | 7 | ||||
-rw-r--r-- | tools/perf/lib/Documentation/man/libperf.rst | 100 | ||||
-rw-r--r-- | tools/perf/lib/Documentation/tutorial/tutorial.rst | 123 | ||||
-rw-r--r-- | tools/perf/tests/bp_signal.c | 10 | ||||
-rw-r--r-- | tools/perf/trace/beauty/sockaddr.c | 2 | ||||
-rw-r--r-- | tools/perf/ui/browsers/hists.c | 277 | ||||
-rw-r--r-- | tools/perf/ui/browsers/hists.h | 2 | ||||
-rw-r--r-- | tools/perf/ui/browsers/res_sample.c | 2 | ||||
-rw-r--r-- | tools/perf/ui/browsers/scripts.c | 2 | ||||
-rw-r--r-- | tools/perf/ui/gtk/Build | 7 | ||||
-rw-r--r-- | tools/perf/ui/tui/util.c | 12 | ||||
-rw-r--r-- | tools/perf/ui/util.h | 2 | ||||
-rw-r--r-- | tools/perf/util/annotate.c | 19 | ||||
-rw-r--r-- | tools/perf/util/annotate.h | 5 | ||||
-rw-r--r-- | tools/perf/util/c++/clang.cpp | 4 | ||||
-rw-r--r-- | tools/perf/util/expr.y | 3 | ||||
-rw-r--r-- | tools/perf/util/header.c | 2 | ||||
-rw-r--r-- | tools/perf/util/mmap.c | 40 | ||||
-rw-r--r-- | tools/perf/util/mmap.h | 13 | ||||
-rw-r--r-- | tools/perf/util/parse-events.y | 2 | ||||
-rw-r--r-- | tools/perf/util/sort.c | 3 | ||||
-rw-r--r-- | tools/perf/util/sort.h | 2 |
74 files changed, 407 insertions, 374 deletions
diff --git a/tools/perf/lib/Build b/tools/lib/perf/Build index 2ef9a4ec6d99..2ef9a4ec6d99 100644 --- a/tools/perf/lib/Build +++ b/tools/lib/perf/Build diff --git a/tools/perf/lib/Makefile b/tools/lib/perf/Makefile index 0f233638ef1f..3718d65cffac 100644 --- a/tools/perf/lib/Makefile +++ b/tools/lib/perf/Makefile @@ -60,7 +60,7 @@ else endif INCLUDES = \ --I$(srctree)/tools/perf/lib/include \ +-I$(srctree)/tools/lib/perf/include \ -I$(srctree)/tools/lib/ \ -I$(srctree)/tools/include \ -I$(srctree)/tools/arch/$(SRCARCH)/include/ \ @@ -181,7 +181,10 @@ install_pkgconfig: $(LIBPERF_PC) $(call QUIET_INSTALL, $(LIBPERF_PC)) \ $(call do_install,$(LIBPERF_PC),$(libdir_SQ)/pkgconfig,644) -install: install_lib install_headers install_pkgconfig +install_doc: + $(Q)$(MAKE) -C Documentation install-man install-html install-examples + +install: install_lib install_headers install_pkgconfig install_doc FORCE: diff --git a/tools/perf/lib/core.c b/tools/lib/perf/core.c index 58fc894b76c5..58fc894b76c5 100644 --- a/tools/perf/lib/core.c +++ b/tools/lib/perf/core.c diff --git a/tools/perf/lib/cpumap.c b/tools/lib/perf/cpumap.c index f93f4e703e4c..f93f4e703e4c 100644 --- a/tools/perf/lib/cpumap.c +++ b/tools/lib/perf/cpumap.c diff --git a/tools/perf/lib/evlist.c b/tools/lib/perf/evlist.c index ae9e65aa2491..5b9f2ca50591 100644 --- a/tools/perf/lib/evlist.c +++ b/tools/lib/perf/evlist.c @@ -164,6 +164,9 @@ void perf_evlist__set_maps(struct perf_evlist *evlist, evlist->threads = perf_thread_map__get(threads); } + if (!evlist->all_cpus && cpus) + evlist->all_cpus = perf_cpu_map__get(cpus); + perf_evlist__propagate_maps(evlist); } diff --git a/tools/perf/lib/evsel.c b/tools/lib/perf/evsel.c index 4dc06289f4c7..4dc06289f4c7 100644 --- a/tools/perf/lib/evsel.c +++ b/tools/lib/perf/evsel.c diff --git a/tools/perf/lib/include/internal/cpumap.h b/tools/lib/perf/include/internal/cpumap.h index 840d4032587b..840d4032587b 100644 --- a/tools/perf/lib/include/internal/cpumap.h +++ b/tools/lib/perf/include/internal/cpumap.h diff --git a/tools/perf/lib/include/internal/evlist.h b/tools/lib/perf/include/internal/evlist.h index 74dc8c3f0b66..74dc8c3f0b66 100644 --- a/tools/perf/lib/include/internal/evlist.h +++ b/tools/lib/perf/include/internal/evlist.h diff --git a/tools/perf/lib/include/internal/evsel.h b/tools/lib/perf/include/internal/evsel.h index 1ffd083b235e..1ffd083b235e 100644 --- a/tools/perf/lib/include/internal/evsel.h +++ b/tools/lib/perf/include/internal/evsel.h diff --git a/tools/perf/lib/include/internal/lib.h b/tools/lib/perf/include/internal/lib.h index 5175d491b2d4..5175d491b2d4 100644 --- a/tools/perf/lib/include/internal/lib.h +++ b/tools/lib/perf/include/internal/lib.h diff --git a/tools/perf/lib/include/internal/mmap.h b/tools/lib/perf/include/internal/mmap.h index be7556e0a2b2..be7556e0a2b2 100644 --- a/tools/perf/lib/include/internal/mmap.h +++ b/tools/lib/perf/include/internal/mmap.h diff --git a/tools/perf/lib/include/internal/tests.h b/tools/lib/perf/include/internal/tests.h index 2093e8868a67..2093e8868a67 100644 --- a/tools/perf/lib/include/internal/tests.h +++ b/tools/lib/perf/include/internal/tests.h diff --git a/tools/perf/lib/include/internal/threadmap.h b/tools/lib/perf/include/internal/threadmap.h index df748baf9eda..df748baf9eda 100644 --- a/tools/perf/lib/include/internal/threadmap.h +++ b/tools/lib/perf/include/internal/threadmap.h diff --git a/tools/perf/lib/include/internal/xyarray.h b/tools/lib/perf/include/internal/xyarray.h index 51e35d6c8ec4..51e35d6c8ec4 100644 --- a/tools/perf/lib/include/internal/xyarray.h +++ b/tools/lib/perf/include/internal/xyarray.h diff --git a/tools/perf/lib/include/perf/core.h b/tools/lib/perf/include/perf/core.h index a3f6d68edad7..a3f6d68edad7 100644 --- a/tools/perf/lib/include/perf/core.h +++ b/tools/lib/perf/include/perf/core.h diff --git a/tools/perf/lib/include/perf/cpumap.h b/tools/lib/perf/include/perf/cpumap.h index 6a17ad730cbc..6a17ad730cbc 100644 --- a/tools/perf/lib/include/perf/cpumap.h +++ b/tools/lib/perf/include/perf/cpumap.h diff --git a/tools/perf/lib/include/perf/event.h b/tools/lib/perf/include/perf/event.h index 18106899cb4e..18106899cb4e 100644 --- a/tools/perf/lib/include/perf/event.h +++ b/tools/lib/perf/include/perf/event.h diff --git a/tools/perf/lib/include/perf/evlist.h b/tools/lib/perf/include/perf/evlist.h index 0a7479dc13bf..0a7479dc13bf 100644 --- a/tools/perf/lib/include/perf/evlist.h +++ b/tools/lib/perf/include/perf/evlist.h diff --git a/tools/perf/lib/include/perf/evsel.h b/tools/lib/perf/include/perf/evsel.h index c82ec39a4ad0..c82ec39a4ad0 100644 --- a/tools/perf/lib/include/perf/evsel.h +++ b/tools/lib/perf/include/perf/evsel.h diff --git a/tools/perf/lib/include/perf/mmap.h b/tools/lib/perf/include/perf/mmap.h index 9508ad90d8b9..9508ad90d8b9 100644 --- a/tools/perf/lib/include/perf/mmap.h +++ b/tools/lib/perf/include/perf/mmap.h diff --git a/tools/perf/lib/include/perf/threadmap.h b/tools/lib/perf/include/perf/threadmap.h index a7c50de8d010..a7c50de8d010 100644 --- a/tools/perf/lib/include/perf/threadmap.h +++ b/tools/lib/perf/include/perf/threadmap.h diff --git a/tools/perf/lib/internal.h b/tools/lib/perf/internal.h index 2c27e158de6b..2c27e158de6b 100644 --- a/tools/perf/lib/internal.h +++ b/tools/lib/perf/internal.h diff --git a/tools/perf/lib/lib.c b/tools/lib/perf/lib.c index 18658931fc71..18658931fc71 100644 --- a/tools/perf/lib/lib.c +++ b/tools/lib/perf/lib.c diff --git a/tools/perf/lib/libperf.map b/tools/lib/perf/libperf.map index 7be1af8a546c..7be1af8a546c 100644 --- a/tools/perf/lib/libperf.map +++ b/tools/lib/perf/libperf.map diff --git a/tools/perf/lib/libperf.pc.template b/tools/lib/perf/libperf.pc.template index 117e4a237b55..117e4a237b55 100644 --- a/tools/perf/lib/libperf.pc.template +++ b/tools/lib/perf/libperf.pc.template diff --git a/tools/perf/lib/mmap.c b/tools/lib/perf/mmap.c index 79d5ed6c38cc..79d5ed6c38cc 100644 --- a/tools/perf/lib/mmap.c +++ b/tools/lib/perf/mmap.c diff --git a/tools/perf/lib/tests/Makefile b/tools/lib/perf/tests/Makefile index a43cd08c5c03..96841775feaf 100644 --- a/tools/perf/lib/tests/Makefile +++ b/tools/lib/perf/tests/Makefile @@ -16,7 +16,7 @@ all: include $(srctree)/tools/scripts/Makefile.include -INCLUDE = -I$(srctree)/tools/perf/lib/include -I$(srctree)/tools/include -I$(srctree)/tools/lib +INCLUDE = -I$(srctree)/tools/lib/perf/include -I$(srctree)/tools/include -I$(srctree)/tools/lib $(TESTS_A): FORCE $(QUIET_LINK)$(CC) $(INCLUDE) $(CFLAGS) -o $@ $(subst -a,.c,$@) ../libperf.a $(LIBAPI) diff --git a/tools/perf/lib/tests/test-cpumap.c b/tools/lib/perf/tests/test-cpumap.c index c8d45091e7c2..c8d45091e7c2 100644 --- a/tools/perf/lib/tests/test-cpumap.c +++ b/tools/lib/perf/tests/test-cpumap.c diff --git a/tools/perf/lib/tests/test-evlist.c b/tools/lib/perf/tests/test-evlist.c index 6d8ebe0c2504..6d8ebe0c2504 100644 --- a/tools/perf/lib/tests/test-evlist.c +++ b/tools/lib/perf/tests/test-evlist.c diff --git a/tools/perf/lib/tests/test-evsel.c b/tools/lib/perf/tests/test-evsel.c index 135722ac965b..135722ac965b 100644 --- a/tools/perf/lib/tests/test-evsel.c +++ b/tools/lib/perf/tests/test-evsel.c diff --git a/tools/perf/lib/tests/test-threadmap.c b/tools/lib/perf/tests/test-threadmap.c index 7dc4d6fbedde..7dc4d6fbedde 100644 --- a/tools/perf/lib/tests/test-threadmap.c +++ b/tools/lib/perf/tests/test-threadmap.c diff --git a/tools/perf/lib/threadmap.c b/tools/lib/perf/threadmap.c index e92c368b0a6c..e92c368b0a6c 100644 --- a/tools/perf/lib/threadmap.c +++ b/tools/lib/perf/threadmap.c diff --git a/tools/perf/lib/xyarray.c b/tools/lib/perf/xyarray.c index dcd901d154bb..dcd901d154bb 100644 --- a/tools/perf/lib/xyarray.c +++ b/tools/lib/perf/xyarray.c diff --git a/tools/perf/Documentation/perf-annotate.txt b/tools/perf/Documentation/perf-annotate.txt index e8c972f89357..1b5042f134a8 100644 --- a/tools/perf/Documentation/perf-annotate.txt +++ b/tools/perf/Documentation/perf-annotate.txt @@ -112,6 +112,12 @@ OPTIONS --objdump=<path>:: Path to objdump binary. +--prefix=PREFIX:: +--prefix-strip=N:: + Remove first N entries from source file path names in executables + and add PREFIX. This allows to display source code compiled on systems + with different file system layout. + --skip-missing:: Skip symbols that cannot be annotated. diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt index 8dbe2119686a..db61f16ffa56 100644 --- a/tools/perf/Documentation/perf-report.txt +++ b/tools/perf/Documentation/perf-report.txt @@ -367,6 +367,12 @@ OPTIONS --objdump=<path>:: Path to objdump binary. +--prefix=PREFIX:: +--prefix-strip=N:: + Remove first N entries from source file path names in executables + and add PREFIX. This allows to display source code compiled on systems + with different file system layout. + --group:: Show event group information together. It forces group output also if there are no groups defined in data file. diff --git a/tools/perf/Documentation/perf-sched.txt b/tools/perf/Documentation/perf-sched.txt index 63f938b887dd..5fbe42bd599b 100644 --- a/tools/perf/Documentation/perf-sched.txt +++ b/tools/perf/Documentation/perf-sched.txt @@ -110,6 +110,10 @@ OPTIONS for 'perf sched timehist' --max-stack:: Maximum number of functions to display in backtrace, default 5. +-C=:: +--cpu=:: + Only show events for the given CPU(s) (comma separated list). + -p=:: --pid=:: Only show events for given process ID (comma separated list). diff --git a/tools/perf/Documentation/perf-top.txt b/tools/perf/Documentation/perf-top.txt index 5596129a71cf..324b6b53c86b 100644 --- a/tools/perf/Documentation/perf-top.txt +++ b/tools/perf/Documentation/perf-top.txt @@ -158,6 +158,12 @@ Default is to monitor all CPUS. -M:: --disassembler-style=:: Set disassembler style for objdump. +--prefix=PREFIX:: +--prefix-strip=N:: + Remove first N entries from source file path names in executables + and add PREFIX. This allows to display source code compiled on systems + with different file system layout. + --source:: Interleave source code with assembly code. Enabled by default, disable with --no-source. diff --git a/tools/perf/MANIFEST b/tools/perf/MANIFEST index 4934edb5adfd..5d7b947320fb 100644 --- a/tools/perf/MANIFEST +++ b/tools/perf/MANIFEST @@ -7,6 +7,7 @@ tools/lib/traceevent tools/lib/api tools/lib/bpf tools/lib/subcmd +tools/lib/perf tools/lib/argv_split.c tools/lib/ctype.c tools/lib/hweight.c diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config index c90f4146e5a2..80e55e796be9 100644 --- a/tools/perf/Makefile.config +++ b/tools/perf/Makefile.config @@ -286,7 +286,7 @@ ifeq ($(DEBUG),0) endif endif -INC_FLAGS += -I$(src-perf)/lib/include +INC_FLAGS += -I$(srctree)/tools/lib/perf/include INC_FLAGS += -I$(src-perf)/util/include INC_FLAGS += -I$(src-perf)/arch/$(SRCARCH)/include INC_FLAGS += -I$(srctree)/tools/include/ diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index eae5d5e95952..3eda9d4b88e7 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -230,7 +230,7 @@ LIB_DIR = $(srctree)/tools/lib/api/ TRACE_EVENT_DIR = $(srctree)/tools/lib/traceevent/ BPF_DIR = $(srctree)/tools/lib/bpf/ SUBCMD_DIR = $(srctree)/tools/lib/subcmd/ -LIBPERF_DIR = $(srctree)/tools/perf/lib/ +LIBPERF_DIR = $(srctree)/tools/lib/perf/ # Set FEATURE_TESTS to 'all' so all possible feature checkers are executed. # Without this setting the output feature dump file misses some features, for diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 5898662bc8fb..ff61795a4d13 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -535,6 +535,10 @@ int cmd_annotate(int argc, const char **argv) "Display raw encoding of assembly instructions (default)"), OPT_STRING('M', "disassembler-style", &annotate.opts.disassembler_style, "disassembler style", "Specify disassembler style (e.g. -M intel for intel syntax)"), + OPT_STRING(0, "prefix", &annotate.opts.prefix, "prefix", + "Add prefix to source file path names in programs (with --prefix-strip)"), + OPT_STRING(0, "prefix-strip", &annotate.opts.prefix_strip, "N", + "Strip first N entries of source file path name in programs (with --prefix)"), OPT_STRING(0, "objdump", &annotate.opts.objdump_path, "path", "objdump binary to use for disassembly and annotations"), OPT_BOOLEAN(0, "group", &symbol_conf.event_group, @@ -574,6 +578,9 @@ int cmd_annotate(int argc, const char **argv) annotate.sym_hist_filter = argv[0]; } + if (annotate_check_args(&annotate.opts) < 0) + return -EINVAL; + if (symbol_conf.show_nr_samples && annotate.use_gtk) { pr_err("--show-nr-samples is not available in --gtk mode at this time\n"); return ret; diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c index e69f44941aad..246ac0b4d54f 100644 --- a/tools/perf/builtin-c2c.c +++ b/tools/perf/builtin-c2c.c @@ -595,8 +595,8 @@ tot_hitm_cmp(struct perf_hpp_fmt *fmt __maybe_unused, { struct c2c_hist_entry *c2c_left; struct c2c_hist_entry *c2c_right; - unsigned int tot_hitm_left; - unsigned int tot_hitm_right; + uint64_t tot_hitm_left; + uint64_t tot_hitm_right; c2c_left = container_of(left, struct c2c_hist_entry, he); c2c_right = container_of(right, struct c2c_hist_entry, he); @@ -629,7 +629,8 @@ __f ## _cmp(struct perf_hpp_fmt *fmt __maybe_unused, \ \ c2c_left = container_of(left, struct c2c_hist_entry, he); \ c2c_right = container_of(right, struct c2c_hist_entry, he); \ - return c2c_left->stats.__f - c2c_right->stats.__f; \ + return (uint64_t) c2c_left->stats.__f - \ + (uint64_t) c2c_right->stats.__f; \ } #define STAT_FN(__f) \ @@ -682,7 +683,8 @@ ld_llcmiss_cmp(struct perf_hpp_fmt *fmt __maybe_unused, c2c_left = container_of(left, struct c2c_hist_entry, he); c2c_right = container_of(right, struct c2c_hist_entry, he); - return llc_miss(&c2c_left->stats) - llc_miss(&c2c_right->stats); + return (uint64_t) llc_miss(&c2c_left->stats) - + (uint64_t) llc_miss(&c2c_right->stats); } static uint64_t total_records(struct c2c_stats *stats) @@ -2384,7 +2386,7 @@ static int perf_c2c__browse_cacheline(struct hist_entry *he) c2c_browser__update_nr_entries(browser); while (1) { - key = hist_browser__run(browser, "? - help", true); + key = hist_browser__run(browser, "? - help", true, 0); switch (key) { case 's': @@ -2453,7 +2455,7 @@ static int perf_c2c__hists_browse(struct hists *hists) c2c_browser__update_nr_entries(browser); while (1) { - key = hist_browser__run(browser, "? - help", true); + key = hist_browser__run(browser, "? - help", true, 0); switch (key) { case 'q': diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index fb19ef63cc35..4c301466101b 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -62,6 +62,7 @@ #include <linux/string.h> #include <linux/time64.h> #include <linux/zalloc.h> +#include <linux/bitmap.h> struct switch_output { bool enabled; @@ -93,7 +94,7 @@ struct record { bool timestamp_boundary; struct switch_output switch_output; unsigned long long samples; - cpu_set_t affinity_mask; + struct mmap_cpu_mask affinity_mask; unsigned long output_max_size; /* = 0: unlimited */ }; @@ -961,10 +962,15 @@ static struct perf_event_header finished_round_event = { static void record__adjust_affinity(struct record *rec, struct mmap *map) { if (rec->opts.affinity != PERF_AFFINITY_SYS && - !CPU_EQUAL(&rec->affinity_mask, &map->affinity_mask)) { - CPU_ZERO(&rec->affinity_mask); - CPU_OR(&rec->affinity_mask, &rec->affinity_mask, &map->affinity_mask); - sched_setaffinity(0, sizeof(rec->affinity_mask), &rec->affinity_mask); + !bitmap_equal(rec->affinity_mask.bits, map->affinity_mask.bits, + rec->affinity_mask.nbits)) { + bitmap_zero(rec->affinity_mask.bits, rec->affinity_mask.nbits); + bitmap_or(rec->affinity_mask.bits, rec->affinity_mask.bits, + map->affinity_mask.bits, rec->affinity_mask.nbits); + sched_setaffinity(0, MMAP_CPU_MASK_BYTES(&rec->affinity_mask), + (cpu_set_t *)rec->affinity_mask.bits); + if (verbose == 2) + mmap_cpu_mask__scnprintf(&rec->affinity_mask, "thread"); } } @@ -2433,7 +2439,6 @@ int cmd_record(int argc, const char **argv) # undef REASON #endif - CPU_ZERO(&rec->affinity_mask); rec->opts.affinity = PERF_AFFINITY_SYS; rec->evlist = evlist__new(); @@ -2499,6 +2504,16 @@ int cmd_record(int argc, const char **argv) symbol__init(NULL); + if (rec->opts.affinity != PERF_AFFINITY_SYS) { + rec->affinity_mask.nbits = cpu__max_cpu(); + rec->affinity_mask.bits = bitmap_alloc(rec->affinity_mask.nbits); + if (!rec->affinity_mask.bits) { + pr_err("Failed to allocate thread mask for %zd cpus\n", rec->affinity_mask.nbits); + return -ENOMEM; + } + pr_debug2("thread mask[%zd]: empty\n", rec->affinity_mask.nbits); + } + err = record__auxtrace_init(rec); if (err) goto out; @@ -2613,6 +2628,7 @@ int cmd_record(int argc, const char **argv) err = __cmd_record(&record, argc, argv); out: + bitmap_free(rec->affinity_mask.bits); evlist__delete(rec->evlist); symbol__exit(); auxtrace_record__free(rec->itr); diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index de988589d99b..9483b3f0cae3 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -412,10 +412,10 @@ static int report__setup_sample_type(struct report *rep) PERF_SAMPLE_BRANCH_ANY)) rep->nonany_branch_mode = true; -#ifndef HAVE_LIBUNWIND_SUPPORT +#if !defined(HAVE_LIBUNWIND_SUPPORT) && !defined(HAVE_DWARF_SUPPORT) if (dwarf_callchain_users) { - ui__warning("Please install libunwind development packages " - "during the perf build.\n"); + ui__warning("Please install libunwind or libdw " + "development packages during the perf build.\n"); } #endif @@ -1164,7 +1164,8 @@ int cmd_report(int argc, const char **argv) report_callchain_help, &report_parse_callchain_opt, callchain_default_opt), OPT_BOOLEAN(0, "children", &symbol_conf.cumulate_callchain, - "Accumulate callchains of children and show total overhead as well"), + "Accumulate callchains of children and show total overhead as well. " + "Enabled by default, use --no-children to disable."), OPT_INTEGER(0, "max-stack", &report.max_stack, "Set the maximum stack depth when parsing the callchain, " "anything beyond the specified depth will be ignored. " @@ -1207,6 +1208,10 @@ int cmd_report(int argc, const char **argv) "Display raw encoding of assembly instructions (default)"), OPT_STRING('M', "disassembler-style", &report.annotation_opts.disassembler_style, "disassembler style", "Specify disassembler style (e.g. -M intel for intel syntax)"), + OPT_STRING(0, "prefix", &report.annotation_opts.prefix, "prefix", + "Add prefix to source file path names in programs (with --prefix-strip)"), + OPT_STRING(0, "prefix-strip", &report.annotation_opts.prefix_strip, "N", + "Strip first N entries of source file path name in programs (with --prefix)"), OPT_BOOLEAN(0, "show-total-period", &symbol_conf.show_total_period, "Show a column with the sum of periods"), OPT_BOOLEAN_SET(0, "group", &symbol_conf.event_group, &report.group_set, @@ -1286,6 +1291,9 @@ int cmd_report(int argc, const char **argv) report.symbol_filter_str = argv[0]; } + if (annotate_check_args(&report.annotation_opts) < 0) + return -EINVAL; + if (report.mmaps_mode) report.tasks_mode = true; diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index 8a12d71364c3..82fcc2c15fe4 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -51,6 +51,9 @@ #define SYM_LEN 129 #define MAX_PID 1024000 +static const char *cpu_list; +static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS); + struct sched_atom; struct task_desc { @@ -2008,6 +2011,9 @@ static void timehist_print_sample(struct perf_sched *sched, char nstr[30]; u64 wait_time; + if (cpu_list && !test_bit(sample->cpu, cpu_bitmap)) + return; + timestamp__scnprintf_usec(t, tstr, sizeof(tstr)); printf("%15s [%04d] ", tstr, sample->cpu); @@ -2994,6 +3000,12 @@ static int perf_sched__timehist(struct perf_sched *sched) if (IS_ERR(session)) return PTR_ERR(session); + if (cpu_list) { + err = perf_session__cpu_bitmap(session, cpu_list, cpu_bitmap); + if (err < 0) + goto out; + } + evlist = session->evlist; symbol__init(&session->header.env); @@ -3429,6 +3441,7 @@ int cmd_sched(int argc, const char **argv) "analyze events only for given process id(s)"), OPT_STRING('t', "tid", &symbol_conf.tid_list_str, "tid[,tid...]", "analyze events only for given thread id(s)"), + OPT_STRING('C', "cpu", &cpu_list, "cpu", "list of cpus to profile"), OPT_PARENT(sched_options) }; diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 795e353de095..8affcab75604 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -1512,6 +1512,10 @@ int cmd_top(int argc, const char **argv) "objdump binary to use for disassembly and annotations"), OPT_STRING('M', "disassembler-style", &top.annotation_opts.disassembler_style, "disassembler style", "Specify disassembler style (e.g. -M intel for intel syntax)"), + OPT_STRING(0, "prefix", &top.annotation_opts.prefix, "prefix", + "Add prefix to source file path names in programs (with --prefix-strip)"), + OPT_STRING(0, "prefix-strip", &top.annotation_opts.prefix_strip, "N", + "Strip first N entries of source file path name in programs (with --prefix)"), OPT_STRING('u', "uid", &target->uid_str, "user", "user to profile"), OPT_CALLBACK(0, "percent-limit", &top, "percent", "Don't show entries under that percent", parse_percent_limit), @@ -1582,6 +1586,9 @@ int cmd_top(int argc, const char **argv) if (argc) usage_with_options(top_usage, options); + if (annotate_check_args(&top.annotation_opts) < 0) + goto out_delete_evlist; + if (!top.evlist->core.nr_entries && perf_evlist__add_default(top.evlist) < 0) { pr_err("Not enough memory for event selector list\n"); diff --git a/tools/perf/examples/bpf/5sec.c b/tools/perf/examples/bpf/5sec.c index b9c203219691..65c4ff6892d9 100644 --- a/tools/perf/examples/bpf/5sec.c +++ b/tools/perf/examples/bpf/5sec.c @@ -39,11 +39,13 @@ Copyright (C) 2018 Red Hat, Inc., Arnaldo Carvalho de Melo <acme@redhat.com> */ -#include <bpf.h> +#include <bpf/bpf.h> -int probe(hrtimer_nanosleep, rqtp->tv_sec)(void *ctx, int err, long sec) +#define NSEC_PER_SEC 1000000000L + +int probe(hrtimer_nanosleep, rqtp)(void *ctx, int err, long long sec) { - return sec == 5; + return sec / NSEC_PER_SEC == 5ULL; } license(GPL); diff --git a/tools/perf/examples/bpf/empty.c b/tools/perf/examples/bpf/empty.c index 3776d26db9e7..7d7fb0c9fe76 100644 --- a/tools/perf/examples/bpf/empty.c +++ b/tools/perf/examples/bpf/empty.c @@ -1,3 +1,3 @@ -#include <bpf.h> +#include <bpf/bpf.h> license(GPL); diff --git a/tools/perf/examples/bpf/sys_enter_openat.c b/tools/perf/examples/bpf/sys_enter_openat.c index 9cd124b09392..c4481c390d23 100644 --- a/tools/perf/examples/bpf/sys_enter_openat.c +++ b/tools/perf/examples/bpf/sys_enter_openat.c @@ -14,7 +14,7 @@ * the return value. */ -#include <bpf.h> +#include <bpf/bpf.h> struct syscall_enter_openat_args { unsigned long long unused; diff --git a/tools/perf/include/bpf/pid_filter.h b/tools/perf/include/bpf/pid_filter.h index 6e61c4bdf548..607189a315b2 100644 --- a/tools/perf/include/bpf/pid_filter.h +++ b/tools/perf/include/bpf/pid_filter.h @@ -3,7 +3,7 @@ #ifndef _PERF_BPF_PID_FILTER_ #define _PERF_BPF_PID_FILTER_ -#include <bpf.h> +#include <bpf/bpf.h> #define pid_filter(name) pid_map(name, bool) diff --git a/tools/perf/include/bpf/stdio.h b/tools/perf/include/bpf/stdio.h index 316af5b2ff35..7ca6fa5463ee 100644 --- a/tools/perf/include/bpf/stdio.h +++ b/tools/perf/include/bpf/stdio.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 -#include <bpf.h> +#include <bpf/bpf.h> struct bpf_map SEC("maps") __bpf_stdout__ = { .type = BPF_MAP_TYPE_PERF_EVENT_ARRAY, diff --git a/tools/perf/include/bpf/unistd.h b/tools/perf/include/bpf/unistd.h index ca7877f9a976..d1a35b6c649d 100644 --- a/tools/perf/include/bpf/unistd.h +++ b/tools/perf/include/bpf/unistd.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: LGPL-2.1 -#include <bpf.h> +#include <bpf/bpf.h> static int (*bpf_get_current_pid_tgid)(void) = (void *)BPF_FUNC_get_current_pid_tgid; diff --git a/tools/perf/lib/Documentation/Makefile b/tools/perf/lib/Documentation/Makefile deleted file mode 100644 index 586425a88795..000000000000 --- a/tools/perf/lib/Documentation/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -all: - rst2man man/libperf.rst > man/libperf.7 - rst2pdf tutorial/tutorial.rst - -clean: - rm -f man/libperf.7 - rm -f tutorial/tutorial.pdf diff --git a/tools/perf/lib/Documentation/man/libperf.rst b/tools/perf/lib/Documentation/man/libperf.rst deleted file mode 100644 index 09a270fccb9c..000000000000 --- a/tools/perf/lib/Documentation/man/libperf.rst +++ /dev/null @@ -1,100 +0,0 @@ -.. SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) - -libperf - -The libperf library provides an API to access the linux kernel perf -events subsystem. It provides the following high level objects: - - - struct perf_cpu_map - - struct perf_thread_map - - struct perf_evlist - - struct perf_evsel - -reference -========= -Function reference by header files: - -perf/core.h ------------ -.. code-block:: c - - typedef int (\*libperf_print_fn_t)(enum libperf_print_level level, - const char \*, va_list ap); - - void libperf_set_print(libperf_print_fn_t fn); - -perf/cpumap.h -------------- -.. code-block:: c - - struct perf_cpu_map \*perf_cpu_map__dummy_new(void); - struct perf_cpu_map \*perf_cpu_map__new(const char \*cpu_list); - struct perf_cpu_map \*perf_cpu_map__read(FILE \*file); - struct perf_cpu_map \*perf_cpu_map__get(struct perf_cpu_map \*map); - void perf_cpu_map__put(struct perf_cpu_map \*map); - int perf_cpu_map__cpu(const struct perf_cpu_map \*cpus, int idx); - int perf_cpu_map__nr(const struct perf_cpu_map \*cpus); - perf_cpu_map__for_each_cpu(cpu, idx, cpus) - -perf/threadmap.h ----------------- -.. code-block:: c - - struct perf_thread_map \*perf_thread_map__new_dummy(void); - void perf_thread_map__set_pid(struct perf_thread_map \*map, int thread, pid_t pid); - char \*perf_thread_map__comm(struct perf_thread_map \*map, int thread); - struct perf_thread_map \*perf_thread_map__get(struct perf_thread_map \*map); - void perf_thread_map__put(struct perf_thread_map \*map); - -perf/evlist.h -------------- -.. code-block:: - - void perf_evlist__init(struct perf_evlist \*evlist); - void perf_evlist__add(struct perf_evlist \*evlist, - struct perf_evsel \*evsel); - void perf_evlist__remove(struct perf_evlist \*evlist, - struct perf_evsel \*evsel); - struct perf_evlist \*perf_evlist__new(void); - void perf_evlist__delete(struct perf_evlist \*evlist); - struct perf_evsel\* perf_evlist__next(struct perf_evlist \*evlist, - struct perf_evsel \*evsel); - int perf_evlist__open(struct perf_evlist \*evlist); - void perf_evlist__close(struct perf_evlist \*evlist); - void perf_evlist__enable(struct perf_evlist \*evlist); - void perf_evlist__disable(struct perf_evlist \*evlist); - perf_evlist__for_each_evsel(evlist, pos) - void perf_evlist__set_maps(struct perf_evlist \*evlist, - struct perf_cpu_map \*cpus, - struct perf_thread_map \*threads); - -perf/evsel.h ------------- -.. code-block:: c - - struct perf_counts_values { - union { - struct { - uint64_t val; - uint64_t ena; - uint64_t run; - }; - uint64_t values[3]; - }; - }; - - void perf_evsel__init(struct perf_evsel \*evsel, - struct perf_event_attr \*attr); - struct perf_evsel \*perf_evsel__new(struct perf_event_attr \*attr); - void perf_evsel__delete(struct perf_evsel \*evsel); - int perf_evsel__open(struct perf_evsel \*evsel, struct perf_cpu_map \*cpus, - struct perf_thread_map \*threads); - void perf_evsel__close(struct perf_evsel \*evsel); - int perf_evsel__read(struct perf_evsel \*evsel, int cpu, int thread, - struct perf_counts_values \*count); - int perf_evsel__enable(struct perf_evsel \*evsel); - int perf_evsel__disable(struct perf_evsel \*evsel); - int perf_evsel__apply_filter(struct perf_evsel \*evsel, const char \*filter); - struct perf_cpu_map \*perf_evsel__cpus(struct perf_evsel \*evsel); - struct perf_thread_map \*perf_evsel__threads(struct perf_evsel \*evsel); - struct perf_event_attr \*perf_evsel__attr(struct perf_evsel \*evsel); diff --git a/tools/perf/lib/Documentation/tutorial/tutorial.rst b/tools/perf/lib/Documentation/tutorial/tutorial.rst deleted file mode 100644 index 7be7bc27b385..000000000000 --- a/tools/perf/lib/Documentation/tutorial/tutorial.rst +++ /dev/null @@ -1,123 +0,0 @@ -.. SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) - -libperf tutorial -================ - -Compile and install libperf from kernel sources -=============================================== -.. code-block:: bash - - git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git - cd linux/tools/perf/lib - make - sudo make install prefix=/usr - -Libperf object -============== -The libperf library provides several high level objects: - -struct perf_cpu_map - Provides a cpu list abstraction. - -struct perf_thread_map - Provides a thread list abstraction. - -struct perf_evsel - Provides an abstraction for single a perf event. - -struct perf_evlist - Gathers several struct perf_evsel object and performs functions on all of them. - -The exported API binds these objects together, -for full reference see the libperf.7 man page. - -Examples -======== -Examples aim to explain libperf functionality on simple use cases. -They are based in on a checked out linux kernel git tree: - -.. code-block:: bash - - $ cd tools/perf/lib/Documentation/tutorial/ - $ ls -d ex-* - ex-1-compile ex-2-evsel-stat ex-3-evlist-stat - -ex-1-compile example -==================== -This example shows the basic usage of *struct perf_cpu_map*, -how to create it and display its cpus: - -.. code-block:: bash - - $ cd ex-1-compile/ - $ make - gcc -o test test.c -lperf - $ ./test - 0 1 2 3 4 5 6 7 - - -The full code listing is here: - -.. code-block:: c - - 1 #include <perf/cpumap.h> - 2 - 3 int main(int argc, char **Argv) - 4 { - 5 struct perf_cpu_map *cpus; - 6 int cpu, tmp; - 7 - 8 cpus = perf_cpu_map__new(NULL); - 9 - 10 perf_cpu_map__for_each_cpu(cpu, tmp, cpus) - 11 fprintf(stdout, "%d ", cpu); - 12 - 13 fprintf(stdout, "\n"); - 14 - 15 perf_cpu_map__put(cpus); - 16 return 0; - 17 } - - -First you need to include the proper header to have *struct perf_cpumap* -declaration and functions: - -.. code-block:: c - - 1 #include <perf/cpumap.h> - - -The *struct perf_cpumap* object is created by *perf_cpu_map__new* call. -The *NULL* argument asks it to populate the object with the current online CPUs list: - -.. code-block:: c - - 8 cpus = perf_cpu_map__new(NULL); - -This is paired with a *perf_cpu_map__put*, that drops its reference at the end, possibly deleting it. - -.. code-block:: c - - 15 perf_cpu_map__put(cpus); - -The iteration through the *struct perf_cpumap* CPUs is done using the *perf_cpu_map__for_each_cpu* -macro which requires 3 arguments: - -- cpu - the cpu numer -- tmp - iteration helper variable -- cpus - the *struct perf_cpumap* object - -.. code-block:: c - - 10 perf_cpu_map__for_each_cpu(cpu, tmp, cpus) - 11 fprintf(stdout, "%d ", cpu); - -ex-2-evsel-stat example -======================= - -TBD - -ex-3-evlist-stat example -======================== - -TBD diff --git a/tools/perf/tests/bp_signal.c b/tools/perf/tests/bp_signal.c index 415903b48578..da8ec1e8e064 100644 --- a/tools/perf/tests/bp_signal.c +++ b/tools/perf/tests/bp_signal.c @@ -263,20 +263,20 @@ int test__bp_signal(struct test *test __maybe_unused, int subtest __maybe_unused if (count1 == 11) pr_debug("failed: RF EFLAG recursion issue detected\n"); else - pr_debug("failed: wrong count for bp1%lld\n", count1); + pr_debug("failed: wrong count for bp1: %lld, expected 1\n", count1); } if (overflows != 3) - pr_debug("failed: wrong overflow hit\n"); + pr_debug("failed: wrong overflow (%d) hit, expected 3\n", overflows); if (overflows_2 != 3) - pr_debug("failed: wrong overflow_2 hit\n"); + pr_debug("failed: wrong overflow_2 (%d) hit, expected 3\n", overflows_2); if (count2 != 3) - pr_debug("failed: wrong count for bp2\n"); + pr_debug("failed: wrong count for bp2 (%lld), expected 3\n", count2); if (count3 != 2) - pr_debug("failed: wrong count for bp3\n"); + pr_debug("failed: wrong count for bp3 (%lld), expected 2\n", count3); return count1 == 1 && overflows == 3 && count2 == 3 && overflows_2 == 3 && count3 == 2 ? TEST_OK : TEST_FAIL; diff --git a/tools/perf/trace/beauty/sockaddr.c b/tools/perf/trace/beauty/sockaddr.c index 173c8f760763..e0c13e6a5788 100644 --- a/tools/perf/trace/beauty/sockaddr.c +++ b/tools/perf/trace/beauty/sockaddr.c @@ -72,5 +72,5 @@ size_t syscall_arg__scnprintf_sockaddr(char *bf, size_t size, struct syscall_arg if (arg->augmented.args) return syscall_arg__scnprintf_augmented_sockaddr(arg, bf, size); - return scnprintf(bf, size, "%#x", arg->val); + return scnprintf(bf, size, "%#lx", arg->val); } diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index d4d3558fdef4..f36dee499320 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -18,7 +18,9 @@ #include "../../util/evlist.h" #include "../../util/header.h" #include "../../util/hist.h" +#include "../../util/machine.h" #include "../../util/map.h" +#include "../../util/maps.h" #include "../../util/symbol.h" #include "../../util/map_symbol.h" #include "../../util/branch.h" @@ -391,6 +393,57 @@ static void hist_entry__init_have_children(struct hist_entry *he) he->init_have_children = true; } +static bool hist_browser__selection_has_children(struct hist_browser *browser) +{ + struct hist_entry *he = browser->he_selection; + struct map_symbol *ms = browser->selection; + + if (!he || !ms) + return false; + + if (ms == &he->ms) + return he->has_children; + + return container_of(ms, struct callchain_list, ms)->has_children; +} + +static bool hist_browser__he_selection_unfolded(struct hist_browser *browser) +{ + return browser->he_selection ? browser->he_selection->unfolded : false; +} + +static bool hist_browser__selection_unfolded(struct hist_browser *browser) +{ + struct hist_entry *he = browser->he_selection; + struct map_symbol *ms = browser->selection; + + if (!he || !ms) + return false; + + if (ms == &he->ms) + return he->unfolded; + + return container_of(ms, struct callchain_list, ms)->unfolded; +} + +static char *hist_browser__selection_sym_name(struct hist_browser *browser, char *bf, size_t size) +{ + struct hist_entry *he = browser->he_selection; + struct map_symbol *ms = browser->selection; + struct callchain_list *callchain_entry; + + if (!he || !ms) + return NULL; + + if (ms == &he->ms) { + hist_entry__sym_snprintf(he, bf, size, 0); + return bf + 4; // skip the level, e.g. '[k] ' + } + + callchain_entry = container_of(ms, struct callchain_list, ms); + return callchain_list__sym_name(callchain_entry, bf, size, browser->show_dso); +} + static bool hist_browser__toggle_fold(struct hist_browser *browser) { struct hist_entry *he = browser->he_selection; @@ -624,10 +677,81 @@ static int hist_browser__title(struct hist_browser *browser, char *bf, size_t si return browser->title ? browser->title(browser, bf, size) : 0; } +static int hist_browser__handle_hotkey(struct hist_browser *browser, bool warn_lost_event, char *title, int key) +{ + switch (key) { + case K_TIMER: { + struct hist_browser_timer *hbt = browser->hbt; + u64 nr_entries; + + WARN_ON_ONCE(!hbt); + + if (hbt) + hbt->timer(hbt->arg); + + if (hist_browser__has_filter(browser) || symbol_conf.report_hierarchy) + hist_browser__update_nr_entries(browser); + + nr_entries = hist_browser__nr_entries(browser); + ui_browser__update_nr_entries(&browser->b, nr_entries); + + if (warn_lost_event && + (browser->hists->stats.nr_lost_warned != + browser->hists->stats.nr_events[PERF_RECORD_LOST])) { + browser->hists->stats.nr_lost_warned = + browser->hists->stats.nr_events[PERF_RECORD_LOST]; + ui_browser__warn_lost_events(&browser->b); + } + + hist_browser__title(browser, title, sizeof(title)); + ui_browser__show_title(&browser->b, title); + break; + } + case 'D': { /* Debug */ + struct hist_entry *h = rb_entry(browser->b.top, struct hist_entry, rb_node); + static int seq; + + ui_helpline__pop(); + ui_helpline__fpush("%d: nr_ent=(%d,%d), etl: %d, rows=%d, idx=%d, fve: idx=%d, row_off=%d, nrows=%d", + seq++, browser->b.nr_entries, browser->hists->nr_entries, + browser->b.extra_title_lines, browser->b.rows, + browser->b.index, browser->b.top_idx, h->row_offset, h->nr_rows); + } + break; + case 'C': + /* Collapse the whole world. */ + hist_browser__set_folding(browser, false); + break; + case 'c': + /* Collapse the selected entry. */ + hist_browser__set_folding_selected(browser, false); + break; + case 'E': + /* Expand the whole world. */ + hist_browser__set_folding(browser, true); + break; + case 'e': + /* Expand the selected entry. */ + hist_browser__set_folding_selected(browser, !hist_browser__he_selection_unfolded(browser)); + break; + case 'H': + browser->show_headers = !browser->show_headers; + hist_browser__update_rows(browser); + break; + case '+': + if (hist_browser__toggle_fold(browser)) + break; + /* fall thru */ + default: + return -1; + } + + return 0; +} + int hist_browser__run(struct hist_browser *browser, const char *help, - bool warn_lost_event) + bool warn_lost_event, int key) { - int key; char title[160]; struct hist_browser_timer *hbt = browser->hbt; int delay_secs = hbt ? hbt->refresh : 0; @@ -640,79 +764,14 @@ int hist_browser__run(struct hist_browser *browser, const char *help, if (ui_browser__show(&browser->b, title, "%s", help) < 0) return -1; + if (key && hist_browser__handle_hotkey(browser, warn_lost_event, title, key)) + goto out; + while (1) { key = ui_browser__run(&browser->b, delay_secs); - switch (key) { - case K_TIMER: { - u64 nr_entries; - - WARN_ON_ONCE(!hbt); - - if (hbt) - hbt->timer(hbt->arg); - - if (hist_browser__has_filter(browser) || - symbol_conf.report_hierarchy) - hist_browser__update_nr_entries(browser); - - nr_entries = hist_browser__nr_entries(browser); - ui_browser__update_nr_entries(&browser->b, nr_entries); - - if (warn_lost_event && - (browser->hists->stats.nr_lost_warned != - browser->hists->stats.nr_events[PERF_RECORD_LOST])) { - browser->hists->stats.nr_lost_warned = - browser->hists->stats.nr_events[PERF_RECORD_LOST]; - ui_browser__warn_lost_events(&browser->b); - } - - hist_browser__title(browser, title, sizeof(title)); - ui_browser__show_title(&browser->b, title); - continue; - } - case 'D': { /* Debug */ - static int seq; - struct hist_entry *h = rb_entry(browser->b.top, - struct hist_entry, rb_node); - ui_helpline__pop(); - ui_helpline__fpush("%d: nr_ent=(%d,%d), etl: %d, rows=%d, idx=%d, fve: idx=%d, row_off=%d, nrows=%d", - seq++, browser->b.nr_entries, - browser->hists->nr_entries, - browser->b.extra_title_lines, - browser->b.rows, - browser->b.index, - browser->b.top_idx, - h->row_offset, h->nr_rows); - } - break; - case 'C': - /* Collapse the whole world. */ - hist_browser__set_folding(browser, false); - break; - case 'c': - /* Collapse the selected entry. */ - hist_browser__set_folding_selected(browser, false); + if (hist_browser__handle_hotkey(browser, warn_lost_event, title, key)) break; - case 'E': - /* Expand the whole world. */ - hist_browser__set_folding(browser, true); - break; - case 'e': - /* Expand the selected entry. */ - hist_browser__set_folding_selected(browser, true); - break; - case 'H': - browser->show_headers = !browser->show_headers; - hist_browser__update_rows(browser); - break; - case K_ENTER: - if (hist_browser__toggle_fold(browser)) - break; - /* fall thru */ - default: - goto out; - } } out: ui_browser__hide(&browser->b); @@ -2339,7 +2398,7 @@ close_file_and_continue: closedir(pwd_dir); if (nr_options) { - choice = ui__popup_menu(nr_options, options); + choice = ui__popup_menu(nr_options, options, NULL); if (choice < nr_options && choice >= 0) { tmp = strdup(abs_path[choice]); if (tmp) { @@ -2411,7 +2470,8 @@ add_annotate_opt(struct hist_browser *browser __maybe_unused, struct popup_action *act, char **optstr, struct map_symbol *ms) { - if (ms->sym == NULL || ms->map->dso->annotate_warned) + if (ms->sym == NULL || ms->map->dso->annotate_warned || + symbol__annotation(ms->sym)->src == NULL) return 0; if (asprintf(optstr, "Annotate %s", ms->sym->name) < 0) @@ -2484,11 +2544,8 @@ add_thread_opt(struct hist_browser *browser, struct popup_action *act, return 1; } -static int -do_zoom_dso(struct hist_browser *browser, struct popup_action *act) +static int hists_browser__zoom_map(struct hist_browser *browser, struct map *map) { - struct map *map = act->ms.map; - if (!hists__has(browser->hists, dso) || map == NULL) return 0; @@ -2511,13 +2568,19 @@ do_zoom_dso(struct hist_browser *browser, struct popup_action *act) } static int +do_zoom_dso(struct hist_browser *browser, struct popup_action *act) +{ + return hists_browser__zoom_map(browser, act->ms.map); +} + +static int add_dso_opt(struct hist_browser *browser, struct popup_action *act, char **optstr, struct map *map) { if (!hists__has(browser->hists, dso) || map == NULL) return 0; - if (asprintf(optstr, "Zoom %s %s DSO", + if (asprintf(optstr, "Zoom %s %s DSO (use the 'k' hotkey to zoom directly into the kernel)", browser->hists->dso_filter ? "out of" : "into", __map__is_kernel(map) ? "the Kernel" : map->dso->short_name) < 0) return 0; @@ -2527,6 +2590,28 @@ add_dso_opt(struct hist_browser *browser, struct popup_action *act, return 1; } +static int do_toggle_callchain(struct hist_browser *browser, struct popup_action *act __maybe_unused) +{ + hist_browser__toggle_fold(browser); + return 0; +} + +static int add_callchain_toggle_opt(struct hist_browser *browser, struct popup_action *act, char **optstr) +{ + char sym_name[512]; + + if (!hist_browser__selection_has_children(browser)) + return 0; + + if (asprintf(optstr, "%s [%s] callchain (one level, same as '+' hotkey, use 'e'/'c' for the whole main level entry)", + hist_browser__selection_unfolded(browser) ? "Collapse" : "Expand", + hist_browser__selection_sym_name(browser, sym_name, sizeof(sym_name))) < 0) + return 0; + + act->fn = do_toggle_callchain; + return 1; +} + static int do_browse_map(struct hist_browser *browser __maybe_unused, struct popup_action *act) @@ -2858,12 +2943,15 @@ static int perf_evsel__hists_browse(struct evsel *evsel, int nr_events, "For symbolic views (--sort has sym):\n\n" \ "ENTER Zoom into DSO/Threads & Annotate current symbol\n" \ "ESC Zoom out\n" \ + "+ Expand/Collapse one callchain level\n" \ "a Annotate current symbol\n" \ "C Collapse all callchains\n" \ "d Zoom into current DSO\n" \ + "e Expand/Collapse main entry callchains\n" \ "E Expand all callchains\n" \ "F Toggle percentage of filtered entries\n" \ "H Display column headers\n" \ + "k Zoom into the kernel map\n" \ "L Change percent limit\n" \ "m Display context menu\n" \ "S Zoom into current Processor Socket\n" \ @@ -2914,13 +3002,13 @@ static int perf_evsel__hists_browse(struct evsel *evsel, int nr_events, while (1) { struct thread *thread = NULL; struct map *map = NULL; - int choice = 0; + int choice; int socked_id = -1; - nr_options = 0; - - key = hist_browser__run(browser, helpline, - warn_lost_event); + key = 0; // reset key +do_hotkey: // key came straight from options ui__popup_menu() + choice = nr_options = 0; + key = hist_browser__run(browser, helpline, warn_lost_event, key); if (browser->he_selection != NULL) { thread = hist_browser__selected_thread(browser); @@ -2950,6 +3038,14 @@ static int perf_evsel__hists_browse(struct evsel *evsel, int nr_events, browser->selection->map->dso->annotate_warned) continue; + if (symbol__annotation(browser->selection->sym)->src == NULL) { + ui_browser__warning(&browser->b, delay_secs * 2, + "No samples for the \"%s\" symbol.\n\n" + "Probably appeared just in a callchain", + browser->selection->sym->name); + continue; + } + actions->ms.map = browser->selection->map; actions->ms.sym = browser->selection->sym; do_annotate(browser, actions); @@ -2961,6 +3057,10 @@ static int perf_evsel__hists_browse(struct evsel *evsel, int nr_events, actions->ms.map = map; do_zoom_dso(browser, actions); continue; + case 'k': + if (browser->selection != NULL) + hists_browser__zoom_map(browser, browser->selection->maps->machine->vmlinux_map); + continue; case 'V': verbose = (verbose + 1) % 4; browser->show_dso = verbose > 0; @@ -3062,6 +3162,7 @@ static int perf_evsel__hists_browse(struct evsel *evsel, int nr_events, continue; } + actions->ms.map = map; top = pstack__peek(browser->pstack); if (top == &browser->hists->dso_filter) { /* @@ -3135,6 +3236,7 @@ skip_annotation: &options[nr_options], thread); nr_options += add_dso_opt(browser, &actions[nr_options], &options[nr_options], map); + nr_options += add_callchain_toggle_opt(browser, &actions[nr_options], &options[nr_options]); nr_options += add_map_opt(browser, &actions[nr_options], &options[nr_options], browser->selection ? @@ -3193,10 +3295,13 @@ skip_scripting: do { struct popup_action *act; - choice = ui__popup_menu(nr_options, options); - if (choice == -1 || choice >= nr_options) + choice = ui__popup_menu(nr_options, options, &key); + if (choice == -1) break; + if (choice == nr_options) + goto do_hotkey; + act = &actions[choice]; key = act->fn(browser, act); } while (key == 1); @@ -3492,7 +3597,7 @@ int block_hists_tui_browse(struct block_hist *bh, struct evsel *evsel, memset(&action, 0, sizeof(action)); while (1) { - key = hist_browser__run(browser, "? - help", true); + key = hist_browser__run(browser, "? - help", true, 0); switch (key) { case 'q': diff --git a/tools/perf/ui/browsers/hists.h b/tools/perf/ui/browsers/hists.h index 078f2f2c7abd..1e938d9ffa5e 100644 --- a/tools/perf/ui/browsers/hists.h +++ b/tools/perf/ui/browsers/hists.h @@ -34,7 +34,7 @@ struct hist_browser { struct hist_browser *hist_browser__new(struct hists *hists); void hist_browser__delete(struct hist_browser *browser); int hist_browser__run(struct hist_browser *browser, const char *help, - bool warn_lost_event); + bool warn_lost_event, int key); void hist_browser__init(struct hist_browser *browser, struct hists *hists); #endif /* _PERF_UI_BROWSER_HISTS_H_ */ diff --git a/tools/perf/ui/browsers/res_sample.c b/tools/perf/ui/browsers/res_sample.c index 76d356a18790..7cb2d6678039 100644 --- a/tools/perf/ui/browsers/res_sample.c +++ b/tools/perf/ui/browsers/res_sample.c @@ -56,7 +56,7 @@ int res_sample_browse(struct res_sample *res_samples, int num_res, return -1; } } - choice = ui__popup_menu(num_res, names); + choice = ui__popup_menu(num_res, names, NULL); for (i = 0; i < num_res; i++) zfree(&names[i]); free(names); diff --git a/tools/perf/ui/browsers/scripts.c b/tools/perf/ui/browsers/scripts.c index fc733a6354d4..47d2c7a8cbe1 100644 --- a/tools/perf/ui/browsers/scripts.c +++ b/tools/perf/ui/browsers/scripts.c @@ -126,7 +126,7 @@ static int list_scripts(char *script_name, bool *custom, SCRIPT_FULLPATH_LEN); if (num < 0) num = 0; - choice = ui__popup_menu(num + max_std, (char * const *)names); + choice = ui__popup_menu(num + max_std, (char * const *)names, NULL); if (choice < 0) { ret = -1; goto out; diff --git a/tools/perf/ui/gtk/Build b/tools/perf/ui/gtk/Build index ec22e899a224..eef708c502f4 100644 --- a/tools/perf/ui/gtk/Build +++ b/tools/perf/ui/gtk/Build @@ -1,4 +1,4 @@ -CFLAGS_gtk += -fPIC $(GTK_CFLAGS) +CFLAGS_gtk += -fPIC $(GTK_CFLAGS) -Wno-deprecated-declarations gtk-y += browser.o gtk-y += hists.o @@ -7,3 +7,8 @@ gtk-y += util.o gtk-y += helpline.o gtk-y += progress.o gtk-y += annotate.o +gtk-y += zalloc.o + +$(OUTPUT)ui/gtk/zalloc.o: ../lib/zalloc.c FORCE + $(call rule_mkdir) + $(call if_changed_dep,cc_o_c) diff --git a/tools/perf/ui/tui/util.c b/tools/perf/ui/tui/util.c index b98dd0e31dc1..0f562e2cb1e8 100644 --- a/tools/perf/ui/tui/util.c +++ b/tools/perf/ui/tui/util.c @@ -23,7 +23,7 @@ static void ui_browser__argv_write(struct ui_browser *browser, ui_browser__write_nstring(browser, *arg, browser->width); } -static int popup_menu__run(struct ui_browser *menu) +static int popup_menu__run(struct ui_browser *menu, int *keyp) { int key; @@ -45,6 +45,11 @@ static int popup_menu__run(struct ui_browser *menu) key = -1; break; default: + if (keyp) { + *keyp = key; + key = menu->nr_entries; + break; + } continue; } @@ -55,7 +60,7 @@ static int popup_menu__run(struct ui_browser *menu) return key; } -int ui__popup_menu(int argc, char * const argv[]) +int ui__popup_menu(int argc, char * const argv[], int *keyp) { struct ui_browser menu = { .entries = (void *)argv, @@ -64,8 +69,7 @@ int ui__popup_menu(int argc, char * const argv[]) .write = ui_browser__argv_write, .nr_entries = argc, }; - - return popup_menu__run(&menu); + return popup_menu__run(&menu, keyp); } int ui_browser__input_window(const char *title, const char *text, char *input, diff --git a/tools/perf/ui/util.h b/tools/perf/ui/util.h index 40891942f465..e30cea807564 100644 --- a/tools/perf/ui/util.h +++ b/tools/perf/ui/util.h @@ -5,7 +5,7 @@ #include <stdarg.h> int ui__getch(int delay_secs); -int ui__popup_menu(int argc, char * const argv[]); +int ui__popup_menu(int argc, char * const argv[], int *keyp); int ui__help_window(const char *text); int ui__dialog_yesno(const char *msg); void __ui__info_window(const char *title, const char *text, const char *exit_msg); diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index f5e77ed237e8..ca73fb74ad03 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -1966,14 +1966,20 @@ static int symbol__disassemble(struct symbol *sym, struct annotate_args *args) err = asprintf(&command, "%s %s%s --start-address=0x%016" PRIx64 " --stop-address=0x%016" PRIx64 - " -l -d %s %s -C \"$1\"", + " -l -d %s %s %s %c%s%c %s%s -C \"$1\"", opts->objdump_path ?: "objdump", opts->disassembler_style ? "-M " : "", opts->disassembler_style ?: "", map__rip_2objdump(map, sym->start), map__rip_2objdump(map, sym->end), opts->show_asm_raw ? "" : "--no-show-raw-insn", - opts->annotate_src ? "-S" : ""); + opts->annotate_src ? "-S" : "", + opts->prefix ? "--prefix " : "", + opts->prefix ? '"' : ' ', + opts->prefix ?: "", + opts->prefix ? '"' : ' ', + opts->prefix_strip ? "--prefix-strip=" : "", + opts->prefix_strip ?: ""); if (err < 0) { pr_err("Failure allocating memory for the command to run\n"); @@ -3204,3 +3210,12 @@ out: free(str1); return err; } + +int annotate_check_args(struct annotation_options *args) +{ + if (args->prefix_strip && !args->prefix) { + pr_err("--prefix-strip requires --prefix\n"); + return -1; + } + return 0; +} diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index 7075d98f69d9..455403e8fede 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h @@ -94,6 +94,8 @@ struct annotation_options { int context; const char *objdump_path; const char *disassembler_style; + const char *prefix; + const char *prefix_strip; unsigned int percent_type; }; @@ -415,4 +417,7 @@ void annotation_config__init(void); int annotate_parse_percent_type(const struct option *opt, const char *_str, int unset); + +int annotate_check_args(struct annotation_options *args); + #endif /* __PERF_ANNOTATE_H */ diff --git a/tools/perf/util/c++/clang.cpp b/tools/perf/util/c++/clang.cpp index fc361c3f8570..c8885dfa3667 100644 --- a/tools/perf/util/c++/clang.cpp +++ b/tools/perf/util/c++/clang.cpp @@ -71,7 +71,11 @@ getModuleFromSource(llvm::opt::ArgStringList CFlags, CompilerInstance Clang; Clang.createDiagnostics(); +#if CLANG_VERSION_MAJOR < 9 Clang.setVirtualFileSystem(&*VFS); +#else + Clang.createFileManager(&*VFS); +#endif #if CLANG_VERSION_MAJOR < 4 IntrusiveRefCntPtr<CompilerInvocation> CI = diff --git a/tools/perf/util/expr.y b/tools/perf/util/expr.y index f9a20a39b64a..7d226241f1d7 100644 --- a/tools/perf/util/expr.y +++ b/tools/perf/util/expr.y @@ -12,7 +12,8 @@ #define MAXIDLEN 256 %} -%pure-parser +%define api.pure full + %parse-param { double *final_val } %parse-param { struct parse_ctx *ctx } %parse-param { const char **pp } diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 93ad27830e2b..4246e7447e54 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -2922,7 +2922,7 @@ int perf_header__fprintf_info(struct perf_session *session, FILE *fp, bool full) if (ret == -1) return -1; - stctime = st.st_ctime; + stctime = st.st_mtime; fprintf(fp, "# captured on : %s", ctime(&stctime)); fprintf(fp, "# header version : %u\n", header->version); diff --git a/tools/perf/util/mmap.c b/tools/perf/util/mmap.c index 063d1b93c53d..3b664fa673a6 100644 --- a/tools/perf/util/mmap.c +++ b/tools/perf/util/mmap.c @@ -23,6 +23,18 @@ #include "mmap.h" #include "../perf.h" #include <internal/lib.h> /* page_size */ +#include <linux/bitmap.h> + +#define MASK_SIZE 1023 +void mmap_cpu_mask__scnprintf(struct mmap_cpu_mask *mask, const char *tag) +{ + char buf[MASK_SIZE + 1]; + size_t len; + + len = bitmap_scnprintf(mask->bits, mask->nbits, buf, MASK_SIZE); + buf[len] = '\0'; + pr_debug("%p: %s mask[%zd]: %s\n", mask, tag, mask->nbits, buf); +} size_t mmap__mmap_len(struct mmap *map) { @@ -207,6 +219,8 @@ static void perf_mmap__aio_munmap(struct mmap *map __maybe_unused) void mmap__munmap(struct mmap *map) { + bitmap_free(map->affinity_mask.bits); + perf_mmap__aio_munmap(map); if (map->data != NULL) { munmap(map->data, mmap__mmap_len(map)); @@ -215,7 +229,7 @@ void mmap__munmap(struct mmap *map) auxtrace_mmap__munmap(&map->auxtrace_mmap); } -static void build_node_mask(int node, cpu_set_t *mask) +static void build_node_mask(int node, struct mmap_cpu_mask *mask) { int c, cpu, nr_cpus; const struct perf_cpu_map *cpu_map = NULL; @@ -228,17 +242,23 @@ static void build_node_mask(int node, cpu_set_t *mask) for (c = 0; c < nr_cpus; c++) { cpu = cpu_map->map[c]; /* map c index to online cpu index */ if (cpu__get_node(cpu) == node) - CPU_SET(cpu, mask); + set_bit(cpu, mask->bits); } } -static void perf_mmap__setup_affinity_mask(struct mmap *map, struct mmap_params *mp) +static int perf_mmap__setup_affinity_mask(struct mmap *map, struct mmap_params *mp) { - CPU_ZERO(&map->affinity_mask); + map->affinity_mask.nbits = cpu__max_cpu(); + map->affinity_mask.bits = bitmap_alloc(map->affinity_mask.nbits); + if (!map->affinity_mask.bits) + return -1; + if (mp->affinity == PERF_AFFINITY_NODE && cpu__max_node() > 1) build_node_mask(cpu__get_node(map->core.cpu), &map->affinity_mask); else if (mp->affinity == PERF_AFFINITY_CPU) - CPU_SET(map->core.cpu, &map->affinity_mask); + set_bit(map->core.cpu, map->affinity_mask.bits); + + return 0; } int mmap__mmap(struct mmap *map, struct mmap_params *mp, int fd, int cpu) @@ -249,7 +269,15 @@ int mmap__mmap(struct mmap *map, struct mmap_params *mp, int fd, int cpu) return -1; } - perf_mmap__setup_affinity_mask(map, mp); + if (mp->affinity != PERF_AFFINITY_SYS && + perf_mmap__setup_affinity_mask(map, mp)) { + pr_debug2("failed to alloc mmap affinity mask, error %d\n", + errno); + return -1; + } + + if (verbose == 2) + mmap_cpu_mask__scnprintf(&map->affinity_mask, "mmap"); map->core.flush = mp->flush; diff --git a/tools/perf/util/mmap.h b/tools/perf/util/mmap.h index bee4e83f7109..9d5f589f02ae 100644 --- a/tools/perf/util/mmap.h +++ b/tools/perf/util/mmap.h @@ -15,6 +15,15 @@ #include "event.h" struct aiocb; + +struct mmap_cpu_mask { + unsigned long *bits; + size_t nbits; +}; + +#define MMAP_CPU_MASK_BYTES(m) \ + (BITS_TO_LONGS(((struct mmap_cpu_mask *)m)->nbits) * sizeof(unsigned long)) + /** * struct mmap - perf's ring buffer mmap details * @@ -31,7 +40,7 @@ struct mmap { int nr_cblocks; } aio; #endif - cpu_set_t affinity_mask; + struct mmap_cpu_mask affinity_mask; void *data; int comp_level; }; @@ -52,4 +61,6 @@ int perf_mmap__push(struct mmap *md, void *to, size_t mmap__mmap_len(struct mmap *map); +void mmap_cpu_mask__scnprintf(struct mmap_cpu_mask *mask, const char *tag); + #endif /*__PERF_MMAP_H */ diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y index e2eea4e601b4..94f8bcd83582 100644 --- a/tools/perf/util/parse-events.y +++ b/tools/perf/util/parse-events.y @@ -1,4 +1,4 @@ -%pure-parser +%define api.pure full %parse-param {void *_parse_state} %parse-param {void *scanner} %lex-param {void* scanner} diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index 9fcba2872130..ab0cfd790ad0 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -324,8 +324,7 @@ static int _hist_entry__sym_snprintf(struct map_symbol *ms, return ret; } -static int hist_entry__sym_snprintf(struct hist_entry *he, char *bf, - size_t size, unsigned int width) +int hist_entry__sym_snprintf(struct hist_entry *he, char *bf, size_t size, unsigned int width) { return _hist_entry__sym_snprintf(&he->ms, he->ip, he->level, bf, size, width); diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h index 5aff9542d9b7..6c862d62d052 100644 --- a/tools/perf/util/sort.h +++ b/tools/perf/util/sort.h @@ -164,6 +164,8 @@ static __pure inline bool hist_entry__has_callchains(struct hist_entry *he) return he->callchain_size != 0; } +int hist_entry__sym_snprintf(struct hist_entry *he, char *bf, size_t size, unsigned int width); + static inline bool hist_entry__has_pairs(struct hist_entry *he) { return !list_empty(&he->pairs.node); |