diff options
author | Ingo Molnar <mingo@elte.hu> | 2011-03-30 09:06:51 +0200 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2011-03-30 09:06:51 +0200 |
commit | ae18cbfe9f147085426635763f1fe0c68f1071e2 (patch) | |
tree | 431ac889666515036c94ca89e939d54f4a765029 /tools | |
parent | 1d321881afb955bba1e0a8f50d3a04e111fcb581 (diff) | |
parent | cd25f8bc2696664877b21d33b7994e12fa570919 (diff) | |
download | linux-ae18cbfe9f147085426635763f1fe0c68f1071e2.tar.gz |
Merge branch 'perf/core' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux-2.6 into perf/core
Diffstat (limited to 'tools')
-rw-r--r-- | tools/perf/builtin-record.c | 19 | ||||
-rw-r--r-- | tools/perf/builtin-top.c | 44 | ||||
-rw-r--r-- | tools/perf/util/debug.c | 10 | ||||
-rw-r--r-- | tools/perf/util/debug.h | 1 | ||||
-rw-r--r-- | tools/perf/util/event.c | 2 | ||||
-rw-r--r-- | tools/perf/util/probe-finder.c | 72 | ||||
-rw-r--r-- | tools/perf/util/probe-finder.h | 2 | ||||
-rw-r--r-- | tools/perf/util/symbol.c | 3 |
8 files changed, 132 insertions, 21 deletions
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 6febcc168a8c..db6adecf46f1 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -275,11 +275,10 @@ try_again: !no_inherit) < 0) { int err = errno; - if (err == EPERM || err == EACCES) - die("Permission error - are you root?\n" - "\t Consider tweaking" - " /proc/sys/kernel/perf_event_paranoid.\n"); - else if (err == ENODEV && cpu_list) { + if (err == EPERM || err == EACCES) { + ui__warning_paranoid(); + exit(EXIT_FAILURE); + } else if (err == ENODEV && cpu_list) { die("No such device - did you specify" " an out-of-range profile CPU?\n"); } else if (err == EINVAL && sample_id_all_avail) { @@ -302,11 +301,19 @@ try_again: && attr->config == PERF_COUNT_HW_CPU_CYCLES) { if (verbose) - warning(" ... trying to fall back to cpu-clock-ticks\n"); + ui__warning("The cycles event is not supported, " + "trying to fall back to cpu-clock-ticks\n"); attr->type = PERF_TYPE_SOFTWARE; attr->config = PERF_COUNT_SW_CPU_CLOCK; goto try_again; } + + if (err == ENOENT) { + ui__warning("The %s event is not supported.\n", + event_name(pos)); + exit(EXIT_FAILURE); + } + printf("\n"); error("sys_perf_event_open() syscall returned with %d (%s). /bin/dmesg may provide additional information.\n", err, strerror(err)); diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 676b4fb0070f..fc1273e976c5 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -850,10 +850,10 @@ try_again: top.evlist->threads, group, inherit) < 0) { int err = errno; - if (err == EPERM || err == EACCES) - die("Permission error - are you root?\n" - "\t Consider tweaking" - " /proc/sys/kernel/perf_event_paranoid.\n"); + if (err == EPERM || err == EACCES) { + ui__warning_paranoid(); + goto out_err; + } /* * If it's cycles then fall back to hrtimer * based cpu-clock-tick sw counter, which @@ -861,25 +861,41 @@ try_again: */ if (attr->type == PERF_TYPE_HARDWARE && attr->config == PERF_COUNT_HW_CPU_CYCLES) { - if (verbose) - warning(" ... trying to fall back to cpu-clock-ticks\n"); + ui__warning("Cycles event not supported,\n" + "trying to fall back to cpu-clock-ticks\n"); attr->type = PERF_TYPE_SOFTWARE; attr->config = PERF_COUNT_SW_CPU_CLOCK; goto try_again; } - printf("\n"); - error("sys_perf_event_open() syscall returned with %d " - "(%s). /bin/dmesg may provide additional information.\n", - err, strerror(err)); - die("No CONFIG_PERF_EVENTS=y kernel support configured?\n"); - exit(-1); + + if (err == ENOENT) { + ui__warning("The %s event is not supported.\n", + event_name(counter)); + goto out_err; + } + + ui__warning("The sys_perf_event_open() syscall " + "returned with %d (%s). /bin/dmesg " + "may provide additional information.\n" + "No CONFIG_PERF_EVENTS=y kernel support " + "configured?\n", err, strerror(err)); + goto out_err; } } - if (perf_evlist__mmap(evlist, mmap_pages, false) < 0) - die("failed to mmap with %d (%s)\n", errno, strerror(errno)); + if (perf_evlist__mmap(evlist, mmap_pages, false) < 0) { + ui__warning("Failed to mmap with %d (%s)\n", + errno, strerror(errno)); + goto out_err; + } + + return; + +out_err: + exit_browser(0); + exit(0); } static int __cmd_top(void) diff --git a/tools/perf/util/debug.c b/tools/perf/util/debug.c index d4536a9e0d8c..155749d74350 100644 --- a/tools/perf/util/debug.c +++ b/tools/perf/util/debug.c @@ -57,6 +57,16 @@ void ui__warning(const char *format, ...) } #endif +void ui__warning_paranoid(void) +{ + ui__warning("Permission error - are you root?\n" + "Consider tweaking /proc/sys/kernel/perf_event_paranoid:\n" + " -1 - Not paranoid at all\n" + " 0 - Disallow raw tracepoint access for unpriv\n" + " 1 - Disallow cpu events for unpriv\n" + " 2 - Disallow kernel profiling for unpriv\n"); +} + void trace_event(union perf_event *event) { unsigned char *raw_event = (void *)event; diff --git a/tools/perf/util/debug.h b/tools/perf/util/debug.h index 93516cf4682c..fd53db47e3de 100644 --- a/tools/perf/util/debug.h +++ b/tools/perf/util/debug.h @@ -36,5 +36,6 @@ int ui_helpline__show_help(const char *format, va_list ap); #endif void ui__warning(const char *format, ...) __attribute__((format(printf, 1, 2))); +void ui__warning_paranoid(void); #endif /* __PERF_DEBUG_H */ diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 2b15c362ef56..1023f67633a4 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -710,7 +710,7 @@ try_again: * in the whole kernel symbol list. */ if ((long long)al->addr < 0 && - cpumode == PERF_RECORD_MISC_KERNEL && + cpumode == PERF_RECORD_MISC_USER && machine && mg != &machine->kmaps) { mg = &machine->kmaps; goto try_again; diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c index 194f9e2a3285..ff416b85f7e8 100644 --- a/tools/perf/util/probe-finder.c +++ b/tools/perf/util/probe-finder.c @@ -1435,6 +1435,38 @@ static int find_probe_point_by_func(struct probe_finder *pf) return _param.retval; } +struct pubname_callback_param { + char *function; + char *file; + Dwarf_Die *cu_die; + Dwarf_Die *sp_die; + int found; +}; + +static int pubname_search_cb(Dwarf *dbg, Dwarf_Global *gl, void *data) +{ + struct pubname_callback_param *param = data; + + if (dwarf_offdie(dbg, gl->die_offset, param->sp_die)) { + if (dwarf_tag(param->sp_die) != DW_TAG_subprogram) + return DWARF_CB_OK; + + if (die_compare_name(param->sp_die, param->function)) { + if (!dwarf_offdie(dbg, gl->cu_offset, param->cu_die)) + return DWARF_CB_OK; + + if (param->file && + strtailcmp(param->file, dwarf_decl_file(param->sp_die))) + return DWARF_CB_OK; + + param->found = 1; + return DWARF_CB_ABORT; + } + } + + return DWARF_CB_OK; +} + /* Find probe points from debuginfo */ static int find_probes(int fd, struct probe_finder *pf) { @@ -1461,6 +1493,27 @@ static int find_probes(int fd, struct probe_finder *pf) off = 0; line_list__init(&pf->lcache); + + /* Fastpath: lookup by function name from .debug_pubnames section */ + if (pp->function) { + struct pubname_callback_param pubname_param = { + .function = pp->function, + .file = pp->file, + .cu_die = &pf->cu_die, + .sp_die = &pf->sp_die, + }; + struct dwarf_callback_param probe_param = { + .data = pf, + }; + + dwarf_getpubnames(dbg, pubname_search_cb, &pubname_param, 0); + if (pubname_param.found) { + ret = probe_point_search_cb(&pf->sp_die, &probe_param); + if (ret) + goto found; + } + } + /* Loop on CUs (Compilation Unit) */ while (!dwarf_nextcu(dbg, off, &noff, &cuhl, NULL, NULL, NULL)) { /* Get the DIE(Debugging Information Entry) of this CU */ @@ -1488,6 +1541,8 @@ static int find_probes(int fd, struct probe_finder *pf) } off = noff; } + +found: line_list__free(&pf->lcache); if (dwfl) dwfl_end(dwfl); @@ -1895,6 +1950,22 @@ int find_line_range(int fd, struct line_range *lr) return -EBADF; } + /* Fastpath: lookup by function name from .debug_pubnames section */ + if (lr->function) { + struct pubname_callback_param pubname_param = { + .function = lr->function, .file = lr->file, + .cu_die = &lf.cu_die, .sp_die = &lf.sp_die, .found = 0}; + struct dwarf_callback_param line_range_param = { + .data = (void *)&lf, .retval = 0}; + + dwarf_getpubnames(dbg, pubname_search_cb, &pubname_param, 0); + if (pubname_param.found) { + line_range_search_cb(&lf.sp_die, &line_range_param); + if (lf.found) + goto found; + } + } + /* Loop on CUs (Compilation Unit) */ while (!lf.found && ret >= 0) { if (dwarf_nextcu(dbg, off, &noff, &cuhl, NULL, NULL, NULL) != 0) @@ -1923,6 +1994,7 @@ int find_line_range(int fd, struct line_range *lr) off = noff; } +found: /* Store comp_dir */ if (lf.found) { comp_dir = cu_get_comp_dir(&lf.cu_die); diff --git a/tools/perf/util/probe-finder.h b/tools/perf/util/probe-finder.h index beaefc3c1223..605730a366db 100644 --- a/tools/perf/util/probe-finder.h +++ b/tools/perf/util/probe-finder.h @@ -49,6 +49,7 @@ struct probe_finder { Dwarf_Addr addr; /* Address */ const char *fname; /* Real file name */ Dwarf_Die cu_die; /* Current CU */ + Dwarf_Die sp_die; struct list_head lcache; /* Line cache for lazy match */ /* For variable searching */ @@ -83,6 +84,7 @@ struct line_finder { int lno_s; /* Start line number */ int lno_e; /* End line number */ Dwarf_Die cu_die; /* Current CU */ + Dwarf_Die sp_die; int found; }; diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 17df793c8924..8f73907a959e 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -1196,6 +1196,8 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name, if (curr_dso == NULL) goto out_elf_end; curr_dso->kernel = self->kernel; + curr_dso->long_name = self->long_name; + curr_dso->long_name_len = self->long_name_len; curr_map = map__new2(start, curr_dso, map->type); if (curr_map == NULL) { @@ -1842,6 +1844,7 @@ int dso__load_vmlinux(struct dso *self, struct map *map, if (fd < 0) return -1; + dso__set_long_name(self, (char *)vmlinux); dso__set_loaded(self, map->type); err = dso__load_sym(self, map, symfs_vmlinux, fd, filter, 0, 0); close(fd); |