aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2010-04-30 03:58:05 -0400
committerIngo Molnar <mingo@elte.hu>2010-04-30 03:58:05 -0400
commitbc4b473f1aa2ef785ccfd890a24a1de5a6660f98 (patch)
tree77bbea692517ae4723b575631222bf715b4a1eb1 /tools
parent3ca50496c2677a2b3fdd3ede86660fd1433beac6 (diff)
parent1c6a800cde3b818fd8320b5d402f2d77d2948c00 (diff)
Merge branch 'perf' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux-2.6 into perf/core
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/Documentation/perf-test.txt22
-rw-r--r--tools/perf/Makefile3
-rw-r--r--tools/perf/builtin-annotate.c2
-rw-r--r--tools/perf/builtin-buildid-list.c2
-rw-r--r--tools/perf/builtin-kmem.c10
-rw-r--r--tools/perf/builtin-record.c36
-rw-r--r--tools/perf/builtin-report.c2
-rw-r--r--tools/perf/builtin-test.c281
-rw-r--r--tools/perf/builtin-top.c15
-rw-r--r--tools/perf/builtin.h1
-rw-r--r--tools/perf/command-list.txt1
-rw-r--r--tools/perf/perf.c1
-rw-r--r--tools/perf/util/event.c89
-rw-r--r--tools/perf/util/event.h4
-rw-r--r--tools/perf/util/header.c70
-rw-r--r--tools/perf/util/header.h2
-rw-r--r--tools/perf/util/map.c121
-rw-r--r--tools/perf/util/map.h86
-rw-r--r--tools/perf/util/probe-event.c20
-rw-r--r--tools/perf/util/session.c9
-rw-r--r--tools/perf/util/session.h40
-rw-r--r--tools/perf/util/symbol.c236
-rw-r--r--tools/perf/util/symbol.h23
23 files changed, 725 insertions, 351 deletions
diff --git a/tools/perf/Documentation/perf-test.txt b/tools/perf/Documentation/perf-test.txt
new file mode 100644
index 000000000000..1c4b5f5b7f71
--- /dev/null
+++ b/tools/perf/Documentation/perf-test.txt
@@ -0,0 +1,22 @@
1perf-test(1)
2============
3
4NAME
5----
6perf-test - Runs sanity tests.
7
8SYNOPSIS
9--------
10[verse]
11'perf test <options>'
12
13DESCRIPTION
14-----------
15This command does assorted sanity tests, initially thru linked routines but
16also will look for a directory with more tests in the form of scripts.
17
18OPTIONS
19-------
20-v::
21--verbose::
22 Be more verbose.
diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index 3ac6b677becd..739c4412b183 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -187,6 +187,8 @@ ifeq ($(ARCH),x86_64)
187 ARCH := x86 187 ARCH := x86
188endif 188endif
189 189
190$(shell sh -c 'mkdir -p $(OUTPUT)arch/$(ARCH)/util/' 2> /dev/null)
191
190# CFLAGS and LDFLAGS are for the users to override from the command line. 192# CFLAGS and LDFLAGS are for the users to override from the command line.
191 193
192# 194#
@@ -488,6 +490,7 @@ BUILTIN_OBJS += $(OUTPUT)builtin-probe.o
488BUILTIN_OBJS += $(OUTPUT)builtin-kmem.o 490BUILTIN_OBJS += $(OUTPUT)builtin-kmem.o
489BUILTIN_OBJS += $(OUTPUT)builtin-lock.o 491BUILTIN_OBJS += $(OUTPUT)builtin-lock.o
490BUILTIN_OBJS += $(OUTPUT)builtin-kvm.o 492BUILTIN_OBJS += $(OUTPUT)builtin-kvm.o
493BUILTIN_OBJS += $(OUTPUT)builtin-test.o
491 494
492PERFLIBS = $(LIB_FILE) 495PERFLIBS = $(LIB_FILE)
493 496
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index f924b4332be6..b57dbcf62af3 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -571,7 +571,7 @@ static int __cmd_annotate(void)
571 perf_session__fprintf(session, stdout); 571 perf_session__fprintf(session, stdout);
572 572
573 if (verbose > 2) 573 if (verbose > 2)
574 dsos__fprintf(&session->kerninfo_root, stdout); 574 perf_session__fprintf_dsos(session, stdout);
575 575
576 perf_session__collapse_resort(&session->hists); 576 perf_session__collapse_resort(&session->hists);
577 perf_session__output_resort(&session->hists, session->event_total[0]); 577 perf_session__output_resort(&session->hists, session->event_total[0]);
diff --git a/tools/perf/builtin-buildid-list.c b/tools/perf/builtin-buildid-list.c
index 623afe3fdcb8..7dc3b2e7a5e4 100644
--- a/tools/perf/builtin-buildid-list.c
+++ b/tools/perf/builtin-buildid-list.c
@@ -46,7 +46,7 @@ static int __cmd_buildid_list(void)
46 if (with_hits) 46 if (with_hits)
47 perf_session__process_events(session, &build_id__mark_dso_hit_ops); 47 perf_session__process_events(session, &build_id__mark_dso_hit_ops);
48 48
49 dsos__fprintf_buildid(&session->kerninfo_root, stdout, with_hits); 49 perf_session__fprintf_dsos_buildid(session, stdout, with_hits);
50 50
51 perf_session__delete(session); 51 perf_session__delete(session);
52 return err; 52 return err;
diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c
index ab906cbd5c79..ee05dba9609a 100644
--- a/tools/perf/builtin-kmem.c
+++ b/tools/perf/builtin-kmem.c
@@ -352,7 +352,7 @@ static void __print_result(struct rb_root *root, struct perf_session *session,
352 int n_lines, int is_caller) 352 int n_lines, int is_caller)
353{ 353{
354 struct rb_node *next; 354 struct rb_node *next;
355 struct kernel_info *kerninfo; 355 struct machine *machine;
356 356
357 printf("%.102s\n", graph_dotted_line); 357 printf("%.102s\n", graph_dotted_line);
358 printf(" %-34s |", is_caller ? "Callsite": "Alloc Ptr"); 358 printf(" %-34s |", is_caller ? "Callsite": "Alloc Ptr");
@@ -361,8 +361,8 @@ static void __print_result(struct rb_root *root, struct perf_session *session,
361 361
362 next = rb_first(root); 362 next = rb_first(root);
363 363
364 kerninfo = kerninfo__findhost(&session->kerninfo_root); 364 machine = perf_session__find_host_machine(session);
365 if (!kerninfo) { 365 if (!machine) {
366 pr_err("__print_result: couldn't find kernel information\n"); 366 pr_err("__print_result: couldn't find kernel information\n");
367 return; 367 return;
368 } 368 }
@@ -370,7 +370,6 @@ static void __print_result(struct rb_root *root, struct perf_session *session,
370 struct alloc_stat *data = rb_entry(next, struct alloc_stat, 370 struct alloc_stat *data = rb_entry(next, struct alloc_stat,
371 node); 371 node);
372 struct symbol *sym = NULL; 372 struct symbol *sym = NULL;
373 struct map_groups *kmaps = &kerninfo->kmaps;
374 struct map *map; 373 struct map *map;
375 char buf[BUFSIZ]; 374 char buf[BUFSIZ];
376 u64 addr; 375 u64 addr;
@@ -378,8 +377,7 @@ static void __print_result(struct rb_root *root, struct perf_session *session,
378 if (is_caller) { 377 if (is_caller) {
379 addr = data->call_site; 378 addr = data->call_site;
380 if (!raw_ip) 379 if (!raw_ip)
381 sym = map_groups__find_function(kmaps, addr, 380 sym = machine__find_kernel_function(machine, addr, &map, NULL);
382 &map, NULL);
383 } else 381 } else
384 addr = data->ptr; 382 addr = data->ptr;
385 383
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 27f992aca8b5..83b308a035c2 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -456,14 +456,14 @@ static void atexit_header(void)
456 } 456 }
457} 457}
458 458
459static void event__synthesize_guest_os(struct kernel_info *kerninfo, 459static void event__synthesize_guest_os(struct machine *machine, void *data)
460 void *data __attribute__((unused)))
461{ 460{
462 int err; 461 int err;
463 char *guest_kallsyms; 462 char *guest_kallsyms;
464 char path[PATH_MAX]; 463 char path[PATH_MAX];
464 struct perf_session *psession = data;
465 465
466 if (is_host_kernel(kerninfo)) 466 if (machine__is_host(machine))
467 return; 467 return;
468 468
469 /* 469 /*
@@ -475,16 +475,15 @@ static void event__synthesize_guest_os(struct kernel_info *kerninfo,
475 *in module instead of in guest kernel. 475 *in module instead of in guest kernel.
476 */ 476 */
477 err = event__synthesize_modules(process_synthesized_event, 477 err = event__synthesize_modules(process_synthesized_event,
478 session, 478 psession, machine);
479 kerninfo);
480 if (err < 0) 479 if (err < 0)
481 pr_err("Couldn't record guest kernel [%d]'s reference" 480 pr_err("Couldn't record guest kernel [%d]'s reference"
482 " relocation symbol.\n", kerninfo->pid); 481 " relocation symbol.\n", machine->pid);
483 482
484 if (is_default_guest(kerninfo)) 483 if (machine__is_default_guest(machine))
485 guest_kallsyms = (char *) symbol_conf.default_guest_kallsyms; 484 guest_kallsyms = (char *) symbol_conf.default_guest_kallsyms;
486 else { 485 else {
487 sprintf(path, "%s/proc/kallsyms", kerninfo->root_dir); 486 sprintf(path, "%s/proc/kallsyms", machine->root_dir);
488 guest_kallsyms = path; 487 guest_kallsyms = path;
489 } 488 }
490 489
@@ -493,13 +492,13 @@ static void event__synthesize_guest_os(struct kernel_info *kerninfo,
493 * have no _text sometimes. 492 * have no _text sometimes.
494 */ 493 */
495 err = event__synthesize_kernel_mmap(process_synthesized_event, 494 err = event__synthesize_kernel_mmap(process_synthesized_event,
496 session, kerninfo, "_text"); 495 psession, machine, "_text");
497 if (err < 0) 496 if (err < 0)
498 err = event__synthesize_kernel_mmap(process_synthesized_event, 497 err = event__synthesize_kernel_mmap(process_synthesized_event,
499 session, kerninfo, "_stext"); 498 psession, machine, "_stext");
500 if (err < 0) 499 if (err < 0)
501 pr_err("Couldn't record guest kernel [%d]'s reference" 500 pr_err("Couldn't record guest kernel [%d]'s reference"
502 " relocation symbol.\n", kerninfo->pid); 501 " relocation symbol.\n", machine->pid);
503} 502}
504 503
505static int __cmd_record(int argc, const char **argv) 504static int __cmd_record(int argc, const char **argv)
@@ -513,7 +512,7 @@ static int __cmd_record(int argc, const char **argv)
513 int child_ready_pipe[2], go_pipe[2]; 512 int child_ready_pipe[2], go_pipe[2];
514 const bool forks = argc > 0; 513 const bool forks = argc > 0;
515 char buf; 514 char buf;
516 struct kernel_info *kerninfo; 515 struct machine *machine;
517 516
518 page_size = sysconf(_SC_PAGE_SIZE); 517 page_size = sysconf(_SC_PAGE_SIZE);
519 518
@@ -682,31 +681,30 @@ static int __cmd_record(int argc, const char **argv)
682 advance_output(err); 681 advance_output(err);
683 } 682 }
684 683
685 kerninfo = kerninfo__findhost(&session->kerninfo_root); 684 machine = perf_session__find_host_machine(session);
686 if (!kerninfo) { 685 if (!machine) {
687 pr_err("Couldn't find native kernel information.\n"); 686 pr_err("Couldn't find native kernel information.\n");
688 return -1; 687 return -1;
689 } 688 }
690 689
691 err = event__synthesize_kernel_mmap(process_synthesized_event, 690 err = event__synthesize_kernel_mmap(process_synthesized_event,
692 session, kerninfo, "_text"); 691 session, machine, "_text");
693 if (err < 0) 692 if (err < 0)
694 err = event__synthesize_kernel_mmap(process_synthesized_event, 693 err = event__synthesize_kernel_mmap(process_synthesized_event,
695 session, kerninfo, "_stext"); 694 session, machine, "_stext");
696 if (err < 0) { 695 if (err < 0) {
697 pr_err("Couldn't record kernel reference relocation symbol.\n"); 696 pr_err("Couldn't record kernel reference relocation symbol.\n");
698 return err; 697 return err;
699 } 698 }
700 699
701 err = event__synthesize_modules(process_synthesized_event, 700 err = event__synthesize_modules(process_synthesized_event,
702 session, kerninfo); 701 session, machine);
703 if (err < 0) { 702 if (err < 0) {
704 pr_err("Couldn't record kernel reference relocation symbol.\n"); 703 pr_err("Couldn't record kernel reference relocation symbol.\n");
705 return err; 704 return err;
706 } 705 }
707 if (perf_guest) 706 if (perf_guest)
708 kerninfo__process_allkernels(&session->kerninfo_root, 707 perf_session__process_machines(session, event__synthesize_guest_os);
709 event__synthesize_guest_os, session);
710 708
711 if (!system_wide && profile_cpu == -1) 709 if (!system_wide && profile_cpu == -1)
712 event__synthesize_thread(target_tid, process_synthesized_event, 710 event__synthesize_thread(target_tid, process_synthesized_event,
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 816edae7c5b2..f1b46eb7ef9a 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -313,7 +313,7 @@ static int __cmd_report(void)
313 perf_session__fprintf(session, stdout); 313 perf_session__fprintf(session, stdout);
314 314
315 if (verbose > 2) 315 if (verbose > 2)
316 dsos__fprintf(&session->kerninfo_root, stdout); 316 perf_session__fprintf_dsos(session, stdout);
317 317
318 next = rb_first(&session->stats_by_id); 318 next = rb_first(&session->stats_by_id);
319 while (next) { 319 while (next) {
diff --git a/tools/perf/builtin-test.c b/tools/perf/builtin-test.c
new file mode 100644
index 000000000000..0339612e7385
--- /dev/null
+++ b/tools/perf/builtin-test.c
@@ -0,0 +1,281 @@
1/*
2 * builtin-test.c
3 *
4 * Builtin regression testing command: ever growing number of sanity tests
5 */
6#include "builtin.h"
7
8#include "util/cache.h"
9#include "util/debug.h"
10#include "util/parse-options.h"
11#include "util/session.h"
12#include "util/symbol.h"
13#include "util/thread.h"
14
15static long page_size;
16
17static int vmlinux_matches_kallsyms_filter(struct map *map __used, struct symbol *sym)
18{
19 bool *visited = symbol__priv(sym);
20 *visited = true;
21 return 0;
22}
23
24static int test__vmlinux_matches_kallsyms(void)
25{
26 int err = -1;
27 struct rb_node *nd;
28 struct symbol *sym;
29 struct map *kallsyms_map, *vmlinux_map;
30 struct machine kallsyms, vmlinux;
31 enum map_type type = MAP__FUNCTION;
32 struct ref_reloc_sym ref_reloc_sym = { .name = "_stext", };
33
34 /*
35 * Step 1:
36 *
37 * Init the machines that will hold kernel, modules obtained from
38 * both vmlinux + .ko files and from /proc/kallsyms split by modules.
39 */
40 machine__init(&kallsyms, "", HOST_KERNEL_ID);
41 machine__init(&vmlinux, "", HOST_KERNEL_ID);
42
43 /*
44 * Step 2:
45 *
46 * Create the kernel maps for kallsyms and the DSO where we will then
47 * load /proc/kallsyms. Also create the modules maps from /proc/modules
48 * and find the .ko files that match them in /lib/modules/`uname -r`/.
49 */
50 if (machine__create_kernel_maps(&kallsyms) < 0) {
51 pr_debug("machine__create_kernel_maps ");
52 return -1;
53 }
54
55 /*
56 * Step 3:
57 *
58 * Load and split /proc/kallsyms into multiple maps, one per module.
59 */
60 if (machine__load_kallsyms(&kallsyms, "/proc/kallsyms", type, NULL) <= 0) {
61 pr_debug("dso__load_kallsyms ");
62 goto out;
63 }
64
65 /*
66 * Step 4:
67 *
68 * kallsyms will be internally on demand sorted by name so that we can
69 * find the reference relocation * symbol, i.e. the symbol we will use
70 * to see if the running kernel was relocated by checking if it has the
71 * same value in the vmlinux file we load.
72 */
73 kallsyms_map = machine__kernel_map(&kallsyms, type);
74
75 sym = map__find_symbol_by_name(kallsyms_map, ref_reloc_sym.name, NULL);
76 if (sym == NULL) {
77 pr_debug("dso__find_symbol_by_name ");
78 goto out;
79 }
80
81 ref_reloc_sym.addr = sym->start;
82
83 /*
84 * Step 5:
85 *
86 * Now repeat step 2, this time for the vmlinux file we'll auto-locate.
87 */
88 if (machine__create_kernel_maps(&vmlinux) < 0) {
89 pr_debug("machine__create_kernel_maps ");
90 goto out;
91 }
92
93 vmlinux_map = machine__kernel_map(&vmlinux, type);
94 map__kmap(vmlinux_map)->ref_reloc_sym = &ref_reloc_sym;
95
96 /*
97 * Step 6:
98 *
99 * Locate a vmlinux file in the vmlinux path that has a buildid that
100 * matches the one of the running kernel.
101 *
102 * While doing that look if we find the ref reloc symbol, if we find it
103 * we'll have its ref_reloc_symbol.unrelocated_addr and then
104 * maps__reloc_vmlinux will notice and set proper ->[un]map_ip routines
105 * to fixup the symbols.
106 */
107 if (machine__load_vmlinux_path(&vmlinux, type,
108 vmlinux_matches_kallsyms_filter) <= 0) {
109 pr_debug("machine__load_vmlinux_path ");
110 goto out;
111 }
112
113 err = 0;
114 /*
115 * Step 7:
116 *
117 * Now look at the symbols in the vmlinux DSO and check if we find all of them
118 * in the kallsyms dso. For the ones that are in both, check its names and
119 * end addresses too.
120 */
121 for (nd = rb_first(&vmlinux_map->dso->symbols[type]); nd; nd = rb_next(nd)) {
122 struct symbol *pair;
123
124 sym = rb_entry(nd, struct symbol, rb_node);
125 pair = machine__find_kernel_symbol(&kallsyms, type, sym->start, NULL, NULL);
126
127 if (pair && pair->start == sym->start) {
128next_pair:
129 if (strcmp(sym->name, pair->name) == 0) {
130 /*
131 * kallsyms don't have the symbol end, so we
132 * set that by using the next symbol start - 1,
133 * in some cases we get this up to a page
134 * wrong, trace_kmalloc when I was developing
135 * this code was one such example, 2106 bytes
136 * off the real size. More than that and we
137 * _really_ have a problem.
138 */
139 s64 skew = sym->end - pair->end;
140 if (llabs(skew) < page_size)
141 continue;
142
143 pr_debug("%#Lx: diff end addr for %s v: %#Lx k: %#Lx\n",
144 sym->start, sym->name, sym->end, pair->end);
145 } else {
146 struct rb_node *nnd = rb_prev(&pair->rb_node);
147
148 if (nnd) {
149 struct symbol *next = rb_entry(nnd, struct symbol, rb_node);
150
151 if (next->start == sym->start) {
152 pair = next;
153 goto next_pair;
154 }
155 }
156 pr_debug("%#Lx: diff name v: %s k: %s\n",
157 sym->start, sym->name, pair->name);
158 }
159 } else
160 pr_debug("%#Lx: %s not on kallsyms\n", sym->start, sym->name);
161
162 err = -1;
163 }
164
165 if (!verbose)
166 goto out;
167
168 pr_info("Maps only in vmlinux:\n");
169
170 for (nd = rb_first(&vmlinux.kmaps.maps[type]); nd; nd = rb_next(nd)) {
171 struct map *pos = rb_entry(nd, struct map, rb_node), *pair;
172 /*
173 * If it is the kernel, kallsyms is always "[kernel.kallsyms]", while
174 * the kernel will have the path for the vmlinux file being used,
175 * so use the short name, less descriptive but the same ("[kernel]" in
176 * both cases.
177 */
178 pair = map_groups__find_by_name(&kallsyms.kmaps, type,
179 (pos->dso->kernel ?
180 pos->dso->short_name :
181 pos->dso->name));
182 if (pair)
183 pair->priv = 1;
184 else
185 map__fprintf(pos, stderr);
186 }
187
188 pr_info("Maps in vmlinux with a different name in kallsyms:\n");
189
190 for (nd = rb_first(&vmlinux.kmaps.maps[type]); nd; nd = rb_next(nd)) {
191 struct map *pos = rb_entry(nd, struct map, rb_node), *pair;
192
193 pair = map_groups__find(&kallsyms.kmaps, type, pos->start);
194 if (pair == NULL || pair->priv)
195 continue;
196
197 if (pair->start == pos->start) {
198 pair->priv = 1;
199 pr_info(" %Lx-%Lx %Lx %s in kallsyms as",
200 pos->start, pos->end, pos->pgoff, pos->dso->name);
201 if (pos->pgoff != pair->pgoff || pos->end != pair->end)
202 pr_info(": \n*%Lx-%Lx %Lx",
203 pair->start, pair->end, pair->pgoff);
204 pr_info(" %s\n", pair->dso->name);
205 pair->priv = 1;
206 }
207 }
208
209 pr_info("Maps only in kallsyms:\n");
210
211 for (nd = rb_first(&kallsyms.kmaps.maps[type]);
212 nd; nd = rb_next(nd)) {
213 struct map *pos = rb_entry(nd, struct map, rb_node);
214
215 if (!pos->priv)
216 map__fprintf(pos, stderr);
217 }
218out:
219 return err;
220}
221
222static struct test {
223 const char *desc;
224 int (*func)(void);
225} tests[] = {
226 {
227 .desc = "vmlinux symtab matches kallsyms",
228 .func = test__vmlinux_matches_kallsyms,
229 },
230 {
231 .func = NULL,
232 },
233};
234
235static int __cmd_test(void)
236{
237 int i = 0;
238
239 page_size = sysconf(_SC_PAGE_SIZE);
240
241 while (tests[i].func) {
242 int err;
243 pr_info("%2d: %s:", i + 1, tests[i].desc);
244 pr_debug("\n--- start ---\n");
245 err = tests[i].func();
246 pr_debug("---- end ----\n%s:", tests[i].desc);
247 pr_info(" %s\n", err ? "FAILED!\n" : "Ok");
248 ++i;
249 }
250
251 return 0;
252}
253
254static const char * const test_usage[] = {
255 "perf test [<options>]",
256 NULL,
257};
258
259static const struct option test_options[] = {
260 OPT_BOOLEAN('v', "verbose", &verbose,
261 "be more verbose (show symbol address, etc)"),
262 OPT_END()
263};
264
265int cmd_test(int argc, const char **argv, const char *prefix __used)
266{
267 argc = parse_options(argc, argv, test_options, test_usage, 0);
268 if (argc)
269 usage_with_options(test_usage, test_options);
270
271 symbol_conf.priv_size = sizeof(int);
272 symbol_conf.sort_by_name = true;
273 symbol_conf.try_vmlinux_path = true;
274
275 if (symbol__init() < 0)
276 return -1;
277
278 setup_pager();
279
280 return __cmd_test();
281}
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index dfd7ea7dabdd..d95281f588d2 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -854,7 +854,7 @@ static void handle_keypress(struct perf_session *session, int c)
854 case 'Q': 854 case 'Q':
855 printf("exiting.\n"); 855 printf("exiting.\n");
856 if (dump_symtab) 856 if (dump_symtab)
857 dsos__fprintf(&session->kerninfo_root, stderr); 857 perf_session__fprintf_dsos(session, stderr);
858 exit(0); 858 exit(0);
859 case 's': 859 case 's':
860 prompt_symbol(&sym_filter_entry, "Enter details symbol"); 860 prompt_symbol(&sym_filter_entry, "Enter details symbol");
@@ -982,7 +982,7 @@ static void event__process_sample(const event_t *self,
982 u64 ip = self->ip.ip; 982 u64 ip = self->ip.ip;
983 struct sym_entry *syme; 983 struct sym_entry *syme;
984 struct addr_location al; 984 struct addr_location al;
985 struct kernel_info *kerninfo; 985 struct machine *machine;
986 u8 origin = self->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; 986 u8 origin = self->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
987 987
988 ++samples; 988 ++samples;
@@ -992,18 +992,17 @@ static void event__process_sample(const event_t *self,
992 ++us_samples; 992 ++us_samples;
993 if (hide_user_symbols) 993 if (hide_user_symbols)
994 return; 994 return;
995 kerninfo = kerninfo__findhost(&session->kerninfo_root); 995 machine = perf_session__find_host_machine(session);
996 break; 996 break;
997 case PERF_RECORD_MISC_KERNEL: 997 case PERF_RECORD_MISC_KERNEL:
998 ++kernel_samples; 998 ++kernel_samples;
999 if (hide_kernel_symbols) 999 if (hide_kernel_symbols)
1000 return; 1000 return;
1001 kerninfo = kerninfo__findhost(&session->kerninfo_root); 1001 machine = perf_session__find_host_machine(session);
1002 break; 1002 break;
1003 case PERF_RECORD_MISC_GUEST_KERNEL: 1003 case PERF_RECORD_MISC_GUEST_KERNEL:
1004 ++guest_kernel_samples; 1004 ++guest_kernel_samples;
1005 kerninfo = kerninfo__find(&session->kerninfo_root, 1005 machine = perf_session__find_machine(session, self->ip.pid);
1006 self->ip.pid);
1007 break; 1006 break;
1008 case PERF_RECORD_MISC_GUEST_USER: 1007 case PERF_RECORD_MISC_GUEST_USER:
1009 ++guest_us_samples; 1008 ++guest_us_samples;
@@ -1016,7 +1015,7 @@ static void event__process_sample(const event_t *self,
1016 return; 1015 return;
1017 } 1016 }
1018 1017
1019 if (!kerninfo && perf_guest) { 1018 if (!machine && perf_guest) {
1020 pr_err("Can't find guest [%d]'s kernel information\n", 1019 pr_err("Can't find guest [%d]'s kernel information\n",
1021 self->ip.pid); 1020 self->ip.pid);
1022 return; 1021 return;
@@ -1041,7 +1040,7 @@ static void event__process_sample(const event_t *self,
1041 * --hide-kernel-symbols, even if the user specifies an 1040 * --hide-kernel-symbols, even if the user specifies an
1042 * invalid --vmlinux ;-) 1041 * invalid --vmlinux ;-)
1043 */ 1042 */
1044 if (al.map == kerninfo->vmlinux_maps[MAP__FUNCTION] && 1043 if (al.map == machine->vmlinux_maps[MAP__FUNCTION] &&
1045 RB_EMPTY_ROOT(&al.map->dso->symbols[MAP__FUNCTION])) { 1044 RB_EMPTY_ROOT(&al.map->dso->symbols[MAP__FUNCTION])) {
1046 pr_err("The %s file can't be used\n", 1045 pr_err("The %s file can't be used\n",
1047 symbol_conf.vmlinux_name); 1046 symbol_conf.vmlinux_name);
diff --git a/tools/perf/builtin.h b/tools/perf/builtin.h
index ab28bca92e52..34a8a9ab9617 100644
--- a/tools/perf/builtin.h
+++ b/tools/perf/builtin.h
@@ -33,5 +33,6 @@ extern int cmd_probe(int argc, const char **argv, const char *prefix);
33extern int cmd_kmem(int argc, const char **argv, const char *prefix); 33extern int cmd_kmem(int argc, const char **argv, const char *prefix);
34extern int cmd_lock(int argc, const char **argv, const char *prefix); 34extern int cmd_lock(int argc, const char **argv, const char *prefix);
35extern int cmd_kvm(int argc, const char **argv, const char *prefix); 35extern int cmd_kvm(int argc, const char **argv, const char *prefix);
36extern int cmd_test(int argc, const char **argv, const char *prefix);
36 37
37#endif 38#endif
diff --git a/tools/perf/command-list.txt b/tools/perf/command-list.txt
index 2a1162d413a8..80a1a446ce35 100644
--- a/tools/perf/command-list.txt
+++ b/tools/perf/command-list.txt
@@ -20,3 +20,4 @@ perf-probe mainporcelain common
20perf-kmem mainporcelain common 20perf-kmem mainporcelain common
21perf-lock mainporcelain common 21perf-lock mainporcelain common
22perf-kvm mainporcelain common 22perf-kvm mainporcelain common
23perf-test mainporcelain common
diff --git a/tools/perf/perf.c b/tools/perf/perf.c
index 985cdb4bd005..5ff9b5b46970 100644
--- a/tools/perf/perf.c
+++ b/tools/perf/perf.c
@@ -308,6 +308,7 @@ static void handle_internal_command(int argc, const char **argv)
308 { "kmem", cmd_kmem, 0 }, 308 { "kmem", cmd_kmem, 0 },
309 { "lock", cmd_lock, 0 }, 309 { "lock", cmd_lock, 0 },
310 { "kvm", cmd_kvm, 0 }, 310 { "kvm", cmd_kvm, 0 },
311 { "test", cmd_test, 0 },
311 }; 312 };
312 unsigned int i; 313 unsigned int i;
313 static const char ext[] = STRIP_EXTENSION; 314 static const char ext[] = STRIP_EXTENSION;
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index e3fa8d3d11b4..1757b0ffeaa9 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -172,17 +172,17 @@ static int event__synthesize_mmap_events(pid_t pid, pid_t tgid,
172 172
173int event__synthesize_modules(event__handler_t process, 173int event__synthesize_modules(event__handler_t process,
174 struct perf_session *session, 174 struct perf_session *session,
175 struct kernel_info *kerninfo) 175 struct machine *machine)
176{ 176{
177 struct rb_node *nd; 177 struct rb_node *nd;
178 struct map_groups *kmaps = &kerninfo->kmaps; 178 struct map_groups *kmaps = &machine->kmaps;
179 u16 misc; 179 u16 misc;
180 180
181 /* 181 /*
182 * kernel uses 0 for user space maps, see kernel/perf_event.c 182 * kernel uses 0 for user space maps, see kernel/perf_event.c
183 * __perf_event_mmap 183 * __perf_event_mmap
184 */ 184 */
185 if (is_host_kernel(kerninfo)) 185 if (machine__is_host(machine))
186 misc = PERF_RECORD_MISC_KERNEL; 186 misc = PERF_RECORD_MISC_KERNEL;
187 else 187 else
188 misc = PERF_RECORD_MISC_GUEST_KERNEL; 188 misc = PERF_RECORD_MISC_GUEST_KERNEL;
@@ -204,7 +204,7 @@ int event__synthesize_modules(event__handler_t process,
204 (sizeof(ev.mmap.filename) - size)); 204 (sizeof(ev.mmap.filename) - size));
205 ev.mmap.start = pos->start; 205 ev.mmap.start = pos->start;
206 ev.mmap.len = pos->end - pos->start; 206 ev.mmap.len = pos->end - pos->start;
207 ev.mmap.pid = kerninfo->pid; 207 ev.mmap.pid = machine->pid;
208 208
209 memcpy(ev.mmap.filename, pos->dso->long_name, 209 memcpy(ev.mmap.filename, pos->dso->long_name,
210 pos->dso->long_name_len + 1); 210 pos->dso->long_name_len + 1);
@@ -267,7 +267,7 @@ static int find_symbol_cb(void *arg, const char *name, char type, u64 start)
267 267
268int event__synthesize_kernel_mmap(event__handler_t process, 268int event__synthesize_kernel_mmap(event__handler_t process,
269 struct perf_session *session, 269 struct perf_session *session,
270 struct kernel_info *kerninfo, 270 struct machine *machine,
271 const char *symbol_name) 271 const char *symbol_name)
272{ 272{
273 size_t size; 273 size_t size;
@@ -288,8 +288,8 @@ int event__synthesize_kernel_mmap(event__handler_t process,
288 */ 288 */
289 struct process_symbol_args args = { .name = symbol_name, }; 289 struct process_symbol_args args = { .name = symbol_name, };
290 290
291 mmap_name = kern_mmap_name(kerninfo, name_buff); 291 mmap_name = machine__mmap_name(machine, name_buff, sizeof(name_buff));
292 if (is_host_kernel(kerninfo)) { 292 if (machine__is_host(machine)) {
293 /* 293 /*
294 * kernel uses PERF_RECORD_MISC_USER for user space maps, 294 * kernel uses PERF_RECORD_MISC_USER for user space maps,
295 * see kernel/perf_event.c __perf_event_mmap 295 * see kernel/perf_event.c __perf_event_mmap
@@ -298,10 +298,10 @@ int event__synthesize_kernel_mmap(event__handler_t process,
298 filename = "/proc/kallsyms"; 298 filename = "/proc/kallsyms";
299 } else { 299 } else {
300 ev.header.misc = PERF_RECORD_MISC_GUEST_KERNEL; 300 ev.header.misc = PERF_RECORD_MISC_GUEST_KERNEL;
301 if (is_default_guest(kerninfo)) 301 if (machine__is_default_guest(machine))
302 filename = (char *) symbol_conf.default_guest_kallsyms; 302 filename = (char *) symbol_conf.default_guest_kallsyms;
303 else { 303 else {
304 sprintf(path, "%s/proc/kallsyms", kerninfo->root_dir); 304 sprintf(path, "%s/proc/kallsyms", machine->root_dir);
305 filename = path; 305 filename = path;
306 } 306 }
307 } 307 }
@@ -309,7 +309,7 @@ int event__synthesize_kernel_mmap(event__handler_t process,
309 if (kallsyms__parse(filename, &args, find_symbol_cb) <= 0) 309 if (kallsyms__parse(filename, &args, find_symbol_cb) <= 0)
310 return -ENOENT; 310 return -ENOENT;
311 311
312 map = kerninfo->vmlinux_maps[MAP__FUNCTION]; 312 map = machine->vmlinux_maps[MAP__FUNCTION];
313 size = snprintf(ev.mmap.filename, sizeof(ev.mmap.filename), 313 size = snprintf(ev.mmap.filename, sizeof(ev.mmap.filename),
314 "%s%s", mmap_name, symbol_name) + 1; 314 "%s%s", mmap_name, symbol_name) + 1;
315 size = ALIGN(size, sizeof(u64)); 315 size = ALIGN(size, sizeof(u64));
@@ -318,7 +318,7 @@ int event__synthesize_kernel_mmap(event__handler_t process,
318 ev.mmap.pgoff = args.start; 318 ev.mmap.pgoff = args.start;
319 ev.mmap.start = map->start; 319 ev.mmap.start = map->start;
320 ev.mmap.len = map->end - ev.mmap.start; 320 ev.mmap.len = map->end - ev.mmap.start;
321 ev.mmap.pid = kerninfo->pid; 321 ev.mmap.pid = machine->pid;
322 322
323 return process(&ev, session); 323 return process(&ev, session);
324} 324}
@@ -389,18 +389,18 @@ static int event__process_kernel_mmap(event_t *self,
389{ 389{
390 struct map *map; 390 struct map *map;
391 char kmmap_prefix[PATH_MAX]; 391 char kmmap_prefix[PATH_MAX];
392 struct kernel_info *kerninfo; 392 struct machine *machine;
393 enum dso_kernel_type kernel_type; 393 enum dso_kernel_type kernel_type;
394 bool is_kernel_mmap; 394 bool is_kernel_mmap;
395 395
396 kerninfo = kerninfo__findnew(&session->kerninfo_root, self->mmap.pid); 396 machine = perf_session__findnew_machine(session, self->mmap.pid);
397 if (!kerninfo) { 397 if (!machine) {
398 pr_err("Can't find id %d's kerninfo\n", self->mmap.pid); 398 pr_err("Can't find id %d's machine\n", self->mmap.pid);
399 goto out_problem; 399 goto out_problem;
400 } 400 }
401 401
402 kern_mmap_name(kerninfo, kmmap_prefix); 402 machine__mmap_name(machine, kmmap_prefix, sizeof(kmmap_prefix));
403 if (is_host_kernel(kerninfo)) 403 if (machine__is_host(machine))
404 kernel_type = DSO_TYPE_KERNEL; 404 kernel_type = DSO_TYPE_KERNEL;
405 else 405 else
406 kernel_type = DSO_TYPE_GUEST_KERNEL; 406 kernel_type = DSO_TYPE_GUEST_KERNEL;
@@ -429,10 +429,8 @@ static int event__process_kernel_mmap(event_t *self,
429 } else 429 } else
430 strcpy(short_module_name, self->mmap.filename); 430 strcpy(short_module_name, self->mmap.filename);
431 431
432 map = map_groups__new_module(&kerninfo->kmaps, 432 map = machine__new_module(machine, self->mmap.start,
433 self->mmap.start, 433 self->mmap.filename);
434 self->mmap.filename,
435 kerninfo);
436 if (map == NULL) 434 if (map == NULL)
437 goto out_problem; 435 goto out_problem;
438 436
@@ -449,27 +447,25 @@ static int event__process_kernel_mmap(event_t *self,
449 * Should be there already, from the build-id table in 447 * Should be there already, from the build-id table in
450 * the header. 448 * the header.
451 */ 449 */
452 struct dso *kernel = __dsos__findnew(&kerninfo->dsos__kernel, 450 struct dso *kernel = __dsos__findnew(&machine->kernel_dsos,
453 kmmap_prefix); 451 kmmap_prefix);
454 if (kernel == NULL) 452 if (kernel == NULL)
455 goto out_problem; 453 goto out_problem;
456 454
457 kernel->kernel = kernel_type; 455 kernel->kernel = kernel_type;
458 if (__map_groups__create_kernel_maps(&kerninfo->kmaps, 456 if (__machine__create_kernel_maps(machine, kernel) < 0)
459 kerninfo->vmlinux_maps, kernel) < 0)
460 goto out_problem; 457 goto out_problem;
461 458
462 event_set_kernel_mmap_len(kerninfo->vmlinux_maps, self); 459 event_set_kernel_mmap_len(machine->vmlinux_maps, self);
463 perf_session__set_kallsyms_ref_reloc_sym(kerninfo->vmlinux_maps, 460 perf_session__set_kallsyms_ref_reloc_sym(machine->vmlinux_maps,
464 symbol_name, 461 symbol_name,
465 self->mmap.pgoff); 462 self->mmap.pgoff);
466 if (is_default_guest(kerninfo)) { 463 if (machine__is_default_guest(machine)) {
467 /* 464 /*
468 * preload dso of guest kernel and modules 465 * preload dso of guest kernel and modules
469 */ 466 */
470 dso__load(kernel, 467 dso__load(kernel, machine->vmlinux_maps[MAP__FUNCTION],
471 kerninfo->vmlinux_maps[MAP__FUNCTION], 468 NULL);
472 NULL);
473 } 469 }
474 } 470 }
475 return 0; 471 return 0;
@@ -479,7 +475,7 @@ out_problem:
479 475
480int event__process_mmap(event_t *self, struct perf_session *session) 476int event__process_mmap(event_t *self, struct perf_session *session)
481{ 477{
482 struct kernel_info *kerninfo; 478 struct machine *machine;
483 struct thread *thread; 479 struct thread *thread;
484 struct map *map; 480 struct map *map;
485 u8 cpumode = self->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; 481 u8 cpumode = self->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
@@ -498,8 +494,8 @@ int event__process_mmap(event_t *self, struct perf_session *session)
498 } 494 }
499 495
500 thread = perf_session__findnew(session, self->mmap.pid); 496 thread = perf_session__findnew(session, self->mmap.pid);
501 kerninfo = kerninfo__findhost(&session->kerninfo_root); 497 machine = perf_session__find_host_machine(session);
502 map = map__new(&kerninfo->dsos__user, self->mmap.start, 498 map = map__new(&machine->user_dsos, self->mmap.start,
503 self->mmap.len, self->mmap.pgoff, 499 self->mmap.len, self->mmap.pgoff,
504 self->mmap.pid, self->mmap.filename, 500 self->mmap.pid, self->mmap.filename,
505 MAP__FUNCTION, session->cwd, session->cwdlen); 501 MAP__FUNCTION, session->cwd, session->cwdlen);
@@ -546,7 +542,7 @@ void thread__find_addr_map(struct thread *self,
546 struct addr_location *al) 542 struct addr_location *al)
547{ 543{
548 struct map_groups *mg = &self->mg; 544 struct map_groups *mg = &self->mg;
549 struct kernel_info *kerninfo = NULL; 545 struct machine *machine = NULL;
550 546
551 al->thread = self; 547 al->thread = self;
552 al->addr = addr; 548 al->addr = addr;
@@ -555,19 +551,19 @@ void thread__find_addr_map(struct thread *self,
555 551
556 if (cpumode == PERF_RECORD_MISC_KERNEL && perf_host) { 552 if (cpumode == PERF_RECORD_MISC_KERNEL && perf_host) {
557 al->level = 'k'; 553 al->level = 'k';
558 kerninfo = kerninfo__findhost(&session->kerninfo_root); 554 machine = perf_session__find_host_machine(session);
559 mg = &kerninfo->kmaps; 555 mg = &machine->kmaps;
560 } else if (cpumode == PERF_RECORD_MISC_USER && perf_host) { 556 } else if (cpumode == PERF_RECORD_MISC_USER && perf_host) {
561 al->level = '.'; 557 al->level = '.';
562 kerninfo = kerninfo__findhost(&session->kerninfo_root); 558 machine = perf_session__find_host_machine(session);
563 } else if (cpumode == PERF_RECORD_MISC_GUEST_KERNEL && perf_guest) { 559 } else if (cpumode == PERF_RECORD_MISC_GUEST_KERNEL && perf_guest) {
564 al->level = 'g'; 560 al->level = 'g';
565 kerninfo = kerninfo__find(&session->kerninfo_root, pid); 561 machine = perf_session__find_machine(session, pid);
566 if (!kerninfo) { 562 if (!machine) {
567 al->map = NULL; 563 al->map = NULL;
568 return; 564 return;
569 } 565 }
570 mg = &kerninfo->kmaps; 566 mg = &machine->kmaps;
571 } else { 567 } else {
572 /* 568 /*
573 * 'u' means guest os user space. 569 * 'u' means guest os user space.
@@ -603,10 +599,9 @@ try_again:
603 * in the whole kernel symbol list. 599 * in the whole kernel symbol list.
604 */ 600 */
605 if ((long long)al->addr < 0 && 601 if ((long long)al->addr < 0 &&
606 cpumode == PERF_RECORD_MISC_KERNEL && 602 cpumode == PERF_RECORD_MISC_KERNEL &&
607 kerninfo && 603 machine && mg != &machine->kmaps) {
608 mg != &kerninfo->kmaps) { 604 mg = &machine->kmaps;
609 mg = &kerninfo->kmaps;
610 goto try_again; 605 goto try_again;
611 } 606 }
612 } else 607 } else
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index 4af2ed5d48ad..b364da5b0cbf 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -156,12 +156,12 @@ void event__synthesize_threads(event__handler_t process,
156 struct perf_session *session); 156 struct perf_session *session);
157int event__synthesize_kernel_mmap(event__handler_t process, 157int event__synthesize_kernel_mmap(event__handler_t process,
158 struct perf_session *session, 158 struct perf_session *session,
159 struct kernel_info *kerninfo, 159 struct machine *machine,
160 const char *symbol_name); 160 const char *symbol_name);
161 161
162int event__synthesize_modules(event__handler_t process, 162int event__synthesize_modules(event__handler_t process,
163 struct perf_session *session, 163 struct perf_session *session,
164 struct kernel_info *kerninfo); 164 struct machine *machine);
165 165
166int event__process_comm(event_t *self, struct perf_session *session); 166int event__process_comm(event_t *self, struct perf_session *session);
167int event__process_lost(event_t *self, struct perf_session *session); 167int event__process_lost(event_t *self, struct perf_session *session);
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 75d016768021..6227dc4cb2cf 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -229,10 +229,9 @@ static int dsos__write_buildid_table(struct perf_header *header, int fd)
229 int err = 0; 229 int err = 0;
230 u16 kmisc, umisc; 230 u16 kmisc, umisc;
231 231
232 for (nd = rb_first(&session->kerninfo_root); nd; nd = rb_next(nd)) { 232 for (nd = rb_first(&session->machines); nd; nd = rb_next(nd)) {
233 struct kernel_info *pos = rb_entry(nd, struct kernel_info, 233 struct machine *pos = rb_entry(nd, struct machine, rb_node);
234 rb_node); 234 if (machine__is_host(pos)) {
235 if (is_host_kernel(pos)) {
236 kmisc = PERF_RECORD_MISC_KERNEL; 235 kmisc = PERF_RECORD_MISC_KERNEL;
237 umisc = PERF_RECORD_MISC_USER; 236 umisc = PERF_RECORD_MISC_USER;
238 } else { 237 } else {
@@ -240,11 +239,11 @@ static int dsos__write_buildid_table(struct perf_header *header, int fd)
240 umisc = PERF_RECORD_MISC_GUEST_USER; 239 umisc = PERF_RECORD_MISC_GUEST_USER;
241 } 240 }
242 241
243 err = __dsos__write_buildid_table(&pos->dsos__kernel, pos->pid, 242 err = __dsos__write_buildid_table(&pos->kernel_dsos, pos->pid,
244 kmisc, fd); 243 kmisc, fd);
245 if (err == 0) 244 if (err == 0)
246 err = __dsos__write_buildid_table(&pos->dsos__user, 245 err = __dsos__write_buildid_table(&pos->user_dsos,
247 pos->pid, umisc, fd); 246 pos->pid, umisc, fd);
248 if (err) 247 if (err)
249 break; 248 break;
250 } 249 }
@@ -378,11 +377,10 @@ static int dsos__cache_build_ids(struct perf_header *self)
378 if (mkdir(debugdir, 0755) != 0 && errno != EEXIST) 377 if (mkdir(debugdir, 0755) != 0 && errno != EEXIST)
379 return -1; 378 return -1;
380 379
381 for (nd = rb_first(&session->kerninfo_root); nd; nd = rb_next(nd)) { 380 for (nd = rb_first(&session->machines); nd; nd = rb_next(nd)) {
382 struct kernel_info *pos = rb_entry(nd, struct kernel_info, 381 struct machine *pos = rb_entry(nd, struct machine, rb_node);
383 rb_node); 382 ret |= __dsos__cache_build_ids(&pos->kernel_dsos, debugdir);
384 ret |= __dsos__cache_build_ids(&pos->dsos__kernel, debugdir); 383 ret |= __dsos__cache_build_ids(&pos->user_dsos, debugdir);
385 ret |= __dsos__cache_build_ids(&pos->dsos__user, debugdir);
386 } 384 }
387 return ret ? -1 : 0; 385 return ret ? -1 : 0;
388} 386}
@@ -394,11 +392,10 @@ static bool dsos__read_build_ids(struct perf_header *self, bool with_hits)
394 struct perf_session, header); 392 struct perf_session, header);
395 struct rb_node *nd; 393 struct rb_node *nd;
396 394
397 for (nd = rb_first(&session->kerninfo_root); nd; nd = rb_next(nd)) { 395 for (nd = rb_first(&session->machines); nd; nd = rb_next(nd)) {
398 struct kernel_info *pos = rb_entry(nd, struct kernel_info, 396 struct machine *pos = rb_entry(nd, struct machine, rb_node);
399 rb_node); 397 ret |= __dsos__read_build_ids(&pos->kernel_dsos, with_hits);
400 ret |= __dsos__read_build_ids(&pos->dsos__kernel, with_hits); 398 ret |= __dsos__read_build_ids(&pos->user_dsos, with_hits);
401 ret |= __dsos__read_build_ids(&pos->dsos__user, with_hits);
402 } 399 }
403 400
404 return ret; 401 return ret;
@@ -685,13 +682,13 @@ static int __event_process_build_id(struct build_id_event *bev,
685{ 682{
686 int err = -1; 683 int err = -1;
687 struct list_head *head; 684 struct list_head *head;
688 struct kernel_info *kerninfo; 685 struct machine *machine;
689 u16 misc; 686 u16 misc;
690 struct dso *dso; 687 struct dso *dso;
691 enum dso_kernel_type dso_type; 688 enum dso_kernel_type dso_type;
692 689
693 kerninfo = kerninfo__findnew(&session->kerninfo_root, bev->pid); 690 machine = perf_session__findnew_machine(session, bev->pid);
694 if (!kerninfo) 691 if (!machine)
695 goto out; 692 goto out;
696 693
697 misc = bev->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; 694 misc = bev->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
@@ -699,16 +696,16 @@ static int __event_process_build_id(struct build_id_event *bev,
699 switch (misc) { 696 switch (misc) {
700 case PERF_RECORD_MISC_KERNEL: 697 case PERF_RECORD_MISC_KERNEL:
701 dso_type = DSO_TYPE_KERNEL; 698 dso_type = DSO_TYPE_KERNEL;
702 head = &kerninfo->dsos__kernel; 699 head = &machine->kernel_dsos;
703 break; 700 break;
704 case PERF_RECORD_MISC_GUEST_KERNEL: 701 case PERF_RECORD_MISC_GUEST_KERNEL:
705 dso_type = DSO_TYPE_GUEST_KERNEL; 702 dso_type = DSO_TYPE_GUEST_KERNEL;
706 head = &kerninfo->dsos__kernel; 703 head = &machine->kernel_dsos;
707 break; 704 break;
708 case PERF_RECORD_MISC_USER: 705 case PERF_RECORD_MISC_USER:
709 case PERF_RECORD_MISC_GUEST_USER: 706 case PERF_RECORD_MISC_GUEST_USER:
710 dso_type = DSO_TYPE_USER; 707 dso_type = DSO_TYPE_USER;
711 head = &kerninfo->dsos__user; 708 head = &machine->user_dsos;
712 break; 709 break;
713 default: 710 default:
714 goto out; 711 goto out;
@@ -1113,8 +1110,7 @@ int event__process_tracing_data(event_t *self,
1113} 1110}
1114 1111
1115int event__synthesize_build_id(struct dso *pos, u16 misc, 1112int event__synthesize_build_id(struct dso *pos, u16 misc,
1116 event__handler_t process, 1113 event__handler_t process, struct machine *machine,
1117 struct kernel_info *kerninfo,
1118 struct perf_session *session) 1114 struct perf_session *session)
1119{ 1115{
1120 event_t ev; 1116 event_t ev;
@@ -1131,7 +1127,7 @@ int event__synthesize_build_id(struct dso *pos, u16 misc,
1131 memcpy(&ev.build_id.build_id, pos->build_id, sizeof(pos->build_id)); 1127 memcpy(&ev.build_id.build_id, pos->build_id, sizeof(pos->build_id));
1132 ev.build_id.header.type = PERF_RECORD_HEADER_BUILD_ID; 1128 ev.build_id.header.type = PERF_RECORD_HEADER_BUILD_ID;
1133 ev.build_id.header.misc = misc; 1129 ev.build_id.header.misc = misc;
1134 ev.build_id.pid = kerninfo->pid; 1130 ev.build_id.pid = machine->pid;
1135 ev.build_id.header.size = sizeof(ev.build_id) + len; 1131 ev.build_id.header.size = sizeof(ev.build_id) + len;
1136 memcpy(&ev.build_id.filename, pos->long_name, pos->long_name_len); 1132 memcpy(&ev.build_id.filename, pos->long_name, pos->long_name_len);
1137 1133
@@ -1142,7 +1138,7 @@ int event__synthesize_build_id(struct dso *pos, u16 misc,
1142 1138
1143static int __event_synthesize_build_ids(struct list_head *head, u16 misc, 1139static int __event_synthesize_build_ids(struct list_head *head, u16 misc,
1144 event__handler_t process, 1140 event__handler_t process,
1145 struct kernel_info *kerninfo, 1141 struct machine *machine,
1146 struct perf_session *session) 1142 struct perf_session *session)
1147{ 1143{
1148 struct dso *pos; 1144 struct dso *pos;
@@ -1153,7 +1149,7 @@ static int __event_synthesize_build_ids(struct list_head *head, u16 misc,
1153 continue; 1149 continue;
1154 1150
1155 err = event__synthesize_build_id(pos, misc, process, 1151 err = event__synthesize_build_id(pos, misc, process,
1156 kerninfo, session); 1152 machine, session);
1157 if (err < 0) 1153 if (err < 0)
1158 return err; 1154 return err;
1159 } 1155 }
@@ -1166,15 +1162,15 @@ int event__synthesize_build_ids(event__handler_t process,
1166{ 1162{
1167 int err = 0; 1163 int err = 0;
1168 u16 kmisc, umisc; 1164 u16 kmisc, umisc;
1169 struct kernel_info *pos; 1165 struct machine *pos;
1170 struct rb_node *nd; 1166 struct rb_node *nd;
1171 1167
1172 if (!dsos__read_build_ids(&session->header, true)) 1168 if (!dsos__read_build_ids(&session->header, true))
1173 return 0; 1169 return 0;
1174 1170
1175 for (nd = rb_first(&session->kerninfo_root); nd; nd = rb_next(nd)) { 1171 for (nd = rb_first(&session->machines); nd; nd = rb_next(nd)) {
1176 pos = rb_entry(nd, struct kernel_info, rb_node); 1172 pos = rb_entry(nd, struct machine, rb_node);
1177 if (is_host_kernel(pos)) { 1173 if (machine__is_host(pos)) {
1178 kmisc = PERF_RECORD_MISC_KERNEL; 1174 kmisc = PERF_RECORD_MISC_KERNEL;
1179 umisc = PERF_RECORD_MISC_USER; 1175 umisc = PERF_RECORD_MISC_USER;
1180 } else { 1176 } else {
@@ -1182,11 +1178,11 @@ int event__synthesize_build_ids(event__handler_t process,
1182 umisc = PERF_RECORD_MISC_GUEST_USER; 1178 umisc = PERF_RECORD_MISC_GUEST_USER;
1183 } 1179 }
1184 1180
1185 err = __event_synthesize_build_ids(&pos->dsos__kernel, 1181 err = __event_synthesize_build_ids(&pos->kernel_dsos, kmisc,
1186 kmisc, process, pos, session); 1182 process, pos, session);
1187 if (err == 0) 1183 if (err == 0)
1188 err = __event_synthesize_build_ids(&pos->dsos__user, 1184 err = __event_synthesize_build_ids(&pos->user_dsos, umisc,
1189 umisc, process, pos, session); 1185 process, pos, session);
1190 if (err) 1186 if (err)
1191 break; 1187 break;
1192 } 1188 }
diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h
index 275915458148..f39443db0706 100644
--- a/tools/perf/util/header.h
+++ b/tools/perf/util/header.h
@@ -120,7 +120,7 @@ int event__process_tracing_data(event_t *self,
120 120
121int event__synthesize_build_id(struct dso *pos, u16 misc, 121int event__synthesize_build_id(struct dso *pos, u16 misc,
122 event__handler_t process, 122 event__handler_t process,
123 struct kernel_info *kerninfo, 123 struct machine *machine,
124 struct perf_session *session); 124 struct perf_session *session);
125int event__synthesize_build_ids(event__handler_t process, 125int event__synthesize_build_ids(event__handler_t process,
126 struct perf_session *session); 126 struct perf_session *session);
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
index 7facd016ec97..44a4df68b3cf 100644
--- a/tools/perf/util/map.c
+++ b/tools/perf/util/map.c
@@ -245,7 +245,7 @@ void map_groups__init(struct map_groups *self)
245 self->maps[i] = RB_ROOT; 245 self->maps[i] = RB_ROOT;
246 INIT_LIST_HEAD(&self->removed_maps[i]); 246 INIT_LIST_HEAD(&self->removed_maps[i]);
247 } 247 }
248 self->this_kerninfo = NULL; 248 self->machine = NULL;
249} 249}
250 250
251void map_groups__flush(struct map_groups *self) 251void map_groups__flush(struct map_groups *self)
@@ -513,133 +513,140 @@ struct map *maps__find(struct rb_root *maps, u64 ip)
513 return NULL; 513 return NULL;
514} 514}
515 515
516struct kernel_info *add_new_kernel_info(struct rb_root *kerninfo_root, 516int machine__init(struct machine *self, const char *root_dir, pid_t pid)
517 pid_t pid, const char *root_dir)
518{ 517{
519 struct rb_node **p = &kerninfo_root->rb_node; 518 map_groups__init(&self->kmaps);
519 RB_CLEAR_NODE(&self->rb_node);
520 INIT_LIST_HEAD(&self->user_dsos);
521 INIT_LIST_HEAD(&self->kernel_dsos);
522
523 self->kmaps.machine = self;
524 self->pid = pid;
525 self->root_dir = strdup(root_dir);
526 return self->root_dir == NULL ? -ENOMEM : 0;
527}
528
529struct machine *machines__add(struct rb_root *self, pid_t pid,
530 const char *root_dir)
531{
532 struct rb_node **p = &self->rb_node;
520 struct rb_node *parent = NULL; 533 struct rb_node *parent = NULL;
521 struct kernel_info *kerninfo, *pos; 534 struct machine *pos, *machine = malloc(sizeof(*machine));
522 535
523 kerninfo = malloc(sizeof(struct kernel_info)); 536 if (!machine)
524 if (!kerninfo)
525 return NULL; 537 return NULL;
526 538
527 kerninfo->pid = pid; 539 if (machine__init(machine, root_dir, pid) != 0) {
528 map_groups__init(&kerninfo->kmaps); 540 free(machine);
529 kerninfo->root_dir = strdup(root_dir); 541 return NULL;
530 RB_CLEAR_NODE(&kerninfo->rb_node); 542 }
531 INIT_LIST_HEAD(&kerninfo->dsos__user);
532 INIT_LIST_HEAD(&kerninfo->dsos__kernel);
533 kerninfo->kmaps.this_kerninfo = kerninfo;
534 543
535 while (*p != NULL) { 544 while (*p != NULL) {
536 parent = *p; 545 parent = *p;
537 pos = rb_entry(parent, struct kernel_info, rb_node); 546 pos = rb_entry(parent, struct machine, rb_node);
538 if (pid < pos->pid) 547 if (pid < pos->pid)
539 p = &(*p)->rb_left; 548 p = &(*p)->rb_left;
540 else 549 else
541 p = &(*p)->rb_right; 550 p = &(*p)->rb_right;
542 } 551 }
543 552
544 rb_link_node(&kerninfo->rb_node, parent, p); 553 rb_link_node(&machine->rb_node, parent, p);
545 rb_insert_color(&kerninfo->rb_node, kerninfo_root); 554 rb_insert_color(&machine->rb_node, self);
546 555
547 return kerninfo; 556 return machine;
548} 557}
549 558
550struct kernel_info *kerninfo__find(struct rb_root *kerninfo_root, pid_t pid) 559struct machine *machines__find(struct rb_root *self, pid_t pid)
551{ 560{
552 struct rb_node **p = &kerninfo_root->rb_node; 561 struct rb_node **p = &self->rb_node;
553 struct rb_node *parent = NULL; 562 struct rb_node *parent = NULL;
554 struct kernel_info *kerninfo; 563 struct machine *machine;
555 struct kernel_info *default_kerninfo = NULL; 564 struct machine *default_machine = NULL;
556 565
557 while (*p != NULL) { 566 while (*p != NULL) {
558 parent = *p; 567 parent = *p;
559 kerninfo = rb_entry(parent, struct kernel_info, rb_node); 568 machine = rb_entry(parent, struct machine, rb_node);
560 if (pid < kerninfo->pid) 569 if (pid < machine->pid)
561 p = &(*p)->rb_left; 570 p = &(*p)->rb_left;
562 else if (pid > kerninfo->pid) 571 else if (pid > machine->pid)
563 p = &(*p)->rb_right; 572 p = &(*p)->rb_right;
564 else 573 else
565 return kerninfo; 574 return machine;
566 if (!kerninfo->pid) 575 if (!machine->pid)
567 default_kerninfo = kerninfo; 576 default_machine = machine;
568 } 577 }
569 578
570 return default_kerninfo; 579 return default_machine;
571} 580}
572 581
573struct kernel_info *kerninfo__findhost(struct rb_root *kerninfo_root) 582/*
583 * FIXME: Why repeatedly search for this?
584 */
585struct machine *machines__find_host(struct rb_root *self)
574{ 586{
575 struct rb_node **p = &kerninfo_root->rb_node; 587 struct rb_node **p = &self->rb_node;
576 struct rb_node *parent = NULL; 588 struct rb_node *parent = NULL;
577 struct kernel_info *kerninfo; 589 struct machine *machine;
578 pid_t pid = HOST_KERNEL_ID; 590 pid_t pid = HOST_KERNEL_ID;
579 591
580 while (*p != NULL) { 592 while (*p != NULL) {
581 parent = *p; 593 parent = *p;
582 kerninfo = rb_entry(parent, struct kernel_info, rb_node); 594 machine = rb_entry(parent, struct machine, rb_node);
583 if (pid < kerninfo->pid) 595 if (pid < machine->pid)
584 p = &(*p)->rb_left; 596 p = &(*p)->rb_left;
585 else if (pid > kerninfo->pid) 597 else if (pid > machine->pid)
586 p = &(*p)->rb_right; 598 p = &(*p)->rb_right;
587 else 599 else
588 return kerninfo; 600 return machine;
589 } 601 }
590 602
591 return NULL; 603 return NULL;
592} 604}
593 605
594struct kernel_info *kerninfo__findnew(struct rb_root *kerninfo_root, pid_t pid) 606struct machine *machines__findnew(struct rb_root *self, pid_t pid)
595{ 607{
596 char path[PATH_MAX]; 608 char path[PATH_MAX];
597 const char *root_dir; 609 const char *root_dir;
598 int ret; 610 struct machine *machine = machines__find(self, pid);
599 struct kernel_info *kerninfo = kerninfo__find(kerninfo_root, pid);
600 611
601 if (!kerninfo || kerninfo->pid != pid) { 612 if (!machine || machine->pid != pid) {
602 if (pid == HOST_KERNEL_ID || pid == DEFAULT_GUEST_KERNEL_ID) 613 if (pid == HOST_KERNEL_ID || pid == DEFAULT_GUEST_KERNEL_ID)
603 root_dir = ""; 614 root_dir = "";
604 else { 615 else {
605 if (!symbol_conf.guestmount) 616 if (!symbol_conf.guestmount)
606 goto out; 617 goto out;
607 sprintf(path, "%s/%d", symbol_conf.guestmount, pid); 618 sprintf(path, "%s/%d", symbol_conf.guestmount, pid);
608 ret = access(path, R_OK); 619 if (access(path, R_OK)) {
609 if (ret) {
610 pr_err("Can't access file %s\n", path); 620 pr_err("Can't access file %s\n", path);
611 goto out; 621 goto out;
612 } 622 }
613 root_dir = path; 623 root_dir = path;
614 } 624 }
615 kerninfo = add_new_kernel_info(kerninfo_root, pid, root_dir); 625 machine = machines__add(self, pid, root_dir);
616 } 626 }
617 627
618out: 628out:
619 return kerninfo; 629 return machine;
620} 630}
621 631
622void kerninfo__process_allkernels(struct rb_root *kerninfo_root, 632void machines__process(struct rb_root *self, machine__process_t process, void *data)
623 process_kernel_info process,
624 void *data)
625{ 633{
626 struct rb_node *nd; 634 struct rb_node *nd;
627 635
628 for (nd = rb_first(kerninfo_root); nd; nd = rb_next(nd)) { 636 for (nd = rb_first(self); nd; nd = rb_next(nd)) {
629 struct kernel_info *pos = rb_entry(nd, struct kernel_info, 637 struct machine *pos = rb_entry(nd, struct machine, rb_node);
630 rb_node);
631 process(pos, data); 638 process(pos, data);
632 } 639 }
633} 640}
634 641
635char *kern_mmap_name(struct kernel_info *kerninfo, char *buff) 642char *machine__mmap_name(struct machine *self, char *bf, size_t size)
636{ 643{
637 if (is_host_kernel(kerninfo)) 644 if (machine__is_host(self))
638 sprintf(buff, "[%s]", "kernel.kallsyms"); 645 snprintf(bf, size, "[%s]", "kernel.kallsyms");
639 else if (is_default_guest(kerninfo)) 646 else if (machine__is_default_guest(self))
640 sprintf(buff, "[%s]", "guest.kernel.kallsyms"); 647 snprintf(bf, size, "[%s]", "guest.kernel.kallsyms");
641 else 648 else
642 sprintf(buff, "[%s.%d]", "guest.kernel.kallsyms", kerninfo->pid); 649 snprintf(bf, size, "[%s.%d]", "guest.kernel.kallsyms", self->pid);
643 650
644 return buff; 651 return bf;
645} 652}
diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h
index 30d38d634e09..f39134512829 100644
--- a/tools/perf/util/map.h
+++ b/tools/perf/util/map.h
@@ -5,6 +5,7 @@
5#include <linux/list.h> 5#include <linux/list.h>
6#include <linux/rbtree.h> 6#include <linux/rbtree.h>
7#include <stdio.h> 7#include <stdio.h>
8#include <stdbool.h>
8#include "types.h" 9#include "types.h"
9 10
10enum map_type { 11enum map_type {
@@ -19,7 +20,7 @@ extern const char *map_type__name[MAP__NR_TYPES];
19struct dso; 20struct dso;
20struct ref_reloc_sym; 21struct ref_reloc_sym;
21struct map_groups; 22struct map_groups;
22struct kernel_info; 23struct machine;
23 24
24struct map { 25struct map {
25 union { 26 union {
@@ -29,6 +30,7 @@ struct map {
29 u64 start; 30 u64 start;
30 u64 end; 31 u64 end;
31 enum map_type type; 32 enum map_type type;
33 u32 priv;
32 u64 pgoff; 34 u64 pgoff;
33 35
34 /* ip -> dso rip */ 36 /* ip -> dso rip */
@@ -46,25 +48,31 @@ struct kmap {
46}; 48};
47 49
48struct map_groups { 50struct map_groups {
49 struct rb_root maps[MAP__NR_TYPES]; 51 struct rb_root maps[MAP__NR_TYPES];
50 struct list_head removed_maps[MAP__NR_TYPES]; 52 struct list_head removed_maps[MAP__NR_TYPES];
51 struct kernel_info *this_kerninfo; 53 struct machine *machine;
52}; 54};
53 55
54/* Native host kernel uses -1 as pid index in kernel_info */ 56/* Native host kernel uses -1 as pid index in machine */
55#define HOST_KERNEL_ID (-1) 57#define HOST_KERNEL_ID (-1)
56#define DEFAULT_GUEST_KERNEL_ID (0) 58#define DEFAULT_GUEST_KERNEL_ID (0)
57 59
58struct kernel_info { 60struct machine {
59 struct rb_node rb_node; 61 struct rb_node rb_node;
60 pid_t pid; 62 pid_t pid;
61 char *root_dir; 63 char *root_dir;
62 struct list_head dsos__user; 64 struct list_head user_dsos;
63 struct list_head dsos__kernel; 65 struct list_head kernel_dsos;
64 struct map_groups kmaps; 66 struct map_groups kmaps;
65 struct map *vmlinux_maps[MAP__NR_TYPES]; 67 struct map *vmlinux_maps[MAP__NR_TYPES];
66}; 68};
67 69
70static inline
71struct map *machine__kernel_map(struct machine *self, enum map_type type)
72{
73 return self->vmlinux_maps[type];
74}
75
68static inline struct kmap *map__kmap(struct map *self) 76static inline struct kmap *map__kmap(struct map *self)
69{ 77{
70 return (struct kmap *)(self + 1); 78 return (struct kmap *)(self + 1);
@@ -124,36 +132,31 @@ int map_groups__clone(struct map_groups *self,
124size_t map_groups__fprintf(struct map_groups *self, int verbose, FILE *fp); 132size_t map_groups__fprintf(struct map_groups *self, int verbose, FILE *fp);
125size_t map_groups__fprintf_maps(struct map_groups *self, int verbose, FILE *fp); 133size_t map_groups__fprintf_maps(struct map_groups *self, int verbose, FILE *fp);
126 134
127struct kernel_info *add_new_kernel_info(struct rb_root *kerninfo_root, 135typedef void (*machine__process_t)(struct machine *self, void *data);
128 pid_t pid, const char *root_dir); 136
129struct kernel_info *kerninfo__find(struct rb_root *kerninfo_root, pid_t pid); 137void machines__process(struct rb_root *self, machine__process_t process, void *data);
130struct kernel_info *kerninfo__findnew(struct rb_root *kerninfo_root, pid_t pid); 138struct machine *machines__add(struct rb_root *self, pid_t pid,
131struct kernel_info *kerninfo__findhost(struct rb_root *kerninfo_root); 139 const char *root_dir);
132char *kern_mmap_name(struct kernel_info *kerninfo, char *buff); 140struct machine *machines__find_host(struct rb_root *self);
141struct machine *machines__find(struct rb_root *self, pid_t pid);
142struct machine *machines__findnew(struct rb_root *self, pid_t pid);
143char *machine__mmap_name(struct machine *self, char *bf, size_t size);
144int machine__init(struct machine *self, const char *root_dir, pid_t pid);
133 145
134/* 146/*
135 * Default guest kernel is defined by parameter --guestkallsyms 147 * Default guest kernel is defined by parameter --guestkallsyms
136 * and --guestmodules 148 * and --guestmodules
137 */ 149 */
138static inline int is_default_guest(struct kernel_info *kerninfo) 150static inline bool machine__is_default_guest(struct machine *self)
139{ 151{
140 if (!kerninfo) 152 return self ? self->pid == DEFAULT_GUEST_KERNEL_ID : false;
141 return 0;
142 return kerninfo->pid == DEFAULT_GUEST_KERNEL_ID;
143} 153}
144 154
145static inline int is_host_kernel(struct kernel_info *kerninfo) 155static inline bool machine__is_host(struct machine *self)
146{ 156{
147 if (!kerninfo) 157 return self ? self->pid == HOST_KERNEL_ID : false;
148 return 0;
149 return kerninfo->pid == HOST_KERNEL_ID;
150} 158}
151 159
152typedef void (*process_kernel_info)(struct kernel_info *kerninfo, void *data);
153void kerninfo__process_allkernels(struct rb_root *kerninfo_root,
154 process_kernel_info process,
155 void *data);
156
157static inline void map_groups__insert(struct map_groups *self, struct map *map) 160static inline void map_groups__insert(struct map_groups *self, struct map *map)
158{ 161{
159 maps__insert(&self->maps[map->type], map); 162 maps__insert(&self->maps[map->type], map);
@@ -178,10 +181,20 @@ struct symbol *map_groups__find_symbol_by_name(struct map_groups *self,
178 symbol_filter_t filter); 181 symbol_filter_t filter);
179 182
180static inline 183static inline
181struct symbol *map_groups__find_function(struct map_groups *self, u64 addr, 184struct symbol *machine__find_kernel_symbol(struct machine *self,
182 struct map **mapp, symbol_filter_t filter) 185 enum map_type type, u64 addr,
186 struct map **mapp,
187 symbol_filter_t filter)
188{
189 return map_groups__find_symbol(&self->kmaps, type, addr, mapp, filter);
190}
191
192static inline
193struct symbol *machine__find_kernel_function(struct machine *self, u64 addr,
194 struct map **mapp,
195 symbol_filter_t filter)
183{ 196{
184 return map_groups__find_symbol(self, MAP__FUNCTION, addr, mapp, filter); 197 return machine__find_kernel_symbol(self, MAP__FUNCTION, addr, mapp, filter);
185} 198}
186 199
187static inline 200static inline
@@ -197,10 +210,7 @@ int map_groups__fixup_overlappings(struct map_groups *self, struct map *map,
197 210
198struct map *map_groups__find_by_name(struct map_groups *self, 211struct map *map_groups__find_by_name(struct map_groups *self,
199 enum map_type type, const char *name); 212 enum map_type type, const char *name);
200struct map *map_groups__new_module(struct map_groups *self, 213struct map *machine__new_module(struct machine *self, u64 start, const char *filename);
201 u64 start,
202 const char *filename,
203 struct kernel_info *kerninfo);
204 214
205void map_groups__flush(struct map_groups *self); 215void map_groups__flush(struct map_groups *self);
206 216
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 9ded38ced234..914c67095d96 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -72,8 +72,7 @@ static int e_snprintf(char *str, size_t size, const char *format, ...)
72} 72}
73 73
74static char *synthesize_perf_probe_point(struct perf_probe_point *pp); 74static char *synthesize_perf_probe_point(struct perf_probe_point *pp);
75static struct map_groups kmap_groups; 75static struct machine machine;
76static struct map *kmaps[MAP__NR_TYPES];
77 76
78/* Initialize symbol maps and path of vmlinux */ 77/* Initialize symbol maps and path of vmlinux */
79static int init_vmlinux(void) 78static int init_vmlinux(void)
@@ -92,12 +91,15 @@ static int init_vmlinux(void)
92 goto out; 91 goto out;
93 } 92 }
94 93
94 ret = machine__init(&machine, "/", 0);
95 if (ret < 0)
96 goto out;
97
95 kernel = dso__new_kernel(symbol_conf.vmlinux_name); 98 kernel = dso__new_kernel(symbol_conf.vmlinux_name);
96 if (kernel == NULL) 99 if (kernel == NULL)
97 die("Failed to create kernel dso."); 100 die("Failed to create kernel dso.");
98 101
99 map_groups__init(&kmap_groups); 102 ret = __machine__create_kernel_maps(&machine, kernel);
100 ret = __map_groups__create_kernel_maps(&kmap_groups, kmaps, kernel);
101 if (ret < 0) 103 if (ret < 0)
102 pr_debug("Failed to create kernel maps.\n"); 104 pr_debug("Failed to create kernel maps.\n");
103 105
@@ -110,12 +112,12 @@ out:
110#ifdef DWARF_SUPPORT 112#ifdef DWARF_SUPPORT
111static int open_vmlinux(void) 113static int open_vmlinux(void)
112{ 114{
113 if (map__load(kmaps[MAP__FUNCTION], NULL) < 0) { 115 if (map__load(machine.vmlinux_maps[MAP__FUNCTION], NULL) < 0) {
114 pr_debug("Failed to load kernel map.\n"); 116 pr_debug("Failed to load kernel map.\n");
115 return -EINVAL; 117 return -EINVAL;
116 } 118 }
117 pr_debug("Try to open %s\n", kmaps[MAP__FUNCTION]->dso->long_name); 119 pr_debug("Try to open %s\n", machine.vmlinux_maps[MAP__FUNCTION]->dso->long_name);
118 return open(kmaps[MAP__FUNCTION]->dso->long_name, O_RDONLY); 120 return open(machine.vmlinux_maps[MAP__FUNCTION]->dso->long_name, O_RDONLY);
119} 121}
120 122
121/* Convert trace point to probe point with debuginfo */ 123/* Convert trace point to probe point with debuginfo */
@@ -125,7 +127,7 @@ static int convert_to_perf_probe_point(struct kprobe_trace_point *tp,
125 struct symbol *sym; 127 struct symbol *sym;
126 int fd, ret = -ENOENT; 128 int fd, ret = -ENOENT;
127 129
128 sym = map__find_symbol_by_name(kmaps[MAP__FUNCTION], 130 sym = map__find_symbol_by_name(machine.vmlinux_maps[MAP__FUNCTION],
129 tp->symbol, NULL); 131 tp->symbol, NULL);
130 if (sym) { 132 if (sym) {
131 fd = open_vmlinux(); 133 fd = open_vmlinux();
@@ -1466,7 +1468,7 @@ static int convert_to_kprobe_trace_events(struct perf_probe_event *pev,
1466 } 1468 }
1467 1469
1468 /* Currently just checking function name from symbol map */ 1470 /* Currently just checking function name from symbol map */
1469 sym = map__find_symbol_by_name(kmaps[MAP__FUNCTION], 1471 sym = map__find_symbol_by_name(machine.vmlinux_maps[MAP__FUNCTION],
1470 tev->point.symbol, NULL); 1472 tev->point.symbol, NULL);
1471 if (!sym) { 1473 if (!sym) {
1472 pr_warning("Kernel symbol \'%s\' not found.\n", 1474 pr_warning("Kernel symbol \'%s\' not found.\n",
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index b7aade2184b2..a8dd73ed1581 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -69,12 +69,11 @@ void perf_session__update_sample_type(struct perf_session *self)
69 69
70int perf_session__create_kernel_maps(struct perf_session *self) 70int perf_session__create_kernel_maps(struct perf_session *self)
71{ 71{
72 int ret; 72 struct rb_root *machines = &self->machines;
73 struct rb_root *root = &self->kerninfo_root; 73 int ret = machines__create_kernel_maps(machines, HOST_KERNEL_ID);
74 74
75 ret = map_groups__create_kernel_maps(root, HOST_KERNEL_ID);
76 if (ret >= 0) 75 if (ret >= 0)
77 ret = map_groups__create_guest_kernel_maps(root); 76 ret = machines__create_guest_kernel_maps(machines);
78 return ret; 77 return ret;
79} 78}
80 79
@@ -97,7 +96,7 @@ struct perf_session *perf_session__new(const char *filename, int mode, bool forc
97 self->cwd = NULL; 96 self->cwd = NULL;
98 self->cwdlen = 0; 97 self->cwdlen = 0;
99 self->unknown_events = 0; 98 self->unknown_events = 0;
100 self->kerninfo_root = RB_ROOT; 99 self->machines = RB_ROOT;
101 self->ordered_samples.flush_limit = ULLONG_MAX; 100 self->ordered_samples.flush_limit = ULLONG_MAX;
102 INIT_LIST_HEAD(&self->ordered_samples.samples_head); 101 INIT_LIST_HEAD(&self->ordered_samples.samples_head);
103 102
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index 796e2291ebd7..61ca92e58ad4 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -25,7 +25,7 @@ struct perf_session {
25 unsigned long mmap_window; 25 unsigned long mmap_window;
26 struct rb_root threads; 26 struct rb_root threads;
27 struct thread *last_match; 27 struct thread *last_match;
28 struct rb_root kerninfo_root; 28 struct rb_root machines;
29 struct events_stats events_stats; 29 struct events_stats events_stats;
30 struct rb_root stats_by_id; 30 struct rb_root stats_by_id;
31 unsigned long event_total[PERF_RECORD_MAX]; 31 unsigned long event_total[PERF_RECORD_MAX];
@@ -102,4 +102,42 @@ int perf_session__browse_hists(struct rb_root *hists, u64 nr_hists,
102 u64 session_total, const char *helpline, 102 u64 session_total, const char *helpline,
103 const char *input_name); 103 const char *input_name);
104#endif 104#endif
105
106static inline
107struct machine *perf_session__find_host_machine(struct perf_session *self)
108{
109 return machines__find_host(&self->machines);
110}
111
112static inline
113struct machine *perf_session__find_machine(struct perf_session *self, pid_t pid)
114{
115 return machines__find(&self->machines, pid);
116}
117
118static inline
119struct machine *perf_session__findnew_machine(struct perf_session *self, pid_t pid)
120{
121 return machines__findnew(&self->machines, pid);
122}
123
124static inline
125void perf_session__process_machines(struct perf_session *self,
126 machine__process_t process)
127{
128 return machines__process(&self->machines, process, self);
129}
130
131static inline
132size_t perf_session__fprintf_dsos(struct perf_session *self, FILE *fp)
133{
134 return machines__fprintf_dsos(&self->machines, fp);
135}
136
137static inline
138size_t perf_session__fprintf_dsos_buildid(struct perf_session *self, FILE *fp,
139 bool with_hits)
140{
141 return machines__fprintf_dsos_buildid(&self->machines, fp, with_hits);
142}
105#endif /* __PERF_SESSION_H */ 143#endif /* __PERF_SESSION_H */
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index e77c33a11de3..4c0146a49063 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -485,7 +485,7 @@ static int dso__split_kallsyms(struct dso *self, struct map *map,
485 symbol_filter_t filter) 485 symbol_filter_t filter)
486{ 486{
487 struct map_groups *kmaps = map__kmap(map)->kmaps; 487 struct map_groups *kmaps = map__kmap(map)->kmaps;
488 struct kernel_info *kerninfo = kmaps->this_kerninfo; 488 struct machine *machine = kmaps->machine;
489 struct map *curr_map = map; 489 struct map *curr_map = map;
490 struct symbol *pos; 490 struct symbol *pos;
491 int count = 0; 491 int count = 0;
@@ -508,8 +508,8 @@ static int dso__split_kallsyms(struct dso *self, struct map *map,
508 508
509 if (strcmp(curr_map->dso->short_name, module)) { 509 if (strcmp(curr_map->dso->short_name, module)) {
510 if (curr_map != map && 510 if (curr_map != map &&
511 self->kernel == DSO_TYPE_GUEST_KERNEL && 511 self->kernel == DSO_TYPE_GUEST_KERNEL &&
512 is_default_guest(kerninfo)) { 512 machine__is_default_guest(machine)) {
513 /* 513 /*
514 * We assume all symbols of a module are 514 * We assume all symbols of a module are
515 * continuous in * kallsyms, so curr_map 515 * continuous in * kallsyms, so curr_map
@@ -527,13 +527,13 @@ static int dso__split_kallsyms(struct dso *self, struct map *map,
527 pr_err("%s/proc/{kallsyms,modules} " 527 pr_err("%s/proc/{kallsyms,modules} "
528 "inconsistency while looking " 528 "inconsistency while looking "
529 "for \"%s\" module!\n", 529 "for \"%s\" module!\n",
530 kerninfo->root_dir, module); 530 machine->root_dir, module);
531 curr_map = map; 531 curr_map = map;
532 goto discard_symbol; 532 goto discard_symbol;
533 } 533 }
534 534
535 if (curr_map->dso->loaded && 535 if (curr_map->dso->loaded &&
536 !is_default_guest(kmaps->this_kerninfo)) 536 !machine__is_default_guest(machine))
537 goto discard_symbol; 537 goto discard_symbol;
538 } 538 }
539 /* 539 /*
@@ -586,7 +586,7 @@ discard_symbol: rb_erase(&pos->rb_node, root);
586 586
587 if (curr_map != map && 587 if (curr_map != map &&
588 self->kernel == DSO_TYPE_GUEST_KERNEL && 588 self->kernel == DSO_TYPE_GUEST_KERNEL &&
589 is_default_guest(kmaps->this_kerninfo)) { 589 machine__is_default_guest(kmaps->machine)) {
590 dso__set_loaded(curr_map->dso, curr_map->type); 590 dso__set_loaded(curr_map->dso, curr_map->type);
591 } 591 }
592 592
@@ -1291,7 +1291,7 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter)
1291 char build_id_hex[BUILD_ID_SIZE * 2 + 1]; 1291 char build_id_hex[BUILD_ID_SIZE * 2 + 1];
1292 int ret = -1; 1292 int ret = -1;
1293 int fd; 1293 int fd;
1294 struct kernel_info *kerninfo; 1294 struct machine *machine;
1295 const char *root_dir; 1295 const char *root_dir;
1296 1296
1297 dso__set_loaded(self, map->type); 1297 dso__set_loaded(self, map->type);
@@ -1301,10 +1301,10 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter)
1301 else if (self->kernel == DSO_TYPE_GUEST_KERNEL) 1301 else if (self->kernel == DSO_TYPE_GUEST_KERNEL)
1302 return dso__load_guest_kernel_sym(self, map, filter); 1302 return dso__load_guest_kernel_sym(self, map, filter);
1303 1303
1304 if (map->groups && map->groups->this_kerninfo) 1304 if (map->groups && map->groups->machine)
1305 kerninfo = map->groups->this_kerninfo; 1305 machine = map->groups->machine;
1306 else 1306 else
1307 kerninfo = NULL; 1307 machine = NULL;
1308 1308
1309 name = malloc(size); 1309 name = malloc(size);
1310 if (!name) 1310 if (!name)
@@ -1359,8 +1359,8 @@ more:
1359 snprintf(name, size, "%s", self->long_name); 1359 snprintf(name, size, "%s", self->long_name);
1360 break; 1360 break;
1361 case DSO__ORIG_GUEST_KMODULE: 1361 case DSO__ORIG_GUEST_KMODULE:
1362 if (map->groups && map->groups->this_kerninfo) 1362 if (map->groups && map->groups->machine)
1363 root_dir = map->groups->this_kerninfo->root_dir; 1363 root_dir = map->groups->machine->root_dir;
1364 else 1364 else
1365 root_dir = ""; 1365 root_dir = "";
1366 snprintf(name, size, "%s%s", root_dir, self->long_name); 1366 snprintf(name, size, "%s%s", root_dir, self->long_name);
@@ -1528,21 +1528,20 @@ static char *get_kernel_version(const char *root_dir)
1528 return strdup(name); 1528 return strdup(name);
1529} 1529}
1530 1530
1531static int map_groups__set_modules_path(struct map_groups *self, 1531static int machine__set_modules_path(struct machine *self)
1532 const char *root_dir)
1533{ 1532{
1534 char *version; 1533 char *version;
1535 char modules_path[PATH_MAX]; 1534 char modules_path[PATH_MAX];
1536 1535
1537 version = get_kernel_version(root_dir); 1536 version = get_kernel_version(self->root_dir);
1538 if (!version) 1537 if (!version)
1539 return -1; 1538 return -1;
1540 1539
1541 snprintf(modules_path, sizeof(modules_path), "%s/lib/modules/%s/kernel", 1540 snprintf(modules_path, sizeof(modules_path), "%s/lib/modules/%s/kernel",
1542 root_dir, version); 1541 self->root_dir, version);
1543 free(version); 1542 free(version);
1544 1543
1545 return map_groups__set_modules_path_dir(self, modules_path); 1544 return map_groups__set_modules_path_dir(&self->kmaps, modules_path);
1546} 1545}
1547 1546
1548/* 1547/*
@@ -1564,14 +1563,12 @@ static struct map *map__new2(u64 start, struct dso *dso, enum map_type type)
1564 return self; 1563 return self;
1565} 1564}
1566 1565
1567struct map *map_groups__new_module(struct map_groups *self, u64 start, 1566struct map *machine__new_module(struct machine *self, u64 start,
1568 const char *filename, 1567 const char *filename)
1569 struct kernel_info *kerninfo)
1570{ 1568{
1571 struct map *map; 1569 struct map *map;
1572 struct dso *dso; 1570 struct dso *dso = __dsos__findnew(&self->kernel_dsos, filename);
1573 1571
1574 dso = __dsos__findnew(&kerninfo->dsos__kernel, filename);
1575 if (dso == NULL) 1572 if (dso == NULL)
1576 return NULL; 1573 return NULL;
1577 1574
@@ -1579,28 +1576,27 @@ struct map *map_groups__new_module(struct map_groups *self, u64 start,
1579 if (map == NULL) 1576 if (map == NULL)
1580 return NULL; 1577 return NULL;
1581 1578
1582 if (is_host_kernel(kerninfo)) 1579 if (machine__is_host(self))
1583 dso->origin = DSO__ORIG_KMODULE; 1580 dso->origin = DSO__ORIG_KMODULE;
1584 else 1581 else
1585 dso->origin = DSO__ORIG_GUEST_KMODULE; 1582 dso->origin = DSO__ORIG_GUEST_KMODULE;
1586 map_groups__insert(self, map); 1583 map_groups__insert(&self->kmaps, map);
1587 return map; 1584 return map;
1588} 1585}
1589 1586
1590static int map_groups__create_modules(struct kernel_info *kerninfo) 1587static int machine__create_modules(struct machine *self)
1591{ 1588{
1592 char *line = NULL; 1589 char *line = NULL;
1593 size_t n; 1590 size_t n;
1594 FILE *file; 1591 FILE *file;
1595 struct map *map; 1592 struct map *map;
1596 const char *root_dir;
1597 const char *modules; 1593 const char *modules;
1598 char path[PATH_MAX]; 1594 char path[PATH_MAX];
1599 1595
1600 if (is_default_guest(kerninfo)) 1596 if (machine__is_default_guest(self))
1601 modules = symbol_conf.default_guest_modules; 1597 modules = symbol_conf.default_guest_modules;
1602 else { 1598 else {
1603 sprintf(path, "%s/proc/modules", kerninfo->root_dir); 1599 sprintf(path, "%s/proc/modules", self->root_dir);
1604 modules = path; 1600 modules = path;
1605 } 1601 }
1606 1602
@@ -1608,8 +1604,6 @@ static int map_groups__create_modules(struct kernel_info *kerninfo)
1608 if (file == NULL) 1604 if (file == NULL)
1609 return -1; 1605 return -1;
1610 1606
1611 root_dir = kerninfo->root_dir;
1612
1613 while (!feof(file)) { 1607 while (!feof(file)) {
1614 char name[PATH_MAX]; 1608 char name[PATH_MAX];
1615 u64 start; 1609 u64 start;
@@ -1638,17 +1632,16 @@ static int map_groups__create_modules(struct kernel_info *kerninfo)
1638 *sep = '\0'; 1632 *sep = '\0';
1639 1633
1640 snprintf(name, sizeof(name), "[%s]", line); 1634 snprintf(name, sizeof(name), "[%s]", line);
1641 map = map_groups__new_module(&kerninfo->kmaps, 1635 map = machine__new_module(self, start, name);
1642 start, name, kerninfo);
1643 if (map == NULL) 1636 if (map == NULL)
1644 goto out_delete_line; 1637 goto out_delete_line;
1645 dso__kernel_module_get_build_id(map->dso, root_dir); 1638 dso__kernel_module_get_build_id(map->dso, self->root_dir);
1646 } 1639 }
1647 1640
1648 free(line); 1641 free(line);
1649 fclose(file); 1642 fclose(file);
1650 1643
1651 return map_groups__set_modules_path(&kerninfo->kmaps, root_dir); 1644 return machine__set_modules_path(self);
1652 1645
1653out_delete_line: 1646out_delete_line:
1654 free(line); 1647 free(line);
@@ -1820,16 +1813,16 @@ static int dso__load_guest_kernel_sym(struct dso *self, struct map *map,
1820{ 1813{
1821 int err; 1814 int err;
1822 const char *kallsyms_filename = NULL; 1815 const char *kallsyms_filename = NULL;
1823 struct kernel_info *kerninfo; 1816 struct machine *machine;
1824 char path[PATH_MAX]; 1817 char path[PATH_MAX];
1825 1818
1826 if (!map->groups) { 1819 if (!map->groups) {
1827 pr_debug("Guest kernel map hasn't the point to groups\n"); 1820 pr_debug("Guest kernel map hasn't the point to groups\n");
1828 return -1; 1821 return -1;
1829 } 1822 }
1830 kerninfo = map->groups->this_kerninfo; 1823 machine = map->groups->machine;
1831 1824
1832 if (is_default_guest(kerninfo)) { 1825 if (machine__is_default_guest(machine)) {
1833 /* 1826 /*
1834 * if the user specified a vmlinux filename, use it and only 1827 * if the user specified a vmlinux filename, use it and only
1835 * it, reporting errors to the user if it cannot be used. 1828 * it, reporting errors to the user if it cannot be used.
@@ -1845,7 +1838,7 @@ static int dso__load_guest_kernel_sym(struct dso *self, struct map *map,
1845 if (!kallsyms_filename) 1838 if (!kallsyms_filename)
1846 return -1; 1839 return -1;
1847 } else { 1840 } else {
1848 sprintf(path, "%s/proc/kallsyms", kerninfo->root_dir); 1841 sprintf(path, "%s/proc/kallsyms", machine->root_dir);
1849 kallsyms_filename = path; 1842 kallsyms_filename = path;
1850 } 1843 }
1851 1844
@@ -1856,9 +1849,8 @@ static int dso__load_guest_kernel_sym(struct dso *self, struct map *map,
1856out_try_fixup: 1849out_try_fixup:
1857 if (err > 0) { 1850 if (err > 0) {
1858 if (kallsyms_filename != NULL) { 1851 if (kallsyms_filename != NULL) {
1859 kern_mmap_name(kerninfo, path); 1852 machine__mmap_name(machine, path, sizeof(path));
1860 dso__set_long_name(self, 1853 dso__set_long_name(self, strdup(path));
1861 strdup(path));
1862 } 1854 }
1863 map__fixup_start(map); 1855 map__fixup_start(map);
1864 map__fixup_end(map); 1856 map__fixup_end(map);
@@ -1897,27 +1889,32 @@ struct dso *__dsos__findnew(struct list_head *head, const char *name)
1897 return dso; 1889 return dso;
1898} 1890}
1899 1891
1900static void __dsos__fprintf(struct list_head *head, FILE *fp) 1892static size_t __dsos__fprintf(struct list_head *head, FILE *fp)
1901{ 1893{
1902 struct dso *pos; 1894 struct dso *pos;
1895 size_t ret = 0;
1903 1896
1904 list_for_each_entry(pos, head, node) { 1897 list_for_each_entry(pos, head, node) {
1905 int i; 1898 int i;
1906 for (i = 0; i < MAP__NR_TYPES; ++i) 1899 for (i = 0; i < MAP__NR_TYPES; ++i)
1907 dso__fprintf(pos, i, fp); 1900 ret += dso__fprintf(pos, i, fp);
1908 } 1901 }
1902
1903 return ret;
1909} 1904}
1910 1905
1911void dsos__fprintf(struct rb_root *kerninfo_root, FILE *fp) 1906size_t machines__fprintf_dsos(struct rb_root *self, FILE *fp)
1912{ 1907{
1913 struct rb_node *nd; 1908 struct rb_node *nd;
1909 size_t ret = 0;
1914 1910
1915 for (nd = rb_first(kerninfo_root); nd; nd = rb_next(nd)) { 1911 for (nd = rb_first(self); nd; nd = rb_next(nd)) {
1916 struct kernel_info *pos = rb_entry(nd, struct kernel_info, 1912 struct machine *pos = rb_entry(nd, struct machine, rb_node);
1917 rb_node); 1913 ret += __dsos__fprintf(&pos->kernel_dsos, fp);
1918 __dsos__fprintf(&pos->dsos__kernel, fp); 1914 ret += __dsos__fprintf(&pos->user_dsos, fp);
1919 __dsos__fprintf(&pos->dsos__user, fp);
1920 } 1915 }
1916
1917 return ret;
1921} 1918}
1922 1919
1923static size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp, 1920static size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp,
@@ -1935,19 +1932,15 @@ static size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp,
1935 return ret; 1932 return ret;
1936} 1933}
1937 1934
1938size_t dsos__fprintf_buildid(struct rb_root *kerninfo_root, 1935size_t machines__fprintf_dsos_buildid(struct rb_root *self, FILE *fp, bool with_hits)
1939 FILE *fp, bool with_hits)
1940{ 1936{
1941 struct rb_node *nd; 1937 struct rb_node *nd;
1942 size_t ret = 0; 1938 size_t ret = 0;
1943 1939
1944 for (nd = rb_first(kerninfo_root); nd; nd = rb_next(nd)) { 1940 for (nd = rb_first(self); nd; nd = rb_next(nd)) {
1945 struct kernel_info *pos = rb_entry(nd, struct kernel_info, 1941 struct machine *pos = rb_entry(nd, struct machine, rb_node);
1946 rb_node); 1942 ret += __dsos__fprintf_buildid(&pos->kernel_dsos, fp, with_hits);
1947 ret += __dsos__fprintf_buildid(&pos->dsos__kernel, 1943 ret += __dsos__fprintf_buildid(&pos->user_dsos, fp, with_hits);
1948 fp, with_hits);
1949 ret += __dsos__fprintf_buildid(&pos->dsos__user,
1950 fp, with_hits);
1951 } 1944 }
1952 return ret; 1945 return ret;
1953} 1946}
@@ -1964,14 +1957,12 @@ struct dso *dso__new_kernel(const char *name)
1964 return self; 1957 return self;
1965} 1958}
1966 1959
1967static struct dso *dso__new_guest_kernel(struct kernel_info *kerninfo, 1960static struct dso *dso__new_guest_kernel(struct machine *machine,
1968 const char *name) 1961 const char *name)
1969{ 1962{
1970 char buff[PATH_MAX]; 1963 char bf[PATH_MAX];
1971 struct dso *self; 1964 struct dso *self = dso__new(name ?: machine__mmap_name(machine, bf, sizeof(bf)));
1972 1965
1973 kern_mmap_name(kerninfo, buff);
1974 self = dso__new(name ?: buff);
1975 if (self != NULL) { 1966 if (self != NULL) {
1976 dso__set_short_name(self, "[guest.kernel]"); 1967 dso__set_short_name(self, "[guest.kernel]");
1977 self->kernel = DSO_TYPE_GUEST_KERNEL; 1968 self->kernel = DSO_TYPE_GUEST_KERNEL;
@@ -1980,64 +1971,78 @@ static struct dso *dso__new_guest_kernel(struct kernel_info *kerninfo,
1980 return self; 1971 return self;
1981} 1972}
1982 1973
1983void dso__read_running_kernel_build_id(struct dso *self, 1974void dso__read_running_kernel_build_id(struct dso *self, struct machine *machine)
1984 struct kernel_info *kerninfo)
1985{ 1975{
1986 char path[PATH_MAX]; 1976 char path[PATH_MAX];
1987 1977
1988 if (is_default_guest(kerninfo)) 1978 if (machine__is_default_guest(machine))
1989 return; 1979 return;
1990 sprintf(path, "%s/sys/kernel/notes", kerninfo->root_dir); 1980 sprintf(path, "%s/sys/kernel/notes", machine->root_dir);
1991 if (sysfs__read_build_id(path, self->build_id, 1981 if (sysfs__read_build_id(path, self->build_id,
1992 sizeof(self->build_id)) == 0) 1982 sizeof(self->build_id)) == 0)
1993 self->has_build_id = true; 1983 self->has_build_id = true;
1994} 1984}
1995 1985
1996static struct dso *dsos__create_kernel(struct kernel_info *kerninfo) 1986static struct dso *machine__create_kernel(struct machine *self)
1997{ 1987{
1998 const char *vmlinux_name = NULL; 1988 const char *vmlinux_name = NULL;
1999 struct dso *kernel; 1989 struct dso *kernel;
2000 1990
2001 if (is_host_kernel(kerninfo)) { 1991 if (machine__is_host(self)) {
2002 vmlinux_name = symbol_conf.vmlinux_name; 1992 vmlinux_name = symbol_conf.vmlinux_name;
2003 kernel = dso__new_kernel(vmlinux_name); 1993 kernel = dso__new_kernel(vmlinux_name);
2004 } else { 1994 } else {
2005 if (is_default_guest(kerninfo)) 1995 if (machine__is_default_guest(self))
2006 vmlinux_name = symbol_conf.default_guest_vmlinux_name; 1996 vmlinux_name = symbol_conf.default_guest_vmlinux_name;
2007 kernel = dso__new_guest_kernel(kerninfo, vmlinux_name); 1997 kernel = dso__new_guest_kernel(self, vmlinux_name);
2008 } 1998 }
2009 1999
2010 if (kernel != NULL) { 2000 if (kernel != NULL) {
2011 dso__read_running_kernel_build_id(kernel, kerninfo); 2001 dso__read_running_kernel_build_id(kernel, self);
2012 dsos__add(&kerninfo->dsos__kernel, kernel); 2002 dsos__add(&self->kernel_dsos, kernel);
2013 } 2003 }
2014 return kernel; 2004 return kernel;
2015} 2005}
2016 2006
2017int __map_groups__create_kernel_maps(struct map_groups *self, 2007int __machine__create_kernel_maps(struct machine *self, struct dso *kernel)
2018 struct map *vmlinux_maps[MAP__NR_TYPES],
2019 struct dso *kernel)
2020{ 2008{
2021 enum map_type type; 2009 enum map_type type;
2022 2010
2023 for (type = 0; type < MAP__NR_TYPES; ++type) { 2011 for (type = 0; type < MAP__NR_TYPES; ++type) {
2024 struct kmap *kmap; 2012 struct kmap *kmap;
2025 2013
2026 vmlinux_maps[type] = map__new2(0, kernel, type); 2014 self->vmlinux_maps[type] = map__new2(0, kernel, type);
2027 if (vmlinux_maps[type] == NULL) 2015 if (self->vmlinux_maps[type] == NULL)
2028 return -1; 2016 return -1;
2029 2017
2030 vmlinux_maps[type]->map_ip = 2018 self->vmlinux_maps[type]->map_ip =
2031 vmlinux_maps[type]->unmap_ip = identity__map_ip; 2019 self->vmlinux_maps[type]->unmap_ip = identity__map_ip;
2032 2020
2033 kmap = map__kmap(vmlinux_maps[type]); 2021 kmap = map__kmap(self->vmlinux_maps[type]);
2034 kmap->kmaps = self; 2022 kmap->kmaps = &self->kmaps;
2035 map_groups__insert(self, vmlinux_maps[type]); 2023 map_groups__insert(&self->kmaps, self->vmlinux_maps[type]);
2036 } 2024 }
2037 2025
2038 return 0; 2026 return 0;
2039} 2027}
2040 2028
2029int machine__create_kernel_maps(struct machine *self)
2030{
2031 struct dso *kernel = machine__create_kernel(self);
2032
2033 if (kernel == NULL ||
2034 __machine__create_kernel_maps(self, kernel) < 0)
2035 return -1;
2036
2037 if (symbol_conf.use_modules && machine__create_modules(self) < 0)
2038 pr_debug("Problems creating module maps, continuing anyway...\n");
2039 /*
2040 * Now that we have all the maps created, just set the ->end of them:
2041 */
2042 map_groups__fixup_end(&self->kmaps);
2043 return 0;
2044}
2045
2041static void vmlinux_path__exit(void) 2046static void vmlinux_path__exit(void)
2042{ 2047{
2043 while (--vmlinux_path__nr_entries >= 0) { 2048 while (--vmlinux_path__nr_entries >= 0) {
@@ -2154,30 +2159,14 @@ out_free_comm_list:
2154 return -1; 2159 return -1;
2155} 2160}
2156 2161
2157int map_groups__create_kernel_maps(struct rb_root *kerninfo_root, pid_t pid) 2162int machines__create_kernel_maps(struct rb_root *self, pid_t pid)
2158{ 2163{
2159 struct kernel_info *kerninfo; 2164 struct machine *machine = machines__findnew(self, pid);
2160 struct dso *kernel;
2161
2162 kerninfo = kerninfo__findnew(kerninfo_root, pid);
2163 if (kerninfo == NULL)
2164 return -1;
2165 kernel = dsos__create_kernel(kerninfo);
2166 if (kernel == NULL)
2167 return -1;
2168 2165
2169 if (__map_groups__create_kernel_maps(&kerninfo->kmaps, 2166 if (machine == NULL)
2170 kerninfo->vmlinux_maps, kernel) < 0)
2171 return -1; 2167 return -1;
2172 2168
2173 if (symbol_conf.use_modules && 2169 return machine__create_kernel_maps(machine);
2174 map_groups__create_modules(kerninfo) < 0)
2175 pr_debug("Problems creating module maps, continuing anyway...\n");
2176 /*
2177 * Now that we have all the maps created, just set the ->end of them:
2178 */
2179 map_groups__fixup_end(&kerninfo->kmaps);
2180 return 0;
2181} 2170}
2182 2171
2183static int hex(char ch) 2172static int hex(char ch)
@@ -2223,7 +2212,7 @@ char *strxfrchar(char *s, char from, char to)
2223 return s; 2212 return s;
2224} 2213}
2225 2214
2226int map_groups__create_guest_kernel_maps(struct rb_root *kerninfo_root) 2215int machines__create_guest_kernel_maps(struct rb_root *self)
2227{ 2216{
2228 int ret = 0; 2217 int ret = 0;
2229 struct dirent **namelist = NULL; 2218 struct dirent **namelist = NULL;
@@ -2234,8 +2223,7 @@ int map_groups__create_guest_kernel_maps(struct rb_root *kerninfo_root)
2234 if (symbol_conf.default_guest_vmlinux_name || 2223 if (symbol_conf.default_guest_vmlinux_name ||
2235 symbol_conf.default_guest_modules || 2224 symbol_conf.default_guest_modules ||
2236 symbol_conf.default_guest_kallsyms) { 2225 symbol_conf.default_guest_kallsyms) {
2237 map_groups__create_kernel_maps(kerninfo_root, 2226 machines__create_kernel_maps(self, DEFAULT_GUEST_KERNEL_ID);
2238 DEFAULT_GUEST_KERNEL_ID);
2239 } 2227 }
2240 2228
2241 if (symbol_conf.guestmount) { 2229 if (symbol_conf.guestmount) {
@@ -2256,8 +2244,7 @@ int map_groups__create_guest_kernel_maps(struct rb_root *kerninfo_root)
2256 pr_debug("Can't access file %s\n", path); 2244 pr_debug("Can't access file %s\n", path);
2257 goto failure; 2245 goto failure;
2258 } 2246 }
2259 map_groups__create_kernel_maps(kerninfo_root, 2247 machines__create_kernel_maps(self, pid);
2260 pid);
2261 } 2248 }
2262failure: 2249failure:
2263 free(namelist); 2250 free(namelist);
@@ -2265,3 +2252,36 @@ failure:
2265 2252
2266 return ret; 2253 return ret;
2267} 2254}
2255
2256int machine__load_kallsyms(struct machine *self, const char *filename,
2257 enum map_type type, symbol_filter_t filter)
2258{
2259 struct map *map = self->vmlinux_maps[type];
2260 int ret = dso__load_kallsyms(map->dso, filename, map, filter);
2261
2262 if (ret > 0) {
2263 dso__set_loaded(map->dso, type);
2264 /*
2265 * Since /proc/kallsyms will have multiple sessions for the
2266 * kernel, with modules between them, fixup the end of all
2267 * sections.
2268 */
2269 __map_groups__fixup_end(&self->kmaps, type);
2270 }
2271
2272 return ret;
2273}
2274
2275int machine__load_vmlinux_path(struct machine *self, enum map_type type,
2276 symbol_filter_t filter)
2277{
2278 struct map *map = self->vmlinux_maps[type];
2279 int ret = dso__load_vmlinux_path(map->dso, map, filter);
2280
2281 if (ret > 0) {
2282 dso__set_loaded(map->dso, type);
2283 map__reloc_vmlinux(map);
2284 }
2285
2286 return ret;
2287}
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 478f5ab37787..a517c17407b7 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -162,9 +162,13 @@ int dso__load_vmlinux_path(struct dso *self, struct map *map,
162 symbol_filter_t filter); 162 symbol_filter_t filter);
163int dso__load_kallsyms(struct dso *self, const char *filename, struct map *map, 163int dso__load_kallsyms(struct dso *self, const char *filename, struct map *map,
164 symbol_filter_t filter); 164 symbol_filter_t filter);
165void dsos__fprintf(struct rb_root *kerninfo_root, FILE *fp); 165int machine__load_kallsyms(struct machine *self, const char *filename,
166size_t dsos__fprintf_buildid(struct rb_root *kerninfo_root, 166 enum map_type type, symbol_filter_t filter);
167 FILE *fp, bool with_hits); 167int machine__load_vmlinux_path(struct machine *self, enum map_type type,
168 symbol_filter_t filter);
169
170size_t machines__fprintf_dsos(struct rb_root *self, FILE *fp);
171size_t machines__fprintf_dsos_buildid(struct rb_root *self, FILE *fp, bool with_hits);
168 172
169size_t dso__fprintf_buildid(struct dso *self, FILE *fp); 173size_t dso__fprintf_buildid(struct dso *self, FILE *fp);
170size_t dso__fprintf(struct dso *self, enum map_type type, FILE *fp); 174size_t dso__fprintf(struct dso *self, enum map_type type, FILE *fp);
@@ -186,8 +190,7 @@ enum dso_origin {
186char dso__symtab_origin(const struct dso *self); 190char dso__symtab_origin(const struct dso *self);
187void dso__set_long_name(struct dso *self, char *name); 191void dso__set_long_name(struct dso *self, char *name);
188void dso__set_build_id(struct dso *self, void *build_id); 192void dso__set_build_id(struct dso *self, void *build_id);
189void dso__read_running_kernel_build_id(struct dso *self, 193void dso__read_running_kernel_build_id(struct dso *self, struct machine *machine);
190 struct kernel_info *kerninfo);
191struct symbol *dso__find_symbol(struct dso *self, enum map_type type, u64 addr); 194struct symbol *dso__find_symbol(struct dso *self, enum map_type type, u64 addr);
192struct symbol *dso__find_symbol_by_name(struct dso *self, enum map_type type, 195struct symbol *dso__find_symbol_by_name(struct dso *self, enum map_type type,
193 const char *name); 196 const char *name);
@@ -200,11 +203,11 @@ int kallsyms__parse(const char *filename, void *arg,
200 int (*process_symbol)(void *arg, const char *name, 203 int (*process_symbol)(void *arg, const char *name,
201 char type, u64 start)); 204 char type, u64 start));
202 205
203int __map_groups__create_kernel_maps(struct map_groups *self, 206int __machine__create_kernel_maps(struct machine *self, struct dso *kernel);
204 struct map *vmlinux_maps[MAP__NR_TYPES], 207int machine__create_kernel_maps(struct machine *self);
205 struct dso *kernel); 208
206int map_groups__create_kernel_maps(struct rb_root *kerninfo_root, pid_t pid); 209int machines__create_kernel_maps(struct rb_root *self, pid_t pid);
207int map_groups__create_guest_kernel_maps(struct rb_root *kerninfo_root); 210int machines__create_guest_kernel_maps(struct rb_root *self);
208 211
209int symbol__init(void); 212int symbol__init(void);
210bool symbol_type__is_a(char symbol_type, enum map_type map_type); 213bool symbol_type__is_a(char symbol_type, enum map_type map_type);