aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf
diff options
context:
space:
mode:
authorHe Kuang <hekuang@huawei.com>2015-09-27 23:52:14 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2015-09-28 16:26:54 -0400
commitffeb883e5662e94b14948078e85812261277ad67 (patch)
tree3f99d5055deba60d63c90e68b99378339440d9b2 /tools/perf
parent0b8891a8e62cb537b65ebc55cfbbb4ec22333c44 (diff)
perf tools: Show proper error message for wrong terms of hw/sw events
Show proper error message and show valid terms when wrong config terms is specified for hw/sw type perf events. This patch makes the original error format function formats_error_string() more generic, which only outputs the static config terms for hw/sw perf events, and prepends pmu formats for pmu events. Before this patch: $ perf record -e 'cpu-clock/freqx=200/' -a sleep 1 invalid or unsupported event: 'cpu-clock/freqx=200/' Run 'perf list' for a list of valid events usage: perf record [<options>] [<command>] or: perf record [<options>] -- <command> [<options>] -e, --event <event> event selector. use 'perf list' to list available events After this patch: $ perf record -e 'cpu-clock/freqx=200/' -a sleep 1 event syntax error: 'cpu-clock/freqx=200/' \___ unknown term valid terms: config,config1,config2,name,period,freq,branch_type,time,call-graph,stack-size Run 'perf list' for a list of valid events usage: perf record [<options>] [<command>] or: perf record [<options>] -- <command> [<options>] -e, --event <event> event selector. use 'perf list' to list available events Signed-off-by: He Kuang <hekuang@huawei.com> Acked-by: Jiri Olsa <jolsa@kernel.org> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Kan Liang <kan.liang@intel.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Wang Nan <wangnan0@huawei.com> Cc: pi3orama@163.com Link: http://lkml.kernel.org/r/1443412336-120050-2-git-send-email-hekuang@huawei.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf')
-rw-r--r--tools/perf/util/parse-events.c29
-rw-r--r--tools/perf/util/parse-events.h1
-rw-r--r--tools/perf/util/parse-events.l2
-rw-r--r--tools/perf/util/pmu.c37
4 files changed, 45 insertions, 24 deletions
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 9dc3fb6ee81e..ea64ec0720ca 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -656,6 +656,9 @@ do { \
656 CHECK_TYPE_VAL(STR); 656 CHECK_TYPE_VAL(STR);
657 break; 657 break;
658 default: 658 default:
659 err->str = strdup("unknown term");
660 err->idx = term->err_term;
661 err->help = parse_events_formats_error_string(NULL);
659 return -EINVAL; 662 return -EINVAL;
660 } 663 }
661 664
@@ -1875,3 +1878,29 @@ void parse_events_evlist_error(struct parse_events_evlist *data,
1875 err->str = strdup(str); 1878 err->str = strdup(str);
1876 WARN_ONCE(!err->str, "WARNING: failed to allocate error string"); 1879 WARN_ONCE(!err->str, "WARNING: failed to allocate error string");
1877} 1880}
1881
1882/*
1883 * Return string contains valid config terms of an event.
1884 * @additional_terms: For terms such as PMU sysfs terms.
1885 */
1886char *parse_events_formats_error_string(char *additional_terms)
1887{
1888 char *str;
1889 static const char *static_terms = "config,config1,config2,name,"
1890 "period,freq,branch_type,time,"
1891 "call-graph,stack-size\n";
1892
1893 /* valid terms */
1894 if (additional_terms) {
1895 if (!asprintf(&str, "valid terms: %s,%s",
1896 additional_terms, static_terms))
1897 goto fail;
1898 } else {
1899 if (!asprintf(&str, "valid terms: %s", static_terms))
1900 goto fail;
1901 }
1902 return str;
1903
1904fail:
1905 return NULL;
1906}
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
index ffee7ece75a6..c7b904a49189 100644
--- a/tools/perf/util/parse-events.h
+++ b/tools/perf/util/parse-events.h
@@ -156,5 +156,6 @@ int print_hwcache_events(const char *event_glob, bool name_only);
156extern int is_valid_tracepoint(const char *event_string); 156extern int is_valid_tracepoint(const char *event_string);
157 157
158int valid_event_mount(const char *eventfs); 158int valid_event_mount(const char *eventfs);
159char *parse_events_formats_error_string(char *additional_terms);
159 160
160#endif /* __PERF_PARSE_EVENTS_H */ 161#endif /* __PERF_PARSE_EVENTS_H */
diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l
index 936d566f48d8..c29832bce496 100644
--- a/tools/perf/util/parse-events.l
+++ b/tools/perf/util/parse-events.l
@@ -174,7 +174,7 @@ modifier_bp [rwx]{1,3}
174 174
175<config>{ 175<config>{
176 /* 176 /*
177 * Please update formats_error_string any time 177 * Please update parse_events_formats_error_string any time
178 * new static term is added. 178 * new static term is added.
179 */ 179 */
180config { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_CONFIG); } 180config { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_CONFIG); }
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index 89c91a1a67e7..ac42c97be9e4 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -626,38 +626,26 @@ static int pmu_resolve_param_term(struct parse_events_term *term,
626 return -1; 626 return -1;
627} 627}
628 628
629static char *formats_error_string(struct list_head *formats) 629static char *pmu_formats_string(struct list_head *formats)
630{ 630{
631 struct perf_pmu_format *format; 631 struct perf_pmu_format *format;
632 char *err, *str; 632 char *str;
633 static const char *static_terms = "config,config1,config2,name," 633 struct strbuf buf;
634 "period,freq,branch_type,time,"
635 "call-graph,stack-size\n";
636 unsigned i = 0; 634 unsigned i = 0;
637 635
638 if (!asprintf(&str, "valid terms:")) 636 if (!formats)
639 return NULL; 637 return NULL;
640 638
639 strbuf_init(&buf, 0);
641 /* sysfs exported terms */ 640 /* sysfs exported terms */
642 list_for_each_entry(format, formats, list) { 641 list_for_each_entry(format, formats, list)
643 char c = i++ ? ',' : ' '; 642 strbuf_addf(&buf, i++ ? ",%s" : "%s",
644 643 format->name);
645 err = str;
646 if (!asprintf(&str, "%s%c%s", err, c, format->name))
647 goto fail;
648 free(err);
649 }
650 644
651 /* static terms */ 645 str = strbuf_detach(&buf, NULL);
652 err = str; 646 strbuf_release(&buf);
653 if (!asprintf(&str, "%s,%s", err, static_terms))
654 goto fail;
655 647
656 free(err);
657 return str; 648 return str;
658fail:
659 free(err);
660 return NULL;
661} 649}
662 650
663/* 651/*
@@ -693,9 +681,12 @@ static int pmu_config_term(struct list_head *formats,
693 if (verbose) 681 if (verbose)
694 printf("Invalid event/parameter '%s'\n", term->config); 682 printf("Invalid event/parameter '%s'\n", term->config);
695 if (err) { 683 if (err) {
684 char *pmu_term = pmu_formats_string(formats);
685
696 err->idx = term->err_term; 686 err->idx = term->err_term;
697 err->str = strdup("unknown term"); 687 err->str = strdup("unknown term");
698 err->help = formats_error_string(formats); 688 err->help = parse_events_formats_error_string(pmu_term);
689 free(pmu_term);
699 } 690 }
700 return -EINVAL; 691 return -EINVAL;
701 } 692 }