Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1759853AbbFBRPN (ORCPT ); Tue, 2 Jun 2015 13:15:13 -0400 Received: from e31.co.us.ibm.com ([32.97.110.149]:36281 "EHLO e31.co.us.ibm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1759374AbbFBRNG (ORCPT ); Tue, 2 Jun 2015 13:13:06 -0400 From: Sukadev Bhattiprolu To: mingo@redhat.com, ak@linux.intel.com, Michael Ellerman , Jiri Olsa , Arnaldo Carvalho de Melo Cc: namhyung@kernel.org, linuxppc-dev@lists.ozlabs.org, Subject: [PATCH v13 11/14] perf, tools: Support long descriptions with perf list -v Date: Tue, 2 Jun 2015 10:12:11 -0700 Message-Id: <1433265135-20426-12-git-send-email-sukadev@linux.vnet.ibm.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1433265135-20426-1-git-send-email-sukadev@linux.vnet.ibm.com> References: <1433265135-20426-1-git-send-email-sukadev@linux.vnet.ibm.com> X-TM-AS-MML: disable X-Content-Scanned: Fidelis XPS MAILER x-cbid: 15060217-8236-0000-0000-00000C012D35 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 11608 Lines: 326 From: Andi Kleen Previously we were dropping the useful longer descriptions that some events have in the event list completely. This patch makes them appear with perf list. Old perf list: baclears: baclears.all [Counts the number of baclears] vs new: perf list -v: ... baclears: baclears.all [The BACLEARS event counts the number of times the front end is resteered, mainly when the Branch Prediction Unit cannot provide a correct prediction and this is corrected by the Branch Address Calculator at the front end. The BACLEARS.ANY event counts the number of baclears for any type of branch] Signed-off-by: Andi Kleen Signed-off-by: Sukadev Bhattiprolu --- tools/perf/builtin-list.c | 9 ++++++--- tools/perf/pmu-events/jevents.c | 29 ++++++++++++++++++++--------- tools/perf/pmu-events/jevents.h | 2 +- tools/perf/pmu-events/pmu-events.h | 1 + tools/perf/util/parse-events.c | 4 ++-- tools/perf/util/parse-events.h | 2 +- tools/perf/util/pmu.c | 17 ++++++++++++----- tools/perf/util/pmu.h | 4 +++- 8 files changed, 46 insertions(+), 22 deletions(-) diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c index 3f058f7..c912368 100644 --- a/tools/perf/builtin-list.c +++ b/tools/perf/builtin-list.c @@ -22,10 +22,13 @@ int cmd_list(int argc, const char **argv, const char *prefix __maybe_unused) { int i; bool raw_dump = false; + bool long_desc_flag = false; struct option list_options[] = { OPT_BOOLEAN(0, "raw-dump", &raw_dump, "Dump raw events"), OPT_BOOLEAN('d', "desc", &desc_flag, "Print extra event descriptions. --no-desc to not print."), + OPT_BOOLEAN('v', "long-desc", &long_desc_flag, + "Print longer event descriptions."), OPT_END() }; const char * const list_usage[] = { @@ -44,7 +47,7 @@ int cmd_list(int argc, const char **argv, const char *prefix __maybe_unused) printf("\nList of pre-defined events (to be used in -e):\n\n"); if (argc == 0) { - print_events(NULL, raw_dump, !desc_flag); + print_events(NULL, raw_dump, !desc_flag, long_desc_flag); return 0; } @@ -63,13 +66,13 @@ int cmd_list(int argc, const char **argv, const char *prefix __maybe_unused) strcmp(argv[i], "hwcache") == 0) print_hwcache_events(NULL, raw_dump); else if (strcmp(argv[i], "pmu") == 0) - print_pmu_events(NULL, raw_dump, !desc_flag); + print_pmu_events(NULL, raw_dump, !desc_flag, long_desc_flag); else { char *sep = strchr(argv[i], ':'), *s; int sep_idx; if (sep == NULL) { - print_events(argv[i], raw_dump, !desc_flag); + print_events(argv[i], raw_dump, !desc_flag, long_desc_flag); continue; } sep_idx = sep - argv[i]; diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c index ab83d85..8990d71 100644 --- a/tools/perf/pmu-events/jevents.c +++ b/tools/perf/pmu-events/jevents.c @@ -203,7 +203,7 @@ static void print_events_table_prefix(FILE *fp, const char *tblname) } static int print_events_table_entry(void *data, char *name, char *event, - char *desc) + char *desc, char *long_desc) { FILE *outfp = data; /* @@ -215,7 +215,8 @@ static int print_events_table_entry(void *data, char *name, char *event, fprintf(outfp, "\t.name = \"%s\",\n", name); fprintf(outfp, "\t.event = \"%s\",\n", event); fprintf(outfp, "\t.desc = \"%s\",\n", desc); - + if (long_desc && long_desc[0]) + fprintf(outfp, "\t.long_desc = \"%s\"", long_desc); fprintf(outfp, "},\n"); return 0; @@ -235,7 +236,7 @@ static void print_events_table_suffix(FILE *outfp) /* Call func with each event in the json file */ int json_events(const char *fn, - int (*func)(void *data, char *name, char *event, char *desc), + int (*func)(void *data, char *name, char *event, char *desc, char *long_desc), void *data) { int err = -EIO; @@ -253,7 +254,8 @@ int json_events(const char *fn, EXPECT(tokens->type == JSMN_ARRAY, tokens, "expected top level array"); tok = tokens + 1; for (i = 0; i < tokens->size; i++) { - char *event = NULL, *desc = NULL, *name = NULL; + char *event = NULL, *desc = NULL, *name = NULL, *long_desc = NULL; + char *extra_desc = NULL; struct msrmap *msr = NULL; jsmntok_t *msrval = NULL; jsmntok_t *precise = NULL; @@ -279,6 +281,9 @@ int json_events(const char *fn, } else if (json_streq(map, field, "BriefDescription")) { addfield(map, &desc, "", "", val); fixdesc(desc); + } else if (json_streq(map, field, "PublicDescription")) { + addfield(map, &long_desc, "", "", val); + fixdesc(long_desc); } else if (json_streq(map, field, "PEBS") && nz) { precise = val; } else if (json_streq(map, field, "MSRIndex") && nz) { @@ -287,10 +292,10 @@ int json_events(const char *fn, msrval = val; } else if (json_streq(map, field, "Errata") && !json_streq(map, val, "null")) { - addfield(map, &desc, ". ", + addfield(map, &extra_desc, ". ", " Spec update: ", val); } else if (json_streq(map, field, "Data_LA") && nz) { - addfield(map, &desc, ". ", + addfield(map, &extra_desc, ". ", " Supports address when precise", NULL); } @@ -298,19 +303,25 @@ int json_events(const char *fn, } if (precise && !strstr(desc, "(Precise Event)")) { if (json_streq(map, precise, "2")) - addfield(map, &desc, " ", "(Must be precise)", + addfield(map, &extra_desc, " ", "(Must be precise)", NULL); else - addfield(map, &desc, " ", + addfield(map, &extra_desc, " ", "(Precise event)", NULL); } + if (desc && extra_desc) + addfield(map, &desc, " ", extra_desc, NULL); + if (long_desc && extra_desc) + addfield(map, &long_desc, " ", extra_desc, NULL); if (msr != NULL) addfield(map, &event, ",", msr->pname, msrval); fixname(name); - err = func(data, name, event, desc); + err = func(data, name, event, desc, long_desc); free(event); free(desc); free(name); + free(extra_desc); + free(long_desc); if (err) break; tok += j; diff --git a/tools/perf/pmu-events/jevents.h b/tools/perf/pmu-events/jevents.h index 996601f..2168ad4 100644 --- a/tools/perf/pmu-events/jevents.h +++ b/tools/perf/pmu-events/jevents.h @@ -2,7 +2,7 @@ #define JEVENTS_H 1 int json_events(const char *fn, - int (*func)(void *data, char *name, char *event, char *desc), + int (*func)(void *data, char *name, char *event, char *desc, char *long_desc), void *data); char *get_cpu_str(void); diff --git a/tools/perf/pmu-events/pmu-events.h b/tools/perf/pmu-events/pmu-events.h index 39fec04..711f049 100644 --- a/tools/perf/pmu-events/pmu-events.h +++ b/tools/perf/pmu-events/pmu-events.h @@ -8,6 +8,7 @@ struct pmu_event { const char *name; const char *event; const char *desc; + const char *long_desc; }; /* diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 65f7572..819e7a5 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -1521,7 +1521,7 @@ out_enomem: /* * Print the help text for the event symbols: */ -void print_events(const char *event_glob, bool name_only, bool quiet_flag) +void print_events(const char *event_glob, bool name_only, bool quiet_flag, bool long_desc) { print_symbol_events(event_glob, PERF_TYPE_HARDWARE, event_symbols_hw, PERF_COUNT_HW_MAX, name_only); @@ -1531,7 +1531,7 @@ void print_events(const char *event_glob, bool name_only, bool quiet_flag) print_hwcache_events(event_glob, name_only); - print_pmu_events(event_glob, name_only, quiet_flag); + print_pmu_events(event_glob, name_only, quiet_flag, long_desc); if (event_glob != NULL) return; diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h index d11f854..d0b640d 100644 --- a/tools/perf/util/parse-events.h +++ b/tools/perf/util/parse-events.h @@ -133,7 +133,7 @@ void parse_events_update_lists(struct list_head *list_event, void parse_events_evlist_error(struct parse_events_evlist *data, int idx, const char *str); -void print_events(const char *event_glob, bool name_only, bool quiet); +void print_events(const char *event_glob, bool name_only, bool quiet, bool long_desc); struct event_symbol { const char *symbol; diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 2cf03a7..96bf8c7 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -208,7 +208,8 @@ static int perf_pmu__parse_snapshot(struct perf_pmu_alias *alias, return 0; } -static int __perf_pmu__new_alias(struct list_head *list, char *name, char *dir, char *desc __maybe_unused, char *val) +static int __perf_pmu__new_alias(struct list_head *list, char *name, char *dir, char *desc __maybe_unused, char *val, + char *long_desc) { struct perf_pmu_alias *alias; int ret; @@ -241,6 +242,9 @@ static int __perf_pmu__new_alias(struct list_head *list, char *name, char *dir, } alias->desc = desc ? strdup(desc) : NULL; + alias->long_desc = long_desc ? + strdup(long_desc) : + desc ? strdup(desc) : NULL; list_add_tail(&alias->list, list); @@ -257,7 +261,7 @@ static int perf_pmu__new_alias(struct list_head *list, char *dir, char *name, FI return -EINVAL; buf[ret] = 0; - return __perf_pmu__new_alias(list, name, dir, NULL, buf); + return __perf_pmu__new_alias(list, name, dir, NULL, buf, NULL); } static inline bool pmu_alias_info_file(char *name) @@ -513,7 +517,8 @@ static int pmu_add_cpu_aliases(void *data) /* need type casts to override 'const' */ __perf_pmu__new_alias(head, (char *)pe->name, NULL, - (char *)pe->desc, (char *)pe->event); + (char *)pe->desc, (char *)pe->event, + (char *)pe->long_desc); } out: @@ -1035,7 +1040,8 @@ static void wordwrap(char *s, int start, int max, int corr) } } -void print_pmu_events(const char *event_glob, bool name_only, bool quiet_flag) +void print_pmu_events(const char *event_glob, bool name_only, bool quiet_flag, + bool long_desc) { struct perf_pmu *pmu; struct perf_pmu_alias *alias; @@ -1082,7 +1088,8 @@ void print_pmu_events(const char *event_glob, bool name_only, bool quiet_flag) pmu, alias); aliases[j].name = strdup(aliases[j].name); /* failure harmless */ - aliases[j].desc = alias->desc; + aliases[j].desc = long_desc ? alias->long_desc : + alias->desc; j++; } if (pmu->selectable) { diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h index 9966c1a..1c95477 100644 --- a/tools/perf/util/pmu.h +++ b/tools/perf/util/pmu.h @@ -39,6 +39,7 @@ struct perf_pmu_info { struct perf_pmu_alias { char *name; char *desc; + char *long_desc; struct list_head terms; /* HEAD struct parse_events_term -> list */ struct list_head list; /* ELEM */ char unit[UNIT_MAX_LEN+1]; @@ -69,7 +70,8 @@ int perf_pmu__format_parse(char *dir, struct list_head *head); struct perf_pmu *perf_pmu__scan(struct perf_pmu *pmu); -void print_pmu_events(const char *event_glob, bool name_only, bool quiet); +void print_pmu_events(const char *event_glob, bool name_only, bool quiet, + bool long_desc); bool pmu_have_event(const char *pname, const char *name); int perf_pmu__scan_file(struct perf_pmu *pmu, const char *name, const char *fmt, -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/