diff options
author | Andi Kleen <ak@linux.intel.com> | 2017-09-13 17:50:06 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2017-09-18 08:40:20 -0400 |
commit | 333b566559019b146905c623bde7f455c1d5add3 (patch) | |
tree | 5a55781d107265752784ba23a2257e18bd922bd1 | |
parent | 75e45e432052c7b1a5da866cff88192db8be1445 (diff) |
perf pmu: Improve error messages for missing PMUs
When a PMU is missing print a better error message mentioning
the missing PMU.
% mkdir empty
% mount --bind empty /sys/devices/msr
% perf stat -M Summary true
event syntax error: '{inst_retired.any,cycles}:W,{cpu_clk_unhalted.thread}:W,{inst_retired.any}:W,{cpu_clk_unhalted.ref_tsc,msr/tsc/}:W,{fp_comp_ops_exe.sse_scalar..'
\___ Cannot find PMU `msr'. Missing kernel support?
It still cannot find the right column for aliases, but it's already a vast improvement.
v2: Check asprintf
Signed-off-by: Andi Kleen <ak@linux.intel.com>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Link: http://lkml.kernel.org/r/20170913215006.32222-1-andi@firstfloor.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r-- | tools/perf/util/metricgroup.c | 2 | ||||
-rw-r--r-- | tools/perf/util/parse-events.c | 18 | ||||
-rw-r--r-- | tools/perf/util/parse-events.h | 3 |
3 files changed, 16 insertions, 7 deletions
diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index 2d60114f1870..fa37ef79517a 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c | |||
@@ -477,7 +477,7 @@ int metricgroup__parse_groups(const struct option *opt, | |||
477 | memset(&parse_error, 0, sizeof(struct parse_events_error)); | 477 | memset(&parse_error, 0, sizeof(struct parse_events_error)); |
478 | ret = parse_events(perf_evlist, extra_events.buf, &parse_error); | 478 | ret = parse_events(perf_evlist, extra_events.buf, &parse_error); |
479 | if (ret) { | 479 | if (ret) { |
480 | pr_err("Cannot set up events %s\n", extra_events.buf); | 480 | parse_events_print_error(&parse_error, extra_events.buf); |
481 | goto out; | 481 | goto out; |
482 | } | 482 | } |
483 | strbuf_release(&extra_events); | 483 | strbuf_release(&extra_events); |
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 75588920fccc..9183913a6174 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c | |||
@@ -1219,11 +1219,17 @@ static int __parse_events_add_pmu(struct parse_events_state *parse_state, | |||
1219 | struct perf_pmu_info info; | 1219 | struct perf_pmu_info info; |
1220 | struct perf_pmu *pmu; | 1220 | struct perf_pmu *pmu; |
1221 | struct perf_evsel *evsel; | 1221 | struct perf_evsel *evsel; |
1222 | struct parse_events_error *err = parse_state->error; | ||
1222 | LIST_HEAD(config_terms); | 1223 | LIST_HEAD(config_terms); |
1223 | 1224 | ||
1224 | pmu = perf_pmu__find(name); | 1225 | pmu = perf_pmu__find(name); |
1225 | if (!pmu) | 1226 | if (!pmu) { |
1227 | if (asprintf(&err->str, | ||
1228 | "Cannot find PMU `%s'. Missing kernel support?", | ||
1229 | name) < 0) | ||
1230 | err->str = NULL; | ||
1226 | return -EINVAL; | 1231 | return -EINVAL; |
1232 | } | ||
1227 | 1233 | ||
1228 | if (pmu->default_config) { | 1234 | if (pmu->default_config) { |
1229 | memcpy(&attr, pmu->default_config, | 1235 | memcpy(&attr, pmu->default_config, |
@@ -1733,8 +1739,8 @@ static int get_term_width(void) | |||
1733 | return ws.ws_col > MAX_WIDTH ? MAX_WIDTH : ws.ws_col; | 1739 | return ws.ws_col > MAX_WIDTH ? MAX_WIDTH : ws.ws_col; |
1734 | } | 1740 | } |
1735 | 1741 | ||
1736 | static void parse_events_print_error(struct parse_events_error *err, | 1742 | void parse_events_print_error(struct parse_events_error *err, |
1737 | const char *event) | 1743 | const char *event) |
1738 | { | 1744 | { |
1739 | const char *str = "invalid or unsupported event: "; | 1745 | const char *str = "invalid or unsupported event: "; |
1740 | char _buf[MAX_WIDTH]; | 1746 | char _buf[MAX_WIDTH]; |
@@ -1789,8 +1795,6 @@ static void parse_events_print_error(struct parse_events_error *err, | |||
1789 | zfree(&err->str); | 1795 | zfree(&err->str); |
1790 | zfree(&err->help); | 1796 | zfree(&err->help); |
1791 | } | 1797 | } |
1792 | |||
1793 | fprintf(stderr, "Run 'perf list' for a list of valid events\n"); | ||
1794 | } | 1798 | } |
1795 | 1799 | ||
1796 | #undef MAX_WIDTH | 1800 | #undef MAX_WIDTH |
@@ -1802,8 +1806,10 @@ int parse_events_option(const struct option *opt, const char *str, | |||
1802 | struct parse_events_error err = { .idx = 0, }; | 1806 | struct parse_events_error err = { .idx = 0, }; |
1803 | int ret = parse_events(evlist, str, &err); | 1807 | int ret = parse_events(evlist, str, &err); |
1804 | 1808 | ||
1805 | if (ret) | 1809 | if (ret) { |
1806 | parse_events_print_error(&err, str); | 1810 | parse_events_print_error(&err, str); |
1811 | fprintf(stderr, "Run 'perf list' for a list of valid events\n"); | ||
1812 | } | ||
1807 | 1813 | ||
1808 | return ret; | 1814 | return ret; |
1809 | } | 1815 | } |
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h index 635135125111..3909ca0639f2 100644 --- a/tools/perf/util/parse-events.h +++ b/tools/perf/util/parse-events.h | |||
@@ -202,6 +202,9 @@ int is_valid_tracepoint(const char *event_string); | |||
202 | int valid_event_mount(const char *eventfs); | 202 | int valid_event_mount(const char *eventfs); |
203 | char *parse_events_formats_error_string(char *additional_terms); | 203 | char *parse_events_formats_error_string(char *additional_terms); |
204 | 204 | ||
205 | void parse_events_print_error(struct parse_events_error *err, | ||
206 | const char *event); | ||
207 | |||
205 | #ifdef HAVE_LIBELF_SUPPORT | 208 | #ifdef HAVE_LIBELF_SUPPORT |
206 | /* | 209 | /* |
207 | * If the probe point starts with '%', | 210 | * If the probe point starts with '%', |