diff options
author | Ingo Molnar <mingo@elte.hu> | 2010-04-30 03:58:05 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2010-04-30 03:58:05 -0400 |
commit | bc4b473f1aa2ef785ccfd890a24a1de5a6660f98 (patch) | |
tree | 77bbea692517ae4723b575631222bf715b4a1eb1 /tools | |
parent | 3ca50496c2677a2b3fdd3ede86660fd1433beac6 (diff) | |
parent | 1c6a800cde3b818fd8320b5d402f2d77d2948c00 (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.txt | 22 | ||||
-rw-r--r-- | tools/perf/Makefile | 3 | ||||
-rw-r--r-- | tools/perf/builtin-annotate.c | 2 | ||||
-rw-r--r-- | tools/perf/builtin-buildid-list.c | 2 | ||||
-rw-r--r-- | tools/perf/builtin-kmem.c | 10 | ||||
-rw-r--r-- | tools/perf/builtin-record.c | 36 | ||||
-rw-r--r-- | tools/perf/builtin-report.c | 2 | ||||
-rw-r--r-- | tools/perf/builtin-test.c | 281 | ||||
-rw-r--r-- | tools/perf/builtin-top.c | 15 | ||||
-rw-r--r-- | tools/perf/builtin.h | 1 | ||||
-rw-r--r-- | tools/perf/command-list.txt | 1 | ||||
-rw-r--r-- | tools/perf/perf.c | 1 | ||||
-rw-r--r-- | tools/perf/util/event.c | 89 | ||||
-rw-r--r-- | tools/perf/util/event.h | 4 | ||||
-rw-r--r-- | tools/perf/util/header.c | 70 | ||||
-rw-r--r-- | tools/perf/util/header.h | 2 | ||||
-rw-r--r-- | tools/perf/util/map.c | 121 | ||||
-rw-r--r-- | tools/perf/util/map.h | 86 | ||||
-rw-r--r-- | tools/perf/util/probe-event.c | 20 | ||||
-rw-r--r-- | tools/perf/util/session.c | 9 | ||||
-rw-r--r-- | tools/perf/util/session.h | 40 | ||||
-rw-r--r-- | tools/perf/util/symbol.c | 236 | ||||
-rw-r--r-- | tools/perf/util/symbol.h | 23 |
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 @@ | |||
1 | perf-test(1) | ||
2 | ============ | ||
3 | |||
4 | NAME | ||
5 | ---- | ||
6 | perf-test - Runs sanity tests. | ||
7 | |||
8 | SYNOPSIS | ||
9 | -------- | ||
10 | [verse] | ||
11 | 'perf test <options>' | ||
12 | |||
13 | DESCRIPTION | ||
14 | ----------- | ||
15 | This command does assorted sanity tests, initially thru linked routines but | ||
16 | also will look for a directory with more tests in the form of scripts. | ||
17 | |||
18 | OPTIONS | ||
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 |
188 | endif | 188 | endif |
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 | |||
488 | BUILTIN_OBJS += $(OUTPUT)builtin-kmem.o | 490 | BUILTIN_OBJS += $(OUTPUT)builtin-kmem.o |
489 | BUILTIN_OBJS += $(OUTPUT)builtin-lock.o | 491 | BUILTIN_OBJS += $(OUTPUT)builtin-lock.o |
490 | BUILTIN_OBJS += $(OUTPUT)builtin-kvm.o | 492 | BUILTIN_OBJS += $(OUTPUT)builtin-kvm.o |
493 | BUILTIN_OBJS += $(OUTPUT)builtin-test.o | ||
491 | 494 | ||
492 | PERFLIBS = $(LIB_FILE) | 495 | PERFLIBS = $(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 | ||
459 | static void event__synthesize_guest_os(struct kernel_info *kerninfo, | 459 | static 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 | ||
505 | static int __cmd_record(int argc, const char **argv) | 504 | static 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 | |||
15 | static long page_size; | ||
16 | |||
17 | static 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 | |||
24 | static 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) { | ||
128 | next_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 | } | ||
218 | out: | ||
219 | return err; | ||
220 | } | ||
221 | |||
222 | static 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 | |||
235 | static 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 | |||
254 | static const char * const test_usage[] = { | ||
255 | "perf test [<options>]", | ||
256 | NULL, | ||
257 | }; | ||
258 | |||
259 | static const struct option test_options[] = { | ||
260 | OPT_BOOLEAN('v', "verbose", &verbose, | ||
261 | "be more verbose (show symbol address, etc)"), | ||
262 | OPT_END() | ||
263 | }; | ||
264 | |||
265 | int 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); | |||
33 | extern int cmd_kmem(int argc, const char **argv, const char *prefix); | 33 | extern int cmd_kmem(int argc, const char **argv, const char *prefix); |
34 | extern int cmd_lock(int argc, const char **argv, const char *prefix); | 34 | extern int cmd_lock(int argc, const char **argv, const char *prefix); |
35 | extern int cmd_kvm(int argc, const char **argv, const char *prefix); | 35 | extern int cmd_kvm(int argc, const char **argv, const char *prefix); |
36 | extern 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 | |||
20 | perf-kmem mainporcelain common | 20 | perf-kmem mainporcelain common |
21 | perf-lock mainporcelain common | 21 | perf-lock mainporcelain common |
22 | perf-kvm mainporcelain common | 22 | perf-kvm mainporcelain common |
23 | perf-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 | ||
173 | int event__synthesize_modules(event__handler_t process, | 173 | int 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 | ||
268 | int event__synthesize_kernel_mmap(event__handler_t process, | 268 | int 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 | ||
480 | int event__process_mmap(event_t *self, struct perf_session *session) | 476 | int 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); |
157 | int event__synthesize_kernel_mmap(event__handler_t process, | 157 | int 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 | ||
162 | int event__synthesize_modules(event__handler_t process, | 162 | int 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 | ||
166 | int event__process_comm(event_t *self, struct perf_session *session); | 166 | int event__process_comm(event_t *self, struct perf_session *session); |
167 | int event__process_lost(event_t *self, struct perf_session *session); | 167 | int 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 | ||
1115 | int event__synthesize_build_id(struct dso *pos, u16 misc, | 1112 | int 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 | ||
1143 | static int __event_synthesize_build_ids(struct list_head *head, u16 misc, | 1139 | static 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 | ||
121 | int event__synthesize_build_id(struct dso *pos, u16 misc, | 121 | int 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); |
125 | int event__synthesize_build_ids(event__handler_t process, | 125 | int 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 | ||
251 | void map_groups__flush(struct map_groups *self) | 251 | void 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 | ||
516 | struct kernel_info *add_new_kernel_info(struct rb_root *kerninfo_root, | 516 | int 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 | |||
529 | struct 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 | ||
550 | struct kernel_info *kerninfo__find(struct rb_root *kerninfo_root, pid_t pid) | 559 | struct 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 | ||
573 | struct kernel_info *kerninfo__findhost(struct rb_root *kerninfo_root) | 582 | /* |
583 | * FIXME: Why repeatedly search for this? | ||
584 | */ | ||
585 | struct 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 | ||
594 | struct kernel_info *kerninfo__findnew(struct rb_root *kerninfo_root, pid_t pid) | 606 | struct 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 | ||
618 | out: | 628 | out: |
619 | return kerninfo; | 629 | return machine; |
620 | } | 630 | } |
621 | 631 | ||
622 | void kerninfo__process_allkernels(struct rb_root *kerninfo_root, | 632 | void 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 | ||
635 | char *kern_mmap_name(struct kernel_info *kerninfo, char *buff) | 642 | char *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 | ||
10 | enum map_type { | 11 | enum map_type { |
@@ -19,7 +20,7 @@ extern const char *map_type__name[MAP__NR_TYPES]; | |||
19 | struct dso; | 20 | struct dso; |
20 | struct ref_reloc_sym; | 21 | struct ref_reloc_sym; |
21 | struct map_groups; | 22 | struct map_groups; |
22 | struct kernel_info; | 23 | struct machine; |
23 | 24 | ||
24 | struct map { | 25 | struct 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 | ||
48 | struct map_groups { | 50 | struct 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 | ||
58 | struct kernel_info { | 60 | struct 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 | ||
70 | static inline | ||
71 | struct map *machine__kernel_map(struct machine *self, enum map_type type) | ||
72 | { | ||
73 | return self->vmlinux_maps[type]; | ||
74 | } | ||
75 | |||
68 | static inline struct kmap *map__kmap(struct map *self) | 76 | static 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, | |||
124 | size_t map_groups__fprintf(struct map_groups *self, int verbose, FILE *fp); | 132 | size_t map_groups__fprintf(struct map_groups *self, int verbose, FILE *fp); |
125 | size_t map_groups__fprintf_maps(struct map_groups *self, int verbose, FILE *fp); | 133 | size_t map_groups__fprintf_maps(struct map_groups *self, int verbose, FILE *fp); |
126 | 134 | ||
127 | struct kernel_info *add_new_kernel_info(struct rb_root *kerninfo_root, | 135 | typedef void (*machine__process_t)(struct machine *self, void *data); |
128 | pid_t pid, const char *root_dir); | 136 | |
129 | struct kernel_info *kerninfo__find(struct rb_root *kerninfo_root, pid_t pid); | 137 | void machines__process(struct rb_root *self, machine__process_t process, void *data); |
130 | struct kernel_info *kerninfo__findnew(struct rb_root *kerninfo_root, pid_t pid); | 138 | struct machine *machines__add(struct rb_root *self, pid_t pid, |
131 | struct kernel_info *kerninfo__findhost(struct rb_root *kerninfo_root); | 139 | const char *root_dir); |
132 | char *kern_mmap_name(struct kernel_info *kerninfo, char *buff); | 140 | struct machine *machines__find_host(struct rb_root *self); |
141 | struct machine *machines__find(struct rb_root *self, pid_t pid); | ||
142 | struct machine *machines__findnew(struct rb_root *self, pid_t pid); | ||
143 | char *machine__mmap_name(struct machine *self, char *bf, size_t size); | ||
144 | int 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 | */ |
138 | static inline int is_default_guest(struct kernel_info *kerninfo) | 150 | static 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 | ||
145 | static inline int is_host_kernel(struct kernel_info *kerninfo) | 155 | static 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 | ||
152 | typedef void (*process_kernel_info)(struct kernel_info *kerninfo, void *data); | ||
153 | void kerninfo__process_allkernels(struct rb_root *kerninfo_root, | ||
154 | process_kernel_info process, | ||
155 | void *data); | ||
156 | |||
157 | static inline void map_groups__insert(struct map_groups *self, struct map *map) | 160 | static 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 | ||
180 | static inline | 183 | static inline |
181 | struct symbol *map_groups__find_function(struct map_groups *self, u64 addr, | 184 | struct 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 | |||
192 | static inline | ||
193 | struct 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 | ||
187 | static inline | 200 | static inline |
@@ -197,10 +210,7 @@ int map_groups__fixup_overlappings(struct map_groups *self, struct map *map, | |||
197 | 210 | ||
198 | struct map *map_groups__find_by_name(struct map_groups *self, | 211 | struct 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); |
200 | struct map *map_groups__new_module(struct map_groups *self, | 213 | struct 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 | ||
205 | void map_groups__flush(struct map_groups *self); | 215 | void 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 | ||
74 | static char *synthesize_perf_probe_point(struct perf_probe_point *pp); | 74 | static char *synthesize_perf_probe_point(struct perf_probe_point *pp); |
75 | static struct map_groups kmap_groups; | 75 | static struct machine machine; |
76 | static struct map *kmaps[MAP__NR_TYPES]; | ||
77 | 76 | ||
78 | /* Initialize symbol maps and path of vmlinux */ | 77 | /* Initialize symbol maps and path of vmlinux */ |
79 | static int init_vmlinux(void) | 78 | static 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 |
111 | static int open_vmlinux(void) | 113 | static 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 | ||
70 | int perf_session__create_kernel_maps(struct perf_session *self) | 70 | int 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 | |||
106 | static inline | ||
107 | struct machine *perf_session__find_host_machine(struct perf_session *self) | ||
108 | { | ||
109 | return machines__find_host(&self->machines); | ||
110 | } | ||
111 | |||
112 | static inline | ||
113 | struct machine *perf_session__find_machine(struct perf_session *self, pid_t pid) | ||
114 | { | ||
115 | return machines__find(&self->machines, pid); | ||
116 | } | ||
117 | |||
118 | static inline | ||
119 | struct machine *perf_session__findnew_machine(struct perf_session *self, pid_t pid) | ||
120 | { | ||
121 | return machines__findnew(&self->machines, pid); | ||
122 | } | ||
123 | |||
124 | static inline | ||
125 | void perf_session__process_machines(struct perf_session *self, | ||
126 | machine__process_t process) | ||
127 | { | ||
128 | return machines__process(&self->machines, process, self); | ||
129 | } | ||
130 | |||
131 | static inline | ||
132 | size_t perf_session__fprintf_dsos(struct perf_session *self, FILE *fp) | ||
133 | { | ||
134 | return machines__fprintf_dsos(&self->machines, fp); | ||
135 | } | ||
136 | |||
137 | static inline | ||
138 | size_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 | ||
1531 | static int map_groups__set_modules_path(struct map_groups *self, | 1531 | static 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 | ||
1567 | struct map *map_groups__new_module(struct map_groups *self, u64 start, | 1566 | struct 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 | ||
1590 | static int map_groups__create_modules(struct kernel_info *kerninfo) | 1587 | static 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 | ||
1653 | out_delete_line: | 1646 | out_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, | |||
1856 | out_try_fixup: | 1849 | out_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 | ||
1900 | static void __dsos__fprintf(struct list_head *head, FILE *fp) | 1892 | static 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 | ||
1911 | void dsos__fprintf(struct rb_root *kerninfo_root, FILE *fp) | 1906 | size_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 | ||
1923 | static size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp, | 1920 | static 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 | ||
1938 | size_t dsos__fprintf_buildid(struct rb_root *kerninfo_root, | 1935 | size_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 | ||
1967 | static struct dso *dso__new_guest_kernel(struct kernel_info *kerninfo, | 1960 | static 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 | ||
1983 | void dso__read_running_kernel_build_id(struct dso *self, | 1974 | void 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 | ||
1996 | static struct dso *dsos__create_kernel(struct kernel_info *kerninfo) | 1986 | static 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 | ||
2017 | int __map_groups__create_kernel_maps(struct map_groups *self, | 2007 | int __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 | ||
2029 | int 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 | |||
2041 | static void vmlinux_path__exit(void) | 2046 | static 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 | ||
2157 | int map_groups__create_kernel_maps(struct rb_root *kerninfo_root, pid_t pid) | 2162 | int 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 | ||
2183 | static int hex(char ch) | 2172 | static 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 | ||
2226 | int map_groups__create_guest_kernel_maps(struct rb_root *kerninfo_root) | 2215 | int 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 | } |
2262 | failure: | 2249 | failure: |
2263 | free(namelist); | 2250 | free(namelist); |
@@ -2265,3 +2252,36 @@ failure: | |||
2265 | 2252 | ||
2266 | return ret; | 2253 | return ret; |
2267 | } | 2254 | } |
2255 | |||
2256 | int 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 | |||
2275 | int 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); |
163 | int dso__load_kallsyms(struct dso *self, const char *filename, struct map *map, | 163 | int dso__load_kallsyms(struct dso *self, const char *filename, struct map *map, |
164 | symbol_filter_t filter); | 164 | symbol_filter_t filter); |
165 | void dsos__fprintf(struct rb_root *kerninfo_root, FILE *fp); | 165 | int machine__load_kallsyms(struct machine *self, const char *filename, |
166 | size_t dsos__fprintf_buildid(struct rb_root *kerninfo_root, | 166 | enum map_type type, symbol_filter_t filter); |
167 | FILE *fp, bool with_hits); | 167 | int machine__load_vmlinux_path(struct machine *self, enum map_type type, |
168 | symbol_filter_t filter); | ||
169 | |||
170 | size_t machines__fprintf_dsos(struct rb_root *self, FILE *fp); | ||
171 | size_t machines__fprintf_dsos_buildid(struct rb_root *self, FILE *fp, bool with_hits); | ||
168 | 172 | ||
169 | size_t dso__fprintf_buildid(struct dso *self, FILE *fp); | 173 | size_t dso__fprintf_buildid(struct dso *self, FILE *fp); |
170 | size_t dso__fprintf(struct dso *self, enum map_type type, FILE *fp); | 174 | size_t dso__fprintf(struct dso *self, enum map_type type, FILE *fp); |
@@ -186,8 +190,7 @@ enum dso_origin { | |||
186 | char dso__symtab_origin(const struct dso *self); | 190 | char dso__symtab_origin(const struct dso *self); |
187 | void dso__set_long_name(struct dso *self, char *name); | 191 | void dso__set_long_name(struct dso *self, char *name); |
188 | void dso__set_build_id(struct dso *self, void *build_id); | 192 | void dso__set_build_id(struct dso *self, void *build_id); |
189 | void dso__read_running_kernel_build_id(struct dso *self, | 193 | void dso__read_running_kernel_build_id(struct dso *self, struct machine *machine); |
190 | struct kernel_info *kerninfo); | ||
191 | struct symbol *dso__find_symbol(struct dso *self, enum map_type type, u64 addr); | 194 | struct symbol *dso__find_symbol(struct dso *self, enum map_type type, u64 addr); |
192 | struct symbol *dso__find_symbol_by_name(struct dso *self, enum map_type type, | 195 | struct 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 | ||
203 | int __map_groups__create_kernel_maps(struct map_groups *self, | 206 | int __machine__create_kernel_maps(struct machine *self, struct dso *kernel); |
204 | struct map *vmlinux_maps[MAP__NR_TYPES], | 207 | int machine__create_kernel_maps(struct machine *self); |
205 | struct dso *kernel); | 208 | |
206 | int map_groups__create_kernel_maps(struct rb_root *kerninfo_root, pid_t pid); | 209 | int machines__create_kernel_maps(struct rb_root *self, pid_t pid); |
207 | int map_groups__create_guest_kernel_maps(struct rb_root *kerninfo_root); | 210 | int machines__create_guest_kernel_maps(struct rb_root *self); |
208 | 211 | ||
209 | int symbol__init(void); | 212 | int symbol__init(void); |
210 | bool symbol_type__is_a(char symbol_type, enum map_type map_type); | 213 | bool symbol_type__is_a(char symbol_type, enum map_type map_type); |