diff options
| -rw-r--r-- | tools/perf/builtin-kmem.c | 2 | ||||
| -rw-r--r-- | tools/perf/util/event.c | 11 | ||||
| -rw-r--r-- | tools/perf/util/symbol.c | 73 | ||||
| -rw-r--r-- | tools/perf/util/symbol.h | 4 | ||||
| -rw-r--r-- | tools/perf/util/thread.c | 62 | ||||
| -rw-r--r-- | tools/perf/util/thread.h | 39 |
6 files changed, 106 insertions, 85 deletions
diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index 5f209514f657..fe73435192b3 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c | |||
| @@ -403,7 +403,7 @@ static void __print_result(struct rb_root *root, int n_lines, int is_caller) | |||
| 403 | if (is_caller) { | 403 | if (is_caller) { |
| 404 | addr = data->call_site; | 404 | addr = data->call_site; |
| 405 | if (!raw_ip) | 405 | if (!raw_ip) |
| 406 | sym = thread__find_function(kthread, addr, NULL); | 406 | sym = map_groups__find_function(kmaps, addr, NULL); |
| 407 | } else | 407 | } else |
| 408 | addr = data->ptr; | 408 | addr = data->ptr; |
| 409 | 409 | ||
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 4dcecafa85dc..ba0de90cd3d4 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c | |||
| @@ -254,13 +254,14 @@ void thread__find_addr_location(struct thread *self, u8 cpumode, | |||
| 254 | struct addr_location *al, | 254 | struct addr_location *al, |
| 255 | symbol_filter_t filter) | 255 | symbol_filter_t filter) |
| 256 | { | 256 | { |
| 257 | struct thread *thread = al->thread = self; | 257 | struct map_groups *mg = &self->mg; |
| 258 | 258 | ||
| 259 | al->thread = self; | ||
| 259 | al->addr = addr; | 260 | al->addr = addr; |
| 260 | 261 | ||
| 261 | if (cpumode & PERF_RECORD_MISC_KERNEL) { | 262 | if (cpumode & PERF_RECORD_MISC_KERNEL) { |
| 262 | al->level = 'k'; | 263 | al->level = 'k'; |
| 263 | thread = kthread; | 264 | mg = kmaps; |
| 264 | } else if (cpumode & PERF_RECORD_MISC_USER) | 265 | } else if (cpumode & PERF_RECORD_MISC_USER) |
| 265 | al->level = '.'; | 266 | al->level = '.'; |
| 266 | else { | 267 | else { |
| @@ -270,7 +271,7 @@ void thread__find_addr_location(struct thread *self, u8 cpumode, | |||
| 270 | return; | 271 | return; |
| 271 | } | 272 | } |
| 272 | try_again: | 273 | try_again: |
| 273 | al->map = thread__find_map(thread, type, al->addr); | 274 | al->map = map_groups__find(mg, type, al->addr); |
| 274 | if (al->map == NULL) { | 275 | if (al->map == NULL) { |
| 275 | /* | 276 | /* |
| 276 | * If this is outside of all known maps, and is a negative | 277 | * If this is outside of all known maps, and is a negative |
| @@ -281,8 +282,8 @@ try_again: | |||
| 281 | * "[vdso]" dso, but for now lets use the old trick of looking | 282 | * "[vdso]" dso, but for now lets use the old trick of looking |
| 282 | * in the whole kernel symbol list. | 283 | * in the whole kernel symbol list. |
| 283 | */ | 284 | */ |
| 284 | if ((long long)al->addr < 0 && thread != kthread) { | 285 | if ((long long)al->addr < 0 && mg != kmaps) { |
| 285 | thread = kthread; | 286 | mg = kmaps; |
| 286 | goto try_again; | 287 | goto try_again; |
| 287 | } | 288 | } |
| 288 | al->sym = NULL; | 289 | al->sym = NULL; |
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 | } |
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 17003efa0b39..6e1da1ea6311 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h | |||
| @@ -113,8 +113,8 @@ size_t kernel_maps__fprintf(FILE *fp); | |||
| 113 | 113 | ||
| 114 | int symbol__init(struct symbol_conf *conf); | 114 | int symbol__init(struct symbol_conf *conf); |
| 115 | 115 | ||
| 116 | struct thread; | 116 | struct map_groups; |
| 117 | struct thread *kthread; | 117 | struct map_groups *kmaps; |
| 118 | extern struct list_head dsos__user, dsos__kernel; | 118 | extern struct list_head dsos__user, dsos__kernel; |
| 119 | extern struct dso *vdso; | 119 | extern struct dso *vdso; |
| 120 | #endif /* __PERF_SYMBOL */ | 120 | #endif /* __PERF_SYMBOL */ |
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c index 603f5610861b..a1285129c831 100644 --- a/tools/perf/util/thread.c +++ b/tools/perf/util/thread.c | |||
| @@ -9,11 +9,9 @@ | |||
| 9 | static struct rb_root threads; | 9 | static struct rb_root threads; |
| 10 | static struct thread *last_match; | 10 | static struct thread *last_match; |
| 11 | 11 | ||
| 12 | void thread__init(struct thread *self, pid_t pid) | 12 | void map_groups__init(struct map_groups *self) |
| 13 | { | 13 | { |
| 14 | int i; | 14 | int i; |
| 15 | self->pid = pid; | ||
| 16 | self->comm = NULL; | ||
| 17 | for (i = 0; i < MAP__NR_TYPES; ++i) { | 15 | for (i = 0; i < MAP__NR_TYPES; ++i) { |
| 18 | self->maps[i] = RB_ROOT; | 16 | self->maps[i] = RB_ROOT; |
| 19 | INIT_LIST_HEAD(&self->removed_maps[i]); | 17 | INIT_LIST_HEAD(&self->removed_maps[i]); |
| @@ -25,7 +23,8 @@ static struct thread *thread__new(pid_t pid) | |||
| 25 | struct thread *self = zalloc(sizeof(*self)); | 23 | struct thread *self = zalloc(sizeof(*self)); |
| 26 | 24 | ||
| 27 | if (self != NULL) { | 25 | if (self != NULL) { |
| 28 | thread__init(self, pid); | 26 | map_groups__init(&self->mg); |
| 27 | self->pid = pid; | ||
| 29 | self->comm = malloc(32); | 28 | self->comm = malloc(32); |
| 30 | if (self->comm) | 29 | if (self->comm) |
| 31 | snprintf(self->comm, 32, ":%d", self->pid); | 30 | snprintf(self->comm, 32, ":%d", self->pid); |
| @@ -57,8 +56,8 @@ static const char *map_type__name[MAP__NR_TYPES] = { | |||
| 57 | [MAP__FUNCTION] = "Functions", | 56 | [MAP__FUNCTION] = "Functions", |
| 58 | }; | 57 | }; |
| 59 | 58 | ||
| 60 | static size_t __thread__fprintf_maps(struct thread *self, | 59 | static size_t __map_groups__fprintf_maps(struct map_groups *self, |
| 61 | enum map_type type, FILE *fp) | 60 | enum map_type type, FILE *fp) |
| 62 | { | 61 | { |
| 63 | size_t printed = fprintf(fp, "%s:\n", map_type__name[type]); | 62 | size_t printed = fprintf(fp, "%s:\n", map_type__name[type]); |
| 64 | struct rb_node *nd; | 63 | struct rb_node *nd; |
| @@ -76,16 +75,16 @@ static size_t __thread__fprintf_maps(struct thread *self, | |||
| 76 | return printed; | 75 | return printed; |
| 77 | } | 76 | } |
| 78 | 77 | ||
| 79 | size_t thread__fprintf_maps(struct thread *self, FILE *fp) | 78 | size_t map_groups__fprintf_maps(struct map_groups *self, FILE *fp) |
| 80 | { | 79 | { |
| 81 | size_t printed = 0, i; | 80 | size_t printed = 0, i; |
| 82 | for (i = 0; i < MAP__NR_TYPES; ++i) | 81 | for (i = 0; i < MAP__NR_TYPES; ++i) |
| 83 | printed += __thread__fprintf_maps(self, i, fp); | 82 | printed += __map_groups__fprintf_maps(self, i, fp); |
| 84 | return printed; | 83 | return printed; |
| 85 | } | 84 | } |
| 86 | 85 | ||
| 87 | static size_t __thread__fprintf_removed_maps(struct thread *self, | 86 | static size_t __map_groups__fprintf_removed_maps(struct map_groups *self, |
| 88 | enum map_type type, FILE *fp) | 87 | enum map_type type, FILE *fp) |
| 89 | { | 88 | { |
| 90 | struct map *pos; | 89 | struct map *pos; |
| 91 | size_t printed = 0; | 90 | size_t printed = 0; |
| @@ -101,20 +100,25 @@ static size_t __thread__fprintf_removed_maps(struct thread *self, | |||
| 101 | return printed; | 100 | return printed; |
| 102 | } | 101 | } |
| 103 | 102 | ||
| 104 | static size_t thread__fprintf_removed_maps(struct thread *self, FILE *fp) | 103 | static size_t map_groups__fprintf_removed_maps(struct map_groups *self, FILE *fp) |
| 105 | { | 104 | { |
| 106 | size_t printed = 0, i; | 105 | size_t printed = 0, i; |
| 107 | for (i = 0; i < MAP__NR_TYPES; ++i) | 106 | for (i = 0; i < MAP__NR_TYPES; ++i) |
| 108 | printed += __thread__fprintf_removed_maps(self, i, fp); | 107 | printed += __map_groups__fprintf_removed_maps(self, i, fp); |
| 109 | return printed; | 108 | return printed; |
| 110 | } | 109 | } |
| 111 | 110 | ||
| 112 | static size_t thread__fprintf(struct thread *self, FILE *fp) | 111 | static size_t map_groups__fprintf(struct map_groups *self, FILE *fp) |
| 113 | { | 112 | { |
| 114 | size_t printed = fprintf(fp, "Thread %d %s\n", self->pid, self->comm); | 113 | size_t printed = map_groups__fprintf_maps(self, fp); |
| 115 | printed += thread__fprintf_removed_maps(self, fp); | ||
| 116 | printed += fprintf(fp, "Removed maps:\n"); | 114 | printed += fprintf(fp, "Removed maps:\n"); |
| 117 | return printed + thread__fprintf_removed_maps(self, fp); | 115 | return printed + map_groups__fprintf_removed_maps(self, fp); |
| 116 | } | ||
| 117 | |||
| 118 | static size_t thread__fprintf(struct thread *self, FILE *fp) | ||
| 119 | { | ||
| 120 | return fprintf(fp, "Thread %d %s\n", self->pid, self->comm) + | ||
| 121 | map_groups__fprintf(&self->mg, fp); | ||
| 118 | } | 122 | } |
| 119 | 123 | ||
| 120 | struct thread *threads__findnew(pid_t pid) | 124 | struct thread *threads__findnew(pid_t pid) |
| @@ -168,7 +172,8 @@ struct thread *register_idle_thread(void) | |||
| 168 | return thread; | 172 | return thread; |
| 169 | } | 173 | } |
| 170 | 174 | ||
| 171 | static void thread__remove_overlappings(struct thread *self, struct map *map) | 175 | static void map_groups__remove_overlappings(struct map_groups *self, |
| 176 | struct map *map) | ||
| 172 | { | 177 | { |
| 173 | struct rb_root *root = &self->maps[map->type]; | 178 | struct rb_root *root = &self->maps[map->type]; |
| 174 | struct rb_node *next = rb_first(root); | 179 | struct rb_node *next = rb_first(root); |
| @@ -238,12 +243,15 @@ struct map *maps__find(struct rb_root *maps, u64 ip) | |||
| 238 | 243 | ||
| 239 | void thread__insert_map(struct thread *self, struct map *map) | 244 | void thread__insert_map(struct thread *self, struct map *map) |
| 240 | { | 245 | { |
| 241 | thread__remove_overlappings(self, map); | 246 | map_groups__remove_overlappings(&self->mg, map); |
| 242 | maps__insert(&self->maps[map->type], map); | 247 | map_groups__insert(&self->mg, map); |
| 243 | } | 248 | } |
| 244 | 249 | ||
| 245 | static int thread__clone_maps(struct thread *self, struct thread *parent, | 250 | /* |
| 246 | enum map_type type) | 251 | * XXX This should not really _copy_ te maps, but refcount them. |
| 252 | */ | ||
| 253 | static int map_groups__clone(struct map_groups *self, | ||
| 254 | struct map_groups *parent, enum map_type type) | ||
| 247 | { | 255 | { |
| 248 | struct rb_node *nd; | 256 | struct rb_node *nd; |
| 249 | for (nd = rb_first(&parent->maps[type]); nd; nd = rb_next(nd)) { | 257 | for (nd = rb_first(&parent->maps[type]); nd; nd = rb_next(nd)) { |
| @@ -251,7 +259,7 @@ static int thread__clone_maps(struct thread *self, struct thread *parent, | |||
| 251 | struct map *new = map__clone(map); | 259 | struct map *new = map__clone(map); |
| 252 | if (new == NULL) | 260 | if (new == NULL) |
| 253 | return -ENOMEM; | 261 | return -ENOMEM; |
| 254 | thread__insert_map(self, new); | 262 | map_groups__insert(self, new); |
| 255 | } | 263 | } |
| 256 | return 0; | 264 | return 0; |
| 257 | } | 265 | } |
| @@ -267,7 +275,7 @@ int thread__fork(struct thread *self, struct thread *parent) | |||
| 267 | return -ENOMEM; | 275 | return -ENOMEM; |
| 268 | 276 | ||
| 269 | for (i = 0; i < MAP__NR_TYPES; ++i) | 277 | for (i = 0; i < MAP__NR_TYPES; ++i) |
| 270 | if (thread__clone_maps(self, parent, i) < 0) | 278 | if (map_groups__clone(&self->mg, &parent->mg, i) < 0) |
| 271 | return -ENOMEM; | 279 | return -ENOMEM; |
| 272 | return 0; | 280 | return 0; |
| 273 | } | 281 | } |
| @@ -286,11 +294,11 @@ size_t threads__fprintf(FILE *fp) | |||
| 286 | return ret; | 294 | return ret; |
| 287 | } | 295 | } |
| 288 | 296 | ||
| 289 | struct symbol *thread__find_symbol(struct thread *self, | 297 | struct symbol *map_groups__find_symbol(struct map_groups *self, |
| 290 | enum map_type type, u64 addr, | 298 | enum map_type type, u64 addr, |
| 291 | symbol_filter_t filter) | 299 | symbol_filter_t filter) |
| 292 | { | 300 | { |
| 293 | struct map *map = thread__find_map(self, type, addr); | 301 | struct map *map = map_groups__find(self, type, addr); |
| 294 | 302 | ||
| 295 | if (map != NULL) | 303 | if (map != NULL) |
| 296 | return map__find_symbol(map, map->map_ip(map, addr), filter); | 304 | return map__find_symbol(map, map->map_ip(map, addr), filter); |
diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h index 686d6e914d9e..a6333f3716af 100644 --- a/tools/perf/util/thread.h +++ b/tools/perf/util/thread.h | |||
| @@ -5,52 +5,63 @@ | |||
| 5 | #include <unistd.h> | 5 | #include <unistd.h> |
| 6 | #include "symbol.h" | 6 | #include "symbol.h" |
| 7 | 7 | ||
| 8 | struct thread { | 8 | struct map_groups { |
| 9 | struct rb_node rb_node; | ||
| 10 | struct rb_root maps[MAP__NR_TYPES]; | 9 | struct rb_root maps[MAP__NR_TYPES]; |
| 11 | struct list_head removed_maps[MAP__NR_TYPES]; | 10 | struct list_head removed_maps[MAP__NR_TYPES]; |
| 12 | pid_t pid; | ||
| 13 | bool use_modules; | 11 | bool use_modules; |
| 12 | }; | ||
| 13 | |||
| 14 | struct thread { | ||
| 15 | struct rb_node rb_node; | ||
| 16 | struct map_groups mg; | ||
| 17 | pid_t pid; | ||
| 14 | char shortname[3]; | 18 | char shortname[3]; |
| 15 | char *comm; | 19 | char *comm; |
| 16 | int comm_len; | 20 | int comm_len; |
| 17 | }; | 21 | }; |
| 18 | 22 | ||
| 19 | void thread__init(struct thread *self, pid_t pid); | 23 | void map_groups__init(struct map_groups *self); |
| 20 | int thread__set_comm(struct thread *self, const char *comm); | 24 | int thread__set_comm(struct thread *self, const char *comm); |
| 21 | int thread__comm_len(struct thread *self); | 25 | int thread__comm_len(struct thread *self); |
| 22 | struct thread *threads__findnew(pid_t pid); | 26 | struct thread *threads__findnew(pid_t pid); |
| 23 | struct thread *register_idle_thread(void); | 27 | struct thread *register_idle_thread(void); |
| 24 | void thread__insert_map(struct thread *self, struct map *map); | 28 | void thread__insert_map(struct thread *self, struct map *map); |
| 25 | int thread__fork(struct thread *self, struct thread *parent); | 29 | int thread__fork(struct thread *self, struct thread *parent); |
| 26 | size_t thread__fprintf_maps(struct thread *self, FILE *fp); | 30 | size_t map_groups__fprintf_maps(struct map_groups *self, FILE *fp); |
| 27 | size_t threads__fprintf(FILE *fp); | 31 | size_t threads__fprintf(FILE *fp); |
| 28 | 32 | ||
| 29 | void maps__insert(struct rb_root *maps, struct map *map); | 33 | void maps__insert(struct rb_root *maps, struct map *map); |
| 30 | struct map *maps__find(struct rb_root *maps, u64 addr); | 34 | struct map *maps__find(struct rb_root *maps, u64 addr); |
| 31 | 35 | ||
| 32 | static inline struct map *thread__find_map(struct thread *self, | 36 | static inline void map_groups__insert(struct map_groups *self, struct map *map) |
| 37 | { | ||
| 38 | maps__insert(&self->maps[map->type], map); | ||
| 39 | } | ||
| 40 | |||
| 41 | static inline struct map *map_groups__find(struct map_groups *self, | ||
| 33 | enum map_type type, u64 addr) | 42 | enum map_type type, u64 addr) |
| 34 | { | 43 | { |
| 35 | return self ? maps__find(&self->maps[type], addr) : NULL; | 44 | return maps__find(&self->maps[type], addr); |
| 36 | } | 45 | } |
| 37 | 46 | ||
| 38 | static inline void __thread__insert_map(struct thread *self, struct map *map) | 47 | static inline struct map *thread__find_map(struct thread *self, |
| 48 | enum map_type type, u64 addr) | ||
| 39 | { | 49 | { |
| 40 | maps__insert(&self->maps[map->type], map); | 50 | return self ? map_groups__find(&self->mg, type, addr) : NULL; |
| 41 | } | 51 | } |
| 42 | 52 | ||
| 43 | void thread__find_addr_location(struct thread *self, u8 cpumode, | 53 | void thread__find_addr_location(struct thread *self, u8 cpumode, |
| 44 | enum map_type type, u64 addr, | 54 | enum map_type type, u64 addr, |
| 45 | struct addr_location *al, | 55 | struct addr_location *al, |
| 46 | symbol_filter_t filter); | 56 | symbol_filter_t filter); |
| 47 | struct symbol *thread__find_symbol(struct thread *self, | 57 | struct symbol *map_groups__find_symbol(struct map_groups *self, |
| 48 | enum map_type type, u64 addr, | 58 | enum map_type type, u64 addr, |
| 49 | symbol_filter_t filter); | 59 | symbol_filter_t filter); |
| 50 | 60 | ||
| 51 | static inline struct symbol * | 61 | static inline struct symbol * |
| 52 | thread__find_function(struct thread *self, u64 addr, symbol_filter_t filter) | 62 | map_groups__find_function(struct map_groups *self, u64 addr, |
| 63 | symbol_filter_t filter) | ||
| 53 | { | 64 | { |
| 54 | return thread__find_symbol(self, MAP__FUNCTION, addr, filter); | 65 | return map_groups__find_symbol(self, MAP__FUNCTION, addr, filter); |
| 55 | } | 66 | } |
| 56 | #endif /* __PERF_THREAD_H */ | 67 | #endif /* __PERF_THREAD_H */ |
