summaryrefslogtreecommitdiffstats
path: root/tools/perf/util
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2014-12-12 09:09:52 +0100
committerIngo Molnar <mingo@kernel.org>2014-12-12 09:09:52 +0100
commit41e950c033b7df997d4b38653efe6554be9b96a7 (patch)
treeb8ffe779d47c768a9652ce9166f4878cee41f2ca /tools/perf/util
parent3459f0d78ffe27a1b341c22eb158b622eaaea3fc (diff)
parente09b18d4907992d3d615b215c1abf585721b2810 (diff)
downloadop-kernel-dev-41e950c033b7df997d4b38653efe6554be9b96a7.zip
op-kernel-dev-41e950c033b7df997d4b38653efe6554be9b96a7.tar.gz
Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/urgent
Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo: User visible changes: - Mark events as (x86 only) in help output for 'perf kvm stat live" (Alexander Yarygin) - Provide a better explanation when mmap fails in 'trace' (Arnaldo Carvalho de Melo) - Add --buildid-dir option to set cache directory, i.e. use: $ perf --buildid-dir /path/to/dir tool --tool-options (Jiri Olsa) - Fix memcpy/memset 'perf bench' output (Rabin Vicent) - Fix 'perf test' attr tests size values to cope with machine state on interrupt ABI changes (Jiri Olsa) - Fixup callchain type parameter handling error message (Kan Liang) Infrastructure changes and cleanups: - calloc/xcalloc: Fix argument order (Arjun Sreedharan) - Move filename__read_int from tools/perf/ to tools/lib, add sysctl__read_int there and use it in place of ad-hoc copies (Arnaldo Carvalho de Melo) - Use single strcmp call instead of two (Jiri Olsa) - Remove extra debugdir variables in 'perf buildid-cache' (Jiri Olsa) - Fix -a segfault related to kcore handling in 'perf buildid-cache' (Jiri Olsa) - Move cpumode resolve code to add_callchain_ip (Kan Liang) - Merge memset into memcpy 'perf bench' (Rabin Vincent) - Change print format from %lu to %PRIu64 in the hists browser (Tom Huynh) Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'tools/perf/util')
-rw-r--r--tools/perf/util/build-id.c9
-rw-r--r--tools/perf/util/callchain.c2
-rw-r--r--tools/perf/util/config.c10
-rw-r--r--tools/perf/util/evlist.c23
-rw-r--r--tools/perf/util/evlist.h1
-rw-r--r--tools/perf/util/machine.c72
-rw-r--r--tools/perf/util/record.c11
-rw-r--r--tools/perf/util/util.c26
-rw-r--r--tools/perf/util/util.h3
9 files changed, 72 insertions, 85 deletions
diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c
index e8d79e5..0c72680 100644
--- a/tools/perf/util/build-id.c
+++ b/tools/perf/util/build-id.c
@@ -410,21 +410,18 @@ int perf_session__cache_build_ids(struct perf_session *session)
{
struct rb_node *nd;
int ret;
- char debugdir[PATH_MAX];
if (no_buildid_cache)
return 0;
- snprintf(debugdir, sizeof(debugdir), "%s", buildid_dir);
-
- if (mkdir(debugdir, 0755) != 0 && errno != EEXIST)
+ if (mkdir(buildid_dir, 0755) != 0 && errno != EEXIST)
return -1;
- ret = machine__cache_build_ids(&session->machines.host, debugdir);
+ ret = machine__cache_build_ids(&session->machines.host, buildid_dir);
for (nd = rb_first(&session->machines.guests); nd; nd = rb_next(nd)) {
struct machine *pos = rb_entry(nd, struct machine, rb_node);
- ret |= machine__cache_build_ids(pos, debugdir);
+ ret |= machine__cache_build_ids(pos, buildid_dir);
}
return ret ? -1 : 0;
}
diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c
index cf524a3..64b377e 100644
--- a/tools/perf/util/callchain.c
+++ b/tools/perf/util/callchain.c
@@ -77,7 +77,7 @@ int parse_callchain_record_opt(const char *arg)
ret = 0;
} else
pr_err("callchain: No more arguments "
- "needed for -g fp\n");
+ "needed for --call-graph fp\n");
break;
#ifdef HAVE_DWARF_UNWIND_SUPPORT
diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c
index 57ff826..e18f653 100644
--- a/tools/perf/util/config.c
+++ b/tools/perf/util/config.c
@@ -522,7 +522,7 @@ static int buildid_dir_command_config(const char *var, const char *value,
const char *v;
/* same dir for all commands */
- if (!prefixcmp(var, "buildid.") && !strcmp(var + 8, "dir")) {
+ if (!strcmp(var, "buildid.dir")) {
v = perf_config_dirname(var, value);
if (!v)
return -1;
@@ -539,12 +539,14 @@ static void check_buildid_dir_config(void)
perf_config(buildid_dir_command_config, &c);
}
-void set_buildid_dir(void)
+void set_buildid_dir(const char *dir)
{
- buildid_dir[0] = '\0';
+ if (dir)
+ scnprintf(buildid_dir, MAXPATHLEN-1, "%s", dir);
/* try config file */
- check_buildid_dir_config();
+ if (buildid_dir[0] == '\0')
+ check_buildid_dir_config();
/* default to $HOME/.debug */
if (buildid_dir[0] == '\0') {
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index cfbe2b9..bb5dfc5 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -8,6 +8,7 @@
*/
#include "util.h"
#include <api/fs/debugfs.h>
+#include <api/fs/fs.h>
#include <poll.h>
#include "cpumap.h"
#include "thread_map.h"
@@ -1483,6 +1484,28 @@ int perf_evlist__strerror_open(struct perf_evlist *evlist __maybe_unused,
return 0;
}
+int perf_evlist__strerror_mmap(struct perf_evlist *evlist, int err, char *buf, size_t size)
+{
+ char sbuf[STRERR_BUFSIZE], *emsg = strerror_r(err, sbuf, sizeof(sbuf));
+ int value;
+
+ switch (err) {
+ case EPERM:
+ sysctl__read_int("kernel/perf_event_mlock_kb", &value);
+ scnprintf(buf, size, "Error:\t%s.\n"
+ "Hint:\tCheck /proc/sys/kernel/perf_event_mlock_kb (%d kB) setting.\n"
+ "Hint:\tTried using %zd kB.\n"
+ "Hint:\tTry using a bigger -m/--mmap-pages value.",
+ emsg, value, evlist->mmap_len / 1024);
+ break;
+ default:
+ scnprintf(buf, size, "%s", emsg);
+ break;
+ }
+
+ return 0;
+}
+
void perf_evlist__to_front(struct perf_evlist *evlist,
struct perf_evsel *move_evsel)
{
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index 649b0c5..0ba93f6 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -185,6 +185,7 @@ size_t perf_evlist__fprintf(struct perf_evlist *evlist, FILE *fp);
int perf_evlist__strerror_tp(struct perf_evlist *evlist, int err, char *buf, size_t size);
int perf_evlist__strerror_open(struct perf_evlist *evlist, int err, char *buf, size_t size);
+int perf_evlist__strerror_mmap(struct perf_evlist *evlist, int err, char *buf, size_t size);
static inline unsigned int perf_mmap__read_head(struct perf_mmap *mm)
{
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 15dd0a9..94de3e4 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -1385,19 +1385,46 @@ struct mem_info *sample__resolve_mem(struct perf_sample *sample,
static int add_callchain_ip(struct thread *thread,
struct symbol **parent,
struct addr_location *root_al,
- int cpumode,
+ bool branch_history,
u64 ip)
{
struct addr_location al;
al.filtered = 0;
al.sym = NULL;
- if (cpumode == -1)
+ if (branch_history)
thread__find_cpumode_addr_location(thread, MAP__FUNCTION,
ip, &al);
- else
+ else {
+ u8 cpumode = PERF_RECORD_MISC_USER;
+
+ if (ip >= PERF_CONTEXT_MAX) {
+ switch (ip) {
+ case PERF_CONTEXT_HV:
+ cpumode = PERF_RECORD_MISC_HYPERVISOR;
+ break;
+ case PERF_CONTEXT_KERNEL:
+ cpumode = PERF_RECORD_MISC_KERNEL;
+ break;
+ case PERF_CONTEXT_USER:
+ cpumode = PERF_RECORD_MISC_USER;
+ break;
+ default:
+ pr_debug("invalid callchain context: "
+ "%"PRId64"\n", (s64) ip);
+ /*
+ * It seems the callchain is corrupted.
+ * Discard all.
+ */
+ callchain_cursor_reset(&callchain_cursor);
+ return 1;
+ }
+ return 0;
+ }
thread__find_addr_location(thread, cpumode, MAP__FUNCTION,
ip, &al);
+ }
+
if (al.sym != NULL) {
if (sort__has_parent && !*parent &&
symbol__match_regex(al.sym, &parent_regex))
@@ -1480,11 +1507,8 @@ static int thread__resolve_callchain_sample(struct thread *thread,
struct addr_location *root_al,
int max_stack)
{
- u8 cpumode = PERF_RECORD_MISC_USER;
int chain_nr = min(max_stack, (int)chain->nr);
- int i;
- int j;
- int err;
+ int i, j, err;
int skip_idx = -1;
int first_call = 0;
@@ -1542,10 +1566,10 @@ static int thread__resolve_callchain_sample(struct thread *thread,
for (i = 0; i < nr; i++) {
err = add_callchain_ip(thread, parent, root_al,
- -1, be[i].to);
+ true, be[i].to);
if (!err)
err = add_callchain_ip(thread, parent, root_al,
- -1, be[i].from);
+ true, be[i].from);
if (err == -EINVAL)
break;
if (err)
@@ -1574,36 +1598,10 @@ check_calls:
#endif
ip = chain->ips[j];
- if (ip >= PERF_CONTEXT_MAX) {
- switch (ip) {
- case PERF_CONTEXT_HV:
- cpumode = PERF_RECORD_MISC_HYPERVISOR;
- break;
- case PERF_CONTEXT_KERNEL:
- cpumode = PERF_RECORD_MISC_KERNEL;
- break;
- case PERF_CONTEXT_USER:
- cpumode = PERF_RECORD_MISC_USER;
- break;
- default:
- pr_debug("invalid callchain context: "
- "%"PRId64"\n", (s64) ip);
- /*
- * It seems the callchain is corrupted.
- * Discard all.
- */
- callchain_cursor_reset(&callchain_cursor);
- return 0;
- }
- continue;
- }
+ err = add_callchain_ip(thread, parent, root_al, false, ip);
- err = add_callchain_ip(thread, parent, root_al,
- cpumode, ip);
- if (err == -EINVAL)
- break;
if (err)
- return err;
+ return (err < 0) ? err : 0;
}
return 0;
diff --git a/tools/perf/util/record.c b/tools/perf/util/record.c
index cf69325..8acd0df 100644
--- a/tools/perf/util/record.c
+++ b/tools/perf/util/record.c
@@ -137,16 +137,7 @@ void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts)
static int get_max_rate(unsigned int *rate)
{
- char path[PATH_MAX];
- const char *procfs = procfs__mountpoint();
-
- if (!procfs)
- return -1;
-
- snprintf(path, PATH_MAX,
- "%s/sys/kernel/perf_event_max_sample_rate", procfs);
-
- return filename__read_int(path, (int *) rate);
+ return sysctl__read_int("kernel/perf_event_max_sample_rate", (int *)rate);
}
static int record_opts__config_freq(struct record_opts *opts)
diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c
index d5eab3f3..b86744f 100644
--- a/tools/perf/util/util.c
+++ b/tools/perf/util/util.c
@@ -442,23 +442,6 @@ unsigned long parse_tag_value(const char *str, struct parse_tag *tags)
return (unsigned long) -1;
}
-int filename__read_int(const char *filename, int *value)
-{
- char line[64];
- int fd = open(filename, O_RDONLY), err = -1;
-
- if (fd < 0)
- return -1;
-
- if (read(fd, line, sizeof(line)) > 0) {
- *value = atoi(line);
- err = 0;
- }
-
- close(fd);
- return err;
-}
-
int filename__read_str(const char *filename, char **buf, size_t *sizep)
{
size_t size = 0, alloc_size = 0;
@@ -523,16 +506,9 @@ const char *get_filename_for_perf_kvm(void)
int perf_event_paranoid(void)
{
- char path[PATH_MAX];
- const char *procfs = procfs__mountpoint();
int value;
- if (!procfs)
- return INT_MAX;
-
- scnprintf(path, PATH_MAX, "%s/sys/kernel/perf_event_paranoid", procfs);
-
- if (filename__read_int(path, &value))
+ if (sysctl__read_int("kernel/perf_event_paranoid", &value))
return INT_MAX;
return value;
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index 419bee0..008b361 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -153,7 +153,7 @@ extern void warning(const char *err, ...) __attribute__((format (printf, 1, 2)))
extern void set_die_routine(void (*routine)(const char *err, va_list params) NORETURN);
extern int prefixcmp(const char *str, const char *prefix);
-extern void set_buildid_dir(void);
+extern void set_buildid_dir(const char *dir);
static inline const char *skip_prefix(const char *str, const char *prefix)
{
@@ -343,7 +343,6 @@ char *get_srcline(struct dso *dso, unsigned long addr, struct symbol *sym,
bool show_sym);
void free_srcline(char *srcline);
-int filename__read_int(const char *filename, int *value);
int filename__read_str(const char *filename, char **buf, size_t *sizep);
int perf_event_paranoid(void);
OpenPOWER on IntegriCloud