Skip to content

Commit a7ca080

Browse files
author
Ingo Molnar
committed
Merge tag 'perf-urgent-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/urgent
Pull various perf tooling fixes from Arnaldo Carvalho de Melo.
2 parents 4166fb6 + 7fb0a5e commit a7ca080

File tree

7 files changed

+68
-13
lines changed

7 files changed

+68
-13
lines changed

tools/perf/builtin-top.c

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
#include "util/debug.h"
4343

4444
#include <assert.h>
45+
#include <elf.h>
4546
#include <fcntl.h>
4647

4748
#include <stdio.h>
@@ -59,6 +60,7 @@
5960
#include <sys/prctl.h>
6061
#include <sys/wait.h>
6162
#include <sys/uio.h>
63+
#include <sys/utsname.h>
6264
#include <sys/mman.h>
6365

6466
#include <linux/unistd.h>
@@ -162,12 +164,40 @@ static void __zero_source_counters(struct hist_entry *he)
162164
symbol__annotate_zero_histograms(sym);
163165
}
164166

167+
static void ui__warn_map_erange(struct map *map, struct symbol *sym, u64 ip)
168+
{
169+
struct utsname uts;
170+
int err = uname(&uts);
171+
172+
ui__warning("Out of bounds address found:\n\n"
173+
"Addr: %" PRIx64 "\n"
174+
"DSO: %s %c\n"
175+
"Map: %" PRIx64 "-%" PRIx64 "\n"
176+
"Symbol: %" PRIx64 "-%" PRIx64 " %c %s\n"
177+
"Arch: %s\n"
178+
"Kernel: %s\n"
179+
"Tools: %s\n\n"
180+
"Not all samples will be on the annotation output.\n\n"
181+
"Please report to [email protected]\n",
182+
ip, map->dso->long_name, dso__symtab_origin(map->dso),
183+
map->start, map->end, sym->start, sym->end,
184+
sym->binding == STB_GLOBAL ? 'g' :
185+
sym->binding == STB_LOCAL ? 'l' : 'w', sym->name,
186+
err ? "[unknown]" : uts.machine,
187+
err ? "[unknown]" : uts.release, perf_version_string);
188+
if (use_browser <= 0)
189+
sleep(5);
190+
191+
map->erange_warned = true;
192+
}
193+
165194
static void perf_top__record_precise_ip(struct perf_top *top,
166195
struct hist_entry *he,
167196
int counter, u64 ip)
168197
{
169198
struct annotation *notes;
170199
struct symbol *sym;
200+
int err;
171201

172202
if (he == NULL || he->ms.sym == NULL ||
173203
((top->sym_filter_entry == NULL ||
@@ -189,9 +219,12 @@ static void perf_top__record_precise_ip(struct perf_top *top,
189219
}
190220

191221
ip = he->ms.map->map_ip(he->ms.map, ip);
192-
symbol__inc_addr_samples(sym, he->ms.map, counter, ip);
222+
err = symbol__inc_addr_samples(sym, he->ms.map, counter, ip);
193223

194224
pthread_mutex_unlock(&notes->lock);
225+
226+
if (err == -ERANGE && !he->ms.map->erange_warned)
227+
ui__warn_map_erange(he->ms.map, sym, ip);
195228
}
196229

197230
static void perf_top__show_details(struct perf_top *top)
@@ -615,6 +648,7 @@ static void *display_thread(void *arg)
615648

616649
/* Tag samples to be skipped. */
617650
static const char *skip_symbols[] = {
651+
"intel_idle",
618652
"default_idle",
619653
"native_safe_halt",
620654
"cpu_idle",

tools/perf/util/annotate.c

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@ int symbol__inc_addr_samples(struct symbol *sym, struct map *map,
6464

6565
pr_debug3("%s: addr=%#" PRIx64 "\n", __func__, map->unmap_ip(map, addr));
6666

67-
if (addr > sym->end)
68-
return 0;
67+
if (addr < sym->start || addr > sym->end)
68+
return -ERANGE;
6969

7070
offset = addr - sym->start;
7171
h = annotation__histogram(notes, evidx);
@@ -561,16 +561,12 @@ void symbol__annotate_decay_histogram(struct symbol *sym, int evidx)
561561
{
562562
struct annotation *notes = symbol__annotation(sym);
563563
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;
566565

567566
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];
574570
}
575571
}
576572

tools/perf/util/hist.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,18 @@ static struct hist_entry *add_hist_entry(struct hists *hists,
256256
if (!cmp) {
257257
he->period += period;
258258
++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+
}
259271
goto out;
260272
}
261273

tools/perf/util/map.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ void map__init(struct map *self, enum map_type type,
3838
RB_CLEAR_NODE(&self->rb_node);
3939
self->groups = NULL;
4040
self->referenced = false;
41+
self->erange_warned = false;
4142
}
4243

4344
struct map *map__new(struct list_head *dsos__list, u64 start, u64 len,

tools/perf/util/map.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ struct map {
3333
u64 end;
3434
u8 /* enum map_type */ type;
3535
bool referenced;
36+
bool erange_warned;
3637
u32 priv;
3738
u64 pgoff;
3839

tools/perf/util/session.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -826,8 +826,16 @@ static struct machine *
826826
{
827827
const u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
828828

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+
}
831839

832840
return perf_session__find_host_machine(session);
833841
}

tools/perf/util/ui/browsers/hists.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,9 @@ static int callchain__count_rows(struct rb_root *chain)
125125

126126
static bool map_symbol__toggle_fold(struct map_symbol *self)
127127
{
128+
if (!self)
129+
return false;
130+
128131
if (!self->has_children)
129132
return false;
130133

0 commit comments

Comments
 (0)