diff options
Diffstat (limited to 'tools/perf')
| -rw-r--r-- | tools/perf/builtin-record.c | 6 | ||||
| -rw-r--r-- | tools/perf/util/header.c | 11 | ||||
| -rw-r--r-- | tools/perf/util/symbol.c | 59 |
3 files changed, 65 insertions, 11 deletions
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index e2c2de201ee..564491fa18b 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c | |||
| @@ -197,7 +197,7 @@ static void sig_atexit(void) | |||
| 197 | if (child_pid > 0) | 197 | if (child_pid > 0) |
| 198 | kill(child_pid, SIGTERM); | 198 | kill(child_pid, SIGTERM); |
| 199 | 199 | ||
| 200 | if (signr == -1) | 200 | if (signr == -1 || signr == SIGUSR1) |
| 201 | return; | 201 | return; |
| 202 | 202 | ||
| 203 | signal(signr, SIG_DFL); | 203 | signal(signr, SIG_DFL); |
| @@ -515,6 +515,7 @@ static int __cmd_record(int argc, const char **argv) | |||
| 515 | atexit(sig_atexit); | 515 | atexit(sig_atexit); |
| 516 | signal(SIGCHLD, sig_handler); | 516 | signal(SIGCHLD, sig_handler); |
| 517 | signal(SIGINT, sig_handler); | 517 | signal(SIGINT, sig_handler); |
| 518 | signal(SIGUSR1, sig_handler); | ||
| 518 | 519 | ||
| 519 | if (forks && (pipe(child_ready_pipe) < 0 || pipe(go_pipe) < 0)) { | 520 | if (forks && (pipe(child_ready_pipe) < 0 || pipe(go_pipe) < 0)) { |
| 520 | perror("failed to create pipes"); | 521 | perror("failed to create pipes"); |
| @@ -606,6 +607,7 @@ static int __cmd_record(int argc, const char **argv) | |||
| 606 | execvp(argv[0], (char **)argv); | 607 | execvp(argv[0], (char **)argv); |
| 607 | 608 | ||
| 608 | perror(argv[0]); | 609 | perror(argv[0]); |
| 610 | kill(getppid(), SIGUSR1); | ||
| 609 | exit(-1); | 611 | exit(-1); |
| 610 | } | 612 | } |
| 611 | 613 | ||
| @@ -762,7 +764,7 @@ static int __cmd_record(int argc, const char **argv) | |||
| 762 | } | 764 | } |
| 763 | } | 765 | } |
| 764 | 766 | ||
| 765 | if (quiet) | 767 | if (quiet || signr == SIGUSR1) |
| 766 | return 0; | 768 | return 0; |
| 767 | 769 | ||
| 768 | fprintf(stderr, "[ perf record: Woken up %ld times to write data ]\n", waking); | 770 | fprintf(stderr, "[ perf record: Woken up %ld times to write data ]\n", waking); |
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index d7e67b167ea..64a85bafde6 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c | |||
| @@ -946,11 +946,16 @@ perf_header__find_attr(u64 id, struct perf_header *header) | |||
| 946 | 946 | ||
| 947 | /* | 947 | /* |
| 948 | * We set id to -1 if the data file doesn't contain sample | 948 | * We set id to -1 if the data file doesn't contain sample |
| 949 | * ids. Check for this and avoid walking through the entire | 949 | * ids. This can happen when the data file contains one type |
| 950 | * list of ids which may be large. | 950 | * of event and in that case, the header can still store the |
| 951 | * event attribute information. Check for this and avoid | ||
| 952 | * walking through the entire list of ids which may be large. | ||
| 951 | */ | 953 | */ |
| 952 | if (id == -1ULL) | 954 | if (id == -1ULL) { |
| 955 | if (header->attrs > 0) | ||
| 956 | return &header->attr[0]->attr; | ||
| 953 | return NULL; | 957 | return NULL; |
| 958 | } | ||
| 954 | 959 | ||
| 955 | for (i = 0; i < header->attrs; i++) { | 960 | for (i = 0; i < header->attrs; i++) { |
| 956 | struct perf_header_attr *attr = header->attr[i]; | 961 | struct perf_header_attr *attr = header->attr[i]; |
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 0500895a45a..d628c8d1cf5 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c | |||
| @@ -532,7 +532,7 @@ static int dso__split_kallsyms(struct dso *self, struct map *map, | |||
| 532 | struct machine *machine = kmaps->machine; | 532 | struct machine *machine = kmaps->machine; |
| 533 | struct map *curr_map = map; | 533 | struct map *curr_map = map; |
| 534 | struct symbol *pos; | 534 | struct symbol *pos; |
| 535 | int count = 0; | 535 | int count = 0, moved = 0; |
| 536 | struct rb_root *root = &self->symbols[map->type]; | 536 | struct rb_root *root = &self->symbols[map->type]; |
| 537 | struct rb_node *next = rb_first(root); | 537 | struct rb_node *next = rb_first(root); |
| 538 | int kernel_range = 0; | 538 | int kernel_range = 0; |
| @@ -590,6 +590,11 @@ static int dso__split_kallsyms(struct dso *self, struct map *map, | |||
| 590 | char dso_name[PATH_MAX]; | 590 | char dso_name[PATH_MAX]; |
| 591 | struct dso *dso; | 591 | struct dso *dso; |
| 592 | 592 | ||
| 593 | if (count == 0) { | ||
| 594 | curr_map = map; | ||
| 595 | goto filter_symbol; | ||
| 596 | } | ||
| 597 | |||
| 593 | if (self->kernel == DSO_TYPE_GUEST_KERNEL) | 598 | if (self->kernel == DSO_TYPE_GUEST_KERNEL) |
| 594 | snprintf(dso_name, sizeof(dso_name), | 599 | snprintf(dso_name, sizeof(dso_name), |
| 595 | "[guest.kernel].%d", | 600 | "[guest.kernel].%d", |
| @@ -615,7 +620,7 @@ static int dso__split_kallsyms(struct dso *self, struct map *map, | |||
| 615 | map_groups__insert(kmaps, curr_map); | 620 | map_groups__insert(kmaps, curr_map); |
| 616 | ++kernel_range; | 621 | ++kernel_range; |
| 617 | } | 622 | } |
| 618 | 623 | filter_symbol: | |
| 619 | if (filter && filter(curr_map, pos)) { | 624 | if (filter && filter(curr_map, pos)) { |
| 620 | discard_symbol: rb_erase(&pos->rb_node, root); | 625 | discard_symbol: rb_erase(&pos->rb_node, root); |
| 621 | symbol__delete(pos); | 626 | symbol__delete(pos); |
| @@ -623,8 +628,9 @@ discard_symbol: rb_erase(&pos->rb_node, root); | |||
| 623 | if (curr_map != map) { | 628 | if (curr_map != map) { |
| 624 | rb_erase(&pos->rb_node, root); | 629 | rb_erase(&pos->rb_node, root); |
| 625 | symbols__insert(&curr_map->dso->symbols[curr_map->type], pos); | 630 | symbols__insert(&curr_map->dso->symbols[curr_map->type], pos); |
| 626 | } | 631 | ++moved; |
| 627 | count++; | 632 | } else |
| 633 | ++count; | ||
| 628 | } | 634 | } |
| 629 | } | 635 | } |
| 630 | 636 | ||
| @@ -634,7 +640,7 @@ discard_symbol: rb_erase(&pos->rb_node, root); | |||
| 634 | dso__set_loaded(curr_map->dso, curr_map->type); | 640 | dso__set_loaded(curr_map->dso, curr_map->type); |
| 635 | } | 641 | } |
| 636 | 642 | ||
| 637 | return count; | 643 | return count + moved; |
| 638 | } | 644 | } |
| 639 | 645 | ||
| 640 | int dso__load_kallsyms(struct dso *self, const char *filename, | 646 | int dso__load_kallsyms(struct dso *self, const char *filename, |
| @@ -2125,14 +2131,55 @@ static struct dso *machine__create_kernel(struct machine *self) | |||
| 2125 | return kernel; | 2131 | return kernel; |
| 2126 | } | 2132 | } |
| 2127 | 2133 | ||
| 2134 | struct process_args { | ||
| 2135 | u64 start; | ||
| 2136 | }; | ||
| 2137 | |||
| 2138 | static int symbol__in_kernel(void *arg, const char *name, | ||
| 2139 | char type __used, u64 start) | ||
| 2140 | { | ||
| 2141 | struct process_args *args = arg; | ||
| 2142 | |||
| 2143 | if (strchr(name, '[')) | ||
| 2144 | return 0; | ||
| 2145 | |||
| 2146 | args->start = start; | ||
| 2147 | return 1; | ||
| 2148 | } | ||
| 2149 | |||
| 2150 | /* Figure out the start address of kernel map from /proc/kallsyms */ | ||
| 2151 | static u64 machine__get_kernel_start_addr(struct machine *machine) | ||
| 2152 | { | ||
| 2153 | const char *filename; | ||
| 2154 | char path[PATH_MAX]; | ||
| 2155 | struct process_args args; | ||
| 2156 | |||
| 2157 | if (machine__is_host(machine)) { | ||
| 2158 | filename = "/proc/kallsyms"; | ||
| 2159 | } else { | ||
| 2160 | if (machine__is_default_guest(machine)) | ||
| 2161 | filename = (char *)symbol_conf.default_guest_kallsyms; | ||
| 2162 | else { | ||
| 2163 | sprintf(path, "%s/proc/kallsyms", machine->root_dir); | ||
| 2164 | filename = path; | ||
| 2165 | } | ||
| 2166 | } | ||
| 2167 | |||
| 2168 | if (kallsyms__parse(filename, &args, symbol__in_kernel) <= 0) | ||
| 2169 | return 0; | ||
| 2170 | |||
| 2171 | return args.start; | ||
| 2172 | } | ||
| 2173 | |||
| 2128 | int __machine__create_kernel_maps(struct machine *self, struct dso *kernel) | 2174 | int __machine__create_kernel_maps(struct machine *self, struct dso *kernel) |
| 2129 | { | 2175 | { |
| 2130 | enum map_type type; | 2176 | enum map_type type; |
| 2177 | u64 start = machine__get_kernel_start_addr(self); | ||
| 2131 | 2178 | ||
| 2132 | for (type = 0; type < MAP__NR_TYPES; ++type) { | 2179 | for (type = 0; type < MAP__NR_TYPES; ++type) { |
| 2133 | struct kmap *kmap; | 2180 | struct kmap *kmap; |
| 2134 | 2181 | ||
| 2135 | self->vmlinux_maps[type] = map__new2(0, kernel, type); | 2182 | self->vmlinux_maps[type] = map__new2(start, kernel, type); |
| 2136 | if (self->vmlinux_maps[type] == NULL) | 2183 | if (self->vmlinux_maps[type] == NULL) |
| 2137 | return -1; | 2184 | return -1; |
| 2138 | 2185 | ||
