aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2015-05-29 14:19:02 -0400
committerIngo Molnar <mingo@kernel.org>2015-05-29 14:19:02 -0400
commit5c9b9bc67c684e40b3a5e7e9facde0fb7200cd8c (patch)
tree754aa0939698ea7cc04587ee0b10be323fc9c64d /tools/perf
parentf1942b96b4b44c1ab0e0b82fef93ba7e1fada7af (diff)
parented426915900db3c58c410b8b38f6ff0e46bf6c96 (diff)
Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core
Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo: User visible changes: - Make Ctrl-C stop processing on TUI, allowing interrupting the load of big perf.data files (Namhyung Kim) - Fix 'perf annotate' -i option, which is currently ignored (Martin Liška) - Add ARM64 perf_regs_load to support libunwind and enable testing (Wang Nan) Infrastructure changes: - Fix thread ref-counting in db-export (Adrian Hunter) - Fix compiler warning about may be accessing uninitialized (Arnaldo Carvalho de Melo) - No need to have two lists for user and kernel DSOs, unify them (Arnaldo Carvalho de Melo) - Function namespace consistency fixups (Arnaldo Carvalho de Melo) - Do not fail on missing Build file, fixing the build on MIPS (Jiri Olsa) - Fix up syscall tests, making those tests pass on ARM64 (Riku Voipio) - Fix 'function unused' warning in 'perf probe' (Wang Nan) Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf')
-rw-r--r--tools/perf/arch/arm64/Build1
-rw-r--r--tools/perf/arch/arm64/include/perf_regs.h3
-rw-r--r--tools/perf/arch/arm64/tests/Build2
-rw-r--r--tools/perf/arch/arm64/tests/dwarf-unwind.c61
-rw-r--r--tools/perf/arch/arm64/tests/regs_load.S46
-rw-r--r--tools/perf/builtin-annotate.c3
-rw-r--r--tools/perf/builtin-kmem.c2
-rw-r--r--tools/perf/tests/Build8
-rw-r--r--tools/perf/tests/builtin-test.c14
-rw-r--r--tools/perf/tests/hists_common.c3
-rw-r--r--tools/perf/tests/mmap-basic.c6
-rw-r--r--tools/perf/tests/openat-syscall-all-cpus.c (renamed from tools/perf/tests/open-syscall-all-cpus.c)12
-rw-r--r--tools/perf/tests/openat-syscall-tp-fields.c (renamed from tools/perf/tests/open-syscall-tp-fields.c)6
-rw-r--r--tools/perf/tests/openat-syscall.c (renamed from tools/perf/tests/open-syscall.c)14
-rw-r--r--tools/perf/tests/parse-events.c12
-rw-r--r--tools/perf/tests/tests.h8
-rw-r--r--tools/perf/ui/browsers/annotate.c4
-rw-r--r--tools/perf/ui/browsers/hists.c4
-rw-r--r--tools/perf/ui/tui/setup.c2
-rw-r--r--tools/perf/util/build-id.c59
-rw-r--r--tools/perf/util/db-export.c19
-rw-r--r--tools/perf/util/dso.c6
-rw-r--r--tools/perf/util/dso.h4
-rw-r--r--tools/perf/util/header.c6
-rw-r--r--tools/perf/util/machine.c46
-rw-r--r--tools/perf/util/machine.h5
-rw-r--r--tools/perf/util/map.c4
-rw-r--r--tools/perf/util/probe-event.c66
-rw-r--r--tools/perf/util/symbol-elf.c6
-rw-r--r--tools/perf/util/vdso.c24
-rw-r--r--tools/perf/util/vdso.h4
31 files changed, 273 insertions, 187 deletions
diff --git a/tools/perf/arch/arm64/Build b/tools/perf/arch/arm64/Build
index 54afe4a467e7..41bf61da476a 100644
--- a/tools/perf/arch/arm64/Build
+++ b/tools/perf/arch/arm64/Build
@@ -1 +1,2 @@
1libperf-y += util/ 1libperf-y += util/
2libperf-$(CONFIG_DWARF_UNWIND) += tests/
diff --git a/tools/perf/arch/arm64/include/perf_regs.h b/tools/perf/arch/arm64/include/perf_regs.h
index 1d3f39c3aa56..4e5af27e3fbf 100644
--- a/tools/perf/arch/arm64/include/perf_regs.h
+++ b/tools/perf/arch/arm64/include/perf_regs.h
@@ -5,8 +5,11 @@
5#include <linux/types.h> 5#include <linux/types.h>
6#include <asm/perf_regs.h> 6#include <asm/perf_regs.h>
7 7
8void perf_regs_load(u64 *regs);
9
8#define PERF_REGS_MASK ((1ULL << PERF_REG_ARM64_MAX) - 1) 10#define PERF_REGS_MASK ((1ULL << PERF_REG_ARM64_MAX) - 1)
9#define PERF_REGS_MAX PERF_REG_ARM64_MAX 11#define PERF_REGS_MAX PERF_REG_ARM64_MAX
12#define PERF_SAMPLE_REGS_ABI PERF_SAMPLE_REGS_ABI_64
10 13
11#define PERF_REG_IP PERF_REG_ARM64_PC 14#define PERF_REG_IP PERF_REG_ARM64_PC
12#define PERF_REG_SP PERF_REG_ARM64_SP 15#define PERF_REG_SP PERF_REG_ARM64_SP
diff --git a/tools/perf/arch/arm64/tests/Build b/tools/perf/arch/arm64/tests/Build
new file mode 100644
index 000000000000..b30eff9bcc83
--- /dev/null
+++ b/tools/perf/arch/arm64/tests/Build
@@ -0,0 +1,2 @@
1libperf-y += regs_load.o
2libperf-y += dwarf-unwind.o
diff --git a/tools/perf/arch/arm64/tests/dwarf-unwind.c b/tools/perf/arch/arm64/tests/dwarf-unwind.c
new file mode 100644
index 000000000000..cf04a4c91c59
--- /dev/null
+++ b/tools/perf/arch/arm64/tests/dwarf-unwind.c
@@ -0,0 +1,61 @@
1#include <string.h>
2#include "perf_regs.h"
3#include "thread.h"
4#include "map.h"
5#include "event.h"
6#include "debug.h"
7#include "tests/tests.h"
8
9#define STACK_SIZE 8192
10
11static int sample_ustack(struct perf_sample *sample,
12 struct thread *thread, u64 *regs)
13{
14 struct stack_dump *stack = &sample->user_stack;
15 struct map *map;
16 unsigned long sp;
17 u64 stack_size, *buf;
18
19 buf = malloc(STACK_SIZE);
20 if (!buf) {
21 pr_debug("failed to allocate sample uregs data\n");
22 return -1;
23 }
24
25 sp = (unsigned long) regs[PERF_REG_ARM64_SP];
26
27 map = map_groups__find(thread->mg, MAP__VARIABLE, (u64) sp);
28 if (!map) {
29 pr_debug("failed to get stack map\n");
30 free(buf);
31 return -1;
32 }
33
34 stack_size = map->end - sp;
35 stack_size = stack_size > STACK_SIZE ? STACK_SIZE : stack_size;
36
37 memcpy(buf, (void *) sp, stack_size);
38 stack->data = (char *) buf;
39 stack->size = stack_size;
40 return 0;
41}
42
43int test__arch_unwind_sample(struct perf_sample *sample,
44 struct thread *thread)
45{
46 struct regs_dump *regs = &sample->user_regs;
47 u64 *buf;
48
49 buf = calloc(1, sizeof(u64) * PERF_REGS_MAX);
50 if (!buf) {
51 pr_debug("failed to allocate sample uregs data\n");
52 return -1;
53 }
54
55 perf_regs_load(buf);
56 regs->abi = PERF_SAMPLE_REGS_ABI;
57 regs->regs = buf;
58 regs->mask = PERF_REGS_MASK;
59
60 return sample_ustack(sample, thread, buf);
61}
diff --git a/tools/perf/arch/arm64/tests/regs_load.S b/tools/perf/arch/arm64/tests/regs_load.S
new file mode 100644
index 000000000000..025b46e579a6
--- /dev/null
+++ b/tools/perf/arch/arm64/tests/regs_load.S
@@ -0,0 +1,46 @@
1#include <linux/linkage.h>
2
3.text
4.type perf_regs_load,%function
5#define STR_REG(r) str x##r, [x0, 8 * r]
6#define LDR_REG(r) ldr x##r, [x0, 8 * r]
7#define SP (8 * 31)
8#define PC (8 * 32)
9ENTRY(perf_regs_load)
10 STR_REG(0)
11 STR_REG(1)
12 STR_REG(2)
13 STR_REG(3)
14 STR_REG(4)
15 STR_REG(5)
16 STR_REG(6)
17 STR_REG(7)
18 STR_REG(8)
19 STR_REG(9)
20 STR_REG(10)
21 STR_REG(11)
22 STR_REG(12)
23 STR_REG(13)
24 STR_REG(14)
25 STR_REG(15)
26 STR_REG(16)
27 STR_REG(17)
28 STR_REG(18)
29 STR_REG(19)
30 STR_REG(20)
31 STR_REG(21)
32 STR_REG(22)
33 STR_REG(23)
34 STR_REG(24)
35 STR_REG(25)
36 STR_REG(26)
37 STR_REG(27)
38 STR_REG(28)
39 STR_REG(29)
40 STR_REG(30)
41 mov x1, sp
42 str x1, [x0, #SP]
43 str x30, [x0, #PC]
44 LDR_REG(1)
45 ret
46ENDPROC(perf_regs_load)
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index c434e1264087..4e08c2d2090e 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -289,7 +289,6 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused)
289 }, 289 },
290 }; 290 };
291 struct perf_data_file file = { 291 struct perf_data_file file = {
292 .path = input_name,
293 .mode = PERF_DATA_MODE_READ, 292 .mode = PERF_DATA_MODE_READ,
294 }; 293 };
295 const struct option options[] = { 294 const struct option options[] = {
@@ -346,6 +345,8 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused)
346 else if (annotate.use_gtk) 345 else if (annotate.use_gtk)
347 use_browser = 2; 346 use_browser = 2;
348 347
348 file.path = input_name;
349
349 setup_browser(true); 350 setup_browser(true);
350 351
351 annotate.session = perf_session__new(&file, false, &annotate.tool); 352 annotate.session = perf_session__new(&file, false, &annotate.tool);
diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c
index 254614b10c4a..950f296dfcf7 100644
--- a/tools/perf/builtin-kmem.c
+++ b/tools/perf/builtin-kmem.c
@@ -644,7 +644,7 @@ static char *compact_gfp_flags(char *gfp_flags)
644{ 644{
645 char *orig_flags = strdup(gfp_flags); 645 char *orig_flags = strdup(gfp_flags);
646 char *new_flags = NULL; 646 char *new_flags = NULL;
647 char *str, *pos; 647 char *str, *pos = NULL;
648 size_t len = 0; 648 size_t len = 0;
649 649
650 if (orig_flags == NULL) 650 if (orig_flags == NULL)
diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build
index 6a8801b32017..ee41e705b2eb 100644
--- a/tools/perf/tests/Build
+++ b/tools/perf/tests/Build
@@ -3,9 +3,9 @@ perf-y += parse-events.o
3perf-y += dso-data.o 3perf-y += dso-data.o
4perf-y += attr.o 4perf-y += attr.o
5perf-y += vmlinux-kallsyms.o 5perf-y += vmlinux-kallsyms.o
6perf-y += open-syscall.o 6perf-y += openat-syscall.o
7perf-y += open-syscall-all-cpus.o 7perf-y += openat-syscall-all-cpus.o
8perf-y += open-syscall-tp-fields.o 8perf-y += openat-syscall-tp-fields.o
9perf-y += mmap-basic.o 9perf-y += mmap-basic.o
10perf-y += perf-record.o 10perf-y += perf-record.o
11perf-y += rdpmc.o 11perf-y += rdpmc.o
@@ -34,7 +34,7 @@ perf-y += kmod-path.o
34 34
35perf-$(CONFIG_X86) += perf-time-to-tsc.o 35perf-$(CONFIG_X86) += perf-time-to-tsc.o
36 36
37ifeq ($(ARCH),$(filter $(ARCH),x86 arm)) 37ifeq ($(ARCH),$(filter $(ARCH),x86 arm arm64))
38perf-$(CONFIG_DWARF_UNWIND) += dwarf-unwind.o 38perf-$(CONFIG_DWARF_UNWIND) += dwarf-unwind.o
39endif 39endif
40 40
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
index f42af98a5c16..87b9961646e4 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -23,12 +23,12 @@ static struct test {
23 .func = test__vmlinux_matches_kallsyms, 23 .func = test__vmlinux_matches_kallsyms,
24 }, 24 },
25 { 25 {
26 .desc = "detect open syscall event", 26 .desc = "detect openat syscall event",
27 .func = test__open_syscall_event, 27 .func = test__openat_syscall_event,
28 }, 28 },
29 { 29 {
30 .desc = "detect open syscall event on all cpus", 30 .desc = "detect openat syscall event on all cpus",
31 .func = test__open_syscall_event_on_all_cpus, 31 .func = test__openat_syscall_event_on_all_cpus,
32 }, 32 },
33 { 33 {
34 .desc = "read samples using the mmap interface", 34 .desc = "read samples using the mmap interface",
@@ -73,8 +73,8 @@ static struct test {
73 .func = test__perf_evsel__tp_sched_test, 73 .func = test__perf_evsel__tp_sched_test,
74 }, 74 },
75 { 75 {
76 .desc = "Generate and check syscalls:sys_enter_open event fields", 76 .desc = "Generate and check syscalls:sys_enter_openat event fields",
77 .func = test__syscall_open_tp_fields, 77 .func = test__syscall_openat_tp_fields,
78 }, 78 },
79 { 79 {
80 .desc = "struct perf_event_attr setup", 80 .desc = "struct perf_event_attr setup",
@@ -126,7 +126,7 @@ static struct test {
126 .desc = "Test parsing with no sample_id_all bit set", 126 .desc = "Test parsing with no sample_id_all bit set",
127 .func = test__parse_no_sample_id_all, 127 .func = test__parse_no_sample_id_all,
128 }, 128 },
129#if defined(__x86_64__) || defined(__i386__) || defined(__arm__) 129#if defined(__x86_64__) || defined(__i386__) || defined(__arm__) || defined(__aarch64__)
130#ifdef HAVE_DWARF_UNWIND_SUPPORT 130#ifdef HAVE_DWARF_UNWIND_SUPPORT
131 { 131 {
132 .desc = "Test dwarf unwind", 132 .desc = "Test dwarf unwind",
diff --git a/tools/perf/tests/hists_common.c b/tools/perf/tests/hists_common.c
index 456f884eb27b..915f60af6a0e 100644
--- a/tools/perf/tests/hists_common.c
+++ b/tools/perf/tests/hists_common.c
@@ -121,8 +121,7 @@ struct machine *setup_fake_machine(struct machines *machines)
121 size_t k; 121 size_t k;
122 struct dso *dso; 122 struct dso *dso;
123 123
124 dso = __dsos__findnew(&machine->user_dsos, 124 dso = machine__findnew_dso(machine, fake_symbols[i].dso_name);
125 fake_symbols[i].dso_name);
126 if (dso == NULL) 125 if (dso == NULL)
127 goto out; 126 goto out;
128 127
diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c
index 9b9622a33932..5855cf471210 100644
--- a/tools/perf/tests/mmap-basic.c
+++ b/tools/perf/tests/mmap-basic.c
@@ -23,10 +23,8 @@ int test__basic_mmap(void)
23 struct cpu_map *cpus; 23 struct cpu_map *cpus;
24 struct perf_evlist *evlist; 24 struct perf_evlist *evlist;
25 cpu_set_t cpu_set; 25 cpu_set_t cpu_set;
26 const char *syscall_names[] = { "getsid", "getppid", "getpgrp", 26 const char *syscall_names[] = { "getsid", "getppid", "getpgid", };
27 "getpgid", }; 27 pid_t (*syscalls[])(void) = { (void *)getsid, getppid, (void*)getpgid };
28 pid_t (*syscalls[])(void) = { (void *)getsid, getppid, getpgrp,
29 (void*)getpgid };
30#define nsyscalls ARRAY_SIZE(syscall_names) 28#define nsyscalls ARRAY_SIZE(syscall_names)
31 unsigned int nr_events[nsyscalls], 29 unsigned int nr_events[nsyscalls],
32 expected_nr_events[nsyscalls], i, j; 30 expected_nr_events[nsyscalls], i, j;
diff --git a/tools/perf/tests/open-syscall-all-cpus.c b/tools/perf/tests/openat-syscall-all-cpus.c
index 3ec885c48f8f..e34dfdf96b5a 100644
--- a/tools/perf/tests/open-syscall-all-cpus.c
+++ b/tools/perf/tests/openat-syscall-all-cpus.c
@@ -4,12 +4,12 @@
4#include "cpumap.h" 4#include "cpumap.h"
5#include "debug.h" 5#include "debug.h"
6 6
7int test__open_syscall_event_on_all_cpus(void) 7int test__openat_syscall_event_on_all_cpus(void)
8{ 8{
9 int err = -1, fd, cpu; 9 int err = -1, fd, cpu;
10 struct cpu_map *cpus; 10 struct cpu_map *cpus;
11 struct perf_evsel *evsel; 11 struct perf_evsel *evsel;
12 unsigned int nr_open_calls = 111, i; 12 unsigned int nr_openat_calls = 111, i;
13 cpu_set_t cpu_set; 13 cpu_set_t cpu_set;
14 struct thread_map *threads = thread_map__new(-1, getpid(), UINT_MAX); 14 struct thread_map *threads = thread_map__new(-1, getpid(), UINT_MAX);
15 char sbuf[STRERR_BUFSIZE]; 15 char sbuf[STRERR_BUFSIZE];
@@ -27,7 +27,7 @@ int test__open_syscall_event_on_all_cpus(void)
27 27
28 CPU_ZERO(&cpu_set); 28 CPU_ZERO(&cpu_set);
29 29
30 evsel = perf_evsel__newtp("syscalls", "sys_enter_open"); 30 evsel = perf_evsel__newtp("syscalls", "sys_enter_openat");
31 if (evsel == NULL) { 31 if (evsel == NULL) {
32 if (tracefs_configured()) 32 if (tracefs_configured())
33 pr_debug("is tracefs mounted on /sys/kernel/tracing?\n"); 33 pr_debug("is tracefs mounted on /sys/kernel/tracing?\n");
@@ -46,7 +46,7 @@ int test__open_syscall_event_on_all_cpus(void)
46 } 46 }
47 47
48 for (cpu = 0; cpu < cpus->nr; ++cpu) { 48 for (cpu = 0; cpu < cpus->nr; ++cpu) {
49 unsigned int ncalls = nr_open_calls + cpu; 49 unsigned int ncalls = nr_openat_calls + cpu;
50 /* 50 /*
51 * XXX eventually lift this restriction in a way that 51 * XXX eventually lift this restriction in a way that
52 * keeps perf building on older glibc installations 52 * keeps perf building on older glibc installations
@@ -66,7 +66,7 @@ int test__open_syscall_event_on_all_cpus(void)
66 goto out_close_fd; 66 goto out_close_fd;
67 } 67 }
68 for (i = 0; i < ncalls; ++i) { 68 for (i = 0; i < ncalls; ++i) {
69 fd = open("/etc/passwd", O_RDONLY); 69 fd = openat(0, "/etc/passwd", O_RDONLY);
70 close(fd); 70 close(fd);
71 } 71 }
72 CPU_CLR(cpus->map[cpu], &cpu_set); 72 CPU_CLR(cpus->map[cpu], &cpu_set);
@@ -96,7 +96,7 @@ int test__open_syscall_event_on_all_cpus(void)
96 break; 96 break;
97 } 97 }
98 98
99 expected = nr_open_calls + cpu; 99 expected = nr_openat_calls + cpu;
100 if (evsel->counts->cpu[cpu].val != expected) { 100 if (evsel->counts->cpu[cpu].val != expected) {
101 pr_debug("perf_evsel__read_on_cpu: expected to intercept %d calls on cpu %d, got %" PRIu64 "\n", 101 pr_debug("perf_evsel__read_on_cpu: expected to intercept %d calls on cpu %d, got %" PRIu64 "\n",
102 expected, cpus->map[cpu], evsel->counts->cpu[cpu].val); 102 expected, cpus->map[cpu], evsel->counts->cpu[cpu].val);
diff --git a/tools/perf/tests/open-syscall-tp-fields.c b/tools/perf/tests/openat-syscall-tp-fields.c
index 127dcae0b760..6245221479d7 100644
--- a/tools/perf/tests/open-syscall-tp-fields.c
+++ b/tools/perf/tests/openat-syscall-tp-fields.c
@@ -5,7 +5,7 @@
5#include "tests.h" 5#include "tests.h"
6#include "debug.h" 6#include "debug.h"
7 7
8int test__syscall_open_tp_fields(void) 8int test__syscall_openat_tp_fields(void)
9{ 9{
10 struct record_opts opts = { 10 struct record_opts opts = {
11 .target = { 11 .target = {
@@ -29,7 +29,7 @@ int test__syscall_open_tp_fields(void)
29 goto out; 29 goto out;
30 } 30 }
31 31
32 evsel = perf_evsel__newtp("syscalls", "sys_enter_open"); 32 evsel = perf_evsel__newtp("syscalls", "sys_enter_openat");
33 if (evsel == NULL) { 33 if (evsel == NULL) {
34 pr_debug("%s: perf_evsel__newtp\n", __func__); 34 pr_debug("%s: perf_evsel__newtp\n", __func__);
35 goto out_delete_evlist; 35 goto out_delete_evlist;
@@ -66,7 +66,7 @@ int test__syscall_open_tp_fields(void)
66 /* 66 /*
67 * Generate the event: 67 * Generate the event:
68 */ 68 */
69 open(filename, flags); 69 openat(AT_FDCWD, filename, flags);
70 70
71 while (1) { 71 while (1) {
72 int before = nr_events; 72 int before = nr_events;
diff --git a/tools/perf/tests/open-syscall.c b/tools/perf/tests/openat-syscall.c
index 07aa319bf334..9f9491bb8e48 100644
--- a/tools/perf/tests/open-syscall.c
+++ b/tools/perf/tests/openat-syscall.c
@@ -3,11 +3,11 @@
3#include "debug.h" 3#include "debug.h"
4#include "tests.h" 4#include "tests.h"
5 5
6int test__open_syscall_event(void) 6int test__openat_syscall_event(void)
7{ 7{
8 int err = -1, fd; 8 int err = -1, fd;
9 struct perf_evsel *evsel; 9 struct perf_evsel *evsel;
10 unsigned int nr_open_calls = 111, i; 10 unsigned int nr_openat_calls = 111, i;
11 struct thread_map *threads = thread_map__new(-1, getpid(), UINT_MAX); 11 struct thread_map *threads = thread_map__new(-1, getpid(), UINT_MAX);
12 char sbuf[STRERR_BUFSIZE]; 12 char sbuf[STRERR_BUFSIZE];
13 13
@@ -16,7 +16,7 @@ int test__open_syscall_event(void)
16 return -1; 16 return -1;
17 } 17 }
18 18
19 evsel = perf_evsel__newtp("syscalls", "sys_enter_open"); 19 evsel = perf_evsel__newtp("syscalls", "sys_enter_openat");
20 if (evsel == NULL) { 20 if (evsel == NULL) {
21 if (tracefs_configured()) 21 if (tracefs_configured())
22 pr_debug("is tracefs mounted on /sys/kernel/tracing?\n"); 22 pr_debug("is tracefs mounted on /sys/kernel/tracing?\n");
@@ -34,8 +34,8 @@ int test__open_syscall_event(void)
34 goto out_evsel_delete; 34 goto out_evsel_delete;
35 } 35 }
36 36
37 for (i = 0; i < nr_open_calls; ++i) { 37 for (i = 0; i < nr_openat_calls; ++i) {
38 fd = open("/etc/passwd", O_RDONLY); 38 fd = openat(0, "/etc/passwd", O_RDONLY);
39 close(fd); 39 close(fd);
40 } 40 }
41 41
@@ -44,9 +44,9 @@ int test__open_syscall_event(void)
44 goto out_close_fd; 44 goto out_close_fd;
45 } 45 }
46 46
47 if (evsel->counts->cpu[0].val != nr_open_calls) { 47 if (evsel->counts->cpu[0].val != nr_openat_calls) {
48 pr_debug("perf_evsel__read_on_cpu: expected to intercept %d calls, got %" PRIu64 "\n", 48 pr_debug("perf_evsel__read_on_cpu: expected to intercept %d calls, got %" PRIu64 "\n",
49 nr_open_calls, evsel->counts->cpu[0].val); 49 nr_openat_calls, evsel->counts->cpu[0].val);
50 goto out_close_fd; 50 goto out_close_fd;
51 } 51 }
52 52
diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c
index 82d2a1636f7f..d76963f7ad3d 100644
--- a/tools/perf/tests/parse-events.c
+++ b/tools/perf/tests/parse-events.c
@@ -427,7 +427,7 @@ static int test__checkevent_list(struct perf_evlist *evlist)
427 TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); 427 TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv);
428 TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); 428 TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
429 429
430 /* syscalls:sys_enter_open:k */ 430 /* syscalls:sys_enter_openat:k */
431 evsel = perf_evsel__next(evsel); 431 evsel = perf_evsel__next(evsel);
432 TEST_ASSERT_VAL("wrong type", PERF_TYPE_TRACEPOINT == evsel->attr.type); 432 TEST_ASSERT_VAL("wrong type", PERF_TYPE_TRACEPOINT == evsel->attr.type);
433 TEST_ASSERT_VAL("wrong sample_type", 433 TEST_ASSERT_VAL("wrong sample_type",
@@ -665,7 +665,7 @@ static int test__group3(struct perf_evlist *evlist __maybe_unused)
665 TEST_ASSERT_VAL("wrong number of entries", 5 == evlist->nr_entries); 665 TEST_ASSERT_VAL("wrong number of entries", 5 == evlist->nr_entries);
666 TEST_ASSERT_VAL("wrong number of groups", 2 == evlist->nr_groups); 666 TEST_ASSERT_VAL("wrong number of groups", 2 == evlist->nr_groups);
667 667
668 /* group1 syscalls:sys_enter_open:H */ 668 /* group1 syscalls:sys_enter_openat:H */
669 evsel = leader = perf_evlist__first(evlist); 669 evsel = leader = perf_evlist__first(evlist);
670 TEST_ASSERT_VAL("wrong type", PERF_TYPE_TRACEPOINT == evsel->attr.type); 670 TEST_ASSERT_VAL("wrong type", PERF_TYPE_TRACEPOINT == evsel->attr.type);
671 TEST_ASSERT_VAL("wrong sample_type", 671 TEST_ASSERT_VAL("wrong sample_type",
@@ -1293,7 +1293,7 @@ struct evlist_test {
1293 1293
1294static struct evlist_test test__events[] = { 1294static struct evlist_test test__events[] = {
1295 { 1295 {
1296 .name = "syscalls:sys_enter_open", 1296 .name = "syscalls:sys_enter_openat",
1297 .check = test__checkevent_tracepoint, 1297 .check = test__checkevent_tracepoint,
1298 .id = 0, 1298 .id = 0,
1299 }, 1299 },
@@ -1353,7 +1353,7 @@ static struct evlist_test test__events[] = {
1353 .id = 11, 1353 .id = 11,
1354 }, 1354 },
1355 { 1355 {
1356 .name = "syscalls:sys_enter_open:k", 1356 .name = "syscalls:sys_enter_openat:k",
1357 .check = test__checkevent_tracepoint_modifier, 1357 .check = test__checkevent_tracepoint_modifier,
1358 .id = 12, 1358 .id = 12,
1359 }, 1359 },
@@ -1408,7 +1408,7 @@ static struct evlist_test test__events[] = {
1408 .id = 22, 1408 .id = 22,
1409 }, 1409 },
1410 { 1410 {
1411 .name = "r1,syscalls:sys_enter_open:k,1:1:hp", 1411 .name = "r1,syscalls:sys_enter_openat:k,1:1:hp",
1412 .check = test__checkevent_list, 1412 .check = test__checkevent_list,
1413 .id = 23, 1413 .id = 23,
1414 }, 1414 },
@@ -1443,7 +1443,7 @@ static struct evlist_test test__events[] = {
1443 .id = 29, 1443 .id = 29,
1444 }, 1444 },
1445 { 1445 {
1446 .name = "group1{syscalls:sys_enter_open:H,cycles:kppp},group2{cycles,1:3}:G,instructions:u", 1446 .name = "group1{syscalls:sys_enter_openat:H,cycles:kppp},group2{cycles,1:3}:G,instructions:u",
1447 .check = test__group3, 1447 .check = test__group3,
1448 .id = 30, 1448 .id = 30,
1449 }, 1449 },
diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h
index a10eaf5c4767..8e5038b48ba8 100644
--- a/tools/perf/tests/tests.h
+++ b/tools/perf/tests/tests.h
@@ -26,14 +26,14 @@ enum {
26 26
27/* Tests */ 27/* Tests */
28int test__vmlinux_matches_kallsyms(void); 28int test__vmlinux_matches_kallsyms(void);
29int test__open_syscall_event(void); 29int test__openat_syscall_event(void);
30int test__open_syscall_event_on_all_cpus(void); 30int test__openat_syscall_event_on_all_cpus(void);
31int test__basic_mmap(void); 31int test__basic_mmap(void);
32int test__PERF_RECORD(void); 32int test__PERF_RECORD(void);
33int test__rdpmc(void); 33int test__rdpmc(void);
34int test__perf_evsel__roundtrip_name_test(void); 34int test__perf_evsel__roundtrip_name_test(void);
35int test__perf_evsel__tp_sched_test(void); 35int test__perf_evsel__tp_sched_test(void);
36int test__syscall_open_tp_fields(void); 36int test__syscall_openat_tp_fields(void);
37int test__pmu(void); 37int test__pmu(void);
38int test__attr(void); 38int test__attr(void);
39int test__dso_data(void); 39int test__dso_data(void);
@@ -62,7 +62,7 @@ int test__fdarray__filter(void);
62int test__fdarray__add(void); 62int test__fdarray__add(void);
63int test__kmod_path__parse(void); 63int test__kmod_path__parse(void);
64 64
65#if defined(__x86_64__) || defined(__i386__) || defined(__arm__) 65#if defined(__x86_64__) || defined(__i386__) || defined(__arm__) || defined(__aarch64__)
66#ifdef HAVE_DWARF_UNWIND_SUPPORT 66#ifdef HAVE_DWARF_UNWIND_SUPPORT
67struct thread; 67struct thread;
68struct perf_sample; 68struct perf_sample;
diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c
index e5250eb2dd57..acb0e23b138e 100644
--- a/tools/perf/ui/browsers/annotate.c
+++ b/tools/perf/ui/browsers/annotate.c
@@ -838,6 +838,10 @@ int map_symbol__tui_annotate(struct map_symbol *ms, struct perf_evsel *evsel,
838int hist_entry__tui_annotate(struct hist_entry *he, struct perf_evsel *evsel, 838int hist_entry__tui_annotate(struct hist_entry *he, struct perf_evsel *evsel,
839 struct hist_browser_timer *hbt) 839 struct hist_browser_timer *hbt)
840{ 840{
841 /* reset abort key so that it can get Ctrl-C as a key */
842 SLang_reset_tty();
843 SLang_init_tty(0, 0, 0);
844
841 return map_symbol__tui_annotate(&he->ms, evsel, hbt); 845 return map_symbol__tui_annotate(&he->ms, evsel, hbt);
842} 846}
843 847
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index f981cb8f0158..e64893f2fd7f 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -1741,6 +1741,10 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
1741 if (browser == NULL) 1741 if (browser == NULL)
1742 return -1; 1742 return -1;
1743 1743
1744 /* reset abort key so that it can get Ctrl-C as a key */
1745 SLang_reset_tty();
1746 SLang_init_tty(0, 0, 0);
1747
1744 if (min_pcnt) { 1748 if (min_pcnt) {
1745 browser->min_pcnt = min_pcnt; 1749 browser->min_pcnt = min_pcnt;
1746 hist_browser__update_nr_entries(browser); 1750 hist_browser__update_nr_entries(browser);
diff --git a/tools/perf/ui/tui/setup.c b/tools/perf/ui/tui/setup.c
index b77e1d771363..60d1f29b4b50 100644
--- a/tools/perf/ui/tui/setup.c
+++ b/tools/perf/ui/tui/setup.c
@@ -129,7 +129,7 @@ int ui__init(void)
129 err = SLsmg_init_smg(); 129 err = SLsmg_init_smg();
130 if (err < 0) 130 if (err < 0)
131 goto out; 131 goto out;
132 err = SLang_init_tty(0, 0, 0); 132 err = SLang_init_tty(-1, 0, 0);
133 if (err < 0) 133 if (err < 0)
134 goto out; 134 goto out;
135 135
diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c
index ad8cfcbaa25d..1f6fc2323ef9 100644
--- a/tools/perf/util/build-id.c
+++ b/tools/perf/util/build-id.c
@@ -162,15 +162,20 @@ static int write_buildid(const char *name, size_t name_len, u8 *build_id,
162 return write_padded(fd, name, name_len + 1, len); 162 return write_padded(fd, name, name_len + 1, len);
163} 163}
164 164
165static int __dsos__write_buildid_table(struct list_head *head, 165static int machine__write_buildid_table(struct machine *machine, int fd)
166 struct machine *machine,
167 pid_t pid, u16 misc, int fd)
168{ 166{
167 int err = 0;
169 char nm[PATH_MAX]; 168 char nm[PATH_MAX];
170 struct dso *pos; 169 struct dso *pos;
170 u16 kmisc = PERF_RECORD_MISC_KERNEL,
171 umisc = PERF_RECORD_MISC_USER;
172
173 if (!machine__is_host(machine)) {
174 kmisc = PERF_RECORD_MISC_GUEST_KERNEL;
175 umisc = PERF_RECORD_MISC_GUEST_USER;
176 }
171 177
172 dsos__for_each_with_build_id(pos, head) { 178 dsos__for_each_with_build_id(pos, &machine->dsos.head) {
173 int err;
174 const char *name; 179 const char *name;
175 size_t name_len; 180 size_t name_len;
176 181
@@ -189,32 +194,12 @@ static int __dsos__write_buildid_table(struct list_head *head,
189 name_len = pos->long_name_len + 1; 194 name_len = pos->long_name_len + 1;
190 } 195 }
191 196
192 err = write_buildid(name, name_len, pos->build_id, 197 err = write_buildid(name, name_len, pos->build_id, machine->pid,
193 pid, misc, fd); 198 pos->kernel ? kmisc : umisc, fd);
194 if (err) 199 if (err)
195 return err; 200 break;
196 }
197
198 return 0;
199}
200
201static int machine__write_buildid_table(struct machine *machine, int fd)
202{
203 int err;
204 u16 kmisc = PERF_RECORD_MISC_KERNEL,
205 umisc = PERF_RECORD_MISC_USER;
206
207 if (!machine__is_host(machine)) {
208 kmisc = PERF_RECORD_MISC_GUEST_KERNEL;
209 umisc = PERF_RECORD_MISC_GUEST_USER;
210 } 201 }
211 202
212 err = __dsos__write_buildid_table(&machine->kernel_dsos.head, machine,
213 machine->pid, kmisc, fd);
214 if (err == 0)
215 err = __dsos__write_buildid_table(&machine->user_dsos.head,
216 machine, machine->pid, umisc,
217 fd);
218 return err; 203 return err;
219} 204}
220 205
@@ -247,13 +232,7 @@ static int __dsos__hit_all(struct list_head *head)
247 232
248static int machine__hit_all_dsos(struct machine *machine) 233static int machine__hit_all_dsos(struct machine *machine)
249{ 234{
250 int err; 235 return __dsos__hit_all(&machine->dsos.head);
251
252 err = __dsos__hit_all(&machine->kernel_dsos.head);
253 if (err)
254 return err;
255
256 return __dsos__hit_all(&machine->user_dsos.head);
257} 236}
258 237
259int dsos__hit_all(struct perf_session *session) 238int dsos__hit_all(struct perf_session *session)
@@ -493,9 +472,7 @@ static int __dsos__cache_build_ids(struct list_head *head,
493 472
494static int machine__cache_build_ids(struct machine *machine) 473static int machine__cache_build_ids(struct machine *machine)
495{ 474{
496 int ret = __dsos__cache_build_ids(&machine->kernel_dsos.head, machine); 475 return __dsos__cache_build_ids(&machine->dsos.head, machine);
497 ret |= __dsos__cache_build_ids(&machine->user_dsos.head, machine);
498 return ret;
499} 476}
500 477
501int perf_session__cache_build_ids(struct perf_session *session) 478int perf_session__cache_build_ids(struct perf_session *session)
@@ -520,11 +497,7 @@ int perf_session__cache_build_ids(struct perf_session *session)
520 497
521static bool machine__read_build_ids(struct machine *machine, bool with_hits) 498static bool machine__read_build_ids(struct machine *machine, bool with_hits)
522{ 499{
523 bool ret; 500 return __dsos__read_build_ids(&machine->dsos.head, with_hits);
524
525 ret = __dsos__read_build_ids(&machine->kernel_dsos.head, with_hits);
526 ret |= __dsos__read_build_ids(&machine->user_dsos.head, with_hits);
527 return ret;
528} 501}
529 502
530bool perf_session__read_build_ids(struct perf_session *session, bool with_hits) 503bool perf_session__read_build_ids(struct perf_session *session, bool with_hits)
diff --git a/tools/perf/util/db-export.c b/tools/perf/util/db-export.c
index eb7a2acb973b..1c9689e4cc17 100644
--- a/tools/perf/util/db-export.c
+++ b/tools/perf/util/db-export.c
@@ -234,7 +234,7 @@ int db_export__symbol(struct db_export *dbe, struct symbol *sym,
234static struct thread *get_main_thread(struct machine *machine, struct thread *thread) 234static struct thread *get_main_thread(struct machine *machine, struct thread *thread)
235{ 235{
236 if (thread->pid_ == thread->tid) 236 if (thread->pid_ == thread->tid)
237 return thread; 237 return thread__get(thread);
238 238
239 if (thread->pid_ == -1) 239 if (thread->pid_ == -1)
240 return NULL; 240 return NULL;
@@ -308,19 +308,18 @@ int db_export__sample(struct db_export *dbe, union perf_event *event,
308 if (err) 308 if (err)
309 return err; 309 return err;
310 310
311 /* FIXME: check refcounting for get_main_thread, that calls machine__find_thread... */
312 main_thread = get_main_thread(al->machine, thread); 311 main_thread = get_main_thread(al->machine, thread);
313 if (main_thread) 312 if (main_thread)
314 comm = machine__thread_exec_comm(al->machine, main_thread); 313 comm = machine__thread_exec_comm(al->machine, main_thread);
315 314
316 err = db_export__thread(dbe, thread, al->machine, comm); 315 err = db_export__thread(dbe, thread, al->machine, comm);
317 if (err) 316 if (err)
318 return err; 317 goto out_put;
319 318
320 if (comm) { 319 if (comm) {
321 err = db_export__comm(dbe, comm, main_thread); 320 err = db_export__comm(dbe, comm, main_thread);
322 if (err) 321 if (err)
323 return err; 322 goto out_put;
324 es.comm_db_id = comm->db_id; 323 es.comm_db_id = comm->db_id;
325 } 324 }
326 325
@@ -328,7 +327,7 @@ int db_export__sample(struct db_export *dbe, union perf_event *event,
328 327
329 err = db_ids_from_al(dbe, al, &es.dso_db_id, &es.sym_db_id, &es.offset); 328 err = db_ids_from_al(dbe, al, &es.dso_db_id, &es.sym_db_id, &es.offset);
330 if (err) 329 if (err)
331 return err; 330 goto out_put;
332 331
333 if ((evsel->attr.sample_type & PERF_SAMPLE_ADDR) && 332 if ((evsel->attr.sample_type & PERF_SAMPLE_ADDR) &&
334 sample_addr_correlates_sym(&evsel->attr)) { 333 sample_addr_correlates_sym(&evsel->attr)) {
@@ -338,20 +337,22 @@ int db_export__sample(struct db_export *dbe, union perf_event *event,
338 err = db_ids_from_al(dbe, &addr_al, &es.addr_dso_db_id, 337 err = db_ids_from_al(dbe, &addr_al, &es.addr_dso_db_id,
339 &es.addr_sym_db_id, &es.addr_offset); 338 &es.addr_sym_db_id, &es.addr_offset);
340 if (err) 339 if (err)
341 return err; 340 goto out_put;
342 if (dbe->crp) { 341 if (dbe->crp) {
343 err = thread_stack__process(thread, comm, sample, al, 342 err = thread_stack__process(thread, comm, sample, al,
344 &addr_al, es.db_id, 343 &addr_al, es.db_id,
345 dbe->crp); 344 dbe->crp);
346 if (err) 345 if (err)
347 return err; 346 goto out_put;
348 } 347 }
349 } 348 }
350 349
351 if (dbe->export_sample) 350 if (dbe->export_sample)
352 return dbe->export_sample(dbe, &es); 351 err = dbe->export_sample(dbe, &es);
353 352
354 return 0; 353out_put:
354 thread__put(main_thread);
355 return err;
355} 356}
356 357
357static struct { 358static struct {
diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c
index 7e11a700303f..b335db3532a2 100644
--- a/tools/perf/util/dso.c
+++ b/tools/perf/util/dso.c
@@ -827,13 +827,13 @@ struct map *dso__new_map(const char *name)
827 return map; 827 return map;
828} 828}
829 829
830struct dso *dso__kernel_findnew(struct machine *machine, const char *name, 830struct dso *machine__findnew_kernel(struct machine *machine, const char *name,
831 const char *short_name, int dso_type) 831 const char *short_name, int dso_type)
832{ 832{
833 /* 833 /*
834 * The kernel dso could be created by build_id processing. 834 * The kernel dso could be created by build_id processing.
835 */ 835 */
836 struct dso *dso = __dsos__findnew(&machine->kernel_dsos, name); 836 struct dso *dso = machine__findnew_dso(machine, name);
837 837
838 /* 838 /*
839 * We need to run this in all cases, since during the build_id 839 * We need to run this in all cases, since during the build_id
diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h
index bcec06ad73a2..24a507a54147 100644
--- a/tools/perf/util/dso.h
+++ b/tools/perf/util/dso.h
@@ -294,8 +294,8 @@ ssize_t dso__data_read_addr(struct dso *dso, struct map *map,
294bool dso__data_status_seen(struct dso *dso, enum dso_data_status_seen by); 294bool dso__data_status_seen(struct dso *dso, enum dso_data_status_seen by);
295 295
296struct map *dso__new_map(const char *name); 296struct map *dso__new_map(const char *name);
297struct dso *dso__kernel_findnew(struct machine *machine, const char *name, 297struct dso *machine__findnew_kernel(struct machine *machine, const char *name,
298 const char *short_name, int dso_type); 298 const char *short_name, int dso_type);
299 299
300void dsos__add(struct dsos *dsos, struct dso *dso); 300void dsos__add(struct dsos *dsos, struct dso *dso);
301struct dso *dsos__addnew(struct dsos *dsos, const char *name); 301struct dso *dsos__addnew(struct dsos *dsos, const char *name);
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 3f0d809d853a..851143a7988d 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -1238,7 +1238,6 @@ static int __event_process_build_id(struct build_id_event *bev,
1238 struct perf_session *session) 1238 struct perf_session *session)
1239{ 1239{
1240 int err = -1; 1240 int err = -1;
1241 struct dsos *dsos;
1242 struct machine *machine; 1241 struct machine *machine;
1243 u16 misc; 1242 u16 misc;
1244 struct dso *dso; 1243 struct dso *dso;
@@ -1253,22 +1252,19 @@ static int __event_process_build_id(struct build_id_event *bev,
1253 switch (misc) { 1252 switch (misc) {
1254 case PERF_RECORD_MISC_KERNEL: 1253 case PERF_RECORD_MISC_KERNEL:
1255 dso_type = DSO_TYPE_KERNEL; 1254 dso_type = DSO_TYPE_KERNEL;
1256 dsos = &machine->kernel_dsos;
1257 break; 1255 break;
1258 case PERF_RECORD_MISC_GUEST_KERNEL: 1256 case PERF_RECORD_MISC_GUEST_KERNEL:
1259 dso_type = DSO_TYPE_GUEST_KERNEL; 1257 dso_type = DSO_TYPE_GUEST_KERNEL;
1260 dsos = &machine->kernel_dsos;
1261 break; 1258 break;
1262 case PERF_RECORD_MISC_USER: 1259 case PERF_RECORD_MISC_USER:
1263 case PERF_RECORD_MISC_GUEST_USER: 1260 case PERF_RECORD_MISC_GUEST_USER:
1264 dso_type = DSO_TYPE_USER; 1261 dso_type = DSO_TYPE_USER;
1265 dsos = &machine->user_dsos;
1266 break; 1262 break;
1267 default: 1263 default:
1268 goto out; 1264 goto out;
1269 } 1265 }
1270 1266
1271 dso = __dsos__findnew(dsos, filename); 1267 dso = machine__findnew_dso(machine, filename);
1272 if (dso != NULL) { 1268 if (dso != NULL) {
1273 char sbuild_id[BUILD_ID_SIZE * 2 + 1]; 1269 char sbuild_id[BUILD_ID_SIZE * 2 + 1];
1274 1270
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 0c0e61cce577..2ed61f59d415 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -26,8 +26,7 @@ int machine__init(struct machine *machine, const char *root_dir, pid_t pid)
26{ 26{
27 map_groups__init(&machine->kmaps, machine); 27 map_groups__init(&machine->kmaps, machine);
28 RB_CLEAR_NODE(&machine->rb_node); 28 RB_CLEAR_NODE(&machine->rb_node);
29 dsos__init(&machine->user_dsos); 29 dsos__init(&machine->dsos);
30 dsos__init(&machine->kernel_dsos);
31 30
32 machine->threads = RB_ROOT; 31 machine->threads = RB_ROOT;
33 pthread_rwlock_init(&machine->threads_lock, NULL); 32 pthread_rwlock_init(&machine->threads_lock, NULL);
@@ -111,9 +110,8 @@ void machine__delete_threads(struct machine *machine)
111void machine__exit(struct machine *machine) 110void machine__exit(struct machine *machine)
112{ 111{
113 map_groups__exit(&machine->kmaps); 112 map_groups__exit(&machine->kmaps);
114 dsos__delete(&machine->user_dsos); 113 dsos__delete(&machine->dsos);
115 dsos__delete(&machine->kernel_dsos); 114 machine__exit_vdso(machine);
116 vdso__exit(machine);
117 zfree(&machine->root_dir); 115 zfree(&machine->root_dir);
118 zfree(&machine->current_tid); 116 zfree(&machine->current_tid);
119 pthread_rwlock_destroy(&machine->threads_lock); 117 pthread_rwlock_destroy(&machine->threads_lock);
@@ -490,9 +488,9 @@ machine__module_dso(struct machine *machine, struct kmod_path *m,
490{ 488{
491 struct dso *dso; 489 struct dso *dso;
492 490
493 dso = dsos__find(&machine->kernel_dsos, m->name, true); 491 dso = dsos__find(&machine->dsos, m->name, true);
494 if (!dso) { 492 if (!dso) {
495 dso = dsos__addnew(&machine->kernel_dsos, m->name); 493 dso = dsos__addnew(&machine->dsos, m->name);
496 if (dso == NULL) 494 if (dso == NULL)
497 return NULL; 495 return NULL;
498 496
@@ -561,13 +559,11 @@ out:
561size_t machines__fprintf_dsos(struct machines *machines, FILE *fp) 559size_t machines__fprintf_dsos(struct machines *machines, FILE *fp)
562{ 560{
563 struct rb_node *nd; 561 struct rb_node *nd;
564 size_t ret = __dsos__fprintf(&machines->host.kernel_dsos.head, fp) + 562 size_t ret = __dsos__fprintf(&machines->host.dsos.head, fp);
565 __dsos__fprintf(&machines->host.user_dsos.head, fp);
566 563
567 for (nd = rb_first(&machines->guests); nd; nd = rb_next(nd)) { 564 for (nd = rb_first(&machines->guests); nd; nd = rb_next(nd)) {
568 struct machine *pos = rb_entry(nd, struct machine, rb_node); 565 struct machine *pos = rb_entry(nd, struct machine, rb_node);
569 ret += __dsos__fprintf(&pos->kernel_dsos.head, fp); 566 ret += __dsos__fprintf(&pos->dsos.head, fp);
570 ret += __dsos__fprintf(&pos->user_dsos.head, fp);
571 } 567 }
572 568
573 return ret; 569 return ret;
@@ -576,8 +572,7 @@ size_t machines__fprintf_dsos(struct machines *machines, FILE *fp)
576size_t machine__fprintf_dsos_buildid(struct machine *m, FILE *fp, 572size_t machine__fprintf_dsos_buildid(struct machine *m, FILE *fp,
577 bool (skip)(struct dso *dso, int parm), int parm) 573 bool (skip)(struct dso *dso, int parm), int parm)
578{ 574{
579 return __dsos__fprintf_buildid(&m->kernel_dsos.head, fp, skip, parm) + 575 return __dsos__fprintf_buildid(&m->dsos.head, fp, skip, parm);
580 __dsos__fprintf_buildid(&m->user_dsos.head, fp, skip, parm);
581} 576}
582 577
583size_t machines__fprintf_dsos_buildid(struct machines *machines, FILE *fp, 578size_t machines__fprintf_dsos_buildid(struct machines *machines, FILE *fp,
@@ -640,9 +635,8 @@ static struct dso *machine__get_kernel(struct machine *machine)
640 if (!vmlinux_name) 635 if (!vmlinux_name)
641 vmlinux_name = "[kernel.kallsyms]"; 636 vmlinux_name = "[kernel.kallsyms]";
642 637
643 kernel = dso__kernel_findnew(machine, vmlinux_name, 638 kernel = machine__findnew_kernel(machine, vmlinux_name,
644 "[kernel]", 639 "[kernel]", DSO_TYPE_KERNEL);
645 DSO_TYPE_KERNEL);
646 } else { 640 } else {
647 char bf[PATH_MAX]; 641 char bf[PATH_MAX];
648 642
@@ -652,9 +646,9 @@ static struct dso *machine__get_kernel(struct machine *machine)
652 vmlinux_name = machine__mmap_name(machine, bf, 646 vmlinux_name = machine__mmap_name(machine, bf,
653 sizeof(bf)); 647 sizeof(bf));
654 648
655 kernel = dso__kernel_findnew(machine, vmlinux_name, 649 kernel = machine__findnew_kernel(machine, vmlinux_name,
656 "[guest.kernel]", 650 "[guest.kernel]",
657 DSO_TYPE_GUEST_KERNEL); 651 DSO_TYPE_GUEST_KERNEL);
658 } 652 }
659 653
660 if (kernel != NULL && (!kernel->has_build_id)) 654 if (kernel != NULL && (!kernel->has_build_id))
@@ -1107,7 +1101,7 @@ static bool machine__uses_kcore(struct machine *machine)
1107{ 1101{
1108 struct dso *dso; 1102 struct dso *dso;
1109 1103
1110 list_for_each_entry(dso, &machine->kernel_dsos.head, node) { 1104 list_for_each_entry(dso, &machine->dsos.head, node) {
1111 if (dso__is_kcore(dso)) 1105 if (dso__is_kcore(dso))
1112 return true; 1106 return true;
1113 } 1107 }
@@ -1154,8 +1148,8 @@ static int machine__process_kernel_mmap_event(struct machine *machine,
1154 struct dso *kernel = NULL; 1148 struct dso *kernel = NULL;
1155 struct dso *dso; 1149 struct dso *dso;
1156 1150
1157 list_for_each_entry(dso, &machine->kernel_dsos.head, node) { 1151 list_for_each_entry(dso, &machine->dsos.head, node) {
1158 if (is_kernel_module(dso->long_name)) 1152 if (dso->kernel && is_kernel_module(dso->long_name))
1159 continue; 1153 continue;
1160 1154
1161 kernel = dso; 1155 kernel = dso;
@@ -1163,8 +1157,7 @@ static int machine__process_kernel_mmap_event(struct machine *machine,
1163 } 1157 }
1164 1158
1165 if (kernel == NULL) 1159 if (kernel == NULL)
1166 kernel = __dsos__findnew(&machine->kernel_dsos, 1160 kernel = machine__findnew_dso(machine, kmmap_prefix);
1167 kmmap_prefix);
1168 if (kernel == NULL) 1161 if (kernel == NULL)
1169 goto out_problem; 1162 goto out_problem;
1170 1163
@@ -1922,3 +1915,8 @@ int machine__get_kernel_start(struct machine *machine)
1922 } 1915 }
1923 return err; 1916 return err;
1924} 1917}
1918
1919struct dso *machine__findnew_dso(struct machine *machine, const char *filename)
1920{
1921 return __dsos__findnew(&machine->dsos, filename);
1922}
diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h
index c7963c63c474..39a0ca06cbd8 100644
--- a/tools/perf/util/machine.h
+++ b/tools/perf/util/machine.h
@@ -34,8 +34,7 @@ struct machine {
34 struct list_head dead_threads; 34 struct list_head dead_threads;
35 struct thread *last_match; 35 struct thread *last_match;
36 struct vdso_info *vdso_info; 36 struct vdso_info *vdso_info;
37 struct dsos user_dsos; 37 struct dsos dsos;
38 struct dsos kernel_dsos;
39 struct map_groups kmaps; 38 struct map_groups kmaps;
40 struct map *vmlinux_maps[MAP__NR_TYPES]; 39 struct map *vmlinux_maps[MAP__NR_TYPES];
41 u64 kernel_start; 40 u64 kernel_start;
@@ -155,6 +154,8 @@ static inline bool machine__is_host(struct machine *machine)
155struct thread *__machine__findnew_thread(struct machine *machine, pid_t pid, pid_t tid); 154struct thread *__machine__findnew_thread(struct machine *machine, pid_t pid, pid_t tid);
156struct thread *machine__findnew_thread(struct machine *machine, pid_t pid, pid_t tid); 155struct thread *machine__findnew_thread(struct machine *machine, pid_t pid, pid_t tid);
157 156
157struct dso *machine__findnew_dso(struct machine *machine, const char *filename);
158
158size_t machine__fprintf(struct machine *machine, FILE *fp); 159size_t machine__fprintf(struct machine *machine, FILE *fp);
159 160
160static inline 161static inline
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
index af572322586d..365011c233a6 100644
--- a/tools/perf/util/map.c
+++ b/tools/perf/util/map.c
@@ -178,9 +178,9 @@ struct map *map__new(struct machine *machine, u64 start, u64 len,
178 178
179 if (vdso) { 179 if (vdso) {
180 pgoff = 0; 180 pgoff = 0;
181 dso = vdso__dso_findnew(machine, thread); 181 dso = machine__findnew_vdso(machine, thread);
182 } else 182 } else
183 dso = __dsos__findnew(&machine->user_dsos, filename); 183 dso = machine__findnew_dso(machine, filename);
184 184
185 if (dso == NULL) 185 if (dso == NULL)
186 goto out_delete; 186 goto out_delete;
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index b0b8a8080009..d27edef5eb5b 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -200,38 +200,6 @@ static void put_target_map(struct map *map, bool user)
200} 200}
201 201
202 202
203static int kernel_get_module_dso(const char *module, struct dso **pdso)
204{
205 struct dso *dso;
206 struct map *map;
207 const char *vmlinux_name;
208 int ret = 0;
209
210 if (module) {
211 list_for_each_entry(dso, &host_machine->kernel_dsos.head,
212 node) {
213 if (strncmp(dso->short_name + 1, module,
214 dso->short_name_len - 2) == 0)
215 goto found;
216 }
217 pr_debug("Failed to find module %s.\n", module);
218 return -ENOENT;
219 }
220
221 map = host_machine->vmlinux_maps[MAP__FUNCTION];
222 dso = map->dso;
223
224 vmlinux_name = symbol_conf.vmlinux_name;
225 dso->load_errno = 0;
226 if (vmlinux_name)
227 ret = dso__load_vmlinux(dso, map, vmlinux_name, false, NULL);
228 else
229 ret = dso__load_vmlinux_path(dso, map, NULL);
230found:
231 *pdso = dso;
232 return ret;
233}
234
235static int convert_exec_to_group(const char *exec, char **result) 203static int convert_exec_to_group(const char *exec, char **result)
236{ 204{
237 char *ptr1, *ptr2, *exec_copy; 205 char *ptr1, *ptr2, *exec_copy;
@@ -279,6 +247,40 @@ static void clear_probe_trace_events(struct probe_trace_event *tevs, int ntevs)
279} 247}
280 248
281#ifdef HAVE_DWARF_SUPPORT 249#ifdef HAVE_DWARF_SUPPORT
250
251static int kernel_get_module_dso(const char *module, struct dso **pdso)
252{
253 struct dso *dso;
254 struct map *map;
255 const char *vmlinux_name;
256 int ret = 0;
257
258 if (module) {
259 list_for_each_entry(dso, &host_machine->dsos.head, node) {
260 if (!dso->kernel)
261 continue;
262 if (strncmp(dso->short_name + 1, module,
263 dso->short_name_len - 2) == 0)
264 goto found;
265 }
266 pr_debug("Failed to find module %s.\n", module);
267 return -ENOENT;
268 }
269
270 map = host_machine->vmlinux_maps[MAP__FUNCTION];
271 dso = map->dso;
272
273 vmlinux_name = symbol_conf.vmlinux_name;
274 dso->load_errno = 0;
275 if (vmlinux_name)
276 ret = dso__load_vmlinux(dso, map, vmlinux_name, false, NULL);
277 else
278 ret = dso__load_vmlinux_path(dso, map, NULL);
279found:
280 *pdso = dso;
281 return ret;
282}
283
282/* 284/*
283 * Some binaries like glibc have special symbols which are on the symbol 285 * Some binaries like glibc have special symbols which are on the symbol
284 * table, but not in the debuginfo. If we can find the address of the 286 * table, but not in the debuginfo. If we can find the address of the
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
index fa10116a12ab..a93ba85509b2 100644
--- a/tools/perf/util/symbol-elf.c
+++ b/tools/perf/util/symbol-elf.c
@@ -1031,11 +1031,7 @@ int dso__load_sym(struct dso *dso, struct map *map,
1031 } 1031 }
1032 curr_dso->symtab_type = dso->symtab_type; 1032 curr_dso->symtab_type = dso->symtab_type;
1033 map_groups__insert(kmaps, curr_map); 1033 map_groups__insert(kmaps, curr_map);
1034 /* 1034 dsos__add(&map->groups->machine->dsos, curr_dso);
1035 * The new DSO should go to the kernel DSOS
1036 */
1037 dsos__add(&map->groups->machine->kernel_dsos,
1038 curr_dso);
1039 dso__set_loaded(curr_dso, map->type); 1035 dso__set_loaded(curr_dso, map->type);
1040 } else 1036 } else
1041 curr_dso = curr_map->dso; 1037 curr_dso = curr_map->dso;
diff --git a/tools/perf/util/vdso.c b/tools/perf/util/vdso.c
index 5c7dd796979d..2e8f6886ca72 100644
--- a/tools/perf/util/vdso.c
+++ b/tools/perf/util/vdso.c
@@ -101,7 +101,7 @@ static char *get_file(struct vdso_file *vdso_file)
101 return vdso; 101 return vdso;
102} 102}
103 103
104void vdso__exit(struct machine *machine) 104void machine__exit_vdso(struct machine *machine)
105{ 105{
106 struct vdso_info *vdso_info = machine->vdso_info; 106 struct vdso_info *vdso_info = machine->vdso_info;
107 107
@@ -120,14 +120,14 @@ void vdso__exit(struct machine *machine)
120 zfree(&machine->vdso_info); 120 zfree(&machine->vdso_info);
121} 121}
122 122
123static struct dso *vdso__new(struct machine *machine, const char *short_name, 123static struct dso *machine__addnew_vdso(struct machine *machine, const char *short_name,
124 const char *long_name) 124 const char *long_name)
125{ 125{
126 struct dso *dso; 126 struct dso *dso;
127 127
128 dso = dso__new(short_name); 128 dso = dso__new(short_name);
129 if (dso != NULL) { 129 if (dso != NULL) {
130 dsos__add(&machine->user_dsos, dso); 130 dsos__add(&machine->dsos, dso);
131 dso__set_long_name(dso, long_name, false); 131 dso__set_long_name(dso, long_name, false);
132 } 132 }
133 133
@@ -236,7 +236,7 @@ static struct dso *vdso__findnew_compat(struct machine *machine,
236 const char *file_name; 236 const char *file_name;
237 struct dso *dso; 237 struct dso *dso;
238 238
239 dso = dsos__find(&machine->user_dsos, vdso_file->dso_name, true); 239 dso = dsos__find(&machine->dsos, vdso_file->dso_name, true);
240 if (dso) 240 if (dso)
241 return dso; 241 return dso;
242 242
@@ -244,10 +244,10 @@ static struct dso *vdso__findnew_compat(struct machine *machine,
244 if (!file_name) 244 if (!file_name)
245 return NULL; 245 return NULL;
246 246
247 return vdso__new(machine, vdso_file->dso_name, file_name); 247 return machine__addnew_vdso(machine, vdso_file->dso_name, file_name);
248} 248}
249 249
250static int vdso__dso_findnew_compat(struct machine *machine, 250static int machine__findnew_vdso_compat(struct machine *machine,
251 struct thread *thread, 251 struct thread *thread,
252 struct vdso_info *vdso_info, 252 struct vdso_info *vdso_info,
253 struct dso **dso) 253 struct dso **dso)
@@ -281,8 +281,8 @@ static int vdso__dso_findnew_compat(struct machine *machine,
281 281
282#endif 282#endif
283 283
284struct dso *vdso__dso_findnew(struct machine *machine, 284struct dso *machine__findnew_vdso(struct machine *machine,
285 struct thread *thread __maybe_unused) 285 struct thread *thread __maybe_unused)
286{ 286{
287 struct vdso_info *vdso_info; 287 struct vdso_info *vdso_info;
288 struct dso *dso; 288 struct dso *dso;
@@ -295,11 +295,11 @@ struct dso *vdso__dso_findnew(struct machine *machine,
295 return NULL; 295 return NULL;
296 296
297#if BITS_PER_LONG == 64 297#if BITS_PER_LONG == 64
298 if (vdso__dso_findnew_compat(machine, thread, vdso_info, &dso)) 298 if (machine__findnew_vdso_compat(machine, thread, vdso_info, &dso))
299 return dso; 299 return dso;
300#endif 300#endif
301 301
302 dso = dsos__find(&machine->user_dsos, DSO__NAME_VDSO, true); 302 dso = dsos__find(&machine->dsos, DSO__NAME_VDSO, true);
303 if (!dso) { 303 if (!dso) {
304 char *file; 304 char *file;
305 305
@@ -307,7 +307,7 @@ struct dso *vdso__dso_findnew(struct machine *machine,
307 if (!file) 307 if (!file)
308 return NULL; 308 return NULL;
309 309
310 dso = vdso__new(machine, DSO__NAME_VDSO, file); 310 dso = machine__addnew_vdso(machine, DSO__NAME_VDSO, file);
311 } 311 }
312 312
313 return dso; 313 return dso;
diff --git a/tools/perf/util/vdso.h b/tools/perf/util/vdso.h
index d97da1616f0c..cdc4fabfc212 100644
--- a/tools/perf/util/vdso.h
+++ b/tools/perf/util/vdso.h
@@ -23,7 +23,7 @@ bool dso__is_vdso(struct dso *dso);
23struct machine; 23struct machine;
24struct thread; 24struct thread;
25 25
26struct dso *vdso__dso_findnew(struct machine *machine, struct thread *thread); 26struct dso *machine__findnew_vdso(struct machine *machine, struct thread *thread);
27void vdso__exit(struct machine *machine); 27void machine__exit_vdso(struct machine *machine);
28 28
29#endif /* __PERF_VDSO__ */ 29#endif /* __PERF_VDSO__ */