Commit 6313e3c21743cc88bb5bd8aa72948ee1e83937b6

Authored by Linus Torvalds

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
... ... @@ -11,6 +11,7 @@
11 11 void pvclock_read_wallclock(struct pvclock_wall_clock *wall,
12 12 struct pvclock_vcpu_time_info *vcpu,
13 13 struct timespec *ts);
  14 +void pvclock_resume(void);
14 15  
15 16 /*
16 17 * Scale a 64-bit delta by scaling and multiplying by a 32-bit fraction,
arch/x86/kernel/pvclock.c
... ... @@ -83,6 +83,11 @@
83 83  
84 84 static atomic64_t last_value = ATOMIC64_INIT(0);
85 85  
  86 +void pvclock_resume(void)
  87 +{
  88 + atomic64_set(&last_value, 0);
  89 +}
  90 +
86 91 cycle_t pvclock_clocksource_read(struct pvclock_vcpu_time_info *src)
87 92 {
88 93 struct pvclock_shadow_time shadow;
... ... @@ -426,6 +426,8 @@
426 426 {
427 427 int cpu;
428 428  
  429 + pvclock_resume();
  430 +
429 431 if (xen_clockevent != &xen_vcpuop_clockevent)
430 432 return;
431 433  
... ... @@ -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