linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Arnaldo Carvalho de Melo <acme@kernel.org>
To: Ingo Molnar <mingo@kernel.org>
Cc: linux-kernel@vger.kernel.org, Linux Weekly News <lwn@lwn.net>,
	Andi Kleen <ak@linux.intel.com>,
	Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>,
	Madhavan Srinivasan <maddy@linux.vnet.ibm.com>,
	Peter Zijlstra <peterz@infradead.org>,
	linuxppc-dev@lists.ozlabs.org,
	Arnaldo Carvalho de Melo <acme@redhat.com>
Subject: [PATCH 11/22] perf pmu: Support alias descriptions
Date: Mon,  3 Oct 2016 23:37:10 -0300	[thread overview]
Message-ID: <1475548641-12182-12-git-send-email-acme@kernel.org> (raw)
In-Reply-To: <1475548641-12182-1-git-send-email-acme@kernel.org>

From: Andi Kleen <ak@linux.intel.com>

Add support to print alias descriptions in perf list, which are taken
from the generated event files.

The sorting code is changed to put the events with descriptions at the
end. The descriptions are printed as possibly multiple word wrapped
lines.

Example output:

% perf list
...
  arith.fpu_div
       [Divide operations executed]
  arith.fpu_div_active
       [Cycles when divider is busy executing divide operations]

Committer notes:

Further testing on a Broadwell machine (ThinkPad t450s), using these
files:

  $ find tools/perf/pmu-events/arch/x86/
  tools/perf/pmu-events/arch/x86/
  tools/perf/pmu-events/arch/x86/Broadwell
  tools/perf/pmu-events/arch/x86/Broadwell/Cache.json
  tools/perf/pmu-events/arch/x86/Broadwell/Other.json
  tools/perf/pmu-events/arch/x86/Broadwell/Frontend.json
  tools/perf/pmu-events/arch/x86/Broadwell/Virtual-Memory.json
  tools/perf/pmu-events/arch/x86/Broadwell/Pipeline.json
  tools/perf/pmu-events/arch/x86/Broadwell/Floating-point.json
  tools/perf/pmu-events/arch/x86/Broadwell/Memory.json
  tools/perf/pmu-events/arch/x86/mapfile.csv
  $

Taken from:

https://github.com/sukadev/linux/tree/json-code+data-v21/tools/perf/pmu-events/arch/x86/

to get this machinery to actually parse JSON files, generate
$(OUTPUT)pmu-events/pmu-events.c, compile it and link it with perf, that
will then use the table it contains, these files will be submitted right
after this patchkit.

  [acme@jouet linux]$ perf list page_walker

  List of pre-defined events (to be used in -e):

    page_walker_loads.dtlb_l1
         [Number of DTLB page walker hits in the L1+FB]
    page_walker_loads.dtlb_l2
         [Number of DTLB page walker hits in the L2]
    page_walker_loads.dtlb_l3
         [Number of DTLB page walker hits in the L3 + XSNP]
    page_walker_loads.dtlb_memory
         [Number of DTLB page walker hits in Memory]
    page_walker_loads.itlb_l1
         [Number of ITLB page walker hits in the L1+FB]
    page_walker_loads.itlb_l2
         [Number of ITLB page walker hits in the L2]
    page_walker_loads.itlb_l3
         [Number of ITLB page walker hits in the L3 + XSNP]

[acme@jouet linux]$

Signed-off-by: Andi Kleen <ak@linux.intel.com>
Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Acked-by: Ingo Molnar <mingo@kernel.org>
Acked-by: Jiri Olsa <jolsa@redhat.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: linuxppc-dev@lists.ozlabs.org
Link: http://lkml.kernel.org/r/1473978296-20712-7-git-send-email-sukadev@linux.vnet.ibm.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/pmu.c | 83 +++++++++++++++++++++++++++++++++++++++++----------
 tools/perf/util/pmu.h |  1 +
 2 files changed, 68 insertions(+), 16 deletions(-)

diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index 10668b7f5272..9857fb14ea86 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -222,7 +222,7 @@ static int perf_pmu__parse_snapshot(struct perf_pmu_alias *alias,
 }
 
 static int __perf_pmu__new_alias(struct list_head *list, char *dir, char *name,
-				 char *desc __maybe_unused, char *val)
+				 char *desc, char *val)
 {
 	struct perf_pmu_alias *alias;
 	int ret;
@@ -255,6 +255,8 @@ static int __perf_pmu__new_alias(struct list_head *list, char *dir, char *name,
 		perf_pmu__parse_snapshot(alias, dir, name);
 	}
 
+	alias->desc = desc ? strdup(desc) : NULL;
+
 	list_add_tail(&alias->list, list);
 
 	return 0;
@@ -1043,11 +1045,42 @@ static char *format_alias_or(char *buf, int len, struct perf_pmu *pmu,
 	return buf;
 }
 
-static int cmp_string(const void *a, const void *b)
+struct pair {
+	char *name;
+	char *desc;
+};
+
+static int cmp_pair(const void *a, const void *b)
+{
+	const struct pair *as = a;
+	const struct pair *bs = b;
+
+	/* Put extra events last */
+	if (!!as->desc != !!bs->desc)
+		return !!as->desc - !!bs->desc;
+	return strcmp(as->name, bs->name);
+}
+
+static void wordwrap(char *s, int start, int max, int corr)
 {
-	const char * const *as = a;
-	const char * const *bs = b;
-	return strcmp(*as, *bs);
+	int column = start;
+	int n;
+
+	while (*s) {
+		int wlen = strcspn(s, " \t");
+
+		if (column + wlen >= max && column > start) {
+			printf("\n%*s", start, "");
+			column = start + corr;
+		}
+		n = printf("%s%.*s", column > start ? " " : "", wlen, s);
+		if (n <= 0)
+			break;
+		s += wlen;
+		column += n;
+		while (isspace(*s))
+			s++;
+	}
 }
 
 void print_pmu_events(const char *event_glob, bool name_only)
@@ -1057,7 +1090,9 @@ void print_pmu_events(const char *event_glob, bool name_only)
 	char buf[1024];
 	int printed = 0;
 	int len, j;
-	char **aliases;
+	struct pair *aliases;
+	int numdesc = 0;
+	int columns = 78;
 
 	pmu = NULL;
 	len = 0;
@@ -1067,14 +1102,15 @@ void print_pmu_events(const char *event_glob, bool name_only)
 		if (pmu->selectable)
 			len++;
 	}
-	aliases = zalloc(sizeof(char *) * len);
+	aliases = zalloc(sizeof(struct pair) * len);
 	if (!aliases)
 		goto out_enomem;
 	pmu = NULL;
 	j = 0;
 	while ((pmu = perf_pmu__scan(pmu)) != NULL) {
 		list_for_each_entry(alias, &pmu->aliases, list) {
-			char *name = format_alias(buf, sizeof(buf), pmu, alias);
+			char *name = alias->desc ? alias->name :
+				format_alias(buf, sizeof(buf), pmu, alias);
 			bool is_cpu = !strcmp(pmu->name, "cpu");
 
 			if (event_glob != NULL &&
@@ -1083,12 +1119,19 @@ void print_pmu_events(const char *event_glob, bool name_only)
 						       event_glob))))
 				continue;
 
-			if (is_cpu && !name_only)
+			if (is_cpu && !name_only && !alias->desc)
 				name = format_alias_or(buf, sizeof(buf), pmu, alias);
 
-			aliases[j] = strdup(name);
-			if (aliases[j] == NULL)
+			aliases[j].name = name;
+			if (is_cpu && !name_only && !alias->desc)
+				aliases[j].name = format_alias_or(buf,
+								  sizeof(buf),
+								  pmu, alias);
+			aliases[j].name = strdup(aliases[j].name);
+			if (!aliases[j].name)
 				goto out_enomem;
+
+			aliases[j].desc = alias->desc;
 			j++;
 		}
 		if (pmu->selectable &&
@@ -1096,25 +1139,33 @@ void print_pmu_events(const char *event_glob, bool name_only)
 			char *s;
 			if (asprintf(&s, "%s//", pmu->name) < 0)
 				goto out_enomem;
-			aliases[j] = s;
+			aliases[j].name = s;
 			j++;
 		}
 	}
 	len = j;
-	qsort(aliases, len, sizeof(char *), cmp_string);
+	qsort(aliases, len, sizeof(struct pair), cmp_pair);
 	for (j = 0; j < len; j++) {
 		if (name_only) {
-			printf("%s ", aliases[j]);
+			printf("%s ", aliases[j].name);
 			continue;
 		}
-		printf("  %-50s [Kernel PMU event]\n", aliases[j]);
+		if (aliases[j].desc) {
+			if (numdesc++ == 0)
+				printf("\n");
+			printf("  %-50s\n", aliases[j].name);
+			printf("%*s", 8, "[");
+			wordwrap(aliases[j].desc, 8, columns, 0);
+			printf("]\n");
+		} else
+			printf("  %-50s [Kernel PMU event]\n", aliases[j].name);
 		printed++;
 	}
 	if (printed && pager_in_use())
 		printf("\n");
 out_free:
 	for (j = 0; j < len; j++)
-		zfree(&aliases[j]);
+		zfree(&aliases[j].name);
 	zfree(&aliases);
 	return;
 
diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h
index 743422ad900b..51d8d0d35e63 100644
--- a/tools/perf/util/pmu.h
+++ b/tools/perf/util/pmu.h
@@ -40,6 +40,7 @@ struct perf_pmu_info {
 
 struct perf_pmu_alias {
 	char *name;
+	char *desc;
 	struct list_head terms; /* HEAD struct parse_events_term -> list */
 	struct list_head list;  /* ELEM */
 	char unit[UNIT_MAX_LEN+1];
-- 
2.7.4

  parent reply	other threads:[~2016-10-04  2:40 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-10-04  2:36 [GIT PULL 00/22] perf/core improvements and fixes Arnaldo Carvalho de Melo
2016-10-04  2:37 ` [PATCH 01/22] perf probe: Check if *ptr2 is zero and not ptr2 Arnaldo Carvalho de Melo
2016-10-04  2:37 ` [PATCH 02/22] perf tools: Experiment with cppcheck Arnaldo Carvalho de Melo
2016-10-04  2:37 ` [PATCH 03/22] tools build: Add support for host programs format Arnaldo Carvalho de Melo
2016-10-04  2:37 ` [PATCH 04/22] tools build: Make fixdep a hostprog Arnaldo Carvalho de Melo
2016-10-04  2:37 ` [PATCH 05/22] perf tools: Add jsmn `jasmine' JSON parser Arnaldo Carvalho de Melo
2016-10-04  2:37 ` [PATCH 06/22] perf jevents: Program to convert JSON file Arnaldo Carvalho de Melo
2016-10-04  2:37 ` [PATCH 07/22] perf pmu: Use pmu_events table to create aliases Arnaldo Carvalho de Melo
2016-10-04  2:37 ` [PATCH 08/22] perf powerpc: Support CPU ID matching for Powerpc Arnaldo Carvalho de Melo
2016-10-04  2:37 ` [PATCH 09/22] perf tools: Support CPU id matching for x86 v2 Arnaldo Carvalho de Melo
2016-10-04  2:37 ` [PATCH 10/22] perf jevents: Handle header line in mapfile Arnaldo Carvalho de Melo
2016-10-04  2:37 ` Arnaldo Carvalho de Melo [this message]
2016-10-04  2:37 ` [PATCH 12/22] perf tools: Query terminal width and use in perf list Arnaldo Carvalho de Melo
2016-10-04  2:37 ` [PATCH 13/22] perf list: Add a --no-desc flag Arnaldo Carvalho de Melo
2016-10-04  2:37 ` [PATCH 14/22] perf pmu: Add override support for event list CPUID Arnaldo Carvalho de Melo
2016-10-04  2:37 ` [PATCH 15/22] perf jevents: Add support for long descriptions Arnaldo Carvalho de Melo
2016-10-04  2:37 ` [PATCH 16/22] perf list: Support long jevents descriptions Arnaldo Carvalho de Melo
2016-10-04  2:37 ` [PATCH 17/22] perf list jevents: Add support for event list topics Arnaldo Carvalho de Melo
2016-10-04  2:37 ` [PATCH 18/22] perf tools: Add README for info on parsing JSON/map files Arnaldo Carvalho de Melo
2016-10-04  2:37 ` [PATCH 19/22] perf tools: Allow period= in perf stat CPU event descriptions Arnaldo Carvalho de Melo
2016-10-04  2:37 ` [PATCH 20/22] perf tools: Make alias matching case-insensitive Arnaldo Carvalho de Melo
2016-10-04  2:37 ` [PATCH 21/22] perf pmu-events: Fix fixed counters on Intel Arnaldo Carvalho de Melo
2016-10-04  2:37 ` [PATCH 22/22] perf pmu-events: Add Skylake frontend MSR support Arnaldo Carvalho de Melo
2016-10-04  8:07 ` [GIT PULL 00/22] perf/core improvements and fixes Ingo Molnar

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1475548641-12182-12-git-send-email-acme@kernel.org \
    --to=acme@kernel.org \
    --cc=acme@redhat.com \
    --cc=ak@linux.intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linuxppc-dev@lists.ozlabs.org \
    --cc=lwn@lwn.net \
    --cc=maddy@linux.vnet.ibm.com \
    --cc=mingo@kernel.org \
    --cc=peterz@infradead.org \
    --cc=sukadev@linux.vnet.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).