Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull perf tool fixes from Ingo Molnar.

* 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
perf kvm: Finding struct machine fails for PERF_RECORD_MMAP
perf annotate: Validate addr in symbol__inc_addr_samples
perf hists browser: Fix NULL deref in hists browsing code
perf hists: Catch and handle out-of-date hist entry maps.
perf annotate: Fix hist decay
perf top: Add intel_idle to the skip list

+68 -13
+35 -1
tools/perf/builtin-top.c
··· 42 42 #include "util/debug.h" 43 43 44 44 #include <assert.h> 45 + #include <elf.h> 45 46 #include <fcntl.h> 46 47 47 48 #include <stdio.h> ··· 60 59 #include <sys/prctl.h> 61 60 #include <sys/wait.h> 62 61 #include <sys/uio.h> 62 + #include <sys/utsname.h> 63 63 #include <sys/mman.h> 64 64 65 65 #include <linux/unistd.h> ··· 164 162 symbol__annotate_zero_histograms(sym); 165 163 } 166 164 165 + static void ui__warn_map_erange(struct map *map, struct symbol *sym, u64 ip) 166 + { 167 + struct utsname uts; 168 + int err = uname(&uts); 169 + 170 + ui__warning("Out of bounds address found:\n\n" 171 + "Addr: %" PRIx64 "\n" 172 + "DSO: %s %c\n" 173 + "Map: %" PRIx64 "-%" PRIx64 "\n" 174 + "Symbol: %" PRIx64 "-%" PRIx64 " %c %s\n" 175 + "Arch: %s\n" 176 + "Kernel: %s\n" 177 + "Tools: %s\n\n" 178 + "Not all samples will be on the annotation output.\n\n" 179 + "Please report to linux-kernel@vger.kernel.org\n", 180 + ip, map->dso->long_name, dso__symtab_origin(map->dso), 181 + map->start, map->end, sym->start, sym->end, 182 + sym->binding == STB_GLOBAL ? 'g' : 183 + sym->binding == STB_LOCAL ? 'l' : 'w', sym->name, 184 + err ? "[unknown]" : uts.machine, 185 + err ? "[unknown]" : uts.release, perf_version_string); 186 + if (use_browser <= 0) 187 + sleep(5); 188 + 189 + map->erange_warned = true; 190 + } 191 + 167 192 static void perf_top__record_precise_ip(struct perf_top *top, 168 193 struct hist_entry *he, 169 194 int counter, u64 ip) 170 195 { 171 196 struct annotation *notes; 172 197 struct symbol *sym; 198 + int err; 173 199 174 200 if (he == NULL || he->ms.sym == NULL || 175 201 ((top->sym_filter_entry == NULL || ··· 219 189 } 220 190 221 191 ip = he->ms.map->map_ip(he->ms.map, ip); 222 - symbol__inc_addr_samples(sym, he->ms.map, counter, ip); 192 + err = symbol__inc_addr_samples(sym, he->ms.map, counter, ip); 223 193 224 194 pthread_mutex_unlock(&notes->lock); 195 + 196 + if (err == -ERANGE && !he->ms.map->erange_warned) 197 + ui__warn_map_erange(he->ms.map, sym, ip); 225 198 } 226 199 227 200 static void perf_top__show_details(struct perf_top *top) ··· 648 615 649 616 /* Tag samples to be skipped. */ 650 617 static const char *skip_symbols[] = { 618 + "intel_idle", 651 619 "default_idle", 652 620 "native_safe_halt", 653 621 "cpu_idle",
+6 -10
tools/perf/util/annotate.c
··· 64 64 65 65 pr_debug3("%s: addr=%#" PRIx64 "\n", __func__, map->unmap_ip(map, addr)); 66 66 67 - if (addr > sym->end) 68 - return 0; 67 + if (addr < sym->start || addr > sym->end) 68 + return -ERANGE; 69 69 70 70 offset = addr - sym->start; 71 71 h = annotation__histogram(notes, evidx); ··· 561 561 { 562 562 struct annotation *notes = symbol__annotation(sym); 563 563 struct sym_hist *h = annotation__histogram(notes, evidx); 564 - struct objdump_line *pos; 565 - int len = sym->end - sym->start; 564 + int len = sym->end - sym->start, offset; 566 565 567 566 h->sum = 0; 568 - 569 - list_for_each_entry(pos, &notes->src->source, node) { 570 - if (pos->offset != -1 && pos->offset < len) { 571 - h->addr[pos->offset] = h->addr[pos->offset] * 7 / 8; 572 - h->sum += h->addr[pos->offset]; 573 - } 567 + for (offset = 0; offset < len; ++offset) { 568 + h->addr[offset] = h->addr[offset] * 7 / 8; 569 + h->sum += h->addr[offset]; 574 570 } 575 571 } 576 572
+12
tools/perf/util/hist.c
··· 256 256 if (!cmp) { 257 257 he->period += period; 258 258 ++he->nr_events; 259 + 260 + /* If the map of an existing hist_entry has 261 + * become out-of-date due to an exec() or 262 + * similar, update it. Otherwise we will 263 + * mis-adjust symbol addresses when computing 264 + * the history counter to increment. 265 + */ 266 + if (he->ms.map != entry->ms.map) { 267 + he->ms.map = entry->ms.map; 268 + if (he->ms.map) 269 + he->ms.map->referenced = true; 270 + } 259 271 goto out; 260 272 } 261 273
+1
tools/perf/util/map.c
··· 38 38 RB_CLEAR_NODE(&self->rb_node); 39 39 self->groups = NULL; 40 40 self->referenced = false; 41 + self->erange_warned = false; 41 42 } 42 43 43 44 struct map *map__new(struct list_head *dsos__list, u64 start, u64 len,
+1
tools/perf/util/map.h
··· 33 33 u64 end; 34 34 u8 /* enum map_type */ type; 35 35 bool referenced; 36 + bool erange_warned; 36 37 u32 priv; 37 38 u64 pgoff; 38 39
+10 -2
tools/perf/util/session.c
··· 826 826 { 827 827 const u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; 828 828 829 - if (cpumode == PERF_RECORD_MISC_GUEST_KERNEL && perf_guest) 830 - return perf_session__find_machine(session, event->ip.pid); 829 + if (cpumode == PERF_RECORD_MISC_GUEST_KERNEL && perf_guest) { 830 + u32 pid; 831 + 832 + if (event->header.type == PERF_RECORD_MMAP) 833 + pid = event->mmap.pid; 834 + else 835 + pid = event->ip.pid; 836 + 837 + return perf_session__find_machine(session, pid); 838 + } 831 839 832 840 return perf_session__find_host_machine(session); 833 841 }
+3
tools/perf/util/ui/browsers/hists.c
··· 125 125 126 126 static bool map_symbol__toggle_fold(struct map_symbol *self) 127 127 { 128 + if (!self) 129 + return false; 130 + 128 131 if (!self->has_children) 129 132 return false; 130 133