Commit 6313e3c21743cc88bb5bd8aa72948ee1e83937b6
Exists in
master
and in
7 other branches
Merge branches 'x86-fixes-for-linus', 'perf-fixes-for-linus' and 'sched-fixes-fo…
…r-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip * 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: x86/pvclock: Zero last_value on resume * 'perf-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: perf record: Fix eternal wait for stillborn child perf header: Don't assume there's no attr info if no sample ids is provided perf symbols: Figure out start address of kernel map from kallsyms perf symbols: Fix kallsyms kernel/module map splitting * 'sched-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: nohz: Fix printk_needs_cpu() return value on offline cpus printk: Fix wake_up_klogd() vs cpu hotplug
Showing 7 changed files Side-by-side Diff
arch/x86/include/asm/pvclock.h
arch/x86/kernel/pvclock.c
arch/x86/xen/time.c
kernel/printk.c
... | ... | @@ -1082,13 +1082,15 @@ |
1082 | 1082 | |
1083 | 1083 | int printk_needs_cpu(int cpu) |
1084 | 1084 | { |
1085 | + if (unlikely(cpu_is_offline(cpu))) | |
1086 | + printk_tick(); | |
1085 | 1087 | return per_cpu(printk_pending, cpu); |
1086 | 1088 | } |
1087 | 1089 | |
1088 | 1090 | void wake_up_klogd(void) |
1089 | 1091 | { |
1090 | 1092 | if (waitqueue_active(&log_wait)) |
1091 | - __raw_get_cpu_var(printk_pending) = 1; | |
1093 | + this_cpu_write(printk_pending, 1); | |
1092 | 1094 | } |
1093 | 1095 | |
1094 | 1096 | /** |
tools/perf/builtin-record.c
... | ... | @@ -197,7 +197,7 @@ |
197 | 197 | if (child_pid > 0) |
198 | 198 | kill(child_pid, SIGTERM); |
199 | 199 | |
200 | - if (signr == -1) | |
200 | + if (signr == -1 || signr == SIGUSR1) | |
201 | 201 | return; |
202 | 202 | |
203 | 203 | signal(signr, SIG_DFL); |
... | ... | @@ -515,6 +515,7 @@ |
515 | 515 | atexit(sig_atexit); |
516 | 516 | signal(SIGCHLD, sig_handler); |
517 | 517 | signal(SIGINT, sig_handler); |
518 | + signal(SIGUSR1, sig_handler); | |
518 | 519 | |
519 | 520 | if (forks && (pipe(child_ready_pipe) < 0 || pipe(go_pipe) < 0)) { |
520 | 521 | perror("failed to create pipes"); |
... | ... | @@ -606,6 +607,7 @@ |
606 | 607 | execvp(argv[0], (char **)argv); |
607 | 608 | |
608 | 609 | perror(argv[0]); |
610 | + kill(getppid(), SIGUSR1); | |
609 | 611 | exit(-1); |
610 | 612 | } |
611 | 613 | |
... | ... | @@ -762,7 +764,7 @@ |
762 | 764 | } |
763 | 765 | } |
764 | 766 | |
765 | - if (quiet) | |
767 | + if (quiet || signr == SIGUSR1) | |
766 | 768 | return 0; |
767 | 769 | |
768 | 770 | fprintf(stderr, "[ perf record: Woken up %ld times to write data ]\n", waking); |
tools/perf/util/header.c
... | ... | @@ -946,11 +946,16 @@ |
946 | 946 | |
947 | 947 | /* |
948 | 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 | |
950 | - * list of ids which may be large. | |
949 | + * ids. This can happen when the data file contains one type | |
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 | 957 | return NULL; |
958 | + } | |
954 | 959 | |
955 | 960 | for (i = 0; i < header->attrs; i++) { |
956 | 961 | struct perf_header_attr *attr = header->attr[i]; |
tools/perf/util/symbol.c
... | ... | @@ -532,7 +532,7 @@ |
532 | 532 | struct machine *machine = kmaps->machine; |
533 | 533 | struct map *curr_map = map; |
534 | 534 | struct symbol *pos; |
535 | - int count = 0; | |
535 | + int count = 0, moved = 0; | |
536 | 536 | struct rb_root *root = &self->symbols[map->type]; |
537 | 537 | struct rb_node *next = rb_first(root); |
538 | 538 | int kernel_range = 0; |
... | ... | @@ -590,6 +590,11 @@ |
590 | 590 | char dso_name[PATH_MAX]; |
591 | 591 | struct dso *dso; |
592 | 592 | |
593 | + if (count == 0) { | |
594 | + curr_map = map; | |
595 | + goto filter_symbol; | |
596 | + } | |
597 | + | |
593 | 598 | if (self->kernel == DSO_TYPE_GUEST_KERNEL) |
594 | 599 | snprintf(dso_name, sizeof(dso_name), |
595 | 600 | "[guest.kernel].%d", |
... | ... | @@ -615,7 +620,7 @@ |
615 | 620 | map_groups__insert(kmaps, curr_map); |
616 | 621 | ++kernel_range; |
617 | 622 | } |
618 | - | |
623 | +filter_symbol: | |
619 | 624 | if (filter && filter(curr_map, pos)) { |
620 | 625 | discard_symbol: rb_erase(&pos->rb_node, root); |
621 | 626 | symbol__delete(pos); |
... | ... | @@ -623,8 +628,9 @@ |
623 | 628 | if (curr_map != map) { |
624 | 629 | rb_erase(&pos->rb_node, root); |
625 | 630 | symbols__insert(&curr_map->dso->symbols[curr_map->type], pos); |
626 | - } | |
627 | - count++; | |
631 | + ++moved; | |
632 | + } else | |
633 | + ++count; | |
628 | 634 | } |
629 | 635 | } |
630 | 636 | |
... | ... | @@ -634,7 +640,7 @@ |
634 | 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 | 646 | int dso__load_kallsyms(struct dso *self, const char *filename, |
641 | 647 | |
642 | 648 | |
... | ... | @@ -2125,14 +2131,55 @@ |
2125 | 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 | 2174 | int __machine__create_kernel_maps(struct machine *self, struct dso *kernel) |
2129 | 2175 | { |
2130 | 2176 | enum map_type type; |
2177 | + u64 start = machine__get_kernel_start_addr(self); | |
2131 | 2178 | |
2132 | 2179 | for (type = 0; type < MAP__NR_TYPES; ++type) { |
2133 | 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 | 2183 | if (self->vmlinux_maps[type] == NULL) |
2137 | 2184 | return -1; |
2138 | 2185 |