aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/parse-events.c
diff options
context:
space:
mode:
authorWang Nan <wangnan0@huawei.com>2016-02-19 06:43:58 -0500
committerArnaldo Carvalho de Melo <acme@redhat.com>2016-02-19 17:12:49 -0500
commit1669e509ea25e4e3e871d913d21b1cac4a96d1e8 (patch)
treefa035bfba42449b302ac41445b4785352903badb /tools/perf/util/parse-events.c
parent17cb5f84b89fd39a143f1c899836f40420a6b799 (diff)
perf stat: Bail out on unsupported event config modifiers
'perf stat' accepts some config terms but doesn't apply them. For example: # perf stat -e 'instructions/no-inherit/' -e 'instructions/inherit/' bash # ls # exit Performance counter stats for 'bash': 266258061 instructions/no-inherit/ 266258061 instructions/inherit/ 1.402183915 seconds time elapsed The result is confusing, because user may expect the first 'instructions' event exclude the 'ls' command. This patch forbid most of these config terms for 'perf stat'. Result: # ./perf stat -e 'instructions/no-inherit/' -e 'instructions/inherit/' bash event syntax error: 'instructions/no-inherit/' \___ 'no-inherit' is not usable in 'perf stat' ... We can add blocked config terms back when 'perf stat' really supports them. This patch also removes unavailable config term from error message: # ./perf stat -e 'instructions/badterm/' ls event syntax error: 'instructions/badterm/' \___ unknown term valid terms: config,config1,config2,name # ./perf stat -e 'cpu/badterm/' ls event syntax error: 'cpu/badterm/' \___ unknown term valid terms: pc,any,inv,edge,cmask,event,in_tx,ldlat,umask,in_tx_cp,offcore_rsp,config,config1,config2,name Signed-off-by: Wang Nan <wangnan0@huawei.com> Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Alexei Starovoitov <ast@kernel.org> Cc: Brendan Gregg <brendan.d.gregg@gmail.com> Cc: Cody P Schafer <dev@codyps.com> Cc: He Kuang <hekuang@huawei.com> Cc: Jeremie Galarneau <jeremie.galarneau@efficios.com> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Kirill Smelkov <kirr@nexedi.com> Cc: Li Zefan <lizefan@huawei.com> Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Zefan Li <lizefan@huawei.com> Cc: pi3orama@163.com Link: http://lkml.kernel.org/r/1455882283-79592-11-git-send-email-wangnan0@huawei.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util/parse-events.c')
-rw-r--r--tools/perf/util/parse-events.c48
1 files changed, 48 insertions, 0 deletions
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index fd085d5f5c79..eb5df43ec68f 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -765,6 +765,41 @@ static const char *config_term_names[__PARSE_EVENTS__TERM_TYPE_NR] = {
765 [PARSE_EVENTS__TERM_TYPE_INHERIT] = "inherit", 765 [PARSE_EVENTS__TERM_TYPE_INHERIT] = "inherit",
766}; 766};
767 767
768static bool config_term_shrinked;
769
770static bool
771config_term_avail(int term_type, struct parse_events_error *err)
772{
773 if (term_type < 0 || term_type >= __PARSE_EVENTS__TERM_TYPE_NR) {
774 err->str = strdup("Invalid term_type");
775 return false;
776 }
777 if (!config_term_shrinked)
778 return true;
779
780 switch (term_type) {
781 case PARSE_EVENTS__TERM_TYPE_CONFIG:
782 case PARSE_EVENTS__TERM_TYPE_CONFIG1:
783 case PARSE_EVENTS__TERM_TYPE_CONFIG2:
784 case PARSE_EVENTS__TERM_TYPE_NAME:
785 return true;
786 default:
787 if (!err)
788 return false;
789
790 /* term_type is validated so indexing is safe */
791 if (asprintf(&err->str, "'%s' is not usable in 'perf stat'",
792 config_term_names[term_type]) < 0)
793 err->str = NULL;
794 return false;
795 }
796}
797
798void parse_events__shrink_config_terms(void)
799{
800 config_term_shrinked = true;
801}
802
768typedef int config_term_func_t(struct perf_event_attr *attr, 803typedef int config_term_func_t(struct perf_event_attr *attr,
769 struct parse_events_term *term, 804 struct parse_events_term *term,
770 struct parse_events_error *err); 805 struct parse_events_error *err);
@@ -834,6 +869,17 @@ do { \
834 return -EINVAL; 869 return -EINVAL;
835 } 870 }
836 871
872 /*
873 * Check term availbility after basic checking so
874 * PARSE_EVENTS__TERM_TYPE_USER can be found and filtered.
875 *
876 * If check availbility at the entry of this function,
877 * user will see "'<sysfs term>' is not usable in 'perf stat'"
878 * if an invalid config term is provided for legacy events
879 * (for example, instructions/badterm/...), which is confusing.
880 */
881 if (!config_term_avail(term->type_term, err))
882 return -EINVAL;
837 return 0; 883 return 0;
838#undef CHECK_TYPE_VAL 884#undef CHECK_TYPE_VAL
839} 885}
@@ -2125,6 +2171,8 @@ static void config_terms_list(char *buf, size_t buf_sz)
2125 for (i = 0; i < __PARSE_EVENTS__TERM_TYPE_NR; i++) { 2171 for (i = 0; i < __PARSE_EVENTS__TERM_TYPE_NR; i++) {
2126 const char *name = config_term_names[i]; 2172 const char *name = config_term_names[i];
2127 2173
2174 if (!config_term_avail(i, NULL))
2175 continue;
2128 if (!name) 2176 if (!name)
2129 continue; 2177 continue;
2130 if (name[0] == '<') 2178 if (name[0] == '<')