summaryrefslogtreecommitdiff
path: root/tools/perf
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2020-01-28 20:44:15 +0300
committerLinus Torvalds <torvalds@linux-foundation.org>2020-01-28 20:44:15 +0300
commitc0e809e244804d428bcd976eaf9369f60508ea8a (patch)
tree99fa85899a3c11d2ebeb6d090f218fda968a0e6a /tools/perf
parent2180f214f4a5d8e2d8b7138d9a59246ee05753b9 (diff)
parent0cc4bd8f70d1ea2940295f1050508c663fe9eff9 (diff)
downloadlinux-c0e809e244804d428bcd976eaf9369f60508ea8a.tar.xz
Merge branch 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull perf updates from Ingo Molnar: "Kernel side changes: - Ftrace is one of the last W^X violators (after this only KLP is left). These patches move it over to the generic text_poke() interface and thereby get rid of this oddity. This requires a surprising amount of surgery, by Peter Zijlstra. - x86/AMD PMUs: add support for 'Large Increment per Cycle Events' to count certain types of events that have a special, quirky hw ABI (by Kim Phillips) - kprobes fixes by Masami Hiramatsu Lots of tooling updates as well, the following subcommands were updated: annotate/report/top, c2c, clang, record, report/top TUI, sched timehist, tests; plus updates were done to the gtk ui, libperf, headers and the parser" * 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (57 commits) perf/x86/amd: Add support for Large Increment per Cycle Events perf/x86/amd: Constrain Large Increment per Cycle events perf/x86/intel/rapl: Add Comet Lake support tracing: Initialize ret in syscall_enter_define_fields() perf header: Use last modification time for timestamp perf c2c: Fix return type for histogram sorting comparision functions perf beauty sockaddr: Fix augmented syscall format warning perf/ui/gtk: Fix gtk2 build perf ui gtk: Add missing zalloc object perf tools: Use %define api.pure full instead of %pure-parser libperf: Setup initial evlist::all_cpus value perf report: Fix no libunwind compiled warning break s390 issue perf tools: Support --prefix/--prefix-strip perf report: Clarify in help that --children is default tools build: Fix test-clang.cpp with Clang 8+ perf clang: Fix build with Clang 9 kprobes: Fix optimize_kprobe()/unoptimize_kprobe() cancellation logic tools lib: Fix builds when glibc contains strlcpy() perf report/top: Make 'e' visible in the help and make it toggle showing callchains perf report/top: Do not offer annotation for symbols without samples ...
Diffstat (limited to 'tools/perf')
-rw-r--r--tools/perf/Documentation/perf-annotate.txt6
-rw-r--r--tools/perf/Documentation/perf-report.txt6
-rw-r--r--tools/perf/Documentation/perf-sched.txt4
-rw-r--r--tools/perf/Documentation/perf-top.txt6
-rw-r--r--tools/perf/MANIFEST1
-rw-r--r--tools/perf/Makefile.config2
-rw-r--r--tools/perf/Makefile.perf2
-rw-r--r--tools/perf/builtin-annotate.c7
-rw-r--r--tools/perf/builtin-c2c.c14
-rw-r--r--tools/perf/builtin-record.c28
-rw-r--r--tools/perf/builtin-report.c16
-rw-r--r--tools/perf/builtin-sched.c13
-rw-r--r--tools/perf/builtin-top.c7
-rw-r--r--tools/perf/lib/Build13
-rw-r--r--tools/perf/lib/Documentation/Makefile7
-rw-r--r--tools/perf/lib/Documentation/man/libperf.rst100
-rw-r--r--tools/perf/lib/Documentation/tutorial/tutorial.rst123
-rw-r--r--tools/perf/lib/Makefile188
-rw-r--r--tools/perf/lib/core.c38
-rw-r--r--tools/perf/lib/cpumap.c345
-rw-r--r--tools/perf/lib/evlist.c641
-rw-r--r--tools/perf/lib/evsel.c301
-rw-r--r--tools/perf/lib/include/internal/cpumap.h19
-rw-r--r--tools/perf/lib/include/internal/evlist.h127
-rw-r--r--tools/perf/lib/include/internal/evsel.h63
-rw-r--r--tools/perf/lib/include/internal/lib.h12
-rw-r--r--tools/perf/lib/include/internal/mmap.h55
-rw-r--r--tools/perf/lib/include/internal/tests.h33
-rw-r--r--tools/perf/lib/include/internal/threadmap.h23
-rw-r--r--tools/perf/lib/include/internal/xyarray.h36
-rw-r--r--tools/perf/lib/include/perf/core.h25
-rw-r--r--tools/perf/lib/include/perf/cpumap.h28
-rw-r--r--tools/perf/lib/include/perf/event.h385
-rw-r--r--tools/perf/lib/include/perf/evlist.h49
-rw-r--r--tools/perf/lib/include/perf/evsel.h40
-rw-r--r--tools/perf/lib/include/perf/mmap.h15
-rw-r--r--tools/perf/lib/include/perf/threadmap.h20
-rw-r--r--tools/perf/lib/internal.h23
-rw-r--r--tools/perf/lib/lib.c48
-rw-r--r--tools/perf/lib/libperf.map51
-rw-r--r--tools/perf/lib/libperf.pc.template11
-rw-r--r--tools/perf/lib/mmap.c275
-rw-r--r--tools/perf/lib/tests/Makefile38
-rw-r--r--tools/perf/lib/tests/test-cpumap.c31
-rw-r--r--tools/perf/lib/tests/test-evlist.c413
-rw-r--r--tools/perf/lib/tests/test-evsel.c135
-rw-r--r--tools/perf/lib/tests/test-threadmap.c31
-rw-r--r--tools/perf/lib/threadmap.c91
-rw-r--r--tools/perf/lib/xyarray.c33
-rw-r--r--tools/perf/tests/bp_signal.c10
-rw-r--r--tools/perf/trace/beauty/sockaddr.c2
-rw-r--r--tools/perf/ui/browsers/hists.c277
-rw-r--r--tools/perf/ui/browsers/hists.h2
-rw-r--r--tools/perf/ui/browsers/res_sample.c2
-rw-r--r--tools/perf/ui/browsers/scripts.c2
-rw-r--r--tools/perf/ui/gtk/Build7
-rw-r--r--tools/perf/ui/tui/util.c12
-rw-r--r--tools/perf/ui/util.h2
-rw-r--r--tools/perf/util/annotate.c19
-rw-r--r--tools/perf/util/annotate.h5
-rw-r--r--tools/perf/util/c++/clang.cpp4
-rw-r--r--tools/perf/util/expr.y3
-rw-r--r--tools/perf/util/header.c2
-rw-r--r--tools/perf/util/mmap.c40
-rw-r--r--tools/perf/util/mmap.h13
-rw-r--r--tools/perf/util/parse-events.y2
-rw-r--r--tools/perf/util/sort.c3
-rw-r--r--tools/perf/util/sort.h2
68 files changed, 388 insertions, 3999 deletions
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/lib/Build b/tools/perf/lib/Build
deleted file mode 100644
index 2ef9a4ec6d99..000000000000
--- a/tools/perf/lib/Build
+++ /dev/null
@@ -1,13 +0,0 @@
-libperf-y += core.o
-libperf-y += cpumap.o
-libperf-y += threadmap.o
-libperf-y += evsel.o
-libperf-y += evlist.o
-libperf-y += mmap.o
-libperf-y += zalloc.o
-libperf-y += xyarray.o
-libperf-y += lib.o
-
-$(OUTPUT)zalloc.o: ../../lib/zalloc.c FORCE
- $(call rule_mkdir)
- $(call if_changed_dep,cc_o_c)
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/lib/Makefile b/tools/perf/lib/Makefile
deleted file mode 100644
index 0f233638ef1f..000000000000
--- a/tools/perf/lib/Makefile
+++ /dev/null
@@ -1,188 +0,0 @@
-# SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
-# Most of this file is copied from tools/lib/bpf/Makefile
-
-LIBPERF_VERSION = 0
-LIBPERF_PATCHLEVEL = 0
-LIBPERF_EXTRAVERSION = 1
-
-MAKEFLAGS += --no-print-directory
-
-ifeq ($(srctree),)
-srctree := $(patsubst %/,%,$(dir $(CURDIR)))
-srctree := $(patsubst %/,%,$(dir $(srctree)))
-srctree := $(patsubst %/,%,$(dir $(srctree)))
-#$(info Determined 'srctree' to be $(srctree))
-endif
-
-INSTALL = install
-
-# Use DESTDIR for installing into a different root directory.
-# This is useful for building a package. The program will be
-# installed in this directory as if it was the root directory.
-# Then the build tool can move it later.
-DESTDIR ?=
-DESTDIR_SQ = '$(subst ','\'',$(DESTDIR))'
-
-include $(srctree)/tools/scripts/Makefile.include
-include $(srctree)/tools/scripts/Makefile.arch
-
-ifeq ($(LP64), 1)
- libdir_relative = lib64
-else
- libdir_relative = lib
-endif
-
-prefix ?=
-libdir = $(prefix)/$(libdir_relative)
-
-# Shell quotes
-libdir_SQ = $(subst ','\'',$(libdir))
-libdir_relative_SQ = $(subst ','\'',$(libdir_relative))
-
-ifeq ("$(origin V)", "command line")
- VERBOSE = $(V)
-endif
-ifndef VERBOSE
- VERBOSE = 0
-endif
-
-ifeq ($(VERBOSE),1)
- Q =
-else
- Q = @
-endif
-
-# Set compile option CFLAGS
-ifdef EXTRA_CFLAGS
- CFLAGS := $(EXTRA_CFLAGS)
-else
- CFLAGS := -g -Wall
-endif
-
-INCLUDES = \
--I$(srctree)/tools/perf/lib/include \
--I$(srctree)/tools/lib/ \
--I$(srctree)/tools/include \
--I$(srctree)/tools/arch/$(SRCARCH)/include/ \
--I$(srctree)/tools/arch/$(SRCARCH)/include/uapi \
--I$(srctree)/tools/include/uapi
-
-# Append required CFLAGS
-override CFLAGS += $(EXTRA_WARNINGS)
-override CFLAGS += -Werror -Wall
-override CFLAGS += -fPIC
-override CFLAGS += $(INCLUDES)
-override CFLAGS += -fvisibility=hidden
-
-all:
-
-export srctree OUTPUT CC LD CFLAGS V
-export DESTDIR DESTDIR_SQ
-
-include $(srctree)/tools/build/Makefile.include
-
-VERSION_SCRIPT := libperf.map
-
-PATCHLEVEL = $(LIBPERF_PATCHLEVEL)
-EXTRAVERSION = $(LIBPERF_EXTRAVERSION)
-VERSION = $(LIBPERF_VERSION).$(LIBPERF_PATCHLEVEL).$(LIBPERF_EXTRAVERSION)
-
-LIBPERF_SO := $(OUTPUT)libperf.so.$(VERSION)
-LIBPERF_A := $(OUTPUT)libperf.a
-LIBPERF_IN := $(OUTPUT)libperf-in.o
-LIBPERF_PC := $(OUTPUT)libperf.pc
-
-LIBPERF_ALL := $(LIBPERF_A) $(OUTPUT)libperf.so*
-
-LIB_DIR := $(srctree)/tools/lib/api/
-
-ifneq ($(OUTPUT),)
-ifneq ($(subdir),)
- API_PATH=$(OUTPUT)/../lib/api/
-else
- API_PATH=$(OUTPUT)
-endif
-else
- API_PATH=$(LIB_DIR)
-endif
-
-LIBAPI = $(API_PATH)libapi.a
-export LIBAPI
-
-$(LIBAPI): FORCE
- $(Q)$(MAKE) -C $(LIB_DIR) O=$(OUTPUT) $(OUTPUT)libapi.a
-
-$(LIBAPI)-clean:
- $(call QUIET_CLEAN, libapi)
- $(Q)$(MAKE) -C $(LIB_DIR) O=$(OUTPUT) clean >/dev/null
-
-$(LIBPERF_IN): FORCE
- $(Q)$(MAKE) $(build)=libperf
-
-$(LIBPERF_A): $(LIBPERF_IN)
- $(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(LIBPERF_IN)
-
-$(LIBPERF_SO): $(LIBPERF_IN) $(LIBAPI)
- $(QUIET_LINK)$(CC) --shared -Wl,-soname,libperf.so \
- -Wl,--version-script=$(VERSION_SCRIPT) $^ -o $@
- @ln -sf $(@F) $(OUTPUT)libperf.so
- @ln -sf $(@F) $(OUTPUT)libperf.so.$(LIBPERF_VERSION)
-
-
-libs: $(LIBPERF_A) $(LIBPERF_SO) $(LIBPERF_PC)
-
-all: fixdep
- $(Q)$(MAKE) libs
-
-clean: $(LIBAPI)-clean
- $(call QUIET_CLEAN, libperf) $(RM) $(LIBPERF_A) \
- *.o *~ *.a *.so *.so.$(VERSION) *.so.$(LIBPERF_VERSION) .*.d .*.cmd LIBPERF-CFLAGS $(LIBPERF_PC)
- $(Q)$(MAKE) -C tests clean
-
-tests: libs
- $(Q)$(MAKE) -C tests
- $(Q)$(MAKE) -C tests run
-
-$(LIBPERF_PC):
- $(QUIET_GEN)sed -e "s|@PREFIX@|$(prefix)|" \
- -e "s|@LIBDIR@|$(libdir_SQ)|" \
- -e "s|@VERSION@|$(VERSION)|" \
- < libperf.pc.template > $@
-
-define do_install_mkdir
- if [ ! -d '$(DESTDIR_SQ)$1' ]; then \
- $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$1'; \
- fi
-endef
-
-define do_install
- if [ ! -d '$(DESTDIR_SQ)$2' ]; then \
- $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$2'; \
- fi; \
- $(INSTALL) $1 $(if $3,-m $3,) '$(DESTDIR_SQ)$2'
-endef
-
-install_lib: libs
- $(call QUIET_INSTALL, $(LIBPERF_ALL)) \
- $(call do_install_mkdir,$(libdir_SQ)); \
- cp -fpR $(LIBPERF_ALL) $(DESTDIR)$(libdir_SQ)
-
-install_headers:
- $(call QUIET_INSTALL, headers) \
- $(call do_install,include/perf/core.h,$(prefix)/include/perf,644); \
- $(call do_install,include/perf/cpumap.h,$(prefix)/include/perf,644); \
- $(call do_install,include/perf/threadmap.h,$(prefix)/include/perf,644); \
- $(call do_install,include/perf/evlist.h,$(prefix)/include/perf,644); \
- $(call do_install,include/perf/evsel.h,$(prefix)/include/perf,644); \
- $(call do_install,include/perf/event.h,$(prefix)/include/perf,644); \
- $(call do_install,include/perf/mmap.h,$(prefix)/include/perf,644);
-
-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
-
-FORCE:
-
-.PHONY: all install clean tests FORCE
diff --git a/tools/perf/lib/core.c b/tools/perf/lib/core.c
deleted file mode 100644
index 58fc894b76c5..000000000000
--- a/tools/perf/lib/core.c
+++ /dev/null
@@ -1,38 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-
-#define __printf(a, b) __attribute__((format(printf, a, b)))
-
-#include <stdio.h>
-#include <stdarg.h>
-#include <unistd.h>
-#include <linux/compiler.h>
-#include <perf/core.h>
-#include <internal/lib.h>
-#include "internal.h"
-
-static int __base_pr(enum libperf_print_level level __maybe_unused, const char *format,
- va_list args)
-{
- return vfprintf(stderr, format, args);
-}
-
-static libperf_print_fn_t __libperf_pr = __base_pr;
-
-__printf(2, 3)
-void libperf_print(enum libperf_print_level level, const char *format, ...)
-{
- va_list args;
-
- if (!__libperf_pr)
- return;
-
- va_start(args, format);
- __libperf_pr(level, format, args);
- va_end(args);
-}
-
-void libperf_init(libperf_print_fn_t fn)
-{
- page_size = sysconf(_SC_PAGE_SIZE);
- __libperf_pr = fn;
-}
diff --git a/tools/perf/lib/cpumap.c b/tools/perf/lib/cpumap.c
deleted file mode 100644
index f93f4e703e4c..000000000000
--- a/tools/perf/lib/cpumap.c
+++ /dev/null
@@ -1,345 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-#include <perf/cpumap.h>
-#include <stdlib.h>
-#include <linux/refcount.h>
-#include <internal/cpumap.h>
-#include <asm/bug.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <ctype.h>
-#include <limits.h>
-
-struct perf_cpu_map *perf_cpu_map__dummy_new(void)
-{
- struct perf_cpu_map *cpus = malloc(sizeof(*cpus) + sizeof(int));
-
- if (cpus != NULL) {
- cpus->nr = 1;
- cpus->map[0] = -1;
- refcount_set(&cpus->refcnt, 1);
- }
-
- return cpus;
-}
-
-static void cpu_map__delete(struct perf_cpu_map *map)
-{
- if (map) {
- WARN_ONCE(refcount_read(&map->refcnt) != 0,
- "cpu_map refcnt unbalanced\n");
- free(map);
- }
-}
-
-struct perf_cpu_map *perf_cpu_map__get(struct perf_cpu_map *map)
-{
- if (map)
- refcount_inc(&map->refcnt);
- return map;
-}
-
-void perf_cpu_map__put(struct perf_cpu_map *map)
-{
- if (map && refcount_dec_and_test(&map->refcnt))
- cpu_map__delete(map);
-}
-
-static struct perf_cpu_map *cpu_map__default_new(void)
-{
- struct perf_cpu_map *cpus;
- int nr_cpus;
-
- nr_cpus = sysconf(_SC_NPROCESSORS_ONLN);
- if (nr_cpus < 0)
- return NULL;
-
- cpus = malloc(sizeof(*cpus) + nr_cpus * sizeof(int));
- if (cpus != NULL) {
- int i;
-
- for (i = 0; i < nr_cpus; ++i)
- cpus->map[i] = i;
-
- cpus->nr = nr_cpus;
- refcount_set(&cpus->refcnt, 1);
- }
-
- return cpus;
-}
-
-static int cmp_int(const void *a, const void *b)
-{
- return *(const int *)a - *(const int*)b;
-}
-
-static struct perf_cpu_map *cpu_map__trim_new(int nr_cpus, int *tmp_cpus)
-{
- size_t payload_size = nr_cpus * sizeof(int);
- struct perf_cpu_map *cpus = malloc(sizeof(*cpus) + payload_size);
- int i, j;
-
- if (cpus != NULL) {
- memcpy(cpus->map, tmp_cpus, payload_size);
- qsort(cpus->map, nr_cpus, sizeof(int), cmp_int);
- /* Remove dups */
- j = 0;
- for (i = 0; i < nr_cpus; i++) {
- if (i == 0 || cpus->map[i] != cpus->map[i - 1])
- cpus->map[j++] = cpus->map[i];
- }
- cpus->nr = j;
- assert(j <= nr_cpus);
- refcount_set(&cpus->refcnt, 1);
- }
-
- return cpus;
-}
-
-struct perf_cpu_map *perf_cpu_map__read(FILE *file)
-{
- struct perf_cpu_map *cpus = NULL;
- int nr_cpus = 0;
- int *tmp_cpus = NULL, *tmp;
- int max_entries = 0;
- int n, cpu, prev;
- char sep;
-
- sep = 0;
- prev = -1;
- for (;;) {
- n = fscanf(file, "%u%c", &cpu, &sep);
- if (n <= 0)
- break;
- if (prev >= 0) {
- int new_max = nr_cpus + cpu - prev - 1;
-
- WARN_ONCE(new_max >= MAX_NR_CPUS, "Perf can support %d CPUs. "
- "Consider raising MAX_NR_CPUS\n", MAX_NR_CPUS);
-
- if (new_max >= max_entries) {
- max_entries = new_max + MAX_NR_CPUS / 2;
- tmp = realloc(tmp_cpus, max_entries * sizeof(int));
- if (tmp == NULL)
- goto out_free_tmp;
- tmp_cpus = tmp;
- }
-
- while (++prev < cpu)
- tmp_cpus[nr_cpus++] = prev;
- }
- if (nr_cpus == max_entries) {
- max_entries += MAX_NR_CPUS;
- tmp = realloc(tmp_cpus, max_entries * sizeof(int));
- if (tmp == NULL)
- goto out_free_tmp;
- tmp_cpus = tmp;
- }
-
- tmp_cpus[nr_cpus++] = cpu;
- if (n == 2 && sep == '-')
- prev = cpu;
- else
- prev = -1;
- if (n == 1 || sep == '\n')
- break;
- }
-
- if (nr_cpus > 0)
- cpus = cpu_map__trim_new(nr_cpus, tmp_cpus);
- else
- cpus = cpu_map__default_new();
-out_free_tmp:
- free(tmp_cpus);
- return cpus;
-}
-
-static struct perf_cpu_map *cpu_map__read_all_cpu_map(void)
-{
- struct perf_cpu_map *cpus = NULL;
- FILE *onlnf;
-
- onlnf = fopen("/sys/devices/system/cpu/online", "r");
- if (!onlnf)
- return cpu_map__default_new();
-
- cpus = perf_cpu_map__read(onlnf);
- fclose(onlnf);
- return cpus;
-}
-
-struct perf_cpu_map *perf_cpu_map__new(const char *cpu_list)
-{
- struct perf_cpu_map *cpus = NULL;
- unsigned long start_cpu, end_cpu = 0;
- char *p = NULL;
- int i, nr_cpus = 0;
- int *tmp_cpus = NULL, *tmp;
- int max_entries = 0;
-
- if (!cpu_list)
- return cpu_map__read_all_cpu_map();
-
- /*
- * must handle the case of empty cpumap to cover
- * TOPOLOGY header for NUMA nodes with no CPU
- * ( e.g., because of CPU hotplug)
- */
- if (!isdigit(*cpu_list) && *cpu_list != '\0')
- goto out;
-
- while (isdigit(*cpu_list)) {
- p = NULL;
- start_cpu = strtoul(cpu_list, &p, 0);
- if (start_cpu >= INT_MAX
- || (*p != '\0' && *p != ',' && *p != '-'))
- goto invalid;
-
- if (*p == '-') {
- cpu_list = ++p;
- p = NULL;
- end_cpu = strtoul(cpu_list, &p, 0);
-
- if (end_cpu >= INT_MAX || (*p != '\0' && *p != ','))
- goto invalid;
-
- if (end_cpu < start_cpu)
- goto invalid;
- } else {
- end_cpu = start_cpu;
- }
-
- WARN_ONCE(end_cpu >= MAX_NR_CPUS, "Perf can support %d CPUs. "
- "Consider raising MAX_NR_CPUS\n", MAX_NR_CPUS);
-
- for (; start_cpu <= end_cpu; start_cpu++) {
- /* check for duplicates */
- for (i = 0; i < nr_cpus; i++)
- if (tmp_cpus[i] == (int)start_cpu)
- goto invalid;
-
- if (nr_cpus == max_entries) {
- max_entries += MAX_NR_CPUS;
- tmp = realloc(tmp_cpus, max_entries * sizeof(int));
- if (tmp == NULL)
- goto invalid;
- tmp_cpus = tmp;
- }
- tmp_cpus[nr_cpus++] = (int)start_cpu;
- }
- if (*p)
- ++p;
-
- cpu_list = p;
- }
-
- if (nr_cpus > 0)
- cpus = cpu_map__trim_new(nr_cpus, tmp_cpus);
- else if (*cpu_list != '\0')
- cpus = cpu_map__default_new();
- else
- cpus = perf_cpu_map__dummy_new();
-invalid:
- free(tmp_cpus);
-out:
- return cpus;
-}
-
-int perf_cpu_map__cpu(const struct perf_cpu_map *cpus, int idx)
-{
- if (idx < cpus->nr)
- return cpus->map[idx];
-
- return -1;
-}
-
-int perf_cpu_map__nr(const struct perf_cpu_map *cpus)
-{
- return cpus ? cpus->nr : 1;
-}
-
-bool perf_cpu_map__empty(const struct perf_cpu_map *map)
-{
- return map ? map->map[0] == -1 : true;
-}
-
-int perf_cpu_map__idx(struct perf_cpu_map *cpus, int cpu)
-{
- int i;
-
- for (i = 0; i < cpus->nr; ++i) {
- if (cpus->map[i] == cpu)
- return i;
- }
-
- return -1;
-}
-
-int perf_cpu_map__max(struct perf_cpu_map *map)
-{
- int i, max = -1;
-
- for (i = 0; i < map->nr; i++) {
- if (map->map[i] > max)
- max = map->map[i];
- }
-
- return max;
-}
-
-/*
- * Merge two cpumaps
- *
- * orig either gets freed and replaced with a new map, or reused
- * with no reference count change (similar to "realloc")
- * other has its reference count increased.
- */
-
-struct perf_cpu_map *perf_cpu_map__merge(struct perf_cpu_map *orig,
- struct perf_cpu_map *other)
-{
- int *tmp_cpus;
- int tmp_len;
- int i, j, k;
- struct perf_cpu_map *merged;
-
- if (!orig && !other)
- return NULL;
- if (!orig) {
- perf_cpu_map__get(other);
- return other;
- }
- if (!other)
- return orig;
- if (orig->nr == other->nr &&
- !memcmp(orig->map, other->map, orig->nr * sizeof(int)))
- return orig;
-
- tmp_len = orig->nr + other->nr;
- tmp_cpus = malloc(tmp_len * sizeof(int));
- if (!tmp_cpus)
- return NULL;
-
- /* Standard merge algorithm from wikipedia */
- i = j = k = 0;
- while (i < orig->nr && j < other->nr) {
- if (orig->map[i] <= other->map[j]) {
- if (orig->map[i] == other->map[j])
- j++;
- tmp_cpus[k++] = orig->map[i++];
- } else
- tmp_cpus[k++] = other->map[j++];
- }
-
- while (i < orig->nr)
- tmp_cpus[k++] = orig->map[i++];
-
- while (j < other->nr)
- tmp_cpus[k++] = other->map[j++];
- assert(k <= tmp_len);
-
- merged = cpu_map__trim_new(k, tmp_cpus);
- free(tmp_cpus);
- perf_cpu_map__put(orig);
- return merged;
-}
diff --git a/tools/perf/lib/evlist.c b/tools/perf/lib/evlist.c
deleted file mode 100644
index ae9e65aa2491..000000000000
--- a/tools/perf/lib/evlist.c
+++ /dev/null
@@ -1,641 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#include <perf/evlist.h>
-#include <perf/evsel.h>
-#include <linux/bitops.h>
-#include <linux/list.h>
-#include <linux/hash.h>
-#include <sys/ioctl.h>
-#include <internal/evlist.h>
-#include <internal/evsel.h>
-#include <internal/xyarray.h>
-#include <internal/mmap.h>
-#include <internal/cpumap.h>
-#include <internal/threadmap.h>
-#include <internal/xyarray.h>
-#include <internal/lib.h>
-#include <linux/zalloc.h>
-#include <sys/ioctl.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <poll.h>
-#include <sys/mman.h>
-#include <perf/cpumap.h>
-#include <perf/threadmap.h>
-#include <api/fd/array.h>
-
-void perf_evlist__init(struct perf_evlist *evlist)
-{
- int i;
-
- for (i = 0; i < PERF_EVLIST__HLIST_SIZE; ++i)
- INIT_HLIST_HEAD(&evlist->heads[i]);
- INIT_LIST_HEAD(&evlist->entries);
- evlist->nr_entries = 0;
- fdarray__init(&evlist->pollfd, 64);
-}
-
-static void __perf_evlist__propagate_maps(struct perf_evlist *evlist,
- struct perf_evsel *evsel)
-{
- /*
- * We already have cpus for evsel (via PMU sysfs) so
- * keep it, if there's no target cpu list defined.
- */
- if (!evsel->own_cpus || evlist->has_user_cpus) {
- perf_cpu_map__put(evsel->cpus);
- evsel->cpus = perf_cpu_map__get(evlist->cpus);
- } else if (evsel->cpus != evsel->own_cpus) {
- perf_cpu_map__put(evsel->cpus);
- evsel->cpus = perf_cpu_map__get(evsel->own_cpus);
- }
-
- perf_thread_map__put(evsel->threads);
- evsel->threads = perf_thread_map__get(evlist->threads);
- evlist->all_cpus = perf_cpu_map__merge(evlist->all_cpus, evsel->cpus);
-}
-
-static void perf_evlist__propagate_maps(struct perf_evlist *evlist)
-{
- struct perf_evsel *evsel;
-
- perf_evlist__for_each_evsel(evlist, evsel)
- __perf_evlist__propagate_maps(evlist, evsel);
-}
-
-void perf_evlist__add(struct perf_evlist *evlist,
- struct perf_evsel *evsel)
-{
- list_add_tail(&evsel->node, &evlist->entries);
- evlist->nr_entries += 1;
- __perf_evlist__propagate_maps(evlist, evsel);
-}
-
-void perf_evlist__remove(struct perf_evlist *evlist,
- struct perf_evsel *evsel)
-{
- list_del_init(&evsel->node);
- evlist->nr_entries -= 1;
-}
-
-struct perf_evlist *perf_evlist__new(void)
-{
- struct perf_evlist *evlist = zalloc(sizeof(*evlist));
-
- if (evlist != NULL)
- perf_evlist__init(evlist);
-
- return evlist;
-}
-
-struct perf_evsel *
-perf_evlist__next(struct perf_evlist *evlist, struct perf_evsel *prev)
-{
- struct perf_evsel *next;
-
- if (!prev) {
- next = list_first_entry(&evlist->entries,
- struct perf_evsel,
- node);
- } else {
- next = list_next_entry(prev, node);
- }
-
- /* Empty list is noticed here so don't need checking on entry. */
- if (&next->node == &evlist->entries)
- return NULL;
-
- return next;
-}
-
-static void perf_evlist__purge(struct perf_evlist *evlist)
-{
- struct perf_evsel *pos, *n;
-
- perf_evlist__for_each_entry_safe(evlist, n, pos) {
- list_del_init(&pos->node);
- perf_evsel__delete(pos);
- }
-
- evlist->nr_entries = 0;
-}
-
-void perf_evlist__exit(struct perf_evlist *evlist)
-{
- perf_cpu_map__put(evlist->cpus);
- perf_thread_map__put(evlist->threads);
- evlist->cpus = NULL;
- evlist->threads = NULL;
- fdarray__exit(&evlist->pollfd);
-}
-
-void perf_evlist__delete(struct perf_evlist *evlist)
-{
- if (evlist == NULL)
- return;
-
- perf_evlist__munmap(evlist);
- perf_evlist__close(evlist);
- perf_evlist__purge(evlist);
- perf_evlist__exit(evlist);
- free(evlist);
-}
-
-void perf_evlist__set_maps(struct perf_evlist *evlist,
- struct perf_cpu_map *cpus,
- struct perf_thread_map *threads)
-{
- /*
- * Allow for the possibility that one or another of the maps isn't being
- * changed i.e. don't put it. Note we are assuming the maps that are
- * being applied are brand new and evlist is taking ownership of the
- * original reference count of 1. If that is not the case it is up to
- * the caller to increase the reference count.
- */
- if (cpus != evlist->cpus) {
- perf_cpu_map__put(evlist->cpus);
- evlist->cpus = perf_cpu_map__get(cpus);
- }
-
- if (threads != evlist->threads) {
- perf_thread_map__put(evlist->threads);
- evlist->threads = perf_thread_map__get(threads);
- }
-
- perf_evlist__propagate_maps(evlist);
-}
-
-int perf_evlist__open(struct perf_evlist *evlist)
-{
- struct perf_evsel *evsel;
- int err;
-
- perf_evlist__for_each_entry(evlist, evsel) {
- err = perf_evsel__open(evsel, evsel->cpus, evsel->threads);
- if (err < 0)
- goto out_err;
- }
-
- return 0;
-
-out_err:
- perf_evlist__close(evlist);
- return err;
-}
-
-void perf_evlist__close(struct perf_evlist *evlist)
-{
- struct perf_evsel *evsel;
-
- perf_evlist__for_each_entry_reverse(evlist, evsel)
- perf_evsel__close(evsel);
-}
-
-void perf_evlist__enable(struct perf_evlist *evlist)
-{
- struct perf_evsel *evsel;
-
- perf_evlist__for_each_entry(evlist, evsel)
- perf_evsel__enable(evsel);
-}
-
-void perf_evlist__disable(struct perf_evlist *evlist)
-{
- struct perf_evsel *evsel;
-
- perf_evlist__for_each_entry(evlist, evsel)
- perf_evsel__disable(evsel);
-}
-
-u64 perf_evlist__read_format(struct perf_evlist *evlist)
-{
- struct perf_evsel *first = perf_evlist__first(evlist);
-
- return first->attr.read_format;
-}
-
-#define SID(e, x, y) xyarray__entry(e->sample_id, x, y)
-
-static void perf_evlist__id_hash(struct perf_evlist *evlist,
- struct perf_evsel *evsel,
- int cpu, int thread, u64 id)
-{
- int hash;
- struct perf_sample_id *sid = SID(evsel, cpu, thread);
-
- sid->id = id;
- sid->evsel = evsel;
- hash = hash_64(sid->id, PERF_EVLIST__HLIST_BITS);
- hlist_add_head(&sid->node, &evlist->heads[hash]);
-}
-
-void perf_evlist__id_add(struct perf_evlist *evlist,
- struct perf_evsel *evsel,
- int cpu, int thread, u64 id)
-{
- perf_evlist__id_hash(evlist, evsel, cpu, thread, id);
- evsel->id[evsel->ids++] = id;
-}
-
-int perf_evlist__id_add_fd(struct perf_evlist *evlist,
- struct perf_evsel *evsel,
- int cpu, int thread, int fd)
-{
- u64 read_data[4] = { 0, };
- int id_idx = 1; /* The first entry is the counter value */
- u64 id;
- int ret;
-
- ret = ioctl(fd, PERF_EVENT_IOC_ID, &id);
- if (!ret)
- goto add;
-
- if (errno != ENOTTY)
- return -1;
-
- /* Legacy way to get event id.. All hail to old kernels! */
-
- /*
- * This way does not work with group format read, so bail
- * out in that case.
- */
- if (perf_evlist__read_format(evlist) & PERF_FORMAT_GROUP)
- return -1;
-
- if (!(evsel->attr.read_format & PERF_FORMAT_ID) ||
- read(fd, &read_data, sizeof(read_data)) == -1)
- return -1;
-
- if (evsel->attr.read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
- ++id_idx;
- if (evsel->attr.read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
- ++id_idx;
-
- id = read_data[id_idx];
-
-add:
- perf_evlist__id_add(evlist, evsel, cpu, thread, id);
- return 0;
-}
-
-int perf_evlist__alloc_pollfd(struct perf_evlist *evlist)
-{
- int nr_cpus = perf_cpu_map__nr(evlist->cpus);
- int nr_threads = perf_thread_map__nr(evlist->threads);
- int nfds = 0;
- struct perf_evsel *evsel;
-
- perf_evlist__for_each_entry(evlist, evsel) {
- if (evsel->system_wide)
- nfds += nr_cpus;
- else
- nfds += nr_cpus * nr_threads;
- }
-
- if (fdarray__available_entries(&evlist->pollfd) < nfds &&
- fdarray__grow(&evlist->pollfd, nfds) < 0)
- return -ENOMEM;
-
- return 0;
-}
-
-int perf_evlist__add_pollfd(struct perf_evlist *evlist, int fd,
- void *ptr, short revent)
-{
- int pos = fdarray__add(&evlist->pollfd, fd, revent | POLLERR | POLLHUP);
-
- if (pos >= 0) {
- evlist->pollfd.priv[pos].ptr = ptr;
- fcntl(fd, F_SETFL, O_NONBLOCK);
- }
-
- return pos;
-}
-
-static void perf_evlist__munmap_filtered(struct fdarray *fda, int fd,
- void *arg __maybe_unused)
-{
- struct perf_mmap *map = fda->priv[fd].ptr;
-
- if (map)
- perf_mmap__put(map);
-}
-
-int perf_evlist__filter_pollfd(struct perf_evlist *evlist, short revents_and_mask)
-{
- return fdarray__filter(&evlist->pollfd, revents_and_mask,
- perf_evlist__munmap_filtered, NULL);
-}
-
-int perf_evlist__poll(struct perf_evlist *evlist, int timeout)
-{
- return fdarray__poll(&evlist->pollfd, timeout);
-}
-
-static struct perf_mmap* perf_evlist__alloc_mmap(struct perf_evlist *evlist, bool overwrite)
-{
- int i;
- struct perf_mmap *map;
-
- map = zalloc(evlist->nr_mmaps * sizeof(struct perf_mmap));
- if (!map)
- return NULL;
-
- for (i = 0; i < evlist->nr_mmaps; i++) {
- struct perf_mmap *prev = i ? &map[i - 1] : NULL;
-
- /*
- * When the perf_mmap() call is made we grab one refcount, plus
- * one extra to let perf_mmap__consume() get the last
- * events after all real references (perf_mmap__get()) are
- * dropped.
- *
- * Each PERF_EVENT_IOC_SET_OUTPUT points to this mmap and
- * thus does perf_mmap__get() on it.
- */
- perf_mmap__init(&map[i], prev, overwrite, NULL);
- }
-
- return map;
-}
-
-static void perf_evlist__set_sid_idx(struct perf_evlist *evlist,
- struct perf_evsel *evsel, int idx, int cpu,
- int thread)
-{
- struct perf_sample_id *sid = SID(evsel, cpu, thread);
-
- sid->idx = idx;
- if (evlist->cpus && cpu >= 0)
- sid->cpu = evlist->cpus->map[cpu];
- else
- sid->cpu = -1;
- if (!evsel->system_wide && evlist->threads && thread >= 0)
- sid->tid = perf_thread_map__pid(evlist->threads, thread);
- else
- sid->tid = -1;
-}
-
-static struct perf_mmap*
-perf_evlist__mmap_cb_get(struct perf_evlist *evlist, bool overwrite, int idx)
-{
- struct perf_mmap *maps;
-
- maps = overwrite ? evlist->mmap_ovw : evlist->mmap;
-
- if (!maps) {
- maps = perf_evlist__alloc_mmap(evlist, overwrite);
- if (!maps)
- return NULL;
-
- if (overwrite)
- evlist->mmap_ovw = maps;
- else
- evlist->mmap = maps;
- }
-
- return &maps[idx];
-}
-
-#define FD(e, x, y) (*(int *) xyarray__entry(e->fd, x, y))
-
-static int
-perf_evlist__mmap_cb_mmap(struct perf_mmap *map, struct perf_mmap_param *mp,
- int output, int cpu)
-{
- return perf_mmap__mmap(map, mp, output, cpu);
-}
-
-static void perf_evlist__set_mmap_first(struct perf_evlist *evlist, struct perf_mmap *map,
- bool overwrite)
-{
- if (overwrite)
- evlist->mmap_ovw_first = map;
- else
- evlist->mmap_first = map;
-}
-
-static int
-mmap_per_evsel(struct perf_evlist *evlist, struct perf_evlist_mmap_ops *ops,
- int idx, struct perf_mmap_param *mp, int cpu_idx,
- int thread, int *_output, int *_output_overwrite)
-{
- int evlist_cpu = perf_cpu_map__cpu(evlist->cpus, cpu_idx);
- struct perf_evsel *evsel;
- int revent;
-
- perf_evlist__for_each_entry(evlist, evsel) {
- bool overwrite = evsel->attr.write_backward;
- struct perf_mmap *map;
- int *output, fd, cpu;
-
- if (evsel->system_wide && thread)
- continue;
-
- cpu = perf_cpu_map__idx(evsel->cpus, evlist_cpu);
- if (cpu == -1)
- continue;
-
- map = ops->get(evlist, overwrite, idx);
- if (map == NULL)
- return -ENOMEM;
-
- if (overwrite) {
- mp->prot = PROT_READ;
- output = _output_overwrite;
- } else {
- mp->prot = PROT_READ | PROT_WRITE;
- output = _output;
- }
-
- fd = FD(evsel, cpu, thread);
-
- if (*output == -1) {
- *output = fd;
-
- /*
- * The last one will be done at perf_mmap__consume(), so that we
- * make sure we don't prevent tools from consuming every last event in
- * the ring buffer.
- *
- * I.e. we can get the POLLHUP meaning that the fd doesn't exist
- * anymore, but the last events for it are still in the ring buffer,
- * waiting to be consumed.
- *
- * Tools can chose to ignore this at their own discretion, but the
- * evlist layer can't just drop it when filtering events in
- * perf_evlist__filter_pollfd().
- */
- refcount_set(&map->refcnt, 2);
-
- if (ops->mmap(map, mp, *output, evlist_cpu) < 0)
- return -1;
-
- if (!idx)
- perf_evlist__set_mmap_first(evlist, map, overwrite);
- } else {
- if (ioctl(fd, PERF_EVENT_IOC_SET_OUTPUT, *output) != 0)
- return -1;
-
- perf_mmap__get(map);
- }
-
- revent = !overwrite ? POLLIN : 0;
-
- if (!evsel->system_wide &&
- perf_evlist__add_pollfd(evlist, fd, map, revent) < 0) {
- perf_mmap__put(map);
- return -1;
- }
-
- if (evsel->attr.read_format & PERF_FORMAT_ID) {
- if (perf_evlist__id_add_fd(evlist, evsel, cpu, thread,
- fd) < 0)
- return -1;
- perf_evlist__set_sid_idx(evlist, evsel, idx, cpu,
- thread);
- }
- }
-
- return 0;
-}
-
-static int
-mmap_per_thread(struct perf_evlist *evlist, struct perf_evlist_mmap_ops *ops,
- struct perf_mmap_param *mp)
-{
- int thread;
- int nr_threads = perf_thread_map__nr(evlist->threads);
-
- for (thread = 0; thread < nr_threads; thread++) {
- int output = -1;
- int output_overwrite = -1;
-
- if (ops->idx)
- ops->idx(evlist, mp, thread, false);
-
- if (mmap_per_evsel(evlist, ops, thread, mp, 0, thread,
- &output, &output_overwrite))
- goto out_unmap;
- }
-
- return 0;
-
-out_unmap:
- perf_evlist__munmap(evlist);
- return -1;
-}
-
-static int
-mmap_per_cpu(struct perf_evlist *evlist, struct perf_evlist_mmap_ops *ops,
- struct perf_mmap_param *mp)
-{
- int nr_threads = perf_thread_map__nr(evlist->threads);
- int nr_cpus = perf_cpu_map__nr(evlist->cpus);
- int cpu, thread;
-
- for (cpu = 0; cpu < nr_cpus; cpu++) {
- int output = -1;
- int output_overwrite = -1;
-
- if (ops->idx)
- ops->idx(evlist, mp, cpu, true);
-
- for (thread = 0; thread < nr_threads; thread++) {
- if (mmap_per_evsel(evlist, ops, cpu, mp, cpu,
- thread, &output, &output_overwrite))
- goto out_unmap;
- }
- }
-
- return 0;
-
-out_unmap:
- perf_evlist__munmap(evlist);
- return -1;
-}
-
-static int perf_evlist__nr_mmaps(struct perf_evlist *evlist)
-{
- int nr_mmaps;
-
- nr_mmaps = perf_cpu_map__nr(evlist->cpus);
- if (perf_cpu_map__empty(evlist->cpus))
- nr_mmaps = perf_thread_map__nr(evlist->threads);
-
- return nr_mmaps;
-}
-
-int perf_evlist__mmap_ops(struct perf_evlist *evlist,
- struct perf_evlist_mmap_ops *ops,
- struct perf_mmap_param *mp)
-{
- struct perf_evsel *evsel;
- const struct perf_cpu_map *cpus = evlist->cpus;
- const struct perf_thread_map *threads = evlist->threads;
-
- if (!ops || !ops->get || !ops->mmap)
- return -EINVAL;
-
- mp->mask = evlist->mmap_len - page_size - 1;
-
- evlist->nr_mmaps = perf_evlist__nr_mmaps(evlist);
-
- perf_evlist__for_each_entry(evlist, evsel) {
- if ((evsel->attr.read_format & PERF_FORMAT_ID) &&
- evsel->sample_id == NULL &&
- perf_evsel__alloc_id(evsel, perf_cpu_map__nr(cpus), threads->nr) < 0)
- return -ENOMEM;
- }
-
- if (evlist->pollfd.entries == NULL && perf_evlist__alloc_pollfd(evlist) < 0)
- return -ENOMEM;
-
- if (perf_cpu_map__empty(cpus))
- return mmap_per_thread(evlist, ops, mp);
-
- return mmap_per_cpu(evlist, ops, mp);
-}
-
-int perf_evlist__mmap(struct perf_evlist *evlist, int pages)
-{
- struct perf_mmap_param mp;
- struct perf_evlist_mmap_ops ops = {
- .get = perf_evlist__mmap_cb_get,
- .mmap = perf_evlist__mmap_cb_mmap,
- };
-
- evlist->mmap_len = (pages + 1) * page_size;
-
- return perf_evlist__mmap_ops(evlist, &ops, &mp);
-}
-
-void perf_evlist__munmap(struct perf_evlist *evlist)
-{
- int i;
-
- if (evlist->mmap) {
- for (i = 0; i < evlist->nr_mmaps; i++)
- perf_mmap__munmap(&evlist->mmap[i]);
- }
-
- if (evlist->mmap_ovw) {
- for (i = 0; i < evlist->nr_mmaps; i++)
- perf_mmap__munmap(&evlist->mmap_ovw[i]);
- }
-
- zfree(&evlist->mmap);
- zfree(&evlist->mmap_ovw);
-}
-
-struct perf_mmap*
-perf_evlist__next_mmap(struct perf_evlist *evlist, struct perf_mmap *map,
- bool overwrite)
-{
- if (map)
- return map->next;
-
- return overwrite ? evlist->mmap_ovw_first : evlist->mmap_first;
-}
diff --git a/tools/perf/lib/evsel.c b/tools/perf/lib/evsel.c
deleted file mode 100644
index 4dc06289f4c7..000000000000
--- a/tools/perf/lib/evsel.c
+++ /dev/null
@@ -1,301 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#include <errno.h>
-#include <unistd.h>
-#include <sys/syscall.h>
-#include <perf/evsel.h>
-#include <perf/cpumap.h>
-#include <perf/threadmap.h>
-#include <linux/list.h>
-#include <internal/evsel.h>
-#include <linux/zalloc.h>
-#include <stdlib.h>
-#include <internal/xyarray.h>
-#include <internal/cpumap.h>
-#include <internal/threadmap.h>
-#include <internal/lib.h>
-#include <linux/string.h>
-#include <sys/ioctl.h>
-
-void perf_evsel__init(struct perf_evsel *evsel, struct perf_event_attr *attr)
-{
- INIT_LIST_HEAD(&evsel->node);
- evsel->attr = *attr;
-}
-
-struct perf_evsel *perf_evsel__new(struct perf_event_attr *attr)
-{
- struct perf_evsel *evsel = zalloc(sizeof(*evsel));
-
- if (evsel != NULL)
- perf_evsel__init(evsel, attr);
-
- return evsel;
-}
-
-void perf_evsel__delete(struct perf_evsel *evsel)
-{
- free(evsel);
-}
-
-#define FD(e, x, y) (*(int *) xyarray__entry(e->fd, x, y))
-
-int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads)
-{
- evsel->fd = xyarray__new(ncpus, nthreads, sizeof(int));
-
- if (evsel->fd) {
- int cpu, thread;
- for (cpu = 0; cpu < ncpus; cpu++) {
- for (thread = 0; thread < nthreads; thread++) {
- FD(evsel, cpu, thread) = -1;
- }
- }
- }
-
- return evsel->fd != NULL ? 0 : -ENOMEM;
-}
-
-static int
-sys_perf_event_open(struct perf_event_attr *attr,
- pid_t pid, int cpu, int group_fd,
- unsigned long flags)
-{
- return syscall(__NR_perf_event_open, attr, pid, cpu, group_fd, flags);
-}
-
-int perf_evsel__open(struct perf_evsel *evsel, struct perf_cpu_map *cpus,
- struct perf_thread_map *threads)
-{
- int cpu, thread, err = 0;
-
- if (cpus == NULL) {
- static struct perf_cpu_map *empty_cpu_map;
-
- if (empty_cpu_map == NULL) {
- empty_cpu_map = perf_cpu_map__dummy_new();
- if (empty_cpu_map == NULL)
- return -ENOMEM;
- }
-
- cpus = empty_cpu_map;
- }
-
- if (threads == NULL) {
- static struct perf_thread_map *empty_thread_map;
-
- if (empty_thread_map == NULL) {
- empty_thread_map = perf_thread_map__new_dummy();
- if (empty_thread_map == NULL)
- return -ENOMEM;
- }
-
- threads = empty_thread_map;
- }
-
- if (evsel->fd == NULL &&
- perf_evsel__alloc_fd(evsel, cpus->nr, threads->nr) < 0)
- return -ENOMEM;
-
- for (cpu = 0; cpu < cpus->nr; cpu++) {
- for (thread = 0; thread < threads->nr; thread++) {
- int fd;
-
- fd = sys_perf_event_open(&evsel->attr,
- threads->map[thread].pid,
- cpus->map[cpu], -1, 0);
-
- if (fd < 0)
- return -errno;
-
- FD(evsel, cpu, thread) = fd;
- }
- }
-
- return err;
-}
-
-static void perf_evsel__close_fd_cpu(struct perf_evsel *evsel, int cpu)
-{
- int thread;
-
- for (thread = 0; thread < xyarray__max_y(evsel->fd); ++thread) {
- if (FD(evsel, cpu, thread) >= 0)
- close(FD(evsel, cpu, thread));
- FD(evsel, cpu, thread) = -1;
- }
-}
-
-void perf_evsel__close_fd(struct perf_evsel *evsel)
-{
- int cpu;
-
- for (cpu = 0; cpu < xyarray__max_x(evsel->fd); cpu++)
- perf_evsel__close_fd_cpu(evsel, cpu);
-}
-
-void perf_evsel__free_fd(struct perf_evsel *evsel)
-{
- xyarray__delete(evsel->fd);
- evsel->fd = NULL;
-}
-
-void perf_evsel__close(struct perf_evsel *evsel)
-{
- if (evsel->fd == NULL)
- return;
-
- perf_evsel__close_fd(evsel);
- perf_evsel__free_fd(evsel);
-}
-
-void perf_evsel__close_cpu(struct perf_evsel *evsel, int cpu)
-{
- if (evsel->fd == NULL)
- return;
-
- perf_evsel__close_fd_cpu(evsel, cpu);
-}
-
-int perf_evsel__read_size(struct perf_evsel *evsel)
-{
- u64 read_format = evsel->attr.read_format;
- int entry = sizeof(u64); /* value */
- int size = 0;
- int nr = 1;
-
- if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
- size += sizeof(u64);
-
- if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
- size += sizeof(u64);
-
- if (read_format & PERF_FORMAT_ID)
- entry += sizeof(u64);
-
- if (read_format & PERF_FORMAT_GROUP) {
- nr = evsel->nr_members;
- size += sizeof(u64);
- }
-
- size += entry * nr;
- return size;
-}
-
-int perf_evsel__read(struct perf_evsel *evsel, int cpu, int thread,
- struct perf_counts_values *count)
-{
- size_t size = perf_evsel__read_size(evsel);
-
- memset(count, 0, sizeof(*count));
-
- if (FD(evsel, cpu, thread) < 0)
- return -EINVAL;
-
- if (readn(FD(evsel, cpu, thread), count->values, size) <= 0)
- return -errno;
-
- return 0;
-}
-
-static int perf_evsel__run_ioctl(struct perf_evsel *evsel,
- int ioc, void *arg,
- int cpu)
-{
- int thread;
-
- for (thread = 0; thread < xyarray__max_y(evsel->fd); thread++) {
- int fd = FD(evsel, cpu, thread),
- err = ioctl(fd, ioc, arg);
-
- if (err)
- return err;
- }
-
- return 0;
-}
-
-int perf_evsel__enable_cpu(struct perf_evsel *evsel, int cpu)
-{
- return perf_evsel__run_ioctl(evsel, PERF_EVENT_IOC_ENABLE, NULL, cpu);
-}
-
-int perf_evsel__enable(struct perf_evsel *evsel)
-{
- int i;
- int err = 0;
-
- for (i = 0; i < xyarray__max_x(evsel->fd) && !err; i++)
- err = perf_evsel__run_ioctl(evsel, PERF_EVENT_IOC_ENABLE, NULL, i);
- return err;
-}
-
-int perf_evsel__disable_cpu(struct perf_evsel *evsel, int cpu)
-{
- return perf_evsel__run_ioctl(evsel, PERF_EVENT_IOC_DISABLE, NULL, cpu);
-}
-
-int perf_evsel__disable(struct perf_evsel *evsel)
-{
- int i;
- int err = 0;
-
- for (i = 0; i < xyarray__max_x(evsel->fd) && !err; i++)
- err = perf_evsel__run_ioctl(evsel, PERF_EVENT_IOC_DISABLE, NULL, i);
- return err;
-}
-
-int perf_evsel__apply_filter(struct perf_evsel *evsel, const char *filter)
-{
- int err = 0, i;
-
- for (i = 0; i < evsel->cpus->nr && !err; i++)
- err = perf_evsel__run_ioctl(evsel,
- PERF_EVENT_IOC_SET_FILTER,
- (void *)filter, i);
- return err;
-}
-
-struct perf_cpu_map *perf_evsel__cpus(struct perf_evsel *evsel)
-{
- return evsel->cpus;
-}
-
-struct perf_thread_map *perf_evsel__threads(struct perf_evsel *evsel)
-{
- return evsel->threads;
-}
-
-struct perf_event_attr *perf_evsel__attr(struct perf_evsel *evsel)
-{
- return &evsel->attr;
-}
-
-int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads)
-{
- if (ncpus == 0 || nthreads == 0)
- return 0;
-
- if (evsel->system_wide)
- nthreads = 1;
-
- evsel->sample_id = xyarray__new(ncpus, nthreads, sizeof(struct perf_sample_id));
- if (evsel->sample_id == NULL)
- return -ENOMEM;
-
- evsel->id = zalloc(ncpus * nthreads * sizeof(u64));
- if (evsel->id == NULL) {
- xyarray__delete(evsel->sample_id);
- evsel->sample_id = NULL;
- return -ENOMEM;
- }
-
- return 0;
-}
-
-void perf_evsel__free_id(struct perf_evsel *evsel)
-{
- xyarray__delete(evsel->sample_id);
- evsel->sample_id = NULL;
- zfree(&evsel->id);
- evsel->ids = 0;
-}
diff --git a/tools/perf/lib/include/internal/cpumap.h b/tools/perf/lib/include/internal/cpumap.h
deleted file mode 100644
index 840d4032587b..000000000000
--- a/tools/perf/lib/include/internal/cpumap.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __LIBPERF_INTERNAL_CPUMAP_H
-#define __LIBPERF_INTERNAL_CPUMAP_H
-
-#include <linux/refcount.h>
-
-struct perf_cpu_map {
- refcount_t refcnt;
- int nr;
- int map[];
-};
-
-#ifndef MAX_NR_CPUS
-#define MAX_NR_CPUS 2048
-#endif
-
-int perf_cpu_map__idx(struct perf_cpu_map *cpus, int cpu);
-
-#endif /* __LIBPERF_INTERNAL_CPUMAP_H */
diff --git a/tools/perf/lib/include/internal/evlist.h b/tools/perf/lib/include/internal/evlist.h
deleted file mode 100644
index 74dc8c3f0b66..000000000000
--- a/tools/perf/lib/include/internal/evlist.h
+++ /dev/null
@@ -1,127 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __LIBPERF_INTERNAL_EVLIST_H
-#define __LIBPERF_INTERNAL_EVLIST_H
-
-#include <linux/list.h>
-#include <api/fd/array.h>
-#include <internal/evsel.h>
-
-#define PERF_EVLIST__HLIST_BITS 8
-#define PERF_EVLIST__HLIST_SIZE (1 << PERF_EVLIST__HLIST_BITS)
-
-struct perf_cpu_map;
-struct perf_thread_map;
-struct perf_mmap_param;
-
-struct perf_evlist {
- struct list_head entries;
- int nr_entries;
- bool has_user_cpus;
- struct perf_cpu_map *cpus;
- struct perf_cpu_map *all_cpus;
- struct perf_thread_map *threads;
- int nr_mmaps;
- size_t mmap_len;
- struct fdarray pollfd;
- struct hlist_head heads[PERF_EVLIST__HLIST_SIZE];
- struct perf_mmap *mmap;
- struct perf_mmap *mmap_ovw;
- struct perf_mmap *mmap_first;
- struct perf_mmap *mmap_ovw_first;
-};
-
-typedef void
-(*perf_evlist_mmap__cb_idx_t)(struct perf_evlist*, struct perf_mmap_param*, int, bool);
-typedef struct perf_mmap*
-(*perf_evlist_mmap__cb_get_t)(struct perf_evlist*, bool, int);
-typedef int
-(*perf_evlist_mmap__cb_mmap_t)(struct perf_mmap*, struct perf_mmap_param*, int, int);
-
-struct perf_evlist_mmap_ops {
- perf_evlist_mmap__cb_idx_t idx;
- perf_evlist_mmap__cb_get_t get;
- perf_evlist_mmap__cb_mmap_t mmap;
-};
-
-int perf_evlist__alloc_pollfd(struct perf_evlist *evlist);
-int perf_evlist__add_pollfd(struct perf_evlist *evlist, int fd,
- void *ptr, short revent);
-
-int perf_evlist__mmap_ops(struct perf_evlist *evlist,
- struct perf_evlist_mmap_ops *ops,
- struct perf_mmap_param *mp);
-
-void perf_evlist__init(struct perf_evlist *evlist);
-void perf_evlist__exit(struct perf_evlist *evlist);
-
-/**
- * __perf_evlist__for_each_entry - iterate thru all the evsels
- * @list: list_head instance to iterate
- * @evsel: struct perf_evsel iterator
- */
-#define __perf_evlist__for_each_entry(list, evsel) \
- list_for_each_entry(evsel, list, node)
-
-/**
- * evlist__for_each_entry - iterate thru all the evsels
- * @evlist: perf_evlist instance to iterate
- * @evsel: struct perf_evsel iterator
- */
-#define perf_evlist__for_each_entry(evlist, evsel) \
- __perf_evlist__for_each_entry(&(evlist)->entries, evsel)
-
-/**
- * __perf_evlist__for_each_entry_reverse - iterate thru all the evsels in reverse order
- * @list: list_head instance to iterate
- * @evsel: struct evsel iterator
- */
-#define __perf_evlist__for_each_entry_reverse(list, evsel) \
- list_for_each_entry_reverse(evsel, list, node)
-
-/**
- * perf_evlist__for_each_entry_reverse - iterate thru all the evsels in reverse order
- * @evlist: evlist instance to iterate
- * @evsel: struct evsel iterator
- */
-#define perf_evlist__for_each_entry_reverse(evlist, evsel) \
- __perf_evlist__for_each_entry_reverse(&(evlist)->entries, evsel)
-
-/**
- * __perf_evlist__for_each_entry_safe - safely iterate thru all the evsels
- * @list: list_head instance to iterate
- * @tmp: struct evsel temp iterator
- * @evsel: struct evsel iterator
- */
-#define __perf_evlist__for_each_entry_safe(list, tmp, evsel) \
- list_for_each_entry_safe(evsel, tmp, list, node)
-
-/**
- * perf_evlist__for_each_entry_safe - safely iterate thru all the evsels
- * @evlist: evlist instance to iterate
- * @evsel: struct evsel iterator
- * @tmp: struct evsel temp iterator
- */
-#define perf_evlist__for_each_entry_safe(evlist, tmp, evsel) \
- __perf_evlist__for_each_entry_safe(&(evlist)->entries, tmp, evsel)
-
-static inline struct perf_evsel *perf_evlist__first(struct perf_evlist *evlist)
-{
- return list_entry(evlist->entries.next, struct perf_evsel, node);
-}
-
-static inline struct perf_evsel *perf_evlist__last(struct perf_evlist *evlist)
-{
- return list_entry(evlist->entries.prev, struct perf_evsel, node);
-}
-
-u64 perf_evlist__read_format(struct perf_evlist *evlist);
-
-void perf_evlist__id_add(struct perf_evlist *evlist,
- struct perf_evsel *evsel,
- int cpu, int thread, u64 id);
-
-int perf_evlist__id_add_fd(struct perf_evlist *evlist,
- struct perf_evsel *evsel,
- int cpu, int thread, int fd);
-
-#endif /* __LIBPERF_INTERNAL_EVLIST_H */
diff --git a/tools/perf/lib/include/internal/evsel.h b/tools/perf/lib/include/internal/evsel.h
deleted file mode 100644
index 1ffd083b235e..000000000000
--- a/tools/perf/lib/include/internal/evsel.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __LIBPERF_INTERNAL_EVSEL_H
-#define __LIBPERF_INTERNAL_EVSEL_H
-
-#include <linux/types.h>
-#include <linux/perf_event.h>
-#include <stdbool.h>
-#include <sys/types.h>
-
-struct perf_cpu_map;
-struct perf_thread_map;
-struct xyarray;
-
-/*
- * Per fd, to map back from PERF_SAMPLE_ID to evsel, only used when there are
- * more than one entry in the evlist.
- */
-struct perf_sample_id {
- struct hlist_node node;
- u64 id;
- struct perf_evsel *evsel;
- /*
- * 'idx' will be used for AUX area sampling. A sample will have AUX area
- * data that will be queued for decoding, where there are separate
- * queues for each CPU (per-cpu tracing) or task (per-thread tracing).
- * The sample ID can be used to lookup 'idx' which is effectively the
- * queue number.
- */
- int idx;
- int cpu;
- pid_t tid;
-
- /* Holds total ID period value for PERF_SAMPLE_READ processing. */
- u64 period;
-};
-
-struct perf_evsel {
- struct list_head node;
- struct perf_event_attr attr;
- struct perf_cpu_map *cpus;
- struct perf_cpu_map *own_cpus;
- struct perf_thread_map *threads;
- struct xyarray *fd;
- struct xyarray *sample_id;
- u64 *id;
- u32 ids;
-
- /* parse modifier helper */
- int nr_members;
- bool system_wide;
-};
-
-void perf_evsel__init(struct perf_evsel *evsel, struct perf_event_attr *attr);
-int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads);
-void perf_evsel__close_fd(struct perf_evsel *evsel);
-void perf_evsel__free_fd(struct perf_evsel *evsel);
-int perf_evsel__read_size(struct perf_evsel *evsel);
-int perf_evsel__apply_filter(struct perf_evsel *evsel, const char *filter);
-
-int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads);
-void perf_evsel__free_id(struct perf_evsel *evsel);
-
-#endif /* __LIBPERF_INTERNAL_EVSEL_H */
diff --git a/tools/perf/lib/include/internal/lib.h b/tools/perf/lib/include/internal/lib.h
deleted file mode 100644
index 5175d491b2d4..000000000000
--- a/tools/perf/lib/include/internal/lib.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __LIBPERF_INTERNAL_LIB_H
-#define __LIBPERF_INTERNAL_LIB_H
-
-#include <sys/types.h>
-
-extern unsigned int page_size;
-
-ssize_t readn(int fd, void *buf, size_t n);
-ssize_t writen(int fd, const void *buf, size_t n);
-
-#endif /* __LIBPERF_INTERNAL_CPUMAP_H */
diff --git a/tools/perf/lib/include/internal/mmap.h b/tools/perf/lib/include/internal/mmap.h
deleted file mode 100644
index be7556e0a2b2..000000000000
--- a/tools/perf/lib/include/internal/mmap.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __LIBPERF_INTERNAL_MMAP_H
-#define __LIBPERF_INTERNAL_MMAP_H
-
-#include <linux/compiler.h>
-#include <linux/refcount.h>
-#include <linux/types.h>
-#include <stdbool.h>
-
-/* perf sample has 16 bits size limit */
-#define PERF_SAMPLE_MAX_SIZE (1 << 16)
-
-struct perf_mmap;
-
-typedef void (*libperf_unmap_cb_t)(struct perf_mmap *map);
-
-/**
- * struct perf_mmap - perf's ring buffer mmap details
- *
- * @refcnt - e.g. code using PERF_EVENT_IOC_SET_OUTPUT to share this
- */
-struct perf_mmap {
- void *base;
- int mask;
- int fd;
- int cpu;
- refcount_t refcnt;
- u64 prev;
- u64 start;
- u64 end;
- bool overwrite;
- u64 flush;
- libperf_unmap_cb_t unmap_cb;
- char event_copy[PERF_SAMPLE_MAX_SIZE] __aligned(8);
- struct perf_mmap *next;
-};
-
-struct perf_mmap_param {
- int prot;
- int mask;
-};
-
-size_t perf_mmap__mmap_len(struct perf_mmap *map);
-
-void perf_mmap__init(struct perf_mmap *map, struct perf_mmap *prev,
- bool overwrite, libperf_unmap_cb_t unmap_cb);
-int perf_mmap__mmap(struct perf_mmap *map, struct perf_mmap_param *mp,
- int fd, int cpu);
-void perf_mmap__munmap(struct perf_mmap *map);
-void perf_mmap__get(struct perf_mmap *map);
-void perf_mmap__put(struct perf_mmap *map);
-
-u64 perf_mmap__read_head(struct perf_mmap *map);
-
-#endif /* __LIBPERF_INTERNAL_MMAP_H */
diff --git a/tools/perf/lib/include/internal/tests.h b/tools/perf/lib/include/internal/tests.h
deleted file mode 100644
index 2093e8868a67..000000000000
--- a/tools/perf/lib/include/internal/tests.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __LIBPERF_INTERNAL_TESTS_H
-#define __LIBPERF_INTERNAL_TESTS_H
-
-#include <stdio.h>
-
-int tests_failed;
-
-#define __T_START \
-do { \
- fprintf(stdout, "- running %s...", __FILE__); \
- fflush(NULL); \
- tests_failed = 0; \
-} while (0)
-
-#define __T_END \
-do { \
- if (tests_failed) \
- fprintf(stdout, " FAILED (%d)\n", tests_failed); \
- else \
- fprintf(stdout, "OK\n"); \
-} while (0)
-
-#define __T(text, cond) \
-do { \
- if (!(cond)) { \
- fprintf(stderr, "FAILED %s:%d %s\n", __FILE__, __LINE__, text); \
- tests_failed++; \
- return -1; \
- } \
-} while (0)
-
-#endif /* __LIBPERF_INTERNAL_TESTS_H */
diff --git a/tools/perf/lib/include/internal/threadmap.h b/tools/perf/lib/include/internal/threadmap.h
deleted file mode 100644
index df748baf9eda..000000000000
--- a/tools/perf/lib/include/internal/threadmap.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __LIBPERF_INTERNAL_THREADMAP_H
-#define __LIBPERF_INTERNAL_THREADMAP_H
-
-#include <linux/refcount.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-struct thread_map_data {
- pid_t pid;
- char *comm;
-};
-
-struct perf_thread_map {
- refcount_t refcnt;
- int nr;
- int err_thread;
- struct thread_map_data map[];
-};
-
-struct perf_thread_map *perf_thread_map__realloc(struct perf_thread_map *map, int nr);
-
-#endif /* __LIBPERF_INTERNAL_THREADMAP_H */
diff --git a/tools/perf/lib/include/internal/xyarray.h b/tools/perf/lib/include/internal/xyarray.h
deleted file mode 100644
index 51e35d6c8ec4..000000000000
--- a/tools/perf/lib/include/internal/xyarray.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __LIBPERF_INTERNAL_XYARRAY_H
-#define __LIBPERF_INTERNAL_XYARRAY_H
-
-#include <linux/compiler.h>
-#include <sys/types.h>
-
-struct xyarray {
- size_t row_size;
- size_t entry_size;
- size_t entries;
- size_t max_x;
- size_t max_y;
- char contents[] __aligned(8);
-};
-
-struct xyarray *xyarray__new(int xlen, int ylen, size_t entry_size);
-void xyarray__delete(struct xyarray *xy);
-void xyarray__reset(struct xyarray *xy);
-
-static inline void *xyarray__entry(struct xyarray *xy, int x, int y)
-{
- return &xy->contents[x * xy->row_size + y * xy->entry_size];
-}
-
-static inline int xyarray__max_y(struct xyarray *xy)
-{
- return xy->max_y;
-}
-
-static inline int xyarray__max_x(struct xyarray *xy)
-{
- return xy->max_x;
-}
-
-#endif /* __LIBPERF_INTERNAL_XYARRAY_H */
diff --git a/tools/perf/lib/include/perf/core.h b/tools/perf/lib/include/perf/core.h
deleted file mode 100644
index a3f6d68edad7..000000000000
--- a/tools/perf/lib/include/perf/core.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __LIBPERF_CORE_H
-#define __LIBPERF_CORE_H
-
-#include <stdarg.h>
-
-#ifndef LIBPERF_API
-#define LIBPERF_API __attribute__((visibility("default")))
-#endif
-
-enum libperf_print_level {
- LIBPERF_ERR,
- LIBPERF_WARN,
- LIBPERF_INFO,
- LIBPERF_DEBUG,
- LIBPERF_DEBUG2,
- LIBPERF_DEBUG3,
-};
-
-typedef int (*libperf_print_fn_t)(enum libperf_print_level level,
- const char *, va_list ap);
-
-LIBPERF_API void libperf_init(libperf_print_fn_t fn);
-
-#endif /* __LIBPERF_CORE_H */
diff --git a/tools/perf/lib/include/perf/cpumap.h b/tools/perf/lib/include/perf/cpumap.h
deleted file mode 100644
index 6a17ad730cbc..000000000000
--- a/tools/perf/lib/include/perf/cpumap.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __LIBPERF_CPUMAP_H
-#define __LIBPERF_CPUMAP_H
-
-#include <perf/core.h>
-#include <stdio.h>
-#include <stdbool.h>
-
-struct perf_cpu_map;
-
-LIBPERF_API struct perf_cpu_map *perf_cpu_map__dummy_new(void);
-LIBPERF_API struct perf_cpu_map *perf_cpu_map__new(const char *cpu_list);
-LIBPERF_API struct perf_cpu_map *perf_cpu_map__read(FILE *file);
-LIBPERF_API struct perf_cpu_map *perf_cpu_map__get(struct perf_cpu_map *map);
-LIBPERF_API struct perf_cpu_map *perf_cpu_map__merge(struct perf_cpu_map *orig,
- struct perf_cpu_map *other);
-LIBPERF_API void perf_cpu_map__put(struct perf_cpu_map *map);
-LIBPERF_API int perf_cpu_map__cpu(const struct perf_cpu_map *cpus, int idx);
-LIBPERF_API int perf_cpu_map__nr(const struct perf_cpu_map *cpus);
-LIBPERF_API bool perf_cpu_map__empty(const struct perf_cpu_map *map);
-LIBPERF_API int perf_cpu_map__max(struct perf_cpu_map *map);
-
-#define perf_cpu_map__for_each_cpu(cpu, idx, cpus) \
- for ((idx) = 0, (cpu) = perf_cpu_map__cpu(cpus, idx); \
- (idx) < perf_cpu_map__nr(cpus); \
- (idx)++, (cpu) = perf_cpu_map__cpu(cpus, idx))
-
-#endif /* __LIBPERF_CPUMAP_H */
diff --git a/tools/perf/lib/include/perf/event.h b/tools/perf/lib/include/perf/event.h
deleted file mode 100644
index 18106899cb4e..000000000000
--- a/tools/perf/lib/include/perf/event.h
+++ /dev/null
@@ -1,385 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __LIBPERF_EVENT_H
-#define __LIBPERF_EVENT_H
-
-#include <linux/perf_event.h>
-#include <linux/types.h>
-#include <linux/limits.h>
-#include <linux/bpf.h>
-#include <sys/types.h> /* pid_t */
-
-struct perf_record_mmap {
- struct perf_event_header header;
- __u32 pid, tid;
- __u64 start;
- __u64 len;
- __u64 pgoff;
- char filename[PATH_MAX];
-};
-
-struct perf_record_mmap2 {
- struct perf_event_header header;
- __u32 pid, tid;
- __u64 start;
- __u64 len;
- __u64 pgoff;
- __u32 maj;
- __u32 min;
- __u64 ino;
- __u64 ino_generation;
- __u32 prot;
- __u32 flags;
- char filename[PATH_MAX];
-};
-
-struct perf_record_comm {
- struct perf_event_header header;
- __u32 pid, tid;
- char comm[16];
-};
-
-struct perf_record_namespaces {
- struct perf_event_header header;
- __u32 pid, tid;
- __u64 nr_namespaces;
- struct perf_ns_link_info link_info[];
-};
-
-struct perf_record_fork {
- struct perf_event_header header;
- __u32 pid, ppid;
- __u32 tid, ptid;
- __u64 time;
-};
-
-struct perf_record_lost {
- struct perf_event_header header;
- __u64 id;
- __u64 lost;
-};
-
-struct perf_record_lost_samples {
- struct perf_event_header header;
- __u64 lost;
-};
-
-/*
- * PERF_FORMAT_ENABLED | PERF_FORMAT_RUNNING | PERF_FORMAT_ID
- */
-struct perf_record_read {
- struct perf_event_header header;
- __u32 pid, tid;
- __u64 value;
- __u64 time_enabled;
- __u64 time_running;
- __u64 id;
-};
-
-struct perf_record_throttle {
- struct perf_event_header header;
- __u64 time;
- __u64 id;
- __u64 stream_id;
-};
-
-#ifndef KSYM_NAME_LEN
-#define KSYM_NAME_LEN 256
-#endif
-
-struct perf_record_ksymbol {
- struct perf_event_header header;
- __u64 addr;
- __u32 len;
- __u16 ksym_type;
- __u16 flags;
- char name[KSYM_NAME_LEN];
-};
-
-struct perf_record_bpf_event {
- struct perf_event_header header;
- __u16 type;
- __u16 flags;
- __u32 id;
-
- /* for bpf_prog types */
- __u8 tag[BPF_TAG_SIZE]; // prog tag
-};
-
-struct perf_record_sample {
- struct perf_event_header header;
- __u64 array[];
-};
-
-struct perf_record_switch {
- struct perf_event_header header;
- __u32 next_prev_pid;
- __u32 next_prev_tid;
-};
-
-struct perf_record_header_attr {
- struct perf_event_header header;
- struct perf_event_attr attr;
- __u64 id[];
-};
-
-enum {
- PERF_CPU_MAP__CPUS = 0,
- PERF_CPU_MAP__MASK = 1,
-};
-
-struct cpu_map_entries {
- __u16 nr;
- __u16 cpu[];
-};
-
-struct perf_record_record_cpu_map {
- __u16 nr;
- __u16 long_size;
- unsigned long mask[];
-};
-
-struct perf_record_cpu_map_data {
- __u16 type;
- char data[];
-};
-
-struct perf_record_cpu_map {
- struct perf_event_header header;
- struct perf_record_cpu_map_data data;
-};
-
-enum {
- PERF_EVENT_UPDATE__UNIT = 0,
- PERF_EVENT_UPDATE__SCALE = 1,
- PERF_EVENT_UPDATE__NAME = 2,
- PERF_EVENT_UPDATE__CPUS = 3,
-};
-
-struct perf_record_event_update_cpus {
- struct perf_record_cpu_map_data cpus;
-};
-
-struct perf_record_event_update_scale {
- double scale;
-};
-
-struct perf_record_event_update {
- struct perf_event_header header;
- __u64 type;
- __u64 id;
- char data[];
-};
-
-#define MAX_EVENT_NAME 64
-
-struct perf_trace_event_type {
- __u64 event_id;
- char name[MAX_EVENT_NAME];
-};
-
-struct perf_record_header_event_type {
- struct perf_event_header header;
- struct perf_trace_event_type event_type;
-};
-
-struct perf_record_header_tracing_data {
- struct perf_event_header header;
- __u32 size;
-};
-
-struct perf_record_header_build_id {
- struct perf_event_header header;
- pid_t pid;
- __u8 build_id[24];
- char filename[];
-};
-
-struct id_index_entry {
- __u64 id;
- __u64 idx;
- __u64 cpu;
- __u64 tid;
-};
-
-struct perf_record_id_index {
- struct perf_event_header header;
- __u64 nr;
- struct id_index_entry entries[0];
-};
-
-struct perf_record_auxtrace_info {
- struct perf_event_header header;
- __u32 type;
- __u32 reserved__; /* For alignment */
- __u64 priv[];
-};
-
-struct perf_record_auxtrace {
- struct perf_event_header header;
- __u64 size;
- __u64 offset;
- __u64 reference;
- __u32 idx;
- __u32 tid;
- __u32 cpu;
- __u32 reserved__; /* For alignment */
-};
-
-#define MAX_AUXTRACE_ERROR_MSG 64
-
-struct perf_record_auxtrace_error {
- struct perf_event_header header;
- __u32 type;
- __u32 code;
- __u32 cpu;
- __u32 pid;
- __u32 tid;
- __u32 fmt;
- __u64 ip;
- __u64 time;
- char msg[MAX_AUXTRACE_ERROR_MSG];
-};
-
-struct perf_record_aux {
- struct perf_event_header header;
- __u64 aux_offset;
- __u64 aux_size;
- __u64 flags;
-};
-
-struct perf_record_itrace_start {
- struct perf_event_header header;
- __u32 pid;
- __u32 tid;
-};
-
-struct perf_record_thread_map_entry {
- __u64 pid;
- char comm[16];
-};
-
-struct perf_record_thread_map {
- struct perf_event_header header;
- __u64 nr;
- struct perf_record_thread_map_entry entries[];
-};
-
-enum {
- PERF_STAT_CONFIG_TERM__AGGR_MODE = 0,
- PERF_STAT_CONFIG_TERM__INTERVAL = 1,
- PERF_STAT_CONFIG_TERM__SCALE = 2,
- PERF_STAT_CONFIG_TERM__MAX = 3,
-};
-
-struct perf_record_stat_config_entry {
- __u64 tag;
- __u64 val;
-};
-
-struct perf_record_stat_config {
- struct perf_event_header header;
- __u64 nr;
- struct perf_record_stat_config_entry data[];
-};
-
-struct perf_record_stat {
- struct perf_event_header header;
-
- __u64 id;
- __u32 cpu;
- __u32 thread;
-
- union {
- struct {
- __u64 val;
- __u64 ena;
- __u64 run;
- };
- __u64 values[3];
- };
-};
-
-struct perf_record_stat_round {
- struct perf_event_header header;
- __u64 type;
- __u64 time;
-};
-
-struct perf_record_time_conv {
- struct perf_event_header header;
- __u64 time_shift;
- __u64 time_mult;
- __u64 time_zero;
-};
-
-struct perf_record_header_feature {
- struct perf_event_header header;
- __u64 feat_id;
- char data[];
-};
-
-struct perf_record_compressed {
- struct perf_event_header header;
- char data[];
-};
-
-enum perf_user_event_type { /* above any possible kernel type */
- PERF_RECORD_USER_TYPE_START = 64,
- PERF_RECORD_HEADER_ATTR = 64,
- PERF_RECORD_HEADER_EVENT_TYPE = 65, /* deprecated */
- PERF_RECORD_HEADER_TRACING_DATA = 66,
- PERF_RECORD_HEADER_BUILD_ID = 67,
- PERF_RECORD_FINISHED_ROUND = 68,
- PERF_RECORD_ID_INDEX = 69,
- PERF_RECORD_AUXTRACE_INFO = 70,
- PERF_RECORD_AUXTRACE = 71,
- PERF_RECORD_AUXTRACE_ERROR = 72,
- PERF_RECORD_THREAD_MAP = 73,
- PERF_RECORD_CPU_MAP = 74,
- PERF_RECORD_STAT_CONFIG = 75,
- PERF_RECORD_STAT = 76,
- PERF_RECORD_STAT_ROUND = 77,
- PERF_RECORD_EVENT_UPDATE = 78,
- PERF_RECORD_TIME_CONV = 79,
- PERF_RECORD_HEADER_FEATURE = 80,
- PERF_RECORD_COMPRESSED = 81,
- PERF_RECORD_HEADER_MAX
-};
-
-union perf_event {
- struct perf_event_header header;
- struct perf_record_mmap mmap;
- struct perf_record_mmap2 mmap2;
- struct perf_record_comm comm;
- struct perf_record_namespaces namespaces;
- struct perf_record_fork fork;
- struct perf_record_lost lost;
- struct perf_record_lost_samples lost_samples;
- struct perf_record_read read;
- struct perf_record_throttle throttle;
- struct perf_record_sample sample;
- struct perf_record_bpf_event bpf;
- struct perf_record_ksymbol ksymbol;
- struct perf_record_header_attr attr;
- struct perf_record_event_update event_update;
- struct perf_record_header_event_type event_type;
- struct perf_record_header_tracing_data tracing_data;
- struct perf_record_header_build_id build_id;
- struct perf_record_id_index id_index;
- struct perf_record_auxtrace_info auxtrace_info;
- struct perf_record_auxtrace auxtrace;
- struct perf_record_auxtrace_error auxtrace_error;
- struct perf_record_aux aux;
- struct perf_record_itrace_start itrace_start;
- struct perf_record_switch context_switch;
- struct perf_record_thread_map thread_map;
- struct perf_record_cpu_map cpu_map;
- struct perf_record_stat_config stat_config;
- struct perf_record_stat stat;
- struct perf_record_stat_round stat_round;
- struct perf_record_time_conv time_conv;
- struct perf_record_header_feature feat;
- struct perf_record_compressed pack;
-};
-
-#endif /* __LIBPERF_EVENT_H */
diff --git a/tools/perf/lib/include/perf/evlist.h b/tools/perf/lib/include/perf/evlist.h
deleted file mode 100644
index 0a7479dc13bf..000000000000
--- a/tools/perf/lib/include/perf/evlist.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __LIBPERF_EVLIST_H
-#define __LIBPERF_EVLIST_H
-
-#include <perf/core.h>
-#include <stdbool.h>
-
-struct perf_evlist;
-struct perf_evsel;
-struct perf_cpu_map;
-struct perf_thread_map;
-
-LIBPERF_API void perf_evlist__add(struct perf_evlist *evlist,
- struct perf_evsel *evsel);
-LIBPERF_API void perf_evlist__remove(struct perf_evlist *evlist,
- struct perf_evsel *evsel);
-LIBPERF_API struct perf_evlist *perf_evlist__new(void);
-LIBPERF_API void perf_evlist__delete(struct perf_evlist *evlist);
-LIBPERF_API struct perf_evsel* perf_evlist__next(struct perf_evlist *evlist,
- struct perf_evsel *evsel);
-LIBPERF_API int perf_evlist__open(struct perf_evlist *evlist);
-LIBPERF_API void perf_evlist__close(struct perf_evlist *evlist);
-LIBPERF_API void perf_evlist__enable(struct perf_evlist *evlist);
-LIBPERF_API void perf_evlist__disable(struct perf_evlist *evlist);
-
-#define perf_evlist__for_each_evsel(evlist, pos) \
- for ((pos) = perf_evlist__next((evlist), NULL); \
- (pos) != NULL; \
- (pos) = perf_evlist__next((evlist), (pos)))
-
-LIBPERF_API void perf_evlist__set_maps(struct perf_evlist *evlist,
- struct perf_cpu_map *cpus,
- struct perf_thread_map *threads);
-LIBPERF_API int perf_evlist__poll(struct perf_evlist *evlist, int timeout);
-LIBPERF_API int perf_evlist__filter_pollfd(struct perf_evlist *evlist,
- short revents_and_mask);
-
-LIBPERF_API int perf_evlist__mmap(struct perf_evlist *evlist, int pages);
-LIBPERF_API void perf_evlist__munmap(struct perf_evlist *evlist);
-
-LIBPERF_API struct perf_mmap *perf_evlist__next_mmap(struct perf_evlist *evlist,
- struct perf_mmap *map,
- bool overwrite);
-#define perf_evlist__for_each_mmap(evlist, pos, overwrite) \
- for ((pos) = perf_evlist__next_mmap((evlist), NULL, overwrite); \
- (pos) != NULL; \
- (pos) = perf_evlist__next_mmap((evlist), (pos), overwrite))
-
-#endif /* __LIBPERF_EVLIST_H */
diff --git a/tools/perf/lib/include/perf/evsel.h b/tools/perf/lib/include/perf/evsel.h
deleted file mode 100644
index c82ec39a4ad0..000000000000
--- a/tools/perf/lib/include/perf/evsel.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __LIBPERF_EVSEL_H
-#define __LIBPERF_EVSEL_H
-
-#include <stdint.h>
-#include <perf/core.h>
-
-struct perf_evsel;
-struct perf_event_attr;
-struct perf_cpu_map;
-struct perf_thread_map;
-
-struct perf_counts_values {
- union {
- struct {
- uint64_t val;
- uint64_t ena;
- uint64_t run;
- };
- uint64_t values[3];
- };
-};
-
-LIBPERF_API struct perf_evsel *perf_evsel__new(struct perf_event_attr *attr);
-LIBPERF_API void perf_evsel__delete(struct perf_evsel *evsel);
-LIBPERF_API int perf_evsel__open(struct perf_evsel *evsel, struct perf_cpu_map *cpus,
- struct perf_thread_map *threads);
-LIBPERF_API void perf_evsel__close(struct perf_evsel *evsel);
-LIBPERF_API void perf_evsel__close_cpu(struct perf_evsel *evsel, int cpu);
-LIBPERF_API int perf_evsel__read(struct perf_evsel *evsel, int cpu, int thread,
- struct perf_counts_values *count);
-LIBPERF_API int perf_evsel__enable(struct perf_evsel *evsel);
-LIBPERF_API int perf_evsel__enable_cpu(struct perf_evsel *evsel, int cpu);
-LIBPERF_API int perf_evsel__disable(struct perf_evsel *evsel);
-LIBPERF_API int perf_evsel__disable_cpu(struct perf_evsel *evsel, int cpu);
-LIBPERF_API struct perf_cpu_map *perf_evsel__cpus(struct perf_evsel *evsel);
-LIBPERF_API struct perf_thread_map *perf_evsel__threads(struct perf_evsel *evsel);
-LIBPERF_API struct perf_event_attr *perf_evsel__attr(struct perf_evsel *evsel);
-
-#endif /* __LIBPERF_EVSEL_H */
diff --git a/tools/perf/lib/include/perf/mmap.h b/tools/perf/lib/include/perf/mmap.h
deleted file mode 100644
index 9508ad90d8b9..000000000000
--- a/tools/perf/lib/include/perf/mmap.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __LIBPERF_MMAP_H
-#define __LIBPERF_MMAP_H
-
-#include <perf/core.h>
-
-struct perf_mmap;
-union perf_event;
-
-LIBPERF_API void perf_mmap__consume(struct perf_mmap *map);
-LIBPERF_API int perf_mmap__read_init(struct perf_mmap *map);
-LIBPERF_API void perf_mmap__read_done(struct perf_mmap *map);
-LIBPERF_API union perf_event *perf_mmap__read_event(struct perf_mmap *map);
-
-#endif /* __LIBPERF_MMAP_H */
diff --git a/tools/perf/lib/include/perf/threadmap.h b/tools/perf/lib/include/perf/threadmap.h
deleted file mode 100644
index a7c50de8d010..000000000000
--- a/tools/perf/lib/include/perf/threadmap.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __LIBPERF_THREADMAP_H
-#define __LIBPERF_THREADMAP_H
-
-#include <perf/core.h>
-#include <sys/types.h>
-
-struct perf_thread_map;
-
-LIBPERF_API struct perf_thread_map *perf_thread_map__new_dummy(void);
-
-LIBPERF_API void perf_thread_map__set_pid(struct perf_thread_map *map, int thread, pid_t pid);
-LIBPERF_API char *perf_thread_map__comm(struct perf_thread_map *map, int thread);
-LIBPERF_API int perf_thread_map__nr(struct perf_thread_map *threads);
-LIBPERF_API pid_t perf_thread_map__pid(struct perf_thread_map *map, int thread);
-
-LIBPERF_API struct perf_thread_map *perf_thread_map__get(struct perf_thread_map *map);
-LIBPERF_API void perf_thread_map__put(struct perf_thread_map *map);
-
-#endif /* __LIBPERF_THREADMAP_H */
diff --git a/tools/perf/lib/internal.h b/tools/perf/lib/internal.h
deleted file mode 100644
index 2c27e158de6b..000000000000
--- a/tools/perf/lib/internal.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __LIBPERF_INTERNAL_H
-#define __LIBPERF_INTERNAL_H
-
-#include <perf/core.h>
-
-void libperf_print(enum libperf_print_level level,
- const char *format, ...)
- __attribute__((format(printf, 2, 3)));
-
-#define __pr(level, fmt, ...) \
-do { \
- libperf_print(level, "libperf: " fmt, ##__VA_ARGS__); \
-} while (0)
-
-#define pr_err(fmt, ...) __pr(LIBPERF_ERR, fmt, ##__VA_ARGS__)
-#define pr_warning(fmt, ...) __pr(LIBPERF_WARN, fmt, ##__VA_ARGS__)
-#define pr_info(fmt, ...) __pr(LIBPERF_INFO, fmt, ##__VA_ARGS__)
-#define pr_debug(fmt, ...) __pr(LIBPERF_DEBUG, fmt, ##__VA_ARGS__)
-#define pr_debug2(fmt, ...) __pr(LIBPERF_DEBUG2, fmt, ##__VA_ARGS__)
-#define pr_debug3(fmt, ...) __pr(LIBPERF_DEBUG3, fmt, ##__VA_ARGS__)
-
-#endif /* __LIBPERF_INTERNAL_H */
diff --git a/tools/perf/lib/lib.c b/tools/perf/lib/lib.c
deleted file mode 100644
index 18658931fc71..000000000000
--- a/tools/perf/lib/lib.c
+++ /dev/null
@@ -1,48 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#include <unistd.h>
-#include <stdbool.h>
-#include <errno.h>
-#include <linux/kernel.h>
-#include <internal/lib.h>
-
-unsigned int page_size;
-
-static ssize_t ion(bool is_read, int fd, void *buf, size_t n)
-{
- void *buf_start = buf;
- size_t left = n;
-
- while (left) {
- /* buf must be treated as const if !is_read. */
- ssize_t ret = is_read ? read(fd, buf, left) :
- write(fd, buf, left);
-
- if (ret < 0 && errno == EINTR)
- continue;
- if (ret <= 0)
- return ret;
-
- left -= ret;
- buf += ret;
- }
-
- BUG_ON((size_t)(buf - buf_start) != n);
- return n;
-}
-
-/*
- * Read exactly 'n' bytes or return an error.
- */
-ssize_t readn(int fd, void *buf, size_t n)
-{
- return ion(true, fd, buf, n);
-}
-
-/*
- * Write exactly 'n' bytes or return an error.
- */
-ssize_t writen(int fd, const void *buf, size_t n)
-{
- /* ion does not modify buf. */
- return ion(false, fd, (void *)buf, n);
-}
diff --git a/tools/perf/lib/libperf.map b/tools/perf/lib/libperf.map
deleted file mode 100644
index 7be1af8a546c..000000000000
--- a/tools/perf/lib/libperf.map
+++ /dev/null
@@ -1,51 +0,0 @@
-LIBPERF_0.0.1 {
- global:
- libperf_init;
- perf_cpu_map__dummy_new;
- perf_cpu_map__get;
- perf_cpu_map__put;
- perf_cpu_map__new;
- perf_cpu_map__read;
- perf_cpu_map__nr;
- perf_cpu_map__cpu;
- perf_cpu_map__empty;
- perf_cpu_map__max;
- perf_thread_map__new_dummy;
- perf_thread_map__set_pid;
- perf_thread_map__comm;
- perf_thread_map__nr;
- perf_thread_map__pid;
- perf_thread_map__get;
- perf_thread_map__put;
- perf_evsel__new;
- perf_evsel__delete;
- perf_evsel__enable;
- perf_evsel__disable;
- perf_evsel__open;
- perf_evsel__close;
- perf_evsel__read;
- perf_evsel__cpus;
- perf_evsel__threads;
- perf_evsel__attr;
- perf_evlist__new;
- perf_evlist__delete;
- perf_evlist__open;
- perf_evlist__close;
- perf_evlist__enable;
- perf_evlist__disable;
- perf_evlist__add;
- perf_evlist__remove;
- perf_evlist__next;
- perf_evlist__set_maps;
- perf_evlist__poll;
- perf_evlist__mmap;
- perf_evlist__munmap;
- perf_evlist__filter_pollfd;
- perf_evlist__next_mmap;
- perf_mmap__consume;
- perf_mmap__read_init;
- perf_mmap__read_done;
- perf_mmap__read_event;
- local:
- *;
-};
diff --git a/tools/perf/lib/libperf.pc.template b/tools/perf/lib/libperf.pc.template
deleted file mode 100644
index 117e4a237b55..000000000000
--- a/tools/perf/lib/libperf.pc.template
+++ /dev/null
@@ -1,11 +0,0 @@
-# SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
-
-prefix=@PREFIX@
-libdir=@LIBDIR@
-includedir=${prefix}/include
-
-Name: libperf
-Description: perf library
-Version: @VERSION@
-Libs: -L${libdir} -lperf
-Cflags: -I${includedir}
diff --git a/tools/perf/lib/mmap.c b/tools/perf/lib/mmap.c
deleted file mode 100644
index 79d5ed6c38cc..000000000000
--- a/tools/perf/lib/mmap.c
+++ /dev/null
@@ -1,275 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#include <sys/mman.h>
-#include <inttypes.h>
-#include <asm/bug.h>
-#include <errno.h>
-#include <string.h>
-#include <linux/ring_buffer.h>
-#include <linux/perf_event.h>
-#include <perf/mmap.h>
-#include <perf/event.h>
-#include <internal/mmap.h>
-#include <internal/lib.h>
-#include <linux/kernel.h>
-#include "internal.h"
-
-void perf_mmap__init(struct perf_mmap *map, struct perf_mmap *prev,
- bool overwrite, libperf_unmap_cb_t unmap_cb)
-{
- map->fd = -1;
- map->overwrite = overwrite;
- map->unmap_cb = unmap_cb;
- refcount_set(&map->refcnt, 0);
- if (prev)
- prev->next = map;
-}
-
-size_t perf_mmap__mmap_len(struct perf_mmap *map)
-{
- return map->mask + 1 + page_size;
-}
-
-int perf_mmap__mmap(struct perf_mmap *map, struct perf_mmap_param *mp,
- int fd, int cpu)
-{
- map->prev = 0;
- map->mask = mp->mask;
- map->base = mmap(NULL, perf_mmap__mmap_len(map), mp->prot,
- MAP_SHARED, fd, 0);
- if (map->base == MAP_FAILED) {
- map->base = NULL;
- return -1;
- }
-
- map->fd = fd;
- map->cpu = cpu;
- return 0;
-}
-
-void perf_mmap__munmap(struct perf_mmap *map)
-{
- if (map && map->base != NULL) {
- munmap(map->base, perf_mmap__mmap_len(map));
- map->base = NULL;
- map->fd = -1;
- refcount_set(&map->refcnt, 0);
- }
- if (map && map->unmap_cb)
- map->unmap_cb(map);
-}
-
-void perf_mmap__get(struct perf_mmap *map)
-{
- refcount_inc(&map->refcnt);
-}
-
-void perf_mmap__put(struct perf_mmap *map)
-{
- BUG_ON(map->base && refcount_read(&map->refcnt) == 0);
-
- if (refcount_dec_and_test(&map->refcnt))
- perf_mmap__munmap(map);
-}
-
-static inline void perf_mmap__write_tail(struct perf_mmap *md, u64 tail)
-{
- ring_buffer_write_tail(md->base, tail);
-}
-
-u64 perf_mmap__read_head(struct perf_mmap *map)
-{
- return ring_buffer_read_head(map->base);
-}
-
-static bool perf_mmap__empty(struct perf_mmap *map)
-{
- struct perf_event_mmap_page *pc = map->base;
-
- return perf_mmap__read_head(map) == map->prev && !pc->aux_size;
-}
-
-void perf_mmap__consume(struct perf_mmap *map)
-{
- if (!map->overwrite) {
- u64 old = map->prev;
-
- perf_mmap__write_tail(map, old);
- }
-
- if (refcount_read(&map->refcnt) == 1 && perf_mmap__empty(map))
- perf_mmap__put(map);
-}
-
-static int overwrite_rb_find_range(void *buf, int mask, u64 *start, u64 *end)
-{
- struct perf_event_header *pheader;
- u64 evt_head = *start;
- int size = mask + 1;
-
- pr_debug2("%s: buf=%p, start=%"PRIx64"\n", __func__, buf, *start);
- pheader = (struct perf_event_header *)(buf + (*start & mask));
- while (true) {
- if (evt_head - *start >= (unsigned int)size) {
- pr_debug("Finished reading overwrite ring buffer: rewind\n");
- if (evt_head - *start > (unsigned int)size)
- evt_head -= pheader->size;
- *end = evt_head;
- return 0;
- }
-
- pheader = (struct perf_event_header *)(buf + (evt_head & mask));
-
- if (pheader->size == 0) {
- pr_debug("Finished reading overwrite ring buffer: get start\n");
- *end = evt_head;
- return 0;
- }
-
- evt_head += pheader->size;
- pr_debug3("move evt_head: %"PRIx64"\n", evt_head);
- }
- WARN_ONCE(1, "Shouldn't get here\n");
- return -1;
-}
-
-/*
- * Report the start and end of the available data in ringbuffer
- */
-static int __perf_mmap__read_init(struct perf_mmap *md)
-{
- u64 head = perf_mmap__read_head(md);
- u64 old = md->prev;
- unsigned char *data = md->base + page_size;
- unsigned long size;
-
- md->start = md->overwrite ? head : old;
- md->end = md->overwrite ? old : head;
-
- if ((md->end - md->start) < md->flush)
- return -EAGAIN;
-
- size = md->end - md->start;
- if (size > (unsigned long)(md->mask) + 1) {
- if (!md->overwrite) {
- WARN_ONCE(1, "failed to keep up with mmap data. (warn only once)\n");
-
- md->prev = head;
- perf_mmap__consume(md);
- return -EAGAIN;
- }
-
- /*
- * Backward ring buffer is full. We still have a chance to read
- * most of data from it.
- */
- if (overwrite_rb_find_range(data, md->mask, &md->start, &md->end))
- return -EINVAL;
- }
-
- return 0;
-}
-
-int perf_mmap__read_init(struct perf_mmap *map)
-{
- /*
- * Check if event was unmapped due to a POLLHUP/POLLERR.
- */
- if (!refcount_read(&map->refcnt))
- return -ENOENT;
-
- return __perf_mmap__read_init(map);
-}
-
-/*
- * Mandatory for overwrite mode
- * The direction of overwrite mode is backward.
- * The last perf_mmap__read() will set tail to map->core.prev.
- * Need to correct the map->core.prev to head which is the end of next read.
- */
-void perf_mmap__read_done(struct perf_mmap *map)
-{
- /*
- * Check if event was unmapped due to a POLLHUP/POLLERR.
- */
- if (!refcount_read(&map->refcnt))
- return;
-
- map->prev = perf_mmap__read_head(map);
-}
-
-/* When check_messup is true, 'end' must points to a good entry */
-static union perf_event *perf_mmap__read(struct perf_mmap *map,
- u64 *startp, u64 end)
-{
- unsigned char *data = map->base + page_size;
- union perf_event *event = NULL;
- int diff = end - *startp;
-
- if (diff >= (int)sizeof(event->header)) {
- size_t size;
-
- event = (union perf_event *)&data[*startp & map->mask];
- size = event->header.size;
-
- if (size < sizeof(event->header) || diff < (int)size)
- return NULL;
-
- /*
- * Event straddles the mmap boundary -- header should always
- * be inside due to u64 alignment of output.
- */
- if ((*startp & map->mask) + size != ((*startp + size) & map->mask)) {
- unsigned int offset = *startp;
- unsigned int len = min(sizeof(*event), size), cpy;
- void *dst = map->event_copy;
-
- do {
- cpy = min(map->mask + 1 - (offset & map->mask), len);
- memcpy(dst, &data[offset & map->mask], cpy);
- offset += cpy;
- dst += cpy;
- len -= cpy;
- } while (len);
-
- event = (union perf_event *)map->event_copy;
- }
-
- *startp += size;
- }
-
- return event;
-}
-
-/*
- * Read event from ring buffer one by one.
- * Return one event for each call.
- *
- * Usage:
- * perf_mmap__read_init()
- * while(event = perf_mmap__read_event()) {
- * //process the event
- * perf_mmap__consume()
- * }
- * perf_mmap__read_done()
- */
-union perf_event *perf_mmap__read_event(struct perf_mmap *map)
-{
- union perf_event *event;
-
- /*
- * Check if event was unmapped due to a POLLHUP/POLLERR.
- */
- if (!refcount_read(&map->refcnt))
- return NULL;
-
- /* non-overwirte doesn't pause the ringbuffer */
- if (!map->overwrite)
- map->end = perf_mmap__read_head(map);
-
- event = perf_mmap__read(map, &map->start, map->end);
-
- if (!map->overwrite)
- map->prev = map->start;
-
- return event;
-}
diff --git a/tools/perf/lib/tests/Makefile b/tools/perf/lib/tests/Makefile
deleted file mode 100644
index a43cd08c5c03..000000000000
--- a/tools/perf/lib/tests/Makefile
+++ /dev/null
@@ -1,38 +0,0 @@
-# SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
-
-TESTS = test-cpumap test-threadmap test-evlist test-evsel
-
-TESTS_SO := $(addsuffix -so,$(TESTS))
-TESTS_A := $(addsuffix -a,$(TESTS))
-
-# Set compile option CFLAGS
-ifdef EXTRA_CFLAGS
- CFLAGS := $(EXTRA_CFLAGS)
-else
- CFLAGS := -g -Wall
-endif
-
-all:
-
-include $(srctree)/tools/scripts/Makefile.include
-
-INCLUDE = -I$(srctree)/tools/perf/lib/include -I$(srctree)/tools/include -I$(srctree)/tools/lib
-
-$(TESTS_A): FORCE
- $(QUIET_LINK)$(CC) $(INCLUDE) $(CFLAGS) -o $@ $(subst -a,.c,$@) ../libperf.a $(LIBAPI)
-
-$(TESTS_SO): FORCE
- $(QUIET_LINK)$(CC) $(INCLUDE) $(CFLAGS) -L.. -o $@ $(subst -so,.c,$@) $(LIBAPI) -lperf
-
-all: $(TESTS_A) $(TESTS_SO)
-
-run:
- @echo "running static:"
- @for i in $(TESTS_A); do ./$$i; done
- @echo "running dynamic:"
- @for i in $(TESTS_SO); do LD_LIBRARY_PATH=../ ./$$i; done
-
-clean:
- $(call QUIET_CLEAN, tests)$(RM) $(TESTS_A) $(TESTS_SO)
-
-.PHONY: all clean FORCE
diff --git a/tools/perf/lib/tests/test-cpumap.c b/tools/perf/lib/tests/test-cpumap.c
deleted file mode 100644
index c8d45091e7c2..000000000000
--- a/tools/perf/lib/tests/test-cpumap.c
+++ /dev/null
@@ -1,31 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#include <stdarg.h>
-#include <stdio.h>
-#include <perf/cpumap.h>
-#include <internal/tests.h>
-
-static int libperf_print(enum libperf_print_level level,
- const char *fmt, va_list ap)
-{
- return vfprintf(stderr, fmt, ap);
-}
-
-int main(int argc, char **argv)
-{
- struct perf_cpu_map *cpus;
-
- __T_START;
-
- libperf_init(libperf_print);
-
- cpus = perf_cpu_map__dummy_new();
- if (!cpus)
- return -1;
-
- perf_cpu_map__get(cpus);
- perf_cpu_map__put(cpus);
- perf_cpu_map__put(cpus);
-
- __T_END;
- return 0;
-}
diff --git a/tools/perf/lib/tests/test-evlist.c b/tools/perf/lib/tests/test-evlist.c
deleted file mode 100644
index 6d8ebe0c2504..000000000000
--- a/tools/perf/lib/tests/test-evlist.c
+++ /dev/null
@@ -1,413 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#define _GNU_SOURCE // needed for sched.h to get sched_[gs]etaffinity and CPU_(ZERO,SET)
-#include <sched.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <linux/perf_event.h>
-#include <linux/limits.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <sys/prctl.h>
-#include <perf/cpumap.h>
-#include <perf/threadmap.h>
-#include <perf/evlist.h>
-#include <perf/evsel.h>
-#include <perf/mmap.h>
-#include <perf/event.h>
-#include <internal/tests.h>
-#include <api/fs/fs.h>
-
-static int libperf_print(enum libperf_print_level level,
- const char *fmt, va_list ap)
-{
- return vfprintf(stderr, fmt, ap);
-}
-
-static int test_stat_cpu(void)
-{
- struct perf_cpu_map *cpus;
- struct perf_evlist *evlist;
- struct perf_evsel *evsel;
- struct perf_event_attr attr1 = {
- .type = PERF_TYPE_SOFTWARE,
- .config = PERF_COUNT_SW_CPU_CLOCK,
- };
- struct perf_event_attr attr2 = {
- .type = PERF_TYPE_SOFTWARE,
- .config = PERF_COUNT_SW_TASK_CLOCK,
- };
- int err, cpu, tmp;
-
- cpus = perf_cpu_map__new(NULL);
- __T("failed to create cpus", cpus);
-
- evlist = perf_evlist__new();
- __T("failed to create evlist", evlist);
-
- evsel = perf_evsel__new(&attr1);
- __T("failed to create evsel1", evsel);
-
- perf_evlist__add(evlist, evsel);
-
- evsel = perf_evsel__new(&attr2);
- __T("failed to create evsel2", evsel);
-
- perf_evlist__add(evlist, evsel);
-
- perf_evlist__set_maps(evlist, cpus, NULL);
-
- err = perf_evlist__open(evlist);
- __T("failed to open evsel", err == 0);
-
- perf_evlist__for_each_evsel(evlist, evsel) {
- cpus = perf_evsel__cpus(evsel);
-
- perf_cpu_map__for_each_cpu(cpu, tmp, cpus) {
- struct perf_counts_values counts = { .val = 0 };
-
- perf_evsel__read(evsel, cpu, 0, &counts);
- __T("failed to read value for evsel", counts.val != 0);
- }
- }
-
- perf_evlist__close(evlist);
- perf_evlist__delete(evlist);
-
- perf_cpu_map__put(cpus);
- return 0;
-}
-
-static int test_stat_thread(void)
-{
- struct perf_counts_values counts = { .val = 0 };
- struct perf_thread_map *threads;
- struct perf_evlist *evlist;
- struct perf_evsel *evsel;
- struct perf_event_attr attr1 = {
- .type = PERF_TYPE_SOFTWARE,
- .config = PERF_COUNT_SW_CPU_CLOCK,
- };
- struct perf_event_attr attr2 = {
- .type = PERF_TYPE_SOFTWARE,
- .config = PERF_COUNT_SW_TASK_CLOCK,
- };
- int err;
-
- threads = perf_thread_map__new_dummy();
- __T("failed to create threads", threads);
-
- perf_thread_map__set_pid(threads, 0, 0);
-
- evlist = perf_evlist__new();
- __T("failed to create evlist", evlist);
-
- evsel = perf_evsel__new(&attr1);
- __T("failed to create evsel1", evsel);
-
- perf_evlist__add(evlist, evsel);
-
- evsel = perf_evsel__new(&attr2);
- __T("failed to create evsel2", evsel);
-
- perf_evlist__add(evlist, evsel);
-
- perf_evlist__set_maps(evlist, NULL, threads);
-
- err = perf_evlist__open(evlist);
- __T("failed to open evsel", err == 0);
-
- perf_evlist__for_each_evsel(evlist, evsel) {
- perf_evsel__read(evsel, 0, 0, &counts);
- __T("failed to read value for evsel", counts.val != 0);
- }
-
- perf_evlist__close(evlist);
- perf_evlist__delete(evlist);
-
- perf_thread_map__put(threads);
- return 0;
-}
-
-static int test_stat_thread_enable(void)
-{
- struct perf_counts_values counts = { .val = 0 };
- struct perf_thread_map *threads;
- struct perf_evlist *evlist;
- struct perf_evsel *evsel;
- struct perf_event_attr attr1 = {
- .type = PERF_TYPE_SOFTWARE,
- .config = PERF_COUNT_SW_CPU_CLOCK,
- .disabled = 1,
- };
- struct perf_event_attr attr2 = {
- .type = PERF_TYPE_SOFTWARE,
- .config = PERF_COUNT_SW_TASK_CLOCK,
- .disabled = 1,
- };
- int err;
-
- threads = perf_thread_map__new_dummy();
- __T("failed to create threads", threads);
-
- perf_thread_map__set_pid(threads, 0, 0);
-
- evlist = perf_evlist__new();
- __T("failed to create evlist", evlist);
-
- evsel = perf_evsel__new(&attr1);
- __T("failed to create evsel1", evsel);
-
- perf_evlist__add(evlist, evsel);
-
- evsel = perf_evsel__new(&attr2);
- __T("failed to create evsel2", evsel);
-
- perf_evlist__add(evlist, evsel);
-
- perf_evlist__set_maps(evlist, NULL, threads);
-
- err = perf_evlist__open(evlist);
- __T("failed to open evsel", err == 0);
-
- perf_evlist__for_each_evsel(evlist, evsel) {
- perf_evsel__read(evsel, 0, 0, &counts);
- __T("failed to read value for evsel", counts.val == 0);
- }
-
- perf_evlist__enable(evlist);
-
- perf_evlist__for_each_evsel(evlist, evsel) {
- perf_evsel__read(evsel, 0, 0, &counts);
- __T("failed to read value for evsel", counts.val != 0);
- }
-
- perf_evlist__disable(evlist);
-
- perf_evlist__close(evlist);
- perf_evlist__delete(evlist);
-
- perf_thread_map__put(threads);
- return 0;
-}
-
-static int test_mmap_thread(void)
-{
- struct perf_evlist *evlist;
- struct perf_evsel *evsel;
- struct perf_mmap *map;
- struct perf_cpu_map *cpus;
- struct perf_thread_map *threads;
- struct perf_event_attr attr = {
- .type = PERF_TYPE_TRACEPOINT,
- .sample_period = 1,
- .wakeup_watermark = 1,
- .disabled = 1,
- };
- char path[PATH_MAX];
- int id, err, pid, go_pipe[2];
- union perf_event *event;
- char bf;
- int count = 0;
-
- snprintf(path, PATH_MAX, "%s/kernel/debug/tracing/events/syscalls/sys_enter_prctl/id",
- sysfs__mountpoint());
-
- if (filename__read_int(path, &id)) {
- fprintf(stderr, "error: failed to get tracepoint id: %s\n", path);
- return -1;
- }
-
- attr.config = id;
-
- err = pipe(go_pipe);
- __T("failed to create pipe", err == 0);
-
- fflush(NULL);
-
- pid = fork();
- if (!pid) {
- int i;
-
- read(go_pipe[0], &bf, 1);
-
- /* Generate 100 prctl calls. */
- for (i = 0; i < 100; i++)
- prctl(0, 0, 0, 0, 0);
-
- exit(0);
- }
-
- threads = perf_thread_map__new_dummy();
- __T("failed to create threads", threads);
-
- cpus = perf_cpu_map__dummy_new();
- __T("failed to create cpus", cpus);
-
- perf_thread_map__set_pid(threads, 0, pid);
-
- evlist = perf_evlist__new();
- __T("failed to create evlist", evlist);
-
- evsel = perf_evsel__new(&attr);
- __T("failed to create evsel1", evsel);
-
- perf_evlist__add(evlist, evsel);
-
- perf_evlist__set_maps(evlist, cpus, threads);
-
- err = perf_evlist__open(evlist);
- __T("failed to open evlist", err == 0);
-
- err = perf_evlist__mmap(evlist, 4);
- __T("failed to mmap evlist", err == 0);
-
- perf_evlist__enable(evlist);
-
- /* kick the child and wait for it to finish */
- write(go_pipe[1], &bf, 1);
- waitpid(pid, NULL, 0);
-
- /*
- * There's no need to call perf_evlist__disable,
- * monitored process is dead now.
- */
-
- perf_evlist__for_each_mmap(evlist, map, false) {
- if (perf_mmap__read_init(map) < 0)
- continue;
-
- while ((event = perf_mmap__read_event(map)) != NULL) {
- count++;
- perf_mmap__consume(map);
- }
-
- perf_mmap__read_done(map);
- }
-
- /* calls perf_evlist__munmap/perf_evlist__close */
- perf_evlist__delete(evlist);
-
- perf_thread_map__put(threads);
- perf_cpu_map__put(cpus);
-
- /*
- * The generated prctl calls should match the
- * number of events in the buffer.
- */
- __T("failed count", count == 100);
-
- return 0;
-}
-
-static int test_mmap_cpus(void)
-{
- struct perf_evlist *evlist;
- struct perf_evsel *evsel;
- struct perf_mmap *map;
- struct perf_cpu_map *cpus;
- struct perf_event_attr attr = {
- .type = PERF_TYPE_TRACEPOINT,
- .sample_period = 1,
- .wakeup_watermark = 1,
- .disabled = 1,
- };
- cpu_set_t saved_mask;
- char path[PATH_MAX];
- int id, err, cpu, tmp;
- union perf_event *event;
- int count = 0;
-
- snprintf(path, PATH_MAX, "%s/kernel/debug/tracing/events/syscalls/sys_enter_prctl/id",
- sysfs__mountpoint());
-
- if (filename__read_int(path, &id)) {
- fprintf(stderr, "error: failed to get tracepoint id: %s\n", path);
- return -1;
- }
-
- attr.config = id;
-
- cpus = perf_cpu_map__new(NULL);
- __T("failed to create cpus", cpus);
-
- evlist = perf_evlist__new();
- __T("failed to create evlist", evlist);
-
- evsel = perf_evsel__new(&attr);
- __T("failed to create evsel1", evsel);
-
- perf_evlist__add(evlist, evsel);
-
- perf_evlist__set_maps(evlist, cpus, NULL);
-
- err = perf_evlist__open(evlist);
- __T("failed to open evlist", err == 0);
-
- err = perf_evlist__mmap(evlist, 4);
- __T("failed to mmap evlist", err == 0);
-
- perf_evlist__enable(evlist);
-
- err = sched_getaffinity(0, sizeof(saved_mask), &saved_mask);
- __T("sched_getaffinity failed", err == 0);
-
- perf_cpu_map__for_each_cpu(cpu, tmp, cpus) {
- cpu_set_t mask;
-
- CPU_ZERO(&mask);
- CPU_SET(cpu, &mask);
-
- err = sched_setaffinity(0, sizeof(mask), &mask);
- __T("sched_setaffinity failed", err == 0);
-
- prctl(0, 0, 0, 0, 0);
- }
-
- err = sched_setaffinity(0, sizeof(saved_mask), &saved_mask);
- __T("sched_setaffinity failed", err == 0);
-
- perf_evlist__disable(evlist);
-
- perf_evlist__for_each_mmap(evlist, map, false) {
- if (perf_mmap__read_init(map) < 0)
- continue;
-
- while ((event = perf_mmap__read_event(map)) != NULL) {
- count++;
- perf_mmap__consume(map);
- }
-
- perf_mmap__read_done(map);
- }
-
- /* calls perf_evlist__munmap/perf_evlist__close */
- perf_evlist__delete(evlist);
-
- /*
- * The generated prctl events should match the
- * number of cpus or be bigger (we are system-wide).
- */
- __T("failed count", count >= perf_cpu_map__nr(cpus));
-
- perf_cpu_map__put(cpus);
-
- return 0;
-}
-
-int main(int argc, char **argv)
-{
- __T_START;
-
- libperf_init(libperf_print);
-
- test_stat_cpu();
- test_stat_thread();
- test_stat_thread_enable();
- test_mmap_thread();
- test_mmap_cpus();
-
- __T_END;
- return 0;
-}
diff --git a/tools/perf/lib/tests/test-evsel.c b/tools/perf/lib/tests/test-evsel.c
deleted file mode 100644
index 135722ac965b..000000000000
--- a/tools/perf/lib/tests/test-evsel.c
+++ /dev/null
@@ -1,135 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#include <stdarg.h>
-#include <stdio.h>
-#include <linux/perf_event.h>
-#include <perf/cpumap.h>
-#include <perf/threadmap.h>
-#include <perf/evsel.h>
-#include <internal/tests.h>
-
-static int libperf_print(enum libperf_print_level level,
- const char *fmt, va_list ap)
-{
- return vfprintf(stderr, fmt, ap);
-}
-
-static int test_stat_cpu(void)
-{
- struct perf_cpu_map *cpus;
- struct perf_evsel *evsel;
- struct perf_event_attr attr = {
- .type = PERF_TYPE_SOFTWARE,
- .config = PERF_COUNT_SW_CPU_CLOCK,
- };
- int err, cpu, tmp;
-
- cpus = perf_cpu_map__new(NULL);
- __T("failed to create cpus", cpus);
-
- evsel = perf_evsel__new(&attr);
- __T("failed to create evsel", evsel);
-
- err = perf_evsel__open(evsel, cpus, NULL);
- __T("failed to open evsel", err == 0);
-
- perf_cpu_map__for_each_cpu(cpu, tmp, cpus) {
- struct perf_counts_values counts = { .val = 0 };
-
- perf_evsel__read(evsel, cpu, 0, &counts);
- __T("failed to read value for evsel", counts.val != 0);
- }
-
- perf_evsel__close(evsel);
- perf_evsel__delete(evsel);
-
- perf_cpu_map__put(cpus);
- return 0;
-}
-
-static int test_stat_thread(void)
-{
- struct perf_counts_values counts = { .val = 0 };
- struct perf_thread_map *threads;
- struct perf_evsel *evsel;
- struct perf_event_attr attr = {
- .type = PERF_TYPE_SOFTWARE,
- .config = PERF_COUNT_SW_TASK_CLOCK,
- };
- int err;
-
- threads = perf_thread_map__new_dummy();
- __T("failed to create threads", threads);
-
- perf_thread_map__set_pid(threads, 0, 0);
-
- evsel = perf_evsel__new(&attr);
- __T("failed to create evsel", evsel);
-
- err = perf_evsel__open(evsel, NULL, threads);
- __T("failed to open evsel", err == 0);
-
- perf_evsel__read(evsel, 0, 0, &counts);
- __T("failed to read value for evsel", counts.val != 0);
-
- perf_evsel__close(evsel);
- perf_evsel__delete(evsel);
-
- perf_thread_map__put(threads);
- return 0;
-}
-
-static int test_stat_thread_enable(void)
-{
- struct perf_counts_values counts = { .val = 0 };
- struct perf_thread_map *threads;
- struct perf_evsel *evsel;
- struct perf_event_attr attr = {
- .type = PERF_TYPE_SOFTWARE,
- .config = PERF_COUNT_SW_TASK_CLOCK,
- .disabled = 1,
- };
- int err;
-
- threads = perf_thread_map__new_dummy();
- __T("failed to create threads", threads);
-
- perf_thread_map__set_pid(threads, 0, 0);
-
- evsel = perf_evsel__new(&attr);
- __T("failed to create evsel", evsel);
-
- err = perf_evsel__open(evsel, NULL, threads);
- __T("failed to open evsel", err == 0);
-
- perf_evsel__read(evsel, 0, 0, &counts);
- __T("failed to read value for evsel", counts.val == 0);
-
- err = perf_evsel__enable(evsel);
- __T("failed to enable evsel", err == 0);
-
- perf_evsel__read(evsel, 0, 0, &counts);
- __T("failed to read value for evsel", counts.val != 0);
-
- err = perf_evsel__disable(evsel);
- __T("failed to enable evsel", err == 0);
-
- perf_evsel__close(evsel);
- perf_evsel__delete(evsel);
-
- perf_thread_map__put(threads);
- return 0;
-}
-
-int main(int argc, char **argv)
-{
- __T_START;
-
- libperf_init(libperf_print);
-
- test_stat_cpu();
- test_stat_thread();
- test_stat_thread_enable();
-
- __T_END;
- return 0;
-}
diff --git a/tools/perf/lib/tests/test-threadmap.c b/tools/perf/lib/tests/test-threadmap.c
deleted file mode 100644
index 7dc4d6fbedde..000000000000
--- a/tools/perf/lib/tests/test-threadmap.c
+++ /dev/null
@@ -1,31 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#include <stdarg.h>
-#include <stdio.h>
-#include <perf/threadmap.h>
-#include <internal/tests.h>
-
-static int libperf_print(enum libperf_print_level level,
- const char *fmt, va_list ap)
-{
- return vfprintf(stderr, fmt, ap);
-}
-
-int main(int argc, char **argv)
-{
- struct perf_thread_map *threads;
-
- __T_START;
-
- libperf_init(libperf_print);
-
- threads = perf_thread_map__new_dummy();
- if (!threads)
- return -1;
-
- perf_thread_map__get(threads);
- perf_thread_map__put(threads);
- perf_thread_map__put(threads);
-
- __T_END;
- return 0;
-}
diff --git a/tools/perf/lib/threadmap.c b/tools/perf/lib/threadmap.c
deleted file mode 100644
index e92c368b0a6c..000000000000
--- a/tools/perf/lib/threadmap.c
+++ /dev/null
@@ -1,91 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#include <perf/threadmap.h>
-#include <stdlib.h>
-#include <linux/refcount.h>
-#include <internal/threadmap.h>
-#include <string.h>
-#include <asm/bug.h>
-#include <stdio.h>
-
-static void perf_thread_map__reset(struct perf_thread_map *map, int start, int nr)
-{
- size_t size = (nr - start) * sizeof(map->map[0]);
-
- memset(&map->map[start], 0, size);
- map->err_thread = -1;
-}
-
-struct perf_thread_map *perf_thread_map__realloc(struct perf_thread_map *map, int nr)
-{
- size_t size = sizeof(*map) + sizeof(map->map[0]) * nr;
- int start = map ? map->nr : 0;
-
- map = realloc(map, size);
- /*
- * We only realloc to add more items, let's reset new items.
- */
- if (map)
- perf_thread_map__reset(map, start, nr);
-
- return map;
-}
-
-#define thread_map__alloc(__nr) perf_thread_map__realloc(NULL, __nr)
-
-void perf_thread_map__set_pid(struct perf_thread_map *map, int thread, pid_t pid)
-{
- map->map[thread].pid = pid;
-}
-
-char *perf_thread_map__comm(struct perf_thread_map *map, int thread)
-{
- return map->map[thread].comm;
-}
-
-struct perf_thread_map *perf_thread_map__new_dummy(void)
-{
- struct perf_thread_map *threads = thread_map__alloc(1);
-
- if (threads != NULL) {
- perf_thread_map__set_pid(threads, 0, -1);
- threads->nr = 1;
- refcount_set(&threads->refcnt, 1);
- }
- return threads;
-}
-
-static void perf_thread_map__delete(struct perf_thread_map *threads)
-{
- if (threads) {
- int i;
-
- WARN_ONCE(refcount_read(&threads->refcnt) != 0,
- "thread map refcnt unbalanced\n");
- for (i = 0; i < threads->nr; i++)
- free(perf_thread_map__comm(threads, i));
- free(threads);
- }
-}
-
-struct perf_thread_map *perf_thread_map__get(struct perf_thread_map *map)
-{
- if (map)
- refcount_inc(&map->refcnt);
- return map;
-}
-
-void perf_thread_map__put(struct perf_thread_map *map)
-{
- if (map && refcount_dec_and_test(&map->refcnt))
- perf_thread_map__delete(map);
-}
-
-int perf_thread_map__nr(struct perf_thread_map *threads)
-{
- return threads ? threads->nr : 1;
-}
-
-pid_t perf_thread_map__pid(struct perf_thread_map *map, int thread)
-{
- return map->map[thread].pid;
-}
diff --git a/tools/perf/lib/xyarray.c b/tools/perf/lib/xyarray.c
deleted file mode 100644
index dcd901d154bb..000000000000
--- a/tools/perf/lib/xyarray.c
+++ /dev/null
@@ -1,33 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#include <internal/xyarray.h>
-#include <linux/zalloc.h>
-#include <stdlib.h>
-#include <string.h>
-
-struct xyarray *xyarray__new(int xlen, int ylen, size_t entry_size)
-{
- size_t row_size = ylen * entry_size;
- struct xyarray *xy = zalloc(sizeof(*xy) + xlen * row_size);
-
- if (xy != NULL) {
- xy->entry_size = entry_size;
- xy->row_size = row_size;
- xy->entries = xlen * ylen;
- xy->max_x = xlen;
- xy->max_y = ylen;
- }
-
- return xy;
-}
-
-void xyarray__reset(struct xyarray *xy)
-{
- size_t n = xy->entries * xy->entry_size;
-
- memset(xy->contents, 0, n);
-}
-
-void xyarray__delete(struct xyarray *xy)
-{
- free(xy);
-}
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);