diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2009-12-11 11:50:36 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-12-12 01:42:09 -0500 |
commit | 9958e1f0aee632c3665162c9c93cf8fde8006a94 (patch) | |
tree | ffd81c34d3ca8044c3fe0d670dc1786113624bbb /tools/perf/util/symbol.c | |
parent | 58e9f94138c1d9c47f6a63632ca7a78fc6dcc15f (diff) |
perf symbols: Rename kthreads to kmaps, using another abstraction for it
Using a struct thread instance just to hold the kernel space maps
(vmlinux + modules) is overkill and confuses people trying to
understand the perf symbols abstractions.
The kernel maps are really present in all threads, i.e. the kernel
is a library, not a separate thread.
So introduce the 'map_groups' abstraction and use it for the kernel
maps, now in the kmaps global variable.
It, in turn, will move, together with the threads list to the
perf_file abstraction, so that we can support multiple perf_file
instances, needed by perf diff.
Brainstormed-with: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Cc: Frédéric Weisbecker <fweisbec@gmail.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Paul Mackerras <paulus@samba.org>
LKML-Reference: <1260550239-5372-1-git-send-email-acme@infradead.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'tools/perf/util/symbol.c')
-rw-r--r-- | tools/perf/util/symbol.c | 73 |
1 files changed, 37 insertions, 36 deletions
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index e7508ad3450f..936202342949 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c | |||
@@ -29,11 +29,11 @@ enum dso_origin { | |||
29 | }; | 29 | }; |
30 | 30 | ||
31 | static void dsos__add(struct list_head *head, struct dso *dso); | 31 | static void dsos__add(struct list_head *head, struct dso *dso); |
32 | static struct map *thread__find_map_by_name(struct thread *self, char *name); | 32 | static struct map *map_groups__find_by_name(struct map_groups *self, char *name); |
33 | static struct map *map__new2(u64 start, struct dso *dso, enum map_type type); | 33 | static struct map *map__new2(u64 start, struct dso *dso, enum map_type type); |
34 | struct symbol *dso__find_symbol(struct dso *self, enum map_type type, u64 addr); | 34 | struct symbol *dso__find_symbol(struct dso *self, enum map_type type, u64 addr); |
35 | static int dso__load_kernel_sym(struct dso *self, struct map *map, | 35 | static int dso__load_kernel_sym(struct dso *self, struct map *map, |
36 | struct thread *thread, symbol_filter_t filter); | 36 | struct map_groups *mg, symbol_filter_t filter); |
37 | unsigned int symbol__priv_size; | 37 | unsigned int symbol__priv_size; |
38 | static int vmlinux_path__nr_entries; | 38 | static int vmlinux_path__nr_entries; |
39 | static char **vmlinux_path; | 39 | static char **vmlinux_path; |
@@ -43,8 +43,8 @@ static struct symbol_conf symbol_conf__defaults = { | |||
43 | .try_vmlinux_path = true, | 43 | .try_vmlinux_path = true, |
44 | }; | 44 | }; |
45 | 45 | ||
46 | static struct thread kthread_mem; | 46 | static struct map_groups kmaps_mem; |
47 | struct thread *kthread = &kthread_mem; | 47 | struct map_groups *kmaps = &kmaps_mem; |
48 | 48 | ||
49 | bool dso__loaded(const struct dso *self, enum map_type type) | 49 | bool dso__loaded(const struct dso *self, enum map_type type) |
50 | { | 50 | { |
@@ -79,7 +79,7 @@ static void symbols__fixup_end(struct rb_root *self) | |||
79 | curr->end = roundup(curr->start, 4096); | 79 | curr->end = roundup(curr->start, 4096); |
80 | } | 80 | } |
81 | 81 | ||
82 | static void __thread__fixup_maps_end(struct thread *self, enum map_type type) | 82 | static void __map_groups__fixup_end(struct map_groups *self, enum map_type type) |
83 | { | 83 | { |
84 | struct map *prev, *curr; | 84 | struct map *prev, *curr; |
85 | struct rb_node *nd, *prevnd = rb_first(&self->maps[type]); | 85 | struct rb_node *nd, *prevnd = rb_first(&self->maps[type]); |
@@ -102,11 +102,11 @@ static void __thread__fixup_maps_end(struct thread *self, enum map_type type) | |||
102 | curr->end = ~0UL; | 102 | curr->end = ~0UL; |
103 | } | 103 | } |
104 | 104 | ||
105 | static void thread__fixup_maps_end(struct thread *self) | 105 | static void map_groups__fixup_end(struct map_groups *self) |
106 | { | 106 | { |
107 | int i; | 107 | int i; |
108 | for (i = 0; i < MAP__NR_TYPES; ++i) | 108 | for (i = 0; i < MAP__NR_TYPES; ++i) |
109 | __thread__fixup_maps_end(self, i); | 109 | __map_groups__fixup_end(self, i); |
110 | } | 110 | } |
111 | 111 | ||
112 | static struct symbol *symbol__new(u64 start, u64 len, const char *name) | 112 | static struct symbol *symbol__new(u64 start, u64 len, const char *name) |
@@ -364,8 +364,8 @@ out_failure: | |||
364 | * kernel range is broken in several maps, named [kernel].N, as we don't have | 364 | * kernel range is broken in several maps, named [kernel].N, as we don't have |
365 | * the original ELF section names vmlinux have. | 365 | * the original ELF section names vmlinux have. |
366 | */ | 366 | */ |
367 | static int dso__split_kallsyms(struct dso *self, struct map *map, struct thread *thread, | 367 | static int dso__split_kallsyms(struct dso *self, struct map *map, |
368 | symbol_filter_t filter) | 368 | struct map_groups *mg, symbol_filter_t filter) |
369 | { | 369 | { |
370 | struct map *curr_map = map; | 370 | struct map *curr_map = map; |
371 | struct symbol *pos; | 371 | struct symbol *pos; |
@@ -382,13 +382,13 @@ static int dso__split_kallsyms(struct dso *self, struct map *map, struct thread | |||
382 | 382 | ||
383 | module = strchr(pos->name, '\t'); | 383 | module = strchr(pos->name, '\t'); |
384 | if (module) { | 384 | if (module) { |
385 | if (!thread->use_modules) | 385 | if (!mg->use_modules) |
386 | goto discard_symbol; | 386 | goto discard_symbol; |
387 | 387 | ||
388 | *module++ = '\0'; | 388 | *module++ = '\0'; |
389 | 389 | ||
390 | if (strcmp(self->name, module)) { | 390 | if (strcmp(self->name, module)) { |
391 | curr_map = thread__find_map_by_name(thread, module); | 391 | curr_map = map_groups__find_by_name(mg, module); |
392 | if (curr_map == NULL) { | 392 | if (curr_map == NULL) { |
393 | pr_debug("/proc/{kallsyms,modules} " | 393 | pr_debug("/proc/{kallsyms,modules} " |
394 | "inconsistency!\n"); | 394 | "inconsistency!\n"); |
@@ -419,7 +419,7 @@ static int dso__split_kallsyms(struct dso *self, struct map *map, struct thread | |||
419 | } | 419 | } |
420 | 420 | ||
421 | curr_map->map_ip = curr_map->unmap_ip = identity__map_ip; | 421 | curr_map->map_ip = curr_map->unmap_ip = identity__map_ip; |
422 | __thread__insert_map(thread, curr_map); | 422 | map_groups__insert(mg, curr_map); |
423 | ++kernel_range; | 423 | ++kernel_range; |
424 | } | 424 | } |
425 | 425 | ||
@@ -440,7 +440,7 @@ discard_symbol: rb_erase(&pos->rb_node, root); | |||
440 | 440 | ||
441 | 441 | ||
442 | static int dso__load_kallsyms(struct dso *self, struct map *map, | 442 | static int dso__load_kallsyms(struct dso *self, struct map *map, |
443 | struct thread *thread, symbol_filter_t filter) | 443 | struct map_groups *mg, symbol_filter_t filter) |
444 | { | 444 | { |
445 | if (dso__load_all_kallsyms(self, map) < 0) | 445 | if (dso__load_all_kallsyms(self, map) < 0) |
446 | return -1; | 446 | return -1; |
@@ -448,13 +448,13 @@ static int dso__load_kallsyms(struct dso *self, struct map *map, | |||
448 | symbols__fixup_end(&self->symbols[map->type]); | 448 | symbols__fixup_end(&self->symbols[map->type]); |
449 | self->origin = DSO__ORIG_KERNEL; | 449 | self->origin = DSO__ORIG_KERNEL; |
450 | 450 | ||
451 | return dso__split_kallsyms(self, map, thread, filter); | 451 | return dso__split_kallsyms(self, map, mg, filter); |
452 | } | 452 | } |
453 | 453 | ||
454 | size_t kernel_maps__fprintf(FILE *fp) | 454 | size_t kernel_maps__fprintf(FILE *fp) |
455 | { | 455 | { |
456 | size_t printed = fprintf(fp, "Kernel maps:\n"); | 456 | size_t printed = fprintf(fp, "Kernel maps:\n"); |
457 | printed += thread__fprintf_maps(kthread, fp); | 457 | printed += map_groups__fprintf_maps(kmaps, fp); |
458 | return printed + fprintf(fp, "END kernel maps\n"); | 458 | return printed + fprintf(fp, "END kernel maps\n"); |
459 | } | 459 | } |
460 | 460 | ||
@@ -745,7 +745,7 @@ out: | |||
745 | } | 745 | } |
746 | 746 | ||
747 | static int dso__load_sym(struct dso *self, struct map *map, | 747 | static int dso__load_sym(struct dso *self, struct map *map, |
748 | struct thread *thread, const char *name, int fd, | 748 | struct map_groups *mg, const char *name, int fd, |
749 | symbol_filter_t filter, int kernel, int kmodule) | 749 | symbol_filter_t filter, int kernel, int kmodule) |
750 | { | 750 | { |
751 | struct map *curr_map = map; | 751 | struct map *curr_map = map; |
@@ -849,7 +849,7 @@ static int dso__load_sym(struct dso *self, struct map *map, | |||
849 | snprintf(dso_name, sizeof(dso_name), | 849 | snprintf(dso_name, sizeof(dso_name), |
850 | "%s%s", self->short_name, section_name); | 850 | "%s%s", self->short_name, section_name); |
851 | 851 | ||
852 | curr_map = thread__find_map_by_name(thread, dso_name); | 852 | curr_map = map_groups__find_by_name(mg, dso_name); |
853 | if (curr_map == NULL) { | 853 | if (curr_map == NULL) { |
854 | u64 start = sym.st_value; | 854 | u64 start = sym.st_value; |
855 | 855 | ||
@@ -868,7 +868,7 @@ static int dso__load_sym(struct dso *self, struct map *map, | |||
868 | curr_map->map_ip = identity__map_ip; | 868 | curr_map->map_ip = identity__map_ip; |
869 | curr_map->unmap_ip = identity__map_ip; | 869 | curr_map->unmap_ip = identity__map_ip; |
870 | curr_dso->origin = DSO__ORIG_KERNEL; | 870 | curr_dso->origin = DSO__ORIG_KERNEL; |
871 | __thread__insert_map(kthread, curr_map); | 871 | map_groups__insert(kmaps, curr_map); |
872 | dsos__add(&dsos__kernel, curr_dso); | 872 | dsos__add(&dsos__kernel, curr_dso); |
873 | } else | 873 | } else |
874 | curr_dso = curr_map->dso; | 874 | curr_dso = curr_map->dso; |
@@ -1094,7 +1094,7 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter) | |||
1094 | dso__set_loaded(self, map->type); | 1094 | dso__set_loaded(self, map->type); |
1095 | 1095 | ||
1096 | if (self->kernel) | 1096 | if (self->kernel) |
1097 | return dso__load_kernel_sym(self, map, kthread, filter); | 1097 | return dso__load_kernel_sym(self, map, kmaps, filter); |
1098 | 1098 | ||
1099 | name = malloc(size); | 1099 | name = malloc(size); |
1100 | if (!name) | 1100 | if (!name) |
@@ -1180,7 +1180,7 @@ out: | |||
1180 | return ret; | 1180 | return ret; |
1181 | } | 1181 | } |
1182 | 1182 | ||
1183 | static struct map *thread__find_map_by_name(struct thread *self, char *name) | 1183 | static struct map *map_groups__find_by_name(struct map_groups *self, char *name) |
1184 | { | 1184 | { |
1185 | struct rb_node *nd; | 1185 | struct rb_node *nd; |
1186 | 1186 | ||
@@ -1228,7 +1228,7 @@ static int dsos__set_modules_path_dir(char *dirname) | |||
1228 | (int)(dot - dent->d_name), dent->d_name); | 1228 | (int)(dot - dent->d_name), dent->d_name); |
1229 | 1229 | ||
1230 | strxfrchar(dso_name, '-', '_'); | 1230 | strxfrchar(dso_name, '-', '_'); |
1231 | map = thread__find_map_by_name(kthread, dso_name); | 1231 | map = map_groups__find_by_name(kmaps, dso_name); |
1232 | if (map == NULL) | 1232 | if (map == NULL) |
1233 | continue; | 1233 | continue; |
1234 | 1234 | ||
@@ -1281,7 +1281,7 @@ static struct map *map__new2(u64 start, struct dso *dso, enum map_type type) | |||
1281 | return self; | 1281 | return self; |
1282 | } | 1282 | } |
1283 | 1283 | ||
1284 | static int thread__create_module_maps(struct thread *self) | 1284 | static int map_groups__create_module_maps(struct map_groups *self) |
1285 | { | 1285 | { |
1286 | char *line = NULL; | 1286 | char *line = NULL; |
1287 | size_t n; | 1287 | size_t n; |
@@ -1338,7 +1338,7 @@ static int thread__create_module_maps(struct thread *self) | |||
1338 | dso->has_build_id = true; | 1338 | dso->has_build_id = true; |
1339 | 1339 | ||
1340 | dso->origin = DSO__ORIG_KMODULE; | 1340 | dso->origin = DSO__ORIG_KMODULE; |
1341 | __thread__insert_map(self, map); | 1341 | map_groups__insert(self, map); |
1342 | dsos__add(&dsos__kernel, dso); | 1342 | dsos__add(&dsos__kernel, dso); |
1343 | } | 1343 | } |
1344 | 1344 | ||
@@ -1353,7 +1353,8 @@ out_failure: | |||
1353 | return -1; | 1353 | return -1; |
1354 | } | 1354 | } |
1355 | 1355 | ||
1356 | static int dso__load_vmlinux(struct dso *self, struct map *map, struct thread *thread, | 1356 | static int dso__load_vmlinux(struct dso *self, struct map *map, |
1357 | struct map_groups *mg, | ||
1357 | const char *vmlinux, symbol_filter_t filter) | 1358 | const char *vmlinux, symbol_filter_t filter) |
1358 | { | 1359 | { |
1359 | int err = -1, fd; | 1360 | int err = -1, fd; |
@@ -1387,14 +1388,14 @@ static int dso__load_vmlinux(struct dso *self, struct map *map, struct thread *t | |||
1387 | return -1; | 1388 | return -1; |
1388 | 1389 | ||
1389 | dso__set_loaded(self, map->type); | 1390 | dso__set_loaded(self, map->type); |
1390 | err = dso__load_sym(self, map, thread, self->long_name, fd, filter, 1, 0); | 1391 | err = dso__load_sym(self, map, mg, self->long_name, fd, filter, 1, 0); |
1391 | close(fd); | 1392 | close(fd); |
1392 | 1393 | ||
1393 | return err; | 1394 | return err; |
1394 | } | 1395 | } |
1395 | 1396 | ||
1396 | static int dso__load_kernel_sym(struct dso *self, struct map *map, | 1397 | static int dso__load_kernel_sym(struct dso *self, struct map *map, |
1397 | struct thread *thread, symbol_filter_t filter) | 1398 | struct map_groups *mg, symbol_filter_t filter) |
1398 | { | 1399 | { |
1399 | int err; | 1400 | int err; |
1400 | bool is_kallsyms; | 1401 | bool is_kallsyms; |
@@ -1404,7 +1405,7 @@ static int dso__load_kernel_sym(struct dso *self, struct map *map, | |||
1404 | pr_debug("Looking at the vmlinux_path (%d entries long)\n", | 1405 | pr_debug("Looking at the vmlinux_path (%d entries long)\n", |
1405 | vmlinux_path__nr_entries); | 1406 | vmlinux_path__nr_entries); |
1406 | for (i = 0; i < vmlinux_path__nr_entries; ++i) { | 1407 | for (i = 0; i < vmlinux_path__nr_entries; ++i) { |
1407 | err = dso__load_vmlinux(self, map, thread, | 1408 | err = dso__load_vmlinux(self, map, mg, |
1408 | vmlinux_path[i], filter); | 1409 | vmlinux_path[i], filter); |
1409 | if (err > 0) { | 1410 | if (err > 0) { |
1410 | pr_debug("Using %s for symbols\n", | 1411 | pr_debug("Using %s for symbols\n", |
@@ -1420,12 +1421,12 @@ static int dso__load_kernel_sym(struct dso *self, struct map *map, | |||
1420 | if (is_kallsyms) | 1421 | if (is_kallsyms) |
1421 | goto do_kallsyms; | 1422 | goto do_kallsyms; |
1422 | 1423 | ||
1423 | err = dso__load_vmlinux(self, map, thread, self->long_name, filter); | 1424 | err = dso__load_vmlinux(self, map, mg, self->long_name, filter); |
1424 | if (err <= 0) { | 1425 | if (err <= 0) { |
1425 | pr_info("The file %s cannot be used, " | 1426 | pr_info("The file %s cannot be used, " |
1426 | "trying to use /proc/kallsyms...", self->long_name); | 1427 | "trying to use /proc/kallsyms...", self->long_name); |
1427 | do_kallsyms: | 1428 | do_kallsyms: |
1428 | err = dso__load_kallsyms(self, map, thread, filter); | 1429 | err = dso__load_kallsyms(self, map, mg, filter); |
1429 | if (err > 0 && !is_kallsyms) | 1430 | if (err > 0 && !is_kallsyms) |
1430 | dso__set_long_name(self, strdup("[kernel.kallsyms]")); | 1431 | dso__set_long_name(self, strdup("[kernel.kallsyms]")); |
1431 | } | 1432 | } |
@@ -1508,7 +1509,7 @@ size_t dsos__fprintf_buildid(FILE *fp) | |||
1508 | __dsos__fprintf_buildid(&dsos__user, fp)); | 1509 | __dsos__fprintf_buildid(&dsos__user, fp)); |
1509 | } | 1510 | } |
1510 | 1511 | ||
1511 | static int thread__create_kernel_map(struct thread *self, const char *vmlinux) | 1512 | static int map_groups__create_kernel_map(struct map_groups *self, const char *vmlinux) |
1512 | { | 1513 | { |
1513 | struct map *kmap; | 1514 | struct map *kmap; |
1514 | struct dso *kernel = dso__new(vmlinux ?: "[kernel.kallsyms]"); | 1515 | struct dso *kernel = dso__new(vmlinux ?: "[kernel.kallsyms]"); |
@@ -1533,7 +1534,7 @@ static int thread__create_kernel_map(struct thread *self, const char *vmlinux) | |||
1533 | sizeof(kernel->build_id)) == 0) | 1534 | sizeof(kernel->build_id)) == 0) |
1534 | kernel->has_build_id = true; | 1535 | kernel->has_build_id = true; |
1535 | 1536 | ||
1536 | __thread__insert_map(self, kmap); | 1537 | map_groups__insert(self, kmap); |
1537 | dsos__add(&dsos__kernel, kernel); | 1538 | dsos__add(&dsos__kernel, kernel); |
1538 | dsos__add(&dsos__user, vdso); | 1539 | dsos__add(&dsos__user, vdso); |
1539 | 1540 | ||
@@ -1607,23 +1608,23 @@ int symbol__init(struct symbol_conf *conf) | |||
1607 | 1608 | ||
1608 | elf_version(EV_CURRENT); | 1609 | elf_version(EV_CURRENT); |
1609 | symbol__priv_size = pconf->priv_size; | 1610 | symbol__priv_size = pconf->priv_size; |
1610 | thread__init(kthread, 0); | 1611 | map_groups__init(kmaps); |
1611 | 1612 | ||
1612 | if (pconf->try_vmlinux_path && vmlinux_path__init() < 0) | 1613 | if (pconf->try_vmlinux_path && vmlinux_path__init() < 0) |
1613 | return -1; | 1614 | return -1; |
1614 | 1615 | ||
1615 | if (thread__create_kernel_map(kthread, pconf->vmlinux_name) < 0) { | 1616 | if (map_groups__create_kernel_map(kmaps, pconf->vmlinux_name) < 0) { |
1616 | vmlinux_path__exit(); | 1617 | vmlinux_path__exit(); |
1617 | return -1; | 1618 | return -1; |
1618 | } | 1619 | } |
1619 | 1620 | ||
1620 | kthread->use_modules = pconf->use_modules; | 1621 | kmaps->use_modules = pconf->use_modules; |
1621 | if (pconf->use_modules && thread__create_module_maps(kthread) < 0) | 1622 | if (pconf->use_modules && map_groups__create_module_maps(kmaps) < 0) |
1622 | pr_debug("Failed to load list of modules in use, " | 1623 | pr_debug("Failed to load list of modules in use, " |
1623 | "continuing...\n"); | 1624 | "continuing...\n"); |
1624 | /* | 1625 | /* |
1625 | * Now that we have all the maps created, just set the ->end of them: | 1626 | * Now that we have all the maps created, just set the ->end of them: |
1626 | */ | 1627 | */ |
1627 | thread__fixup_maps_end(kthread); | 1628 | map_groups__fixup_end(kmaps); |
1628 | return 0; | 1629 | return 0; |
1629 | } | 1630 | } |