linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v21 00/20] perf, tools: Add support for PMU events in JSON format
@ 2016-09-15 22:24 Sukadev Bhattiprolu
  2016-09-15 22:24 ` [PATCH v21 01/19] perf, tools: Add jsmn `jasmine' JSON parser Sukadev Bhattiprolu
                   ` (20 more replies)
  0 siblings, 21 replies; 70+ messages in thread
From: Sukadev Bhattiprolu @ 2016-09-15 22:24 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo; +Cc: peterz, maddy, linuxppc-dev, linux-kernel

CPUs support a large number of performance monitoring events (PMU events)
and often these events are very specific to an architecture/model of the
CPU. To use most of these PMU events with perf, we currently have to identify
them by their raw codes:

	perf stat -e r100f2 sleep 1

This patchset allows architectures to specify these PMU events in JSON
files located in 'tools/perf/pmu-events/arch/' of the mainline tree.
The events from the JSON files for the architecture are then built into
the perf binary.

At run time, perf identifies the specific set of events for the CPU and
creates "event aliases". These aliases allow users to specify events by
"name" as:

	perf stat -e pm_1plus_ppc_cmpl sleep 1

The file, 'tools/perf/pmu-events/README' in [PATCH 15/19] gives more
details.

Note:
	- All known events tables for the architecture are included in the
	  perf binary.

	- For architectures that don't have any JSON files, an empty mapping
	  table is created and they should continue to build.

Thanks to input from Andi Kleen, Jiri Olsa, Namhyung Kim and Ingo Molnar.

These patches are available from:

	https://github.com/sukadev/linux.git 
	
	Branch			Description
	------------------------------------------------------
	json-code-v21		Source Code only 
	json-code+data-v21	Both code and data (for build/test/pull)
	
NOTE: 	Only "source code" patches (i.e those in json-code-v21) are being
	emailed. Please pull the json-code+data-v21 branch for build/test.

Changelog[v21]
	- Rebase to recent perf/core
	- Group the PMU events supported by a CPU model into topics and
	  create a separate JSON file for each topic for each CPU (code
	  and input from Jiri Olsa).

Changelog[v20]
	- Rebase to recent perf/core
	- Add Patch 20/20 to allow perf-stat to work with the period= field

Changelog[v19]
	Rebase to recent perf/core; fix couple lines >80 chars.

Changelog[v18]
	Rebase to recent perf/core; fix minor merge conflicts.

Changelog[v17]
	Rebase to recent perf/core; couple of small fixes to processing Intel
	JSON files; allow case-insensitive PMU event names.

Changelog[v16]
	Rebase to recent perf/core; fix minor merge conflicts; drop 3 patches
	that were merged into perf/core.

Changelog[v15]
	Code changes:
	- Fix 'perf list' usage string and update man page.
	- Remove a redundant __maybe_unused tag.
	- Rebase to recent perf/core branch.

	Data files updates: json-files-5 branch
	- Rebase to perf/intel-json-files-5 from Andi Kleen
	- Add patch from Madhavan Srinivasan for couple more Powerpc models

Changelog[v14]
	Comments from Jiri Olsa:
	- Change parameter name/type for pmu_add_cpu_aliases (from void *data
	  to list_head *head)
	- Use asprintf() in file_name_to_tablename() and simplify/reorg code.
	- Use __weak definition from <linux/compile.h>
	- Use fopen() with mode "w" and eliminate unlink()
	- Remove minor TODO.
	- Add error check for return value from strdup() in print_pmu_events().
	- Move independent changes from patches 3,11,12 .. to separate patches
	  for easier review/backport.
	- Clarify mapfile's "header line support" in patch description.
	- Fix build failure with DEBUG=1

	Comment from Andi Kleen:
	- In tools/perf/pmu-events/Build, check for 'mapfile.csv' rather than
	  'mapfile*'

	Misc:
	- Minor changes/clarifications to tools/perf/pmu-events/README.


Changelog[v13]
	Version: Individual patches have their own history :-) that I am
	preserving. Patchset version (v13) is for overall patchset and is
	somewhat arbitrary.

	- Added support for "categories" of events to perf
	- Add mapfile, jevents build dependency on pmu-events.c
	- Silence jevents when parsing JSON files unless V=1 is specified
	- Cleanup error messages
	- Fix memory leak with ->cpuid
	- Rebase to Arnaldo's tree
	- Allow overriding CPUID via environment variable
	- Support long descriptions for events
	- Handle header line in mapfile.csv
	- Cleanup JSON files (trim PublicDescription if identical to/prefix of
	  BriefDescription field)


Andi Kleen (12):
  perf, tools: Add jsmn `jasmine' JSON parser
  perf, tools, jevents: Program to convert JSON file to C style file
  perf, tools: Support CPU id matching for x86 v2
  perf, tools: Support alias descriptions
  perf, tools: Query terminal width and use in perf list
  perf, tools: Add a --no-desc flag to perf list
  perf, tools: Add override support for event list CPUID
  perf, tools: Add support for event list topics
  perf, tools, jevents: Handle header line in mapfile
  perf, tools: Make alias matching case-insensitive
  perf, tools, pmu-events: Fix fixed counters on Intel
  perf, tools, pmu-events: Add Skylake frontend MSR support

Sukadev Bhattiprolu (7):
  perf, tools: Use pmu_events table to create aliases
  perf, tools: Support CPU ID matching for Powerpc
  perf, tools, jevents: Add support for long descriptions
  perf, tools: Add alias support for long descriptions
  perf, tools: Support long descriptions with perf list
  perf, tools: Add README for info on parsing JSON/map files
  Allow period= in perf stat CPU event descriptions.

 tools/lib/subcmd/pager.c               |  16 +
 tools/lib/subcmd/pager.h               |   1 +
 tools/perf/Documentation/perf-list.txt |  12 +-
 tools/perf/Makefile.perf               |  28 +-
 tools/perf/arch/powerpc/util/header.c  |  11 +
 tools/perf/arch/x86/util/header.c      |  24 +-
 tools/perf/builtin-list.c              |  20 +-
 tools/perf/pmu-events/Build            |  11 +
 tools/perf/pmu-events/README           | 148 ++++++
 tools/perf/pmu-events/jevents.c        | 811 +++++++++++++++++++++++++++++++++
 tools/perf/pmu-events/jevents.h        |  18 +
 tools/perf/pmu-events/jsmn.c           | 313 +++++++++++++
 tools/perf/pmu-events/jsmn.h           |  67 +++
 tools/perf/pmu-events/json.c           | 162 +++++++
 tools/perf/pmu-events/json.h           |  42 ++
 tools/perf/pmu-events/pmu-events.h     |  37 ++
 tools/perf/util/header.h               |   1 +
 tools/perf/util/parse-events.c         |   8 +-
 tools/perf/util/parse-events.h         |   3 +-
 tools/perf/util/pmu.c                  | 177 ++++++-
 tools/perf/util/pmu.h                  |   6 +-
 21 files changed, 1880 insertions(+), 36 deletions(-)
 create mode 100644 tools/perf/pmu-events/Build
 create mode 100644 tools/perf/pmu-events/README
 create mode 100644 tools/perf/pmu-events/jevents.c
 create mode 100644 tools/perf/pmu-events/jevents.h
 create mode 100644 tools/perf/pmu-events/jsmn.c
 create mode 100644 tools/perf/pmu-events/jsmn.h
 create mode 100644 tools/perf/pmu-events/json.c
 create mode 100644 tools/perf/pmu-events/json.h
 create mode 100644 tools/perf/pmu-events/pmu-events.h

-- 
1.8.3.1

^ permalink raw reply	[flat|nested] 70+ messages in thread

* [PATCH v21 01/19] perf, tools: Add jsmn `jasmine' JSON parser
  2016-09-15 22:24 [PATCH v21 00/20] perf, tools: Add support for PMU events in JSON format Sukadev Bhattiprolu
@ 2016-09-15 22:24 ` Sukadev Bhattiprolu
  2016-10-04  8:11   ` [tip:perf/urgent] perf " tip-bot for Andi Kleen
  2016-09-15 22:24 ` [PATCH v21 02/19] perf, tools, jevents: Program to convert JSON file to C style file Sukadev Bhattiprolu
                   ` (19 subsequent siblings)
  20 siblings, 1 reply; 70+ messages in thread
From: Sukadev Bhattiprolu @ 2016-09-15 22:24 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo; +Cc: peterz, maddy, linuxppc-dev, linux-kernel

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

I need a JSON parser. This adds the simplest JSON
parser I could find -- Serge Zaitsev's jsmn `jasmine' --
to the perf library. I merely converted it to (mostly)
Linux style and added support for non 0 terminated input.

The parser is quite straight forward and does not
copy any data, just returns tokens with offsets
into the input buffer. So it's relatively efficient
and simple to use.

The code is not fully checkpatch clean, but I didn't
want to completely fork the upstream code.

Original source: http://zserge.bitbucket.org/jsmn.html

In addition I added a simple wrapper that mmaps a json
file and provides some straight forward access functions.

Used in follow-on patches to parse event files.

Signed-off-by: Andi Kleen <ak@linux.intel.com>
Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Acked-by: Namhyung Kim <namhyung@kernel.org>
Acked-by: Jiri Olsa <jolsa@redhat.com>
Acked-by: Ingo Molnar <mingo@kernel.org>
---
v2: Address review feedback.
v3: Minor checkpatch fixes.
v4 (by Sukadev Bhattiprolu)
	- Rebase to 4.0 and fix minor conflicts in tools/perf/Makefile.perf
	- Report error if specified events file is invalid.
v5 (Sukadev Bhattiprolu)
	- Move files to tools/perf/pmu-events/ since parsing of JSON file
	now occurs when _building_ rather than running perf.
---
 tools/perf/pmu-events/jsmn.c | 313 +++++++++++++++++++++++++++++++++++++++++++
 tools/perf/pmu-events/jsmn.h |  67 +++++++++
 tools/perf/pmu-events/json.c | 162 ++++++++++++++++++++++
 tools/perf/pmu-events/json.h |  36 +++++
 4 files changed, 578 insertions(+)
 create mode 100644 tools/perf/pmu-events/jsmn.c
 create mode 100644 tools/perf/pmu-events/jsmn.h
 create mode 100644 tools/perf/pmu-events/json.c
 create mode 100644 tools/perf/pmu-events/json.h

diff --git a/tools/perf/pmu-events/jsmn.c b/tools/perf/pmu-events/jsmn.c
new file mode 100644
index 0000000..11d1fa1
--- /dev/null
+++ b/tools/perf/pmu-events/jsmn.c
@@ -0,0 +1,313 @@
+/*
+ * Copyright (c) 2010 Serge A. Zaitsev
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * Slightly modified by AK to not assume 0 terminated input.
+ */
+
+#include <stdlib.h>
+#include "jsmn.h"
+
+/*
+ * Allocates a fresh unused token from the token pool.
+ */
+static jsmntok_t *jsmn_alloc_token(jsmn_parser *parser,
+				   jsmntok_t *tokens, size_t num_tokens)
+{
+	jsmntok_t *tok;
+
+	if ((unsigned)parser->toknext >= num_tokens)
+		return NULL;
+	tok = &tokens[parser->toknext++];
+	tok->start = tok->end = -1;
+	tok->size = 0;
+	return tok;
+}
+
+/*
+ * Fills token type and boundaries.
+ */
+static void jsmn_fill_token(jsmntok_t *token, jsmntype_t type,
+			    int start, int end)
+{
+	token->type = type;
+	token->start = start;
+	token->end = end;
+	token->size = 0;
+}
+
+/*
+ * Fills next available token with JSON primitive.
+ */
+static jsmnerr_t jsmn_parse_primitive(jsmn_parser *parser, const char *js,
+				      size_t len,
+				      jsmntok_t *tokens, size_t num_tokens)
+{
+	jsmntok_t *token;
+	int start;
+
+	start = parser->pos;
+
+	for (; parser->pos < len; parser->pos++) {
+		switch (js[parser->pos]) {
+#ifndef JSMN_STRICT
+		/*
+		 * In strict mode primitive must be followed by ","
+		 * or "}" or "]"
+		 */
+		case ':':
+#endif
+		case '\t':
+		case '\r':
+		case '\n':
+		case ' ':
+		case ',':
+		case ']':
+		case '}':
+			goto found;
+		default:
+			break;
+		}
+		if (js[parser->pos] < 32 || js[parser->pos] >= 127) {
+			parser->pos = start;
+			return JSMN_ERROR_INVAL;
+		}
+	}
+#ifdef JSMN_STRICT
+	/*
+	 * In strict mode primitive must be followed by a
+	 * comma/object/array.
+	 */
+	parser->pos = start;
+	return JSMN_ERROR_PART;
+#endif
+
+found:
+	token = jsmn_alloc_token(parser, tokens, num_tokens);
+	if (token == NULL) {
+		parser->pos = start;
+		return JSMN_ERROR_NOMEM;
+	}
+	jsmn_fill_token(token, JSMN_PRIMITIVE, start, parser->pos);
+	parser->pos--; /* parent sees closing brackets */
+	return JSMN_SUCCESS;
+}
+
+/*
+ * Fills next token with JSON string.
+ */
+static jsmnerr_t jsmn_parse_string(jsmn_parser *parser, const char *js,
+				   size_t len,
+				   jsmntok_t *tokens, size_t num_tokens)
+{
+	jsmntok_t *token;
+	int start = parser->pos;
+
+	/* Skip starting quote */
+	parser->pos++;
+
+	for (; parser->pos < len; parser->pos++) {
+		char c = js[parser->pos];
+
+		/* Quote: end of string */
+		if (c == '\"') {
+			token = jsmn_alloc_token(parser, tokens, num_tokens);
+			if (token == NULL) {
+				parser->pos = start;
+				return JSMN_ERROR_NOMEM;
+			}
+			jsmn_fill_token(token, JSMN_STRING, start+1,
+					parser->pos);
+			return JSMN_SUCCESS;
+		}
+
+		/* Backslash: Quoted symbol expected */
+		if (c == '\\') {
+			parser->pos++;
+			switch (js[parser->pos]) {
+				/* Allowed escaped symbols */
+			case '\"':
+			case '/':
+			case '\\':
+			case 'b':
+			case 'f':
+			case 'r':
+			case 'n':
+			case 't':
+				break;
+				/* Allows escaped symbol \uXXXX */
+			case 'u':
+				/* TODO */
+				break;
+				/* Unexpected symbol */
+			default:
+				parser->pos = start;
+				return JSMN_ERROR_INVAL;
+			}
+		}
+	}
+	parser->pos = start;
+	return JSMN_ERROR_PART;
+}
+
+/*
+ * Parse JSON string and fill tokens.
+ */
+jsmnerr_t jsmn_parse(jsmn_parser *parser, const char *js, size_t len,
+		     jsmntok_t *tokens, unsigned int num_tokens)
+{
+	jsmnerr_t r;
+	int i;
+	jsmntok_t *token;
+
+	for (; parser->pos < len; parser->pos++) {
+		char c;
+		jsmntype_t type;
+
+		c = js[parser->pos];
+		switch (c) {
+		case '{':
+		case '[':
+			token = jsmn_alloc_token(parser, tokens, num_tokens);
+			if (token == NULL)
+				return JSMN_ERROR_NOMEM;
+			if (parser->toksuper != -1)
+				tokens[parser->toksuper].size++;
+			token->type = (c == '{' ? JSMN_OBJECT : JSMN_ARRAY);
+			token->start = parser->pos;
+			parser->toksuper = parser->toknext - 1;
+			break;
+		case '}':
+		case ']':
+			type = (c == '}' ? JSMN_OBJECT : JSMN_ARRAY);
+			for (i = parser->toknext - 1; i >= 0; i--) {
+				token = &tokens[i];
+				if (token->start != -1 && token->end == -1) {
+					if (token->type != type)
+						return JSMN_ERROR_INVAL;
+					parser->toksuper = -1;
+					token->end = parser->pos + 1;
+					break;
+				}
+			}
+			/* Error if unmatched closing bracket */
+			if (i == -1)
+				return JSMN_ERROR_INVAL;
+			for (; i >= 0; i--) {
+				token = &tokens[i];
+				if (token->start != -1 && token->end == -1) {
+					parser->toksuper = i;
+					break;
+				}
+			}
+			break;
+		case '\"':
+			r = jsmn_parse_string(parser, js, len, tokens,
+					      num_tokens);
+			if (r < 0)
+				return r;
+			if (parser->toksuper != -1)
+				tokens[parser->toksuper].size++;
+			break;
+		case '\t':
+		case '\r':
+		case '\n':
+		case ':':
+		case ',':
+		case ' ':
+			break;
+#ifdef JSMN_STRICT
+			/*
+			 * In strict mode primitives are:
+			 * numbers and booleans.
+			 */
+		case '-':
+		case '0':
+		case '1':
+		case '2':
+		case '3':
+		case '4':
+		case '5':
+		case '6':
+		case '7':
+		case '8':
+		case '9':
+		case 't':
+		case 'f':
+		case 'n':
+#else
+			/*
+			 * In non-strict mode every unquoted value
+			 * is a primitive.
+			 */
+			/*FALL THROUGH */
+		default:
+#endif
+			r = jsmn_parse_primitive(parser, js, len, tokens,
+						 num_tokens);
+			if (r < 0)
+				return r;
+			if (parser->toksuper != -1)
+				tokens[parser->toksuper].size++;
+			break;
+
+#ifdef JSMN_STRICT
+			/* Unexpected char in strict mode */
+		default:
+			return JSMN_ERROR_INVAL;
+#endif
+		}
+	}
+
+	for (i = parser->toknext - 1; i >= 0; i--) {
+		/* Unmatched opened object or array */
+		if (tokens[i].start != -1 && tokens[i].end == -1)
+			return JSMN_ERROR_PART;
+	}
+
+	return JSMN_SUCCESS;
+}
+
+/*
+ * Creates a new parser based over a given  buffer with an array of tokens
+ * available.
+ */
+void jsmn_init(jsmn_parser *parser)
+{
+	parser->pos = 0;
+	parser->toknext = 0;
+	parser->toksuper = -1;
+}
+
+const char *jsmn_strerror(jsmnerr_t err)
+{
+	switch (err) {
+	case JSMN_ERROR_NOMEM:
+		return "No enough tokens";
+	case JSMN_ERROR_INVAL:
+		return "Invalid character inside JSON string";
+	case JSMN_ERROR_PART:
+		return "The string is not a full JSON packet, more bytes expected";
+	case JSMN_SUCCESS:
+		return "Success";
+	default:
+		return "Unknown json error";
+	}
+}
diff --git a/tools/perf/pmu-events/jsmn.h b/tools/perf/pmu-events/jsmn.h
new file mode 100644
index 0000000..d666b10
--- /dev/null
+++ b/tools/perf/pmu-events/jsmn.h
@@ -0,0 +1,67 @@
+#ifndef __JSMN_H_
+#define __JSMN_H_
+
+/*
+ * JSON type identifier. Basic types are:
+ *	o Object
+ *	o Array
+ *	o String
+ *	o Other primitive: number, boolean (true/false) or null
+ */
+typedef enum {
+	JSMN_PRIMITIVE = 0,
+	JSMN_OBJECT = 1,
+	JSMN_ARRAY = 2,
+	JSMN_STRING = 3
+} jsmntype_t;
+
+typedef enum {
+	/* Not enough tokens were provided */
+	JSMN_ERROR_NOMEM = -1,
+	/* Invalid character inside JSON string */
+	JSMN_ERROR_INVAL = -2,
+	/* The string is not a full JSON packet, more bytes expected */
+	JSMN_ERROR_PART = -3,
+	/* Everything was fine */
+	JSMN_SUCCESS = 0
+} jsmnerr_t;
+
+/*
+ * JSON token description.
+ * @param		type	type (object, array, string etc.)
+ * @param		start	start position in JSON data string
+ * @param		end		end position in JSON data string
+ */
+typedef struct {
+	jsmntype_t type;
+	int start;
+	int end;
+	int size;
+} jsmntok_t;
+
+/*
+ * JSON parser. Contains an array of token blocks available. Also stores
+ * the string being parsed now and current position in that string
+ */
+typedef struct {
+	unsigned int pos; /* offset in the JSON string */
+	int toknext; /* next token to allocate */
+	int toksuper; /* superior token node, e.g parent object or array */
+} jsmn_parser;
+
+/*
+ * Create JSON parser over an array of tokens
+ */
+void jsmn_init(jsmn_parser *parser);
+
+/*
+ * Run JSON parser. It parses a JSON data string into and array of tokens,
+ * each describing a single JSON object.
+ */
+jsmnerr_t jsmn_parse(jsmn_parser *parser, const char *js,
+		     size_t len,
+		     jsmntok_t *tokens, unsigned int num_tokens);
+
+const char *jsmn_strerror(jsmnerr_t err);
+
+#endif /* __JSMN_H_ */
diff --git a/tools/perf/pmu-events/json.c b/tools/perf/pmu-events/json.c
new file mode 100644
index 0000000..87f0c4b
--- /dev/null
+++ b/tools/perf/pmu-events/json.c
@@ -0,0 +1,162 @@
+/* Parse JSON files using the JSMN parser. */
+
+/*
+ * Copyright (c) 2014, Intel Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/fcntl.h>
+#include <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+#include "jsmn.h"
+#include "json.h"
+#include <linux/kernel.h>
+
+
+static char *mapfile(const char *fn, size_t *size)
+{
+	unsigned ps = sysconf(_SC_PAGESIZE);
+	struct stat st;
+	char *map = NULL;
+	int err;
+	int fd = open(fn, O_RDONLY);
+
+	if (fd < 0 && verbose && fn) {
+		pr_err("Error opening events file '%s': %s\n", fn,
+				strerror(errno));
+	}
+
+	if (fd < 0)
+		return NULL;
+	err = fstat(fd, &st);
+	if (err < 0)
+		goto out;
+	*size = st.st_size;
+	map = mmap(NULL,
+		   (st.st_size + ps - 1) & ~(ps - 1),
+		   PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
+	if (map == MAP_FAILED)
+		map = NULL;
+out:
+	close(fd);
+	return map;
+}
+
+static void unmapfile(char *map, size_t size)
+{
+	unsigned ps = sysconf(_SC_PAGESIZE);
+	munmap(map, roundup(size, ps));
+}
+
+/*
+ * Parse json file using jsmn. Return array of tokens,
+ * and mapped file. Caller needs to free array.
+ */
+jsmntok_t *parse_json(const char *fn, char **map, size_t *size, int *len)
+{
+	jsmn_parser parser;
+	jsmntok_t *tokens;
+	jsmnerr_t res;
+	unsigned sz;
+
+	*map = mapfile(fn, size);
+	if (!*map)
+		return NULL;
+	/* Heuristic */
+	sz = *size * 16;
+	tokens = malloc(sz);
+	if (!tokens)
+		goto error;
+	jsmn_init(&parser);
+	res = jsmn_parse(&parser, *map, *size, tokens,
+			 sz / sizeof(jsmntok_t));
+	if (res != JSMN_SUCCESS) {
+		pr_err("%s: json error %s\n", fn, jsmn_strerror(res));
+		goto error_free;
+	}
+	if (len)
+		*len = parser.toknext;
+	return tokens;
+error_free:
+	free(tokens);
+error:
+	unmapfile(*map, *size);
+	return NULL;
+}
+
+void free_json(char *map, size_t size, jsmntok_t *tokens)
+{
+	free(tokens);
+	unmapfile(map, size);
+}
+
+static int countchar(char *map, char c, int end)
+{
+	int i;
+	int count = 0;
+	for (i = 0; i < end; i++)
+		if (map[i] == c)
+			count++;
+	return count;
+}
+
+/* Return line number of a jsmn token */
+int json_line(char *map, jsmntok_t *t)
+{
+	return countchar(map, '\n', t->start) + 1;
+}
+
+static const char * const jsmn_types[] = {
+	[JSMN_PRIMITIVE] = "primitive",
+	[JSMN_ARRAY] = "array",
+	[JSMN_OBJECT] = "object",
+	[JSMN_STRING] = "string"
+};
+
+#define LOOKUP(a, i) ((i) < (sizeof(a)/sizeof(*(a))) ? ((a)[i]) : "?")
+
+/* Return type name of a jsmn token */
+const char *json_name(jsmntok_t *t)
+{
+	return LOOKUP(jsmn_types, t->type);
+}
+
+int json_len(jsmntok_t *t)
+{
+	return t->end - t->start;
+}
+
+/* Is string t equal to s? */
+int json_streq(char *map, jsmntok_t *t, const char *s)
+{
+	unsigned len = json_len(t);
+	return len == strlen(s) && !strncasecmp(map + t->start, s, len);
+}
diff --git a/tools/perf/pmu-events/json.h b/tools/perf/pmu-events/json.h
new file mode 100644
index 0000000..6b8337e
--- /dev/null
+++ b/tools/perf/pmu-events/json.h
@@ -0,0 +1,36 @@
+#ifndef JSON_H
+#define JSON_H 1
+
+#include "jsmn.h"
+
+jsmntok_t *parse_json(const char *fn, char **map, size_t *size, int *len);
+void free_json(char *map, size_t size, jsmntok_t *tokens);
+int json_line(char *map, jsmntok_t *t);
+const char *json_name(jsmntok_t *t);
+int json_streq(char *map, jsmntok_t *t, const char *s);
+int json_len(jsmntok_t *t);
+
+extern int verbose;
+
+typedef unsigned int bool;
+
+#ifndef true
+#define	true 1
+#endif
+
+extern int eprintf(int level, int var, const char *fmt, ...);
+#define pr_fmt(fmt)	fmt
+
+#define pr_err(fmt, ...) \
+	eprintf(0, verbose, pr_fmt(fmt), ##__VA_ARGS__)
+
+#ifndef roundup
+#define roundup(x, y) (                                \
+{                                                      \
+        const typeof(y) __y = y;                       \
+        (((x) + (__y - 1)) / __y) * __y;               \
+}                                                      \
+)
+#endif
+
+#endif
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH v21 02/19] perf, tools, jevents: Program to convert JSON file to C style file
  2016-09-15 22:24 [PATCH v21 00/20] perf, tools: Add support for PMU events in JSON format Sukadev Bhattiprolu
  2016-09-15 22:24 ` [PATCH v21 01/19] perf, tools: Add jsmn `jasmine' JSON parser Sukadev Bhattiprolu
@ 2016-09-15 22:24 ` Sukadev Bhattiprolu
  2016-09-15 22:24 ` [PATCH v21 03/19] perf, tools: Use pmu_events table to create aliases Sukadev Bhattiprolu
                   ` (18 subsequent siblings)
  20 siblings, 0 replies; 70+ messages in thread
From: Sukadev Bhattiprolu @ 2016-09-15 22:24 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo; +Cc: peterz, maddy, linuxppc-dev, linux-kernel

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

This is a modified version of an earlier patch by Andi Kleen.

We expect architectures to create JSON files describing the performance
monitoring (PMU) events that each CPU model/family of the architecture
supports.

Following is an example of the JSON file entry for an x86 event:

    	[
    	...
    	{
    	"EventCode": "0x00",
    	"UMask": "0x01",
    	"EventName": "INST_RETIRED.ANY",
    	"BriefDescription": "Instructions retired from execution.",
    	"PublicDescription": "Instructions retired from execution.",
    	"Counter": "Fixed counter 1",
    	"CounterHTOff": "Fixed counter 1",
    	"SampleAfterValue": "2000003",
    	"SampleAfterValue": "2000003",
    	"MSRIndex": "0",
    	"MSRValue": "0",
    	"TakenAlone": "0",
    	"CounterMask": "0",
    	"Invert": "0",
    	"AnyThread": "0",
    	"EdgeDetect": "0",
    	"PEBS": "0",
    	"PRECISE_STORE": "0",
    	"Errata": "null",
    	"Offcore": "0"
    	},
    	...

    	]

All the PMU events supported by a CPU model/family must be grouped into
"topics" such as "Piplelining", "Floating-point", "Virtual-memory" etc.

All events belonging to a topic must be placed in a separate JSON file
(eg: "Pipeling.json") and all the topic JSON files for a CPU model must
be in a separate directory.

	Eg: for the CPU model "Silvermont_core":

    	$ ls tools/perf/pmu-events/arch/x86/Silvermont_core
    	Floating-point.json
    	Memory.json
    	Other.json
    	Pipelining.json
    	Virtualmemory.json

Finally, to allow multiple CPU models to share a single set of JSON files,
architectures must provide a mapping between a model and its set of events:

    	$ grep Silvermont tools/perf/pmu-events/arch/x86/mapfile.csv
    	GenuineIntel-6-4D,V13,Silvermont_core,core
    	GenuineIntel-6-4C,V13,Silvermont_core,core

which maps each CPU, identified by [vendor, family, model, version, type]
to a directory of JSON files. Thus two (or more) CPU models support the
set of PMU events listed in the directory.

    	tools/perf/pmu-events/arch/x86/Silvermont_core/

Given this organization of files, the program, jevents:

	- locates all JSON files for each CPU-model of the architecture,

	- parses all JSON files for the CPU-model and generates a C-style
	  "PMU-events table" (pmu-events.c) for the model

	- locates a mapfile for the architecture

	- builds a global table, mapping each model of CPU to the corresponding
	  PMU-events table.

The 'pmu-events.c' is generated when building perf and added to libperf.a.
The global table pmu_events_map[] table in this pmu-events.c will be used
in perf in a follow-on patch.

If the architecture does not have any JSON files or there is an error in
processing them, an empty mapping file is created. This would allow the
build of perf to proceed even if we are not able to provide aliases for
events.

The parser for JSON files allows parsing Intel style JSON event files. This
allows to use an Intel event list directly with perf. The Intel event lists
can be quite large and are too big to store in unswappable kernel memory.

The conversion from JSON to C-style is straight forward.  The parser knows
(very little) Intel specific information, and can be easily extended to
handle fields for other CPUs.

The parser code is partially shared with an independent parsing library,
which is 2-clause BSD licenced. To avoid any conflicts I marked those
files as BSD licenced too. As part of perf they become GPLv2.

Signed-off-by: Andi Kleen <ak@linux.intel.com>
Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Acked-by: Ingo Molnar <mingo@kernel.org>
---
v2: Address review feedback. Rename option to --event-files
v3: Add JSON example
v4: Update manpages.
v5: Don't remove dot in fixname. Fix compile error. Add include
	protection. Comment realloc.
v6: Include debug/util.h
v7: (Sukadev Bhattiprolu)
	Rebase to 4.0 and fix some conflicts.
v8: (Sukadev Bhattiprolu)
	Move jevents.[hc] to tools/perf/pmu-events/
	Rewrite to locate and process arch specific JSON and "map" files;
	and generate a C file.
	(Removed acked-by Namhyung Kim due to modest changes to patch)
	Compile the generated pmu-events.c and add the pmu-events.o to
	libperf.a
v9: [Sukadev Bhattiprolu/Andi Kleen] Rename ->vfm to ->cpuid and use
	that field to encode the PVR in Power.
	Allow blank lines in mapfile.
	[Jiri Olsa] Pass ARCH as a parameter to jevents so we don't have
	to detect it.
	[Jiri Olsa] Use the infrastrastructure to build pmu-events/perf
	(Makefile changes from Jiri included in this patch).
	[Jiri Olsa, Andi Kleen] Detect changes to JSON files and rebuild
	pmu-events.o only if necessary.

v11: 	- [Andi Kleen] Add mapfile, jevents dependency on pmu-events.c
	- [Jiri Olsa] Be silient if arch doesn't have JSON files
	- Also silence 'jevents' when parsing JSON files unless V=1 is
	  specified during build. Cleanup error messages.

v14:-	- [Jiri Olsa] Fix compile error with DEBUG=1; drop unlink() and
	  use "w" mode with fopen(); simplify file_name_to_table_name()

v15:	- Fix minor conflict in tools/perf/Makefile.perf when rebasing
	  to recent perf/core.

v16:	- Rebase to upstream; fix conflicts in tools/perf/Makefile.perf

v18:	- Rebase to upstream; fix conflicts in tools/perf/Makefile.perf

v20: 	- Rebase to upstream; rename a local variable to 'ldirname' to avoid
	  collision with the dirname().

v21:	- Breakup the large JSON files into separate topics like
	  Pipelining.json, Cache.json etc (by Jiri Olsa).
	- Ensure BriefDescription field is non-null before adding extra
	  description for PEBS events.
---
 tools/perf/Makefile.perf           |  28 +-
 tools/perf/pmu-events/Build        |  11 +
 tools/perf/pmu-events/jevents.c    | 766 +++++++++++++++++++++++++++++++++++++
 tools/perf/pmu-events/jevents.h    |  17 +
 tools/perf/pmu-events/json.h       |   6 +
 tools/perf/pmu-events/pmu-events.h |  36 ++
 6 files changed, 860 insertions(+), 4 deletions(-)
 create mode 100644 tools/perf/pmu-events/Build
 create mode 100644 tools/perf/pmu-events/jevents.c
 create mode 100644 tools/perf/pmu-events/jevents.h
 create mode 100644 tools/perf/pmu-events/pmu-events.h

diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 828cfd7..0abebcb 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -347,6 +347,14 @@ PERF_IN := $(OUTPUT)perf-in.o
 export srctree OUTPUT RM CC LD AR CFLAGS V BISON FLEX AWK
 include $(srctree)/tools/build/Makefile.include
 
+JEVENTS       := $(OUTPUT)pmu-events/jevents
+JEVENTS_IN    := $(OUTPUT)pmu-events/jevents-in.o
+PMU_EVENTS_IN := $(OUTPUT)pmu-events/pmu-events-in.o
+
+export JEVENTS
+
+build := -f $(srctree)/tools/build/Makefile.build dir=. obj
+
 $(PERF_IN): prepare FORCE
 	@(test -f ../../include/uapi/linux/perf_event.h && ( \
         (diff -B ../include/uapi/linux/perf_event.h ../../include/uapi/linux/perf_event.h >/dev/null) \
@@ -434,9 +442,18 @@ $(PERF_IN): prepare FORCE
 	|| echo "Warning: tools/include/linux/coresight-pmu.h differs from kernel" >&2 )) || true
 	$(Q)$(MAKE) $(build)=perf
 
-$(OUTPUT)perf: $(PERFLIBS) $(PERF_IN) $(LIBTRACEEVENT_DYNAMIC_LIST)
+$(JEVENTS_IN): FORCE
+	$(Q)$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=pmu-events obj=jevents
+
+$(JEVENTS): $(JEVENTS_IN)
+	$(QUIET_LINK)$(CC) $(JEVENTS_IN) -o $@
+
+$(PMU_EVENTS_IN): $(JEVENTS) FORCE
+	$(Q)$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=pmu-events obj=pmu-events
+
+$(OUTPUT)perf: $(PERFLIBS) $(PERF_IN) $(PMU_EVENTS_IN) $(LIBTRACEEVENT_DYNAMIC_LIST)
 	$(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $(LIBTRACEEVENT_DYNAMIC_LIST_LDFLAGS) \
-		$(PERF_IN) $(LIBS) -o $@
+		$(PERF_IN) $(PMU_EVENTS_IN) $(LIBS) -o $@
 
 $(GTK_IN): fixdep FORCE
 	$(Q)$(MAKE) $(build)=gtk
@@ -465,6 +482,8 @@ perf.spec $(SCRIPTS) \
 ifneq ($(OUTPUT),)
 %.o: $(OUTPUT)%.o
 	@echo "    # Redirected target $@ => $(OUTPUT)$@"
+pmu-events/%.o: $(OUTPUT)pmu-events/%.o
+	@echo "    # Redirected target $@ => $(OUTPUT)$@"
 util/%.o: $(OUTPUT)util/%.o
 	@echo "    # Redirected target $@ => $(OUTPUT)$@"
 bench/%.o: $(OUTPUT)bench/%.o
@@ -720,10 +739,11 @@ clean:: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clea
 	$(call QUIET_CLEAN, core-objs)  $(RM) $(LIB_FILE) $(OUTPUT)perf-archive $(OUTPUT)perf-with-kcore $(LANG_BINDINGS)
 	$(Q)find $(if $(OUTPUT),$(OUTPUT),.) -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete
 	$(Q)$(RM) $(OUTPUT).config-detected
-	$(call QUIET_CLEAN, core-progs) $(RM) $(ALL_PROGRAMS) perf perf-read-vdso32 perf-read-vdsox32
+	$(call QUIET_CLEAN, core-progs) $(RM) $(ALL_PROGRAMS) perf perf-read-vdso32 perf-read-vdsox32 $(OUTPUT)pmu-events/jevents $(srctree)/tools/perf/pmu-events/pmu-events.c
 	$(call QUIET_CLEAN, core-gen)   $(RM)  *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope* $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)FEATURE-DUMP $(OUTPUT)util/*-bison* $(OUTPUT)util/*-flex* \
 		$(OUTPUT)util/intel-pt-decoder/inat-tables.c $(OUTPUT)fixdep \
-		$(OUTPUT)tests/llvm-src-{base,kbuild,prologue,relocation}.c
+		$(OUTPUT)tests/llvm-src-{base,kbuild,prologue,relocation}.c \
+		$(OUTPUT)pmu-events/pmu-events.c
 	$(QUIET_SUBDIR0)Documentation $(QUIET_SUBDIR1) clean
 	$(python-clean)
 
diff --git a/tools/perf/pmu-events/Build b/tools/perf/pmu-events/Build
new file mode 100644
index 0000000..d2f3430
--- /dev/null
+++ b/tools/perf/pmu-events/Build
@@ -0,0 +1,11 @@
+jevents-y	+= json.o jsmn.o jevents.o
+pmu-events-y	+= pmu-events.o
+JDIR		=  pmu-events/arch/$(ARCH)
+JSON		=  $(shell [ -d $(JDIR) ] &&				\
+			find $(JDIR) -name '*.json' -o -name 'mapfile.csv')
+#
+# Locate/process JSON files in pmu-events/arch/
+# directory and create tables in pmu-events.c.
+#
+$(OUTPUT)pmu-events/pmu-events.c: $(JSON) $(JEVENTS)
+	$(Q)$(call echo-cmd,gen)$(JEVENTS) $(ARCH) pmu-events/arch $(OUTPUT)pmu-events/pmu-events.c $(V)
diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c
new file mode 100644
index 0000000..a9ca86d
--- /dev/null
+++ b/tools/perf/pmu-events/jevents.c
@@ -0,0 +1,766 @@
+#define  _XOPEN_SOURCE 500	/* needed for nftw() */
+
+/* Parse event JSON files */
+
+/*
+ * Copyright (c) 2014, Intel Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <stdarg.h>
+#include <libgen.h>
+#include <dirent.h>
+#include <sys/time.h>			/* getrlimit */
+#include <sys/resource.h>		/* getrlimit */
+#include <ftw.h>
+#include <sys/stat.h>
+#include "jsmn.h"
+#include "json.h"
+#include "jevents.h"
+
+#ifndef __maybe_unused
+#define __maybe_unused                  __attribute__((unused))
+#endif
+
+int verbose;
+char *prog;
+
+int eprintf(int level, int var, const char *fmt, ...)
+{
+
+	int ret;
+	va_list args;
+
+	if (var < level)
+		return 0;
+
+	va_start(args, fmt);
+
+	ret = vfprintf(stderr, fmt, args);
+
+	va_end(args);
+
+	return ret;
+}
+
+__attribute__((weak)) char *get_cpu_str(void)
+{
+	return NULL;
+}
+
+static void addfield(char *map, char **dst, const char *sep,
+		     const char *a, jsmntok_t *bt)
+{
+	unsigned int len = strlen(a) + 1 + strlen(sep);
+	int olen = *dst ? strlen(*dst) : 0;
+	int blen = bt ? json_len(bt) : 0;
+	char *out;
+
+	out = realloc(*dst, len + olen + blen);
+	if (!out) {
+		/* Don't add field in this case */
+		return;
+	}
+	*dst = out;
+
+	if (!olen)
+		*(*dst) = 0;
+	else
+		strcat(*dst, sep);
+	strcat(*dst, a);
+	if (bt)
+		strncat(*dst, map + bt->start, blen);
+}
+
+static void fixname(char *s)
+{
+	for (; *s; s++)
+		*s = tolower(*s);
+}
+
+static void fixdesc(char *s)
+{
+	char *e = s + strlen(s);
+
+	/* Remove trailing dots that look ugly in perf list */
+	--e;
+	while (e >= s && isspace(*e))
+		--e;
+	if (*e == '.')
+		*e = 0;
+}
+
+static struct msrmap {
+	const char *num;
+	const char *pname;
+} msrmap[] = {
+	{ "0x3F6", "ldlat=" },
+	{ "0x1A6", "offcore_rsp=" },
+	{ "0x1A7", "offcore_rsp=" },
+	{ NULL, NULL }
+};
+
+static struct field {
+	const char *field;
+	const char *kernel;
+} fields[] = {
+	{ "EventCode",	"event=" },
+	{ "UMask",	"umask=" },
+	{ "CounterMask", "cmask=" },
+	{ "Invert",	"inv=" },
+	{ "AnyThread",	"any=" },
+	{ "EdgeDetect",	"edge=" },
+	{ "SampleAfterValue", "period=" },
+	{ NULL, NULL }
+};
+
+static void cut_comma(char *map, jsmntok_t *newval)
+{
+	int i;
+
+	/* Cut off everything after comma */
+	for (i = newval->start; i < newval->end; i++) {
+		if (map[i] == ',')
+			newval->end = i;
+	}
+}
+
+static int match_field(char *map, jsmntok_t *field, int nz,
+		       char **event, jsmntok_t *val)
+{
+	struct field *f;
+	jsmntok_t newval = *val;
+
+	for (f = fields; f->field; f++)
+		if (json_streq(map, field, f->field) && nz) {
+			cut_comma(map, &newval);
+			addfield(map, event, ",", f->kernel, &newval);
+			return 1;
+		}
+	return 0;
+}
+
+static struct msrmap *lookup_msr(char *map, jsmntok_t *val)
+{
+	jsmntok_t newval = *val;
+	static bool warned;
+	int i;
+
+	cut_comma(map, &newval);
+	for (i = 0; msrmap[i].num; i++)
+		if (json_streq(map, &newval, msrmap[i].num))
+			return &msrmap[i];
+	if (!warned) {
+		warned = true;
+		pr_err("%s: Unknown MSR in event file %.*s\n", prog,
+			json_len(val), map + val->start);
+	}
+	return NULL;
+}
+
+#define EXPECT(e, t, m) do { if (!(e)) {			\
+	jsmntok_t *loc = (t);					\
+	if (!(t)->start && (t) > tokens)			\
+		loc = (t) - 1;					\
+		pr_err("%s:%d: " m ", got %s\n", fn,		\
+			json_line(map, loc),			\
+			json_name(t));				\
+	goto out_free;						\
+} } while (0)
+
+#define TOPIC_DEPTH 256
+static char *topic_array[TOPIC_DEPTH];
+static int   topic_level;
+
+static char *get_topic(void)
+{
+	char *tp_old, *tp = NULL;
+	int i;
+
+	for (i = 0; i < topic_level + 1; i++) {
+		int n;
+
+		tp_old = tp;
+		n = asprintf(&tp, "%s%s", tp ?: "", topic_array[i]);
+		if (n < 0) {
+			pr_info("%s: asprintf() error %s\n", prog);
+			return NULL;
+		}
+		free(tp_old);
+	}
+
+	for (i = 0; i < (int) strlen(tp); i++) {
+		char c = tp[i];
+
+		if (c == '-')
+			tp[i] = ' ';
+		else if (c == '.') {
+			tp[i] = '\0';
+			break;
+		}
+	}
+
+	return tp;
+}
+
+static int add_topic(int level, char *bname)
+{
+	char *topic;
+
+	level -= 2;
+
+	if (level >= TOPIC_DEPTH)
+		return -EINVAL;
+
+	topic = strdup(bname);
+	if (!topic) {
+		pr_info("%s: strdup() error %s for file %s\n", prog,
+				strerror(errno), bname);
+		return -ENOMEM;
+	}
+
+	free(topic_array[topic_level]);
+	topic_array[topic_level] = topic;
+	topic_level              = level;
+	return 0;
+}
+
+struct perf_entry_data {
+	FILE *outfp;
+	char *topic;
+};
+
+static int close_table;
+
+static void print_events_table_prefix(FILE *fp, const char *tblname)
+{
+	fprintf(fp, "struct pmu_event %s[] = {\n", tblname);
+	close_table = 1;
+}
+
+static int print_events_table_entry(void *data, char *name, char *event,
+				    char *desc)
+{
+	struct perf_entry_data *pd = data;
+	FILE *outfp = pd->outfp;
+	char *topic = pd->topic;
+
+	/*
+	 * TODO: Remove formatting chars after debugging to reduce
+	 *	 string lengths.
+	 */
+	fprintf(outfp, "{\n");
+
+	fprintf(outfp, "\t.name = \"%s\",\n", name);
+	fprintf(outfp, "\t.event = \"%s\",\n", event);
+	fprintf(outfp, "\t.desc = \"%s\",\n", desc);
+	fprintf(outfp, "\t.topic = \"%s\",\n", topic);
+
+	fprintf(outfp, "},\n");
+
+	return 0;
+}
+
+static void print_events_table_suffix(FILE *outfp)
+{
+	fprintf(outfp, "{\n");
+
+	fprintf(outfp, "\t.name = 0,\n");
+	fprintf(outfp, "\t.event = 0,\n");
+	fprintf(outfp, "\t.desc = 0,\n");
+
+	fprintf(outfp, "},\n");
+	fprintf(outfp, "};\n");
+	close_table = 0;
+}
+
+/* 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),
+	  void *data)
+{
+	int err = -EIO;
+	size_t size;
+	jsmntok_t *tokens, *tok;
+	int i, j, len;
+	char *map;
+
+	if (!fn)
+		return -ENOENT;
+
+	tokens = parse_json(fn, &map, &size, &len);
+	if (!tokens)
+		return -EIO;
+	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;
+		struct msrmap *msr = NULL;
+		jsmntok_t *msrval = NULL;
+		jsmntok_t *precise = NULL;
+		jsmntok_t *obj = tok++;
+
+		EXPECT(obj->type == JSMN_OBJECT, obj, "expected object");
+		for (j = 0; j < obj->size; j += 2) {
+			jsmntok_t *field, *val;
+			int nz;
+
+			field = tok + j;
+			EXPECT(field->type == JSMN_STRING, tok + j,
+			       "Expected field name");
+			val = tok + j + 1;
+			EXPECT(val->type == JSMN_STRING, tok + j + 1,
+			       "Expected string value");
+
+			nz = !json_streq(map, val, "0");
+			if (match_field(map, field, nz, &event, val)) {
+				/* ok */
+			} else if (json_streq(map, field, "EventName")) {
+				addfield(map, &name, "", "", val);
+			} else if (json_streq(map, field, "BriefDescription")) {
+				addfield(map, &desc, "", "", val);
+				fixdesc(desc);
+			} else if (json_streq(map, field, "PEBS") && nz) {
+				precise = val;
+			} else if (json_streq(map, field, "MSRIndex") && nz) {
+				msr = lookup_msr(map, val);
+			} else if (json_streq(map, field, "MSRValue")) {
+				msrval = val;
+			} else if (json_streq(map, field, "Errata") &&
+				   !json_streq(map, val, "null")) {
+				addfield(map, &desc, ". ",
+					" Spec update: ", val);
+			} else if (json_streq(map, field, "Data_LA") && nz) {
+				addfield(map, &desc, ". ",
+					" Supports address when precise",
+					NULL);
+			}
+			/* ignore unknown fields */
+		}
+		if (precise && desc && !strstr(desc, "(Precise Event)")) {
+			if (json_streq(map, precise, "2"))
+				addfield(map, &desc, " ", "(Must be precise)",
+						NULL);
+			else
+				addfield(map, &desc, " ",
+						"(Precise event)", NULL);
+		}
+		if (msr != NULL)
+			addfield(map, &event, ",", msr->pname, msrval);
+		fixname(name);
+		err = func(data, name, event, desc);
+		free(event);
+		free(desc);
+		free(name);
+		if (err)
+			break;
+		tok += j;
+	}
+	EXPECT(tok - tokens == len, tok, "unexpected objects at end");
+	err = 0;
+out_free:
+	free_json(map, size, tokens);
+	return err;
+}
+
+static char *file_name_to_table_name(char *fname)
+{
+	unsigned int i;
+	int n;
+	int c;
+	char *tblname;
+
+	/*
+	 * Ensure tablename starts with alphabetic character.
+	 * Derive rest of table name from basename of the JSON file,
+	 * replacing hyphens and stripping out .json suffix.
+	 */
+	n = asprintf(&tblname, "pme_%s", basename(fname));
+	if (n < 0) {
+		pr_info("%s: asprintf() error %s for file %s\n", prog,
+				strerror(errno), fname);
+		return NULL;
+	}
+
+	for (i = 0; i < strlen(tblname); i++) {
+		c = tblname[i];
+
+		if (c == '-')
+			tblname[i] = '_';
+		else if (c == '.') {
+			tblname[i] = '\0';
+			break;
+		} else if (!isalnum(c) && c != '_') {
+			pr_err("%s: Invalid character '%c' in file name %s\n",
+					prog, c, basename(fname));
+			free(tblname);
+			tblname = NULL;
+			break;
+		}
+	}
+
+	return tblname;
+}
+
+static void print_mapping_table_prefix(FILE *outfp)
+{
+	fprintf(outfp, "struct pmu_events_map pmu_events_map[] = {\n");
+}
+
+static void print_mapping_table_suffix(FILE *outfp)
+{
+	/*
+	 * Print the terminating, NULL entry.
+	 */
+	fprintf(outfp, "{\n");
+	fprintf(outfp, "\t.cpuid = 0,\n");
+	fprintf(outfp, "\t.version = 0,\n");
+	fprintf(outfp, "\t.type = 0,\n");
+	fprintf(outfp, "\t.table = 0,\n");
+	fprintf(outfp, "},\n");
+
+	/* and finally, the closing curly bracket for the struct */
+	fprintf(outfp, "};\n");
+}
+
+static int process_mapfile(FILE *outfp, char *fpath)
+{
+	int n = 16384;
+	FILE *mapfp;
+	char *save = NULL;
+	char *line, *p;
+	int line_num;
+	char *tblname;
+
+	pr_info("%s: Processing mapfile %s\n", prog, fpath);
+
+	line = malloc(n);
+	if (!line)
+		return -1;
+
+	mapfp = fopen(fpath, "r");
+	if (!mapfp) {
+		pr_info("%s: Error %s opening %s\n", prog, strerror(errno),
+				fpath);
+		return -1;
+	}
+
+	print_mapping_table_prefix(outfp);
+
+	line_num = 0;
+	while (1) {
+		char *cpuid, *version, *type, *fname;
+
+		line_num++;
+		p = fgets(line, n, mapfp);
+		if (!p)
+			break;
+
+		if (line[0] == '#' || line[0] == '\n')
+			continue;
+
+		if (line[strlen(line)-1] != '\n') {
+			/* TODO Deal with lines longer than 16K */
+			pr_info("%s: Mapfile %s: line %d too long, aborting\n",
+					prog, fpath, line_num);
+			return -1;
+		}
+		line[strlen(line)-1] = '\0';
+
+		cpuid = strtok_r(p, ",", &save);
+		version = strtok_r(NULL, ",", &save);
+		fname = strtok_r(NULL, ",", &save);
+		type = strtok_r(NULL, ",", &save);
+
+		tblname = file_name_to_table_name(fname);
+		fprintf(outfp, "{\n");
+		fprintf(outfp, "\t.cpuid = \"%s\",\n", cpuid);
+		fprintf(outfp, "\t.version = \"%s\",\n", version);
+		fprintf(outfp, "\t.type = \"%s\",\n", type);
+
+		/*
+		 * CHECK: We can't use the type (eg "core") field in the
+		 * table name. For us to do that, we need to somehow tweak
+		 * the other caller of file_name_to_table(), process_json()
+		 * to determine the type. process_json() file has no way
+		 * of knowing these are "core" events unless file name has
+		 * core in it. If filename has core in it, we can safely
+		 * ignore the type field here also.
+		 */
+		fprintf(outfp, "\t.table = %s\n", tblname);
+		fprintf(outfp, "},\n");
+	}
+
+	print_mapping_table_suffix(outfp);
+
+	return 0;
+}
+
+/*
+ * If we fail to locate/process JSON and map files, create a NULL mapping
+ * table. This would at least allow perf to build even if we can't find/use
+ * the aliases.
+ */
+static void create_empty_mapping(const char *output_file)
+{
+	FILE *outfp;
+
+	pr_info("%s: Creating empty pmu_events_map[] table\n", prog);
+
+	/* Truncate file to clear any partial writes to it */
+	outfp = fopen(output_file, "w");
+	if (!outfp) {
+		perror("fopen()");
+		_Exit(1);
+	}
+
+	fprintf(outfp, "#include \"../../pmu-events/pmu-events.h\"\n");
+	print_mapping_table_prefix(outfp);
+	print_mapping_table_suffix(outfp);
+	fclose(outfp);
+}
+
+static int get_maxfds(void)
+{
+	struct rlimit rlim;
+
+	if (getrlimit(RLIMIT_NOFILE, &rlim) == 0)
+		return rlim.rlim_max;
+
+	return 512;
+}
+
+/*
+ * nftw() doesn't let us pass an argument to the processing function,
+ * so use a global variables.
+ */
+static FILE *eventsfp;
+static char *mapfile;
+
+static int process_one_file(const char *fpath, const struct stat *sb,
+			    int typeflag, struct FTW *ftwbuf)
+{
+	char *tblname, *bname  = (char *) fpath + ftwbuf->base;
+	int is_dir  = typeflag == FTW_D;
+	int is_file = typeflag == FTW_F;
+	int level   = ftwbuf->level;
+	int err = 0;
+
+	pr_debug("%s %d %7jd %-20s %s\n",
+		 is_file ? "f" : is_dir ? "d" : "x",
+		 level, sb->st_size, bname, fpath);
+
+	/* base dir */
+	if (level == 0)
+		return 0;
+
+	/* model directory, reset topic */
+	if (level == 1 && is_dir) {
+		if (close_table)
+			print_events_table_suffix(eventsfp);
+
+		/*
+		 * Drop file name suffix. Replace hyphens with underscores.
+		 * Fail if file name contains any alphanum characters besides
+		 * underscores.
+		 */
+		tblname = file_name_to_table_name(bname);
+		if (!tblname) {
+			pr_info("%s: Error determining table name for %s\n", prog,
+				bname);
+			return -1;
+		}
+
+		print_events_table_prefix(eventsfp, tblname);
+		return 0;
+	}
+
+	/*
+	 * Save the mapfile name for now. We will process mapfile
+	 * after processing all JSON files (so we can write out the
+	 * mapping table after all PMU events tables).
+	 *
+	 * TODO: Allow for multiple mapfiles? Punt for now.
+	 */
+	if (level == 1 && is_file) {
+		if (!strncmp(bname, "mapfile.csv", 11)) {
+			if (mapfile) {
+				pr_info("%s: Many mapfiles? Using %s, ignoring %s\n",
+						prog, mapfile, fpath);
+			} else {
+				mapfile = strdup(fpath);
+			}
+			return 0;
+		}
+
+		pr_info("%s: Ignoring file %s\n", prog, fpath);
+		return 0;
+	}
+
+	/*
+	 * If the file name does not have a .json extension,
+	 * ignore it. It could be a readme.txt for instance.
+	 */
+	if (is_file) {
+		char *suffix = bname + strlen(bname) - 5;
+
+		if (strncmp(suffix, ".json", 5)) {
+			pr_info("%s: Ignoring file without .json suffix %s\n", prog,
+				fpath);
+			return 0;
+		}
+	}
+
+	if (level > 1 && add_topic(level, bname))
+		return -ENOMEM;
+
+	/*
+	 * Assume all other files are JSON files.
+	 *
+	 * If mapfile refers to 'power7_core.json', we create a table
+	 * named 'power7_core'. Any inconsistencies between the mapfile
+	 * and directory tree could result in build failure due to table
+	 * names not being found.
+	 *
+	 * Atleast for now, be strict with processing JSON file names.
+	 * i.e. if JSON file name cannot be mapped to C-style table name,
+	 * fail.
+	 */
+	if (is_file) {
+		struct perf_entry_data data = {
+			.topic = get_topic(),
+			.outfp = eventsfp,
+		};
+
+		err = json_events(fpath, print_events_table_entry, &data);
+
+		free(data.topic);
+	}
+
+	return err;
+}
+
+#ifndef PATH_MAX
+#define PATH_MAX	4096
+#endif
+
+/*
+ * Starting in directory 'start_dirname', find the "mapfile.csv" and
+ * the set of JSON files for the architecture 'arch'.
+ *
+ * From each JSON file, create a C-style "PMU events table" from the
+ * JSON file (see struct pmu_event).
+ *
+ * From the mapfile, create a mapping between the CPU revisions and
+ * PMU event tables (see struct pmu_events_map).
+ *
+ * Write out the PMU events tables and the mapping table to pmu-event.c.
+ *
+ * If unable to process the JSON or arch files, create an empty mapping
+ * table so we can continue to build/use  perf even if we cannot use the
+ * PMU event aliases.
+ */
+int main(int argc, char *argv[])
+{
+	int rc;
+	int maxfds;
+	char ldirname[PATH_MAX];
+
+	const char *arch;
+	const char *output_file;
+	const char *start_dirname;
+
+	prog = basename(argv[0]);
+	if (argc < 4) {
+		pr_err("Usage: %s <arch> <starting_dir> <output_file>\n", prog);
+		return 1;
+	}
+
+	arch = argv[1];
+	start_dirname = argv[2];
+	output_file = argv[3];
+
+	if (argc > 4)
+		verbose = atoi(argv[4]);
+
+	eventsfp = fopen(output_file, "w");
+	if (!eventsfp) {
+		pr_err("%s Unable to create required file %s (%s)\n",
+				prog, output_file, strerror(errno));
+		return 2;
+	}
+
+	/* Include pmu-events.h first */
+	fprintf(eventsfp, "#include \"../../pmu-events/pmu-events.h\"\n");
+
+	sprintf(ldirname, "%s/%s", start_dirname, arch);
+
+	/*
+	 * The mapfile allows multiple CPUids to point to the same JSON file,
+	 * so, not sure if there is a need for symlinks within the pmu-events
+	 * directory.
+	 *
+	 * For now, treat symlinks of JSON files as regular files and create
+	 * separate tables for each symlink (presumably, each symlink refers
+	 * to specific version of the CPU).
+	 */
+
+	maxfds = get_maxfds();
+	mapfile = NULL;
+	rc = nftw(ldirname, process_one_file, maxfds, 0);
+	if (rc && verbose) {
+		pr_info("%s: Error walking file tree %s\n", prog, ldirname);
+		goto empty_map;
+	} else if (rc) {
+		goto empty_map;
+	}
+
+	if (close_table)
+		print_events_table_suffix(eventsfp);
+
+	if (!mapfile) {
+		pr_info("%s: No CPU->JSON mapping?\n", prog);
+		goto empty_map;
+	}
+
+	if (process_mapfile(eventsfp, mapfile)) {
+		pr_info("%s: Error processing mapfile %s\n", prog, mapfile);
+		goto empty_map;
+	}
+
+	return 0;
+
+empty_map:
+	fclose(eventsfp);
+	create_empty_mapping(output_file);
+	return 0;
+}
diff --git a/tools/perf/pmu-events/jevents.h b/tools/perf/pmu-events/jevents.h
new file mode 100644
index 0000000..996601f
--- /dev/null
+++ b/tools/perf/pmu-events/jevents.h
@@ -0,0 +1,17 @@
+#ifndef JEVENTS_H
+#define JEVENTS_H 1
+
+int json_events(const char *fn,
+		int (*func)(void *data, char *name, char *event, char *desc),
+		void *data);
+char *get_cpu_str(void);
+
+#ifndef min
+#define min(x, y) ({                            \
+	typeof(x) _min1 = (x);                  \
+	typeof(y) _min2 = (y);                  \
+	(void) (&_min1 == &_min2);              \
+	_min1 < _min2 ? _min1 : _min2; })
+#endif
+
+#endif
diff --git a/tools/perf/pmu-events/json.h b/tools/perf/pmu-events/json.h
index 6b8337e..5339704 100644
--- a/tools/perf/pmu-events/json.h
+++ b/tools/perf/pmu-events/json.h
@@ -24,6 +24,12 @@ extern int eprintf(int level, int var, const char *fmt, ...);
 #define pr_err(fmt, ...) \
 	eprintf(0, verbose, pr_fmt(fmt), ##__VA_ARGS__)
 
+#define pr_info(fmt, ...) \
+	eprintf(1, verbose, pr_fmt(fmt), ##__VA_ARGS__)
+
+#define pr_debug(fmt, ...) \
+	eprintf(2, verbose, pr_fmt(fmt), ##__VA_ARGS__)
+
 #ifndef roundup
 #define roundup(x, y) (                                \
 {                                                      \
diff --git a/tools/perf/pmu-events/pmu-events.h b/tools/perf/pmu-events/pmu-events.h
new file mode 100644
index 0000000..70d5479
--- /dev/null
+++ b/tools/perf/pmu-events/pmu-events.h
@@ -0,0 +1,36 @@
+#ifndef PMU_EVENTS_H
+#define PMU_EVENTS_H
+
+/*
+ * Describe each PMU event. Each CPU has a table of PMU events.
+ */
+struct pmu_event {
+	const char *name;
+	const char *event;
+	const char *desc;
+	const char *topic;
+};
+
+/*
+ *
+ * Map a CPU to its table of PMU events. The CPU is identified by the
+ * cpuid field, which is an arch-specific identifier for the CPU.
+ * The identifier specified in tools/perf/pmu-events/arch/xxx/mapfile
+ * must match the get_cpustr() in tools/perf/arch/xxx/util/header.c)
+ *
+ * The  cpuid can contain any character other than the comma.
+ */
+struct pmu_events_map {
+	const char *cpuid;
+	const char *version;
+	const char *type;		/* core, uncore etc */
+	struct pmu_event *table;
+};
+
+/*
+ * Global table mapping each known CPU for the architecture to its
+ * table of PMU events.
+ */
+extern struct pmu_events_map pmu_events_map[];
+
+#endif
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH v21 03/19] perf, tools: Use pmu_events table to create aliases
  2016-09-15 22:24 [PATCH v21 00/20] perf, tools: Add support for PMU events in JSON format Sukadev Bhattiprolu
  2016-09-15 22:24 ` [PATCH v21 01/19] perf, tools: Add jsmn `jasmine' JSON parser Sukadev Bhattiprolu
  2016-09-15 22:24 ` [PATCH v21 02/19] perf, tools, jevents: Program to convert JSON file to C style file Sukadev Bhattiprolu
@ 2016-09-15 22:24 ` Sukadev Bhattiprolu
  2016-09-27 13:16   ` Arnaldo Carvalho de Melo
  2016-10-04  8:12   ` [tip:perf/urgent] perf pmu: " tip-bot for Sukadev Bhattiprolu
  2016-09-15 22:24 ` [PATCH v21 04/19] perf, tools: Support CPU ID matching for Powerpc Sukadev Bhattiprolu
                   ` (17 subsequent siblings)
  20 siblings, 2 replies; 70+ messages in thread
From: Sukadev Bhattiprolu @ 2016-09-15 22:24 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo; +Cc: peterz, maddy, linuxppc-dev, linux-kernel

At run time (when 'perf' is starting up), locate the specific table
of PMU events that corresponds to the current CPU. Using that table,
create aliases for the each of the PMU events in the CPU. The use
these aliases to parse the user specified perf event.

In short this would allow the user to specify events using their
aliases rather than raw event codes.

Based on input and some earlier patches from Andi Kleen, Jiri Olsa.

Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Acked-by: Jiri Olsa <jolsa@redhat.com>
Acked-by: Ingo Molnar <mingo@kernel.org>
---

Changelog[v4]
	- Split off unrelated code into separate patches.
Changelog[v3]
	- [Jiri Olsa] Fix memory leak in cpuid
Changelog[v2]
	- [Andi Kleen] Replace pmu_events_map->vfm with a generic "cpuid".
---
 tools/perf/util/header.h |  1 +
 tools/perf/util/pmu.c    | 61 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 62 insertions(+)

diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h
index d306ca1..d30109b 100644
--- a/tools/perf/util/header.h
+++ b/tools/perf/util/header.h
@@ -151,4 +151,5 @@ int write_padded(int fd, const void *bf, size_t count, size_t count_aligned);
  */
 int get_cpuid(char *buffer, size_t sz);
 
+char *get_cpuid_str(void);
 #endif /* __PERF_HEADER_H */
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index 2babcdf..c842886 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -12,6 +12,8 @@
 #include "pmu.h"
 #include "parse-events.h"
 #include "cpumap.h"
+#include "header.h"
+#include "pmu-events/pmu-events.h"
 
 struct perf_pmu_format {
 	char *name;
@@ -473,6 +475,62 @@ static struct cpu_map *pmu_cpumask(const char *name)
 	return cpus;
 }
 
+/*
+ * Return the CPU id as a raw string.
+ *
+ * Each architecture should provide a more precise id string that
+ * can be use to match the architecture's "mapfile".
+ */
+char * __weak get_cpuid_str(void)
+{
+	return NULL;
+}
+
+/*
+ * From the pmu_events_map, find the table of PMU events that corresponds
+ * to the current running CPU. Then, add all PMU events from that table
+ * as aliases.
+ */
+static int pmu_add_cpu_aliases(struct list_head *head)
+{
+	int i;
+	struct pmu_events_map *map;
+	struct pmu_event *pe;
+	char *cpuid;
+
+	cpuid = get_cpuid_str();
+	if (!cpuid)
+		return 0;
+
+	i = 0;
+	while (1) {
+		map = &pmu_events_map[i++];
+		if (!map->table)
+			goto out;
+
+		if (!strcmp(map->cpuid, cpuid))
+			break;
+	}
+
+	/*
+	 * Found a matching PMU events table. Create aliases
+	 */
+	i = 0;
+	while (1) {
+		pe = &map->table[i++];
+		if (!pe->name)
+			break;
+
+		/* need type casts to override 'const' */
+		__perf_pmu__new_alias(head, NULL, (char *)pe->name,
+				(char *)pe->desc, (char *)pe->event);
+	}
+
+out:
+	free(cpuid);
+	return 0;
+}
+
 struct perf_event_attr * __weak
 perf_pmu__get_default_config(struct perf_pmu *pmu __maybe_unused)
 {
@@ -497,6 +555,9 @@ static struct perf_pmu *pmu_lookup(const char *name)
 	if (pmu_aliases(name, &aliases))
 		return NULL;
 
+	if (!strcmp(name, "cpu"))
+		(void)pmu_add_cpu_aliases(&aliases);
+
 	if (pmu_type(name, &type))
 		return NULL;
 
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH v21 04/19] perf, tools: Support CPU ID matching for Powerpc
  2016-09-15 22:24 [PATCH v21 00/20] perf, tools: Add support for PMU events in JSON format Sukadev Bhattiprolu
                   ` (2 preceding siblings ...)
  2016-09-15 22:24 ` [PATCH v21 03/19] perf, tools: Use pmu_events table to create aliases Sukadev Bhattiprolu
@ 2016-09-15 22:24 ` Sukadev Bhattiprolu
  2016-10-04  8:13   ` [tip:perf/urgent] perf powerpc: " tip-bot for Sukadev Bhattiprolu
  2016-09-15 22:24 ` [PATCH v21 05/19] perf, tools: Support CPU id matching for x86 v2 Sukadev Bhattiprolu
                   ` (16 subsequent siblings)
  20 siblings, 1 reply; 70+ messages in thread
From: Sukadev Bhattiprolu @ 2016-09-15 22:24 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo; +Cc: peterz, maddy, linuxppc-dev, linux-kernel

Implement code that returns the generic CPU ID string for Powerpc.
This will be used to identify the specific table of PMU events to
parse/compare user specified events against.

Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Acked-by: Jiri Olsa <jolsa@redhat.com>
Acked-by: Ingo Molnar <mingo@kernel.org>
---

Changelog[v14]
	- [Jiri Olsa] Move this independent code off into a separate patch.
---
 tools/perf/arch/powerpc/util/header.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/tools/perf/arch/powerpc/util/header.c b/tools/perf/arch/powerpc/util/header.c
index f8ccee1..9aaa6f5 100644
--- a/tools/perf/arch/powerpc/util/header.c
+++ b/tools/perf/arch/powerpc/util/header.c
@@ -32,3 +32,14 @@ get_cpuid(char *buffer, size_t sz)
 	}
 	return -1;
 }
+
+char *
+get_cpuid_str(void)
+{
+	char *bufp;
+
+	if (asprintf(&bufp, "%.8lx", mfspr(SPRN_PVR)) < 0)
+		bufp = NULL;
+
+	return bufp;
+}
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH v21 05/19] perf, tools: Support CPU id matching for x86 v2
  2016-09-15 22:24 [PATCH v21 00/20] perf, tools: Add support for PMU events in JSON format Sukadev Bhattiprolu
                   ` (3 preceding siblings ...)
  2016-09-15 22:24 ` [PATCH v21 04/19] perf, tools: Support CPU ID matching for Powerpc Sukadev Bhattiprolu
@ 2016-09-15 22:24 ` Sukadev Bhattiprolu
  2016-10-04  8:13   ` [tip:perf/urgent] perf " tip-bot for Andi Kleen
  2016-09-15 22:24 ` [PATCH v21 06/19] perf, tools: Support alias descriptions Sukadev Bhattiprolu
                   ` (15 subsequent siblings)
  20 siblings, 1 reply; 70+ messages in thread
From: Sukadev Bhattiprolu @ 2016-09-15 22:24 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo; +Cc: peterz, maddy, linuxppc-dev, linux-kernel

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

Implement the code to match CPU types to mapfile types for x86
based on CPUID. This extends an existing similar function,
but changes it to use the x86 mapfile cpu description.
This allows to resolve event lists generated by jevents.

Signed-off-by: Andi Kleen <ak@linux.intel.com>
Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Acked-by: Jiri Olsa <jolsa@redhat.com>
Acked-by: Ingo Molnar <mingo@kernel.org>
---

v2: Update to new get_cpuid_str() interface
---
 tools/perf/arch/x86/util/header.c | 24 +++++++++++++++++++++---
 1 file changed, 21 insertions(+), 3 deletions(-)

diff --git a/tools/perf/arch/x86/util/header.c b/tools/perf/arch/x86/util/header.c
index 146d12a..a74a48d 100644
--- a/tools/perf/arch/x86/util/header.c
+++ b/tools/perf/arch/x86/util/header.c
@@ -19,8 +19,8 @@ cpuid(unsigned int op, unsigned int *a, unsigned int *b, unsigned int *c,
 			: "a" (op));
 }
 
-int
-get_cpuid(char *buffer, size_t sz)
+static int
+__get_cpuid(char *buffer, size_t sz, const char *fmt)
 {
 	unsigned int a, b, c, d, lvl;
 	int family = -1, model = -1, step = -1;
@@ -48,7 +48,7 @@ get_cpuid(char *buffer, size_t sz)
 		if (family >= 0x6)
 			model += ((a >> 16) & 0xf) << 4;
 	}
-	nb = scnprintf(buffer, sz, "%s,%u,%u,%u$", vendor, family, model, step);
+	nb = scnprintf(buffer, sz, fmt, vendor, family, model, step);
 
 	/* look for end marker to ensure the entire data fit */
 	if (strchr(buffer, '$')) {
@@ -57,3 +57,21 @@ get_cpuid(char *buffer, size_t sz)
 	}
 	return -1;
 }
+
+int
+get_cpuid(char *buffer, size_t sz)
+{
+	return __get_cpuid(buffer, sz, "%s,%u,%u,%u$");
+}
+
+char *
+get_cpuid_str(void)
+{
+	char *buf = malloc(128);
+
+	if (__get_cpuid(buf, 128, "%s-%u-%X$") < 0) {
+		free(buf);
+		return NULL;
+	}
+	return buf;
+}
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH v21 06/19] perf, tools: Support alias descriptions
  2016-09-15 22:24 [PATCH v21 00/20] perf, tools: Add support for PMU events in JSON format Sukadev Bhattiprolu
                   ` (4 preceding siblings ...)
  2016-09-15 22:24 ` [PATCH v21 05/19] perf, tools: Support CPU id matching for x86 v2 Sukadev Bhattiprolu
@ 2016-09-15 22:24 ` Sukadev Bhattiprolu
  2016-09-27 17:41   ` Arnaldo Carvalho de Melo
  2016-10-04  8:14   ` [tip:perf/urgent] perf pmu: " tip-bot for Andi Kleen
  2016-09-15 22:24 ` [PATCH v21 07/19] perf, tools: Query terminal width and use in perf list Sukadev Bhattiprolu
                   ` (14 subsequent siblings)
  20 siblings, 2 replies; 70+ messages in thread
From: Sukadev Bhattiprolu @ 2016-09-15 22:24 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo; +Cc: peterz, maddy, linuxppc-dev, linux-kernel

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]

Signed-off-by: Andi Kleen <ak@linux.intel.com>
Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Acked-by: Jiri Olsa <jolsa@redhat.com>
Acked-by: Ingo Molnar <mingo@kernel.org>
---

Changelog
	- Delete a redundant free()

Changelog[v14]
	- [Jiri Olsa] Fail, rather than continue if strdup() returns NULL;
	  remove unnecessary __maybe_unused.
---
 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 c842886..af1a612 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;
@@ -1044,11 +1046,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)
@@ -1058,7 +1091,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;
@@ -1068,14 +1103,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 &&
@@ -1084,12 +1120,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 &&
@@ -1097,25 +1140,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 5d7e844..11bda57 100644
--- a/tools/perf/util/pmu.h
+++ b/tools/perf/util/pmu.h
@@ -38,6 +38,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];
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH v21 07/19] perf, tools: Query terminal width and use in perf list
  2016-09-15 22:24 [PATCH v21 00/20] perf, tools: Add support for PMU events in JSON format Sukadev Bhattiprolu
                   ` (5 preceding siblings ...)
  2016-09-15 22:24 ` [PATCH v21 06/19] perf, tools: Support alias descriptions Sukadev Bhattiprolu
@ 2016-09-15 22:24 ` Sukadev Bhattiprolu
  2016-10-04  8:14   ` [tip:perf/urgent] perf " tip-bot for Andi Kleen
  2016-09-15 22:24 ` [PATCH v21 08/19] perf, tools: Add a --no-desc flag to " Sukadev Bhattiprolu
                   ` (13 subsequent siblings)
  20 siblings, 1 reply; 70+ messages in thread
From: Sukadev Bhattiprolu @ 2016-09-15 22:24 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo; +Cc: peterz, maddy, linuxppc-dev, linux-kernel

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

Automatically adapt the now wider and word wrapped perf list
output to wider terminals. This requires querying the terminal
before the auto pager takes over, and exporting this
information from the pager subsystem.

Signed-off-by: Andi Kleen <ak@linux.intel.com>
Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Acked-by: Namhyung Kim <namhyung@kernel.org>
Acked-by: Jiri Olsa <jolsa@redhat.com>
Acked-by: Ingo Molnar <mingo@kernel.org>
---

Changelog[v20]
	- Minor reorg since helpers like setup_pager() are now in
	  tools/lib/subcmd/pager.c
---
 tools/lib/subcmd/pager.c | 16 ++++++++++++++++
 tools/lib/subcmd/pager.h |  1 +
 tools/perf/util/pmu.c    |  3 ++-
 3 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/tools/lib/subcmd/pager.c b/tools/lib/subcmd/pager.c
index d50f3b58..6518bea 100644
--- a/tools/lib/subcmd/pager.c
+++ b/tools/lib/subcmd/pager.c
@@ -3,6 +3,7 @@
 #include <stdio.h>
 #include <string.h>
 #include <signal.h>
+#include <sys/ioctl.h>
 #include "pager.h"
 #include "run-command.h"
 #include "sigchain.h"
@@ -14,6 +15,7 @@
  */
 
 static int spawned_pager;
+static int pager_columns;
 
 void pager_init(const char *pager_env)
 {
@@ -58,9 +60,12 @@ static void wait_for_pager_signal(int signo)
 void setup_pager(void)
 {
 	const char *pager = getenv(subcmd_config.pager_env);
+	struct winsize sz;
 
 	if (!isatty(1))
 		return;
+	if (ioctl(1, TIOCGWINSZ, &sz) == 0)
+		pager_columns = sz.ws_col;
 	if (!pager)
 		pager = getenv("PAGER");
 	if (!(pager || access("/usr/bin/pager", X_OK)))
@@ -98,3 +103,14 @@ int pager_in_use(void)
 {
 	return spawned_pager;
 }
+
+int pager_get_columns(void)
+{
+	char *s;
+
+	s = getenv("COLUMNS");
+	if (s)
+		return atoi(s);
+
+	return (pager_columns ? pager_columns : 80) - 2;
+}
diff --git a/tools/lib/subcmd/pager.h b/tools/lib/subcmd/pager.h
index 8b83714..623f554 100644
--- a/tools/lib/subcmd/pager.h
+++ b/tools/lib/subcmd/pager.h
@@ -5,5 +5,6 @@ extern void pager_init(const char *pager_env);
 
 extern void setup_pager(void);
 extern int pager_in_use(void);
+extern int pager_get_columns(void);
 
 #endif /* __SUBCMD_PAGER_H */
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index af1a612..ef9de3e 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -14,6 +14,7 @@
 #include "cpumap.h"
 #include "header.h"
 #include "pmu-events/pmu-events.h"
+#include "cache.h"
 
 struct perf_pmu_format {
 	char *name;
@@ -1093,7 +1094,7 @@ void print_pmu_events(const char *event_glob, bool name_only)
 	int len, j;
 	struct pair *aliases;
 	int numdesc = 0;
-	int columns = 78;
+	int columns = pager_get_columns();
 
 	pmu = NULL;
 	len = 0;
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH v21 08/19] perf, tools: Add a --no-desc flag to perf list
  2016-09-15 22:24 [PATCH v21 00/20] perf, tools: Add support for PMU events in JSON format Sukadev Bhattiprolu
                   ` (6 preceding siblings ...)
  2016-09-15 22:24 ` [PATCH v21 07/19] perf, tools: Query terminal width and use in perf list Sukadev Bhattiprolu
@ 2016-09-15 22:24 ` Sukadev Bhattiprolu
  2016-10-04  8:15   ` [tip:perf/urgent] perf list: Add a --no-desc flag tip-bot for Andi Kleen
  2016-09-15 22:24 ` [PATCH v21 09/19] perf, tools: Add override support for event list CPUID Sukadev Bhattiprolu
                   ` (12 subsequent siblings)
  20 siblings, 1 reply; 70+ messages in thread
From: Sukadev Bhattiprolu @ 2016-09-15 22:24 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo; +Cc: peterz, maddy, linuxppc-dev, linux-kernel

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

Add a --no-desc flag to perf list to not print the event descriptions
that were earlier added for JSON events. This may be useful to
get a less crowded listing.

It's still default to print descriptions as that is the more useful
default for most users.

Signed-off-by: Andi Kleen <ak@linux.intel.com>
Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Acked-by: Jiri Olsa <jolsa@redhat.com>
Acked-by: Ingo Molnar <mingo@kernel.org>
---

v2: Rename --quiet to --no-desc. Add option to man page.

v18: Fix minor conflict in tools/perf/builtin-list.c; Add !desc_flag
	to the newly introduced print_pmu_events() call site.

v21: Fix minor conflicts in tools/perf/builtin-list.c
---
 tools/perf/Documentation/perf-list.txt |  8 +++++++-
 tools/perf/builtin-list.c              | 14 +++++++++-----
 tools/perf/util/parse-events.c         |  4 ++--
 tools/perf/util/parse-events.h         |  2 +-
 tools/perf/util/pmu.c                  |  4 ++--
 tools/perf/util/pmu.h                  |  2 +-
 6 files changed, 22 insertions(+), 12 deletions(-)

diff --git a/tools/perf/Documentation/perf-list.txt b/tools/perf/Documentation/perf-list.txt
index a126e97..72209bc 100644
--- a/tools/perf/Documentation/perf-list.txt
+++ b/tools/perf/Documentation/perf-list.txt
@@ -8,13 +8,19 @@ perf-list - List all symbolic event types
 SYNOPSIS
 --------
 [verse]
-'perf list' [hw|sw|cache|tracepoint|pmu|event_glob]
+'perf list' [--no-desc] [hw|sw|cache|tracepoint|pmu|event_glob]
 
 DESCRIPTION
 -----------
 This command displays the symbolic event types which can be selected in the
 various perf commands with the -e option.
 
+OPTIONS
+-------
+--no-desc::
+Don't print descriptions.
+
+
 [[EVENT_MODIFIERS]]
 EVENT MODIFIERS
 ---------------
diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c
index 88ee419..b14cb16 100644
--- a/tools/perf/builtin-list.c
+++ b/tools/perf/builtin-list.c
@@ -16,16 +16,20 @@
 #include "util/pmu.h"
 #include <subcmd/parse-options.h>
 
+static bool desc_flag = true;
+
 int cmd_list(int argc, const char **argv, const char *prefix __maybe_unused)
 {
 	int i;
 	bool raw_dump = 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_END()
 	};
 	const char * const list_usage[] = {
-		"perf list [hw|sw|cache|tracepoint|pmu|sdt|event_glob]",
+		"perf list [--no-desc] [hw|sw|cache|tracepoint|pmu|sdt|event_glob]",
 		NULL
 	};
 
@@ -40,7 +44,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);
+		print_events(NULL, raw_dump, !desc_flag);
 		return 0;
 	}
 
@@ -61,14 +65,14 @@ 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);
+			print_pmu_events(NULL, raw_dump, !desc_flag);
 		else if (strcmp(argv[i], "sdt") == 0)
 			print_sdt_events(NULL, NULL, raw_dump);
 		else if ((sep = strchr(argv[i], ':')) != NULL) {
 			int sep_idx;
 
 			if (sep == NULL) {
-				print_events(argv[i], raw_dump);
+				print_events(argv[i], raw_dump, !desc_flag);
 				continue;
 			}
 			sep_idx = sep - argv[i];
@@ -90,7 +94,7 @@ int cmd_list(int argc, const char **argv, const char *prefix __maybe_unused)
 			print_symbol_events(s, PERF_TYPE_SOFTWARE,
 					    event_symbols_sw, PERF_COUNT_SW_MAX, raw_dump);
 			print_hwcache_events(s, raw_dump);
-			print_pmu_events(s, raw_dump);
+			print_pmu_events(s, raw_dump, !desc_flag);
 			print_tracepoint_events(NULL, s, raw_dump);
 			print_sdt_events(NULL, s, raw_dump);
 			free(s);
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 6c913c3..a3c7739 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -2229,7 +2229,7 @@ out_enomem:
 /*
  * Print the help text for the event symbols:
  */
-void print_events(const char *event_glob, bool name_only)
+void print_events(const char *event_glob, bool name_only, bool quiet_flag)
 {
 	print_symbol_events(event_glob, PERF_TYPE_HARDWARE,
 			    event_symbols_hw, PERF_COUNT_HW_MAX, name_only);
@@ -2239,7 +2239,7 @@ void print_events(const char *event_glob, bool name_only)
 
 	print_hwcache_events(event_glob, name_only);
 
-	print_pmu_events(event_glob, name_only);
+	print_pmu_events(event_glob, name_only, quiet_flag);
 
 	if (event_glob != NULL)
 		return;
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
index d1edbf8..795f2579 100644
--- a/tools/perf/util/parse-events.h
+++ b/tools/perf/util/parse-events.h
@@ -171,7 +171,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);
+void print_events(const char *event_glob, bool name_only, bool quiet);
 
 struct event_symbol {
 	const char	*symbol;
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index ef9de3e..cb4c215 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -1085,7 +1085,7 @@ static void wordwrap(char *s, int start, int max, int corr)
 	}
 }
 
-void print_pmu_events(const char *event_glob, bool name_only)
+void print_pmu_events(const char *event_glob, bool name_only, bool quiet_flag)
 {
 	struct perf_pmu *pmu;
 	struct perf_pmu_alias *alias;
@@ -1152,7 +1152,7 @@ void print_pmu_events(const char *event_glob, bool name_only)
 			printf("%s ", aliases[j].name);
 			continue;
 		}
-		if (aliases[j].desc) {
+		if (aliases[j].desc && !quiet_flag) {
 			if (numdesc++ == 0)
 				printf("\n");
 			printf("  %-50s\n", aliases[j].name);
diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h
index 11bda57..42999c7 100644
--- a/tools/perf/util/pmu.h
+++ b/tools/perf/util/pmu.h
@@ -70,7 +70,7 @@ 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);
+void print_pmu_events(const char *event_glob, bool name_only, bool quiet);
 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.8.3.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH v21 09/19] perf, tools: Add override support for event list CPUID
  2016-09-15 22:24 [PATCH v21 00/20] perf, tools: Add support for PMU events in JSON format Sukadev Bhattiprolu
                   ` (7 preceding siblings ...)
  2016-09-15 22:24 ` [PATCH v21 08/19] perf, tools: Add a --no-desc flag to " Sukadev Bhattiprolu
@ 2016-09-15 22:24 ` Sukadev Bhattiprolu
  2016-10-04  8:15   ` [tip:perf/urgent] perf pmu: " tip-bot for Andi Kleen
  2016-09-15 22:24 ` [PATCH v21 10/19] perf, tools, jevents: Add support for long descriptions Sukadev Bhattiprolu
                   ` (11 subsequent siblings)
  20 siblings, 1 reply; 70+ messages in thread
From: Sukadev Bhattiprolu @ 2016-09-15 22:24 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo; +Cc: peterz, maddy, linuxppc-dev, linux-kernel

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

Add a PERF_CPUID variable to override the CPUID of the current CPU (within
the current architecture). This is useful for testing, so that all event
lists can be tested on a single system.

Signed-off-by: Andi Kleen <ak@linux.intel.com>
Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Acked-by: Jiri Olsa <jolsa@redhat.com>
Acked-by: Ingo Molnar <mingo@kernel.org>
---

v2: Fix double free in earlier version.
    Print actual CPUID being used with verbose option.
---
 tools/perf/util/pmu.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index cb4c215..2291d2a 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -501,10 +501,16 @@ static int pmu_add_cpu_aliases(struct list_head *head)
 	struct pmu_event *pe;
 	char *cpuid;
 
-	cpuid = get_cpuid_str();
+	cpuid = getenv("PERF_CPUID");
+	if (cpuid)
+		cpuid = strdup(cpuid);
+	if (!cpuid)
+		cpuid = get_cpuid_str();
 	if (!cpuid)
 		return 0;
 
+	pr_debug("Using CPUID %s\n", cpuid);
+
 	i = 0;
 	while (1) {
 		map = &pmu_events_map[i++];
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH v21 10/19] perf, tools, jevents: Add support for long descriptions
  2016-09-15 22:24 [PATCH v21 00/20] perf, tools: Add support for PMU events in JSON format Sukadev Bhattiprolu
                   ` (8 preceding siblings ...)
  2016-09-15 22:24 ` [PATCH v21 09/19] perf, tools: Add override support for event list CPUID Sukadev Bhattiprolu
@ 2016-09-15 22:24 ` Sukadev Bhattiprolu
  2016-10-04  8:16   ` [tip:perf/urgent] perf " tip-bot for Sukadev Bhattiprolu
  2016-09-15 22:24 ` [PATCH v21 11/19] perf, tools: Add alias " Sukadev Bhattiprolu
                   ` (10 subsequent siblings)
  20 siblings, 1 reply; 70+ messages in thread
From: Sukadev Bhattiprolu @ 2016-09-15 22:24 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo; +Cc: peterz, maddy, linuxppc-dev, linux-kernel

Implement support in jevents to parse long descriptions for events
that may have them in the JSON files. A follow on patch will make this
long description available to user through the 'perf list' command.

Signed-off-by: Andi Kleen <ak@linux.intel.com>
Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Acked-by: Jiri Olsa <jolsa@redhat.com>
Acked-by: Ingo Molnar <mingo@kernel.org>
---

Changelog[v14]
	- [Jiri Olsa] Break up independent parts of the patch into
	  separate patches.

Changelog[v21]
	- Fix minor conflicts in tools/perf/pmu-events/jevents.c and
	  tools/perf/pmu-events/pmu-events.h
---
 tools/perf/pmu-events/jevents.c    | 32 ++++++++++++++++++++++++--------
 tools/perf/pmu-events/jevents.h    |  3 ++-
 tools/perf/pmu-events/pmu-events.h |  1 +
 3 files changed, 27 insertions(+), 9 deletions(-)

diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c
index a9ca86d..f550cad 100644
--- a/tools/perf/pmu-events/jevents.c
+++ b/tools/perf/pmu-events/jevents.c
@@ -268,7 +268,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)
 {
 	struct perf_entry_data *pd = data;
 	FILE *outfp = pd->outfp;
@@ -284,6 +284,8 @@ static int print_events_table_entry(void *data, char *name, char *event,
 	fprintf(outfp, "\t.event = \"%s\",\n", event);
 	fprintf(outfp, "\t.desc = \"%s\",\n", desc);
 	fprintf(outfp, "\t.topic = \"%s\",\n", topic);
+	if (long_desc && long_desc[0])
+		fprintf(outfp, "\t.long_desc = \"%s\",\n", long_desc);
 
 	fprintf(outfp, "},\n");
 
@@ -305,7 +307,8 @@ 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;
@@ -324,6 +327,8 @@ int json_events(const char *fn,
 	tok = tokens + 1;
 	for (i = 0; i < tokens->size; i++) {
 		char *event = NULL, *desc = NULL, *name = NULL;
+		char *long_desc = NULL;
+		char *extra_desc = NULL;
 		struct msrmap *msr = NULL;
 		jsmntok_t *msrval = NULL;
 		jsmntok_t *precise = NULL;
@@ -349,6 +354,10 @@ 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) {
@@ -357,10 +366,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);
 			}
@@ -368,19 +377,26 @@ int json_events(const char *fn,
 		}
 		if (precise && desc && !strstr(desc, "(Precise Event)")) {
 			if (json_streq(map, precise, "2"))
-				addfield(map, &desc, " ", "(Must be precise)",
-						NULL);
+				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(long_desc);
+		free(extra_desc);
 		if (err)
 			break;
 		tok += j;
diff --git a/tools/perf/pmu-events/jevents.h b/tools/perf/pmu-events/jevents.h
index 996601f..b0eb274 100644
--- a/tools/perf/pmu-events/jevents.h
+++ b/tools/perf/pmu-events/jevents.h
@@ -2,7 +2,8 @@
 #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 70d5479..2eaef59 100644
--- a/tools/perf/pmu-events/pmu-events.h
+++ b/tools/perf/pmu-events/pmu-events.h
@@ -9,6 +9,7 @@ struct pmu_event {
 	const char *event;
 	const char *desc;
 	const char *topic;
+	const char *long_desc;
 };
 
 /*
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH v21 11/19] perf, tools: Add alias support for long descriptions
  2016-09-15 22:24 [PATCH v21 00/20] perf, tools: Add support for PMU events in JSON format Sukadev Bhattiprolu
                   ` (9 preceding siblings ...)
  2016-09-15 22:24 ` [PATCH v21 10/19] perf, tools, jevents: Add support for long descriptions Sukadev Bhattiprolu
@ 2016-09-15 22:24 ` Sukadev Bhattiprolu
  2016-10-04  0:20   ` Arnaldo Carvalho de Melo
  2016-09-15 22:24 ` [PATCH v21 12/19] perf, tools: Support long descriptions with perf list Sukadev Bhattiprolu
                   ` (9 subsequent siblings)
  20 siblings, 1 reply; 70+ messages in thread
From: Sukadev Bhattiprolu @ 2016-09-15 22:24 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo; +Cc: peterz, maddy, linuxppc-dev, linux-kernel

Previously we were dropping the useful longer descriptions that some
events have in the event list completely. Now that jevents provides
support for longer descriptions (see previous patch), add support for
parsing the long descriptions

Signed-off-by: Andi Kleen <ak@linux.intel.com>
Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Acked-by: Jiri Olsa <jolsa@redhat.com>
Acked-by: Ingo Molnar <mingo@kernel.org>
---

Changelog[v14]
	- [Jiri Olsa] Break up independent parts of the patch into
	  separate patches.
---
 tools/perf/util/parse-events.c |  5 +++--
 tools/perf/util/parse-events.h |  3 ++-
 tools/perf/util/pmu.c          | 15 ++++++++++-----
 tools/perf/util/pmu.h          |  4 +++-
 4 files changed, 18 insertions(+), 9 deletions(-)

diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index a3c7739..9abd60d 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -2229,7 +2229,8 @@ 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);
@@ -2239,7 +2240,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 795f2579..7efde4a 100644
--- a/tools/perf/util/parse-events.h
+++ b/tools/perf/util/parse-events.h
@@ -171,7 +171,8 @@ 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 2291d2a..43838b3 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -223,7 +223,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, char *val)
+				 char *desc, char *val, char *long_desc)
 {
 	struct perf_pmu_alias *alias;
 	int ret;
@@ -257,6 +257,8 @@ static int __perf_pmu__new_alias(struct list_head *list, char *dir, char *name,
 	}
 
 	alias->desc = desc ? strdup(desc) : NULL;
+	alias->long_desc = long_desc ? strdup(long_desc) :
+				desc ? strdup(desc) : NULL;
 
 	list_add_tail(&alias->list, list);
 
@@ -274,7 +276,7 @@ static int perf_pmu__new_alias(struct list_head *list, char *dir, char *name, FI
 
 	buf[ret] = 0;
 
-	return __perf_pmu__new_alias(list, dir, name, NULL, buf);
+	return __perf_pmu__new_alias(list, dir, name, NULL, buf, NULL);
 }
 
 static inline bool pmu_alias_info_file(char *name)
@@ -532,7 +534,8 @@ static int pmu_add_cpu_aliases(struct list_head *head)
 
 		/* need type casts to override 'const' */
 		__perf_pmu__new_alias(head, NULL, (char *)pe->name,
-				(char *)pe->desc, (char *)pe->event);
+				(char *)pe->desc, (char *)pe->event,
+				(char *)pe->long_desc);
 	}
 
 out:
@@ -1091,7 +1094,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;
@@ -1139,7 +1143,8 @@ void print_pmu_events(const char *event_glob, bool name_only, bool quiet_flag)
 			if (!aliases[j].name)
 				goto out_enomem;
 
-			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 42999c7..1aa614e 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];
@@ -70,7 +71,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.8.3.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH v21 12/19] perf, tools: Support long descriptions with perf list
  2016-09-15 22:24 [PATCH v21 00/20] perf, tools: Add support for PMU events in JSON format Sukadev Bhattiprolu
                   ` (10 preceding siblings ...)
  2016-09-15 22:24 ` [PATCH v21 11/19] perf, tools: Add alias " Sukadev Bhattiprolu
@ 2016-09-15 22:24 ` Sukadev Bhattiprolu
  2016-10-04  0:26   ` Arnaldo Carvalho de Melo
  2016-10-04  8:16   ` [tip:perf/urgent] perf list: Support long jevents descriptions tip-bot for Sukadev Bhattiprolu
  2016-09-15 22:24 ` [PATCH v21 13/19] perf, tools: Add support for event list topics Sukadev Bhattiprolu
                   ` (8 subsequent siblings)
  20 siblings, 2 replies; 70+ messages in thread
From: Sukadev Bhattiprolu @ 2016-09-15 22:24 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo; +Cc: peterz, maddy, linuxppc-dev, linux-kernel

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 <ak@linux.intel.com>
Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Acked-by: Jiri Olsa <jolsa@redhat.com>
Acked-by: Ingo Molnar <mingo@kernel.org>
---

Changelog[v15]
	- [Jir Olsa, Andi Kleen] Fix usage strings; update man page.

Changelog[v14]
	- [Jiri Olsa] Break up independent parts of the patch into
	  separate patches.

Changelog[v18]:
	- Fix minor conflict in tools/perf/builtin-list.c; add long_desc_flag
	  parameter to new print_pmu_events() call site.

Changelog[v21]
	- Fix minor conflicts in tools/perf/builtin-list.c
---
 tools/perf/Documentation/perf-list.txt |  6 +++++-
 tools/perf/builtin-list.c              | 16 +++++++++++-----
 2 files changed, 16 insertions(+), 6 deletions(-)

diff --git a/tools/perf/Documentation/perf-list.txt b/tools/perf/Documentation/perf-list.txt
index 72209bc..41857cc 100644
--- a/tools/perf/Documentation/perf-list.txt
+++ b/tools/perf/Documentation/perf-list.txt
@@ -8,7 +8,7 @@ perf-list - List all symbolic event types
 SYNOPSIS
 --------
 [verse]
-'perf list' [--no-desc] [hw|sw|cache|tracepoint|pmu|event_glob]
+'perf list' [--no-desc] [--long-desc] [hw|sw|cache|tracepoint|pmu|event_glob]
 
 DESCRIPTION
 -----------
@@ -20,6 +20,10 @@ OPTIONS
 --no-desc::
 Don't print descriptions.
 
+-v::
+--long-desc::
+Print longer event descriptions.
+
 
 [[EVENT_MODIFIERS]]
 EVENT MODIFIERS
diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c
index b14cb16..ba9322f 100644
--- a/tools/perf/builtin-list.c
+++ b/tools/perf/builtin-list.c
@@ -22,14 +22,17 @@ 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[] = {
-		"perf list [--no-desc] [hw|sw|cache|tracepoint|pmu|sdt|event_glob]",
+		"perf list [<options>] [hw|sw|cache|tracepoint|pmu|sdt|event_glob]",
 		NULL
 	};
 
@@ -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;
 	}
 
@@ -65,14 +68,16 @@ 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 if (strcmp(argv[i], "sdt") == 0)
 			print_sdt_events(NULL, NULL, raw_dump);
 		else if ((sep = strchr(argv[i], ':')) != NULL) {
 			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];
@@ -94,7 +99,8 @@ int cmd_list(int argc, const char **argv, const char *prefix __maybe_unused)
 			print_symbol_events(s, PERF_TYPE_SOFTWARE,
 					    event_symbols_sw, PERF_COUNT_SW_MAX, raw_dump);
 			print_hwcache_events(s, raw_dump);
-			print_pmu_events(s, raw_dump, !desc_flag);
+			print_pmu_events(s, raw_dump, !desc_flag,
+						long_desc_flag);
 			print_tracepoint_events(NULL, s, raw_dump);
 			print_sdt_events(NULL, s, raw_dump);
 			free(s);
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH v21 13/19] perf, tools: Add support for event list topics
  2016-09-15 22:24 [PATCH v21 00/20] perf, tools: Add support for PMU events in JSON format Sukadev Bhattiprolu
                   ` (11 preceding siblings ...)
  2016-09-15 22:24 ` [PATCH v21 12/19] perf, tools: Support long descriptions with perf list Sukadev Bhattiprolu
@ 2016-09-15 22:24 ` Sukadev Bhattiprolu
  2016-10-04  8:16   ` [tip:perf/urgent] perf list jevents: " tip-bot for Andi Kleen
  2016-09-15 22:24 ` [PATCH v21 14/19] perf, tools, jevents: Handle header line in mapfile Sukadev Bhattiprolu
                   ` (7 subsequent siblings)
  20 siblings, 1 reply; 70+ messages in thread
From: Sukadev Bhattiprolu @ 2016-09-15 22:24 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo; +Cc: peterz, maddy, linuxppc-dev, linux-kernel

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

Add support to group the output of perf list by the Topic field
in the JSON file.

Example output:

% perf list
...
Cache:
  l1d.replacement
       [L1D data line replacements]
  l1d_pend_miss.pending
       [L1D miss oustandings duration in cycles]
  l1d_pend_miss.pending_cycles
       [Cycles with L1D load Misses outstanding]
  l2_l1d_wb_rqsts.all
       [Not rejected writebacks from L1D to L2 cache lines in any state]
  l2_l1d_wb_rqsts.hit_e
       [Not rejected writebacks from L1D to L2 cache lines in E state]
  l2_l1d_wb_rqsts.hit_m
       [Not rejected writebacks from L1D to L2 cache lines in M state]

...
Pipeline:
  arith.fpu_div
       [Divide operations executed]
  arith.fpu_div_active
       [Cycles when divider is busy executing divide operations]
  baclears.any
       [Counts the total number when the front end is resteered, mainly
       when the BPU cannot provide a correct prediction and this is
       corrected by other branch handling mechanisms at the front end]
  br_inst_exec.all_branches
       [Speculative and retired branches]
  br_inst_exec.all_conditional
       [Speculative and retired macro-conditional branches]
  br_inst_exec.all_direct_jmp
       [Speculative and retired macro-unconditional branches excluding
       calls and indirects]
  br_inst_exec.all_direct_near_call
       [Speculative and retired direct near calls]
  br_inst_exec.all_indirect_jump_non_call_ret

Signed-off-by: Andi Kleen <ak@linux.intel.com>
Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Acked-by: Jiri Olsa <jolsa@redhat.com>
Acked-by: Ingo Molnar <mingo@kernel.org>
---

Changelog[v14]
	- [Jiri Olsa] Move jevents support for Topic to a separate patch.
---
 tools/perf/util/pmu.c | 37 +++++++++++++++++++++++++++----------
 tools/perf/util/pmu.h |  1 +
 2 files changed, 28 insertions(+), 10 deletions(-)

diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index 43838b3..ac097fc 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -223,7 +223,8 @@ 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, char *val, char *long_desc)
+				 char *desc, char *val, char *long_desc,
+				 char *topic)
 {
 	struct perf_pmu_alias *alias;
 	int ret;
@@ -259,6 +260,7 @@ static int __perf_pmu__new_alias(struct list_head *list, char *dir, char *name,
 	alias->desc = desc ? strdup(desc) : NULL;
 	alias->long_desc = long_desc ? strdup(long_desc) :
 				desc ? strdup(desc) : NULL;
+	alias->topic = topic ? strdup(topic) : NULL;
 
 	list_add_tail(&alias->list, list);
 
@@ -276,7 +278,7 @@ static int perf_pmu__new_alias(struct list_head *list, char *dir, char *name, FI
 
 	buf[ret] = 0;
 
-	return __perf_pmu__new_alias(list, dir, name, NULL, buf, NULL);
+	return __perf_pmu__new_alias(list, dir, name, NULL, buf, NULL, NULL);
 }
 
 static inline bool pmu_alias_info_file(char *name)
@@ -535,7 +537,7 @@ static int pmu_add_cpu_aliases(struct list_head *head)
 		/* need type casts to override 'const' */
 		__perf_pmu__new_alias(head, NULL, (char *)pe->name,
 				(char *)pe->desc, (char *)pe->event,
-				(char *)pe->long_desc);
+				(char *)pe->long_desc, (char *)pe->topic);
 	}
 
 out:
@@ -1056,19 +1058,26 @@ static char *format_alias_or(char *buf, int len, struct perf_pmu *pmu,
 	return buf;
 }
 
-struct pair {
+struct sevent {
 	char *name;
 	char *desc;
+	char *topic;
 };
 
-static int cmp_pair(const void *a, const void *b)
+static int cmp_sevent(const void *a, const void *b)
 {
-	const struct pair *as = a;
-	const struct pair *bs = b;
+	const struct sevent *as = a;
+	const struct sevent *bs = b;
 
 	/* Put extra events last */
 	if (!!as->desc != !!bs->desc)
 		return !!as->desc - !!bs->desc;
+	if (as->topic && bs->topic) {
+		int n = strcmp(as->topic, bs->topic);
+
+		if (n)
+			return n;
+	}
 	return strcmp(as->name, bs->name);
 }
 
@@ -1102,9 +1111,10 @@ void print_pmu_events(const char *event_glob, bool name_only, bool quiet_flag,
 	char buf[1024];
 	int printed = 0;
 	int len, j;
-	struct pair *aliases;
+	struct sevent *aliases;
 	int numdesc = 0;
 	int columns = pager_get_columns();
+	char *topic = NULL;
 
 	pmu = NULL;
 	len = 0;
@@ -1114,7 +1124,7 @@ void print_pmu_events(const char *event_glob, bool name_only, bool quiet_flag,
 		if (pmu->selectable)
 			len++;
 	}
-	aliases = zalloc(sizeof(struct pair) * len);
+	aliases = zalloc(sizeof(struct sevent) * len);
 	if (!aliases)
 		goto out_enomem;
 	pmu = NULL;
@@ -1145,6 +1155,7 @@ void print_pmu_events(const char *event_glob, bool name_only, bool quiet_flag,
 
 			aliases[j].desc = long_desc ? alias->long_desc :
 						alias->desc;
+			aliases[j].topic = alias->topic;
 			j++;
 		}
 		if (pmu->selectable &&
@@ -1157,7 +1168,7 @@ void print_pmu_events(const char *event_glob, bool name_only, bool quiet_flag,
 		}
 	}
 	len = j;
-	qsort(aliases, len, sizeof(struct pair), cmp_pair);
+	qsort(aliases, len, sizeof(struct sevent), cmp_sevent);
 	for (j = 0; j < len; j++) {
 		if (name_only) {
 			printf("%s ", aliases[j].name);
@@ -1166,6 +1177,12 @@ void print_pmu_events(const char *event_glob, bool name_only, bool quiet_flag,
 		if (aliases[j].desc && !quiet_flag) {
 			if (numdesc++ == 0)
 				printf("\n");
+			if (aliases[j].topic && (!topic ||
+					strcmp(topic, aliases[j].topic))) {
+				printf("%s%s:\n", topic ? "\n" : "",
+						aliases[j].topic);
+				topic = aliases[j].topic;
+			}
 			printf("  %-50s\n", aliases[j].name);
 			printf("%*s", 8, "[");
 			wordwrap(aliases[j].desc, 8, columns, 0);
diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h
index 1aa614e..de26919 100644
--- a/tools/perf/util/pmu.h
+++ b/tools/perf/util/pmu.h
@@ -40,6 +40,7 @@ struct perf_pmu_alias {
 	char *name;
 	char *desc;
 	char *long_desc;
+	char *topic;
 	struct list_head terms; /* HEAD struct parse_events_term -> list */
 	struct list_head list;  /* ELEM */
 	char unit[UNIT_MAX_LEN+1];
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH v21 14/19] perf, tools, jevents: Handle header line in mapfile
  2016-09-15 22:24 [PATCH v21 00/20] perf, tools: Add support for PMU events in JSON format Sukadev Bhattiprolu
                   ` (12 preceding siblings ...)
  2016-09-15 22:24 ` [PATCH v21 13/19] perf, tools: Add support for event list topics Sukadev Bhattiprolu
@ 2016-09-15 22:24 ` Sukadev Bhattiprolu
  2016-10-04  0:36   ` Arnaldo Carvalho de Melo
  2016-10-04  8:13   ` [tip:perf/urgent] perf " tip-bot for Andi Kleen
  2016-09-15 22:24 ` [PATCH v21 15/19] perf, tools: Add README for info on parsing JSON/map files Sukadev Bhattiprolu
                   ` (6 subsequent siblings)
  20 siblings, 2 replies; 70+ messages in thread
From: Sukadev Bhattiprolu @ 2016-09-15 22:24 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo; +Cc: peterz, maddy, linuxppc-dev, linux-kernel

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

To work with existing mapfiles, assume that the first line in
'mapfile.csv' is a header line and skip over it.

Signed-off-by: Andi Kleen <ak@linux.intel.com>
Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Acked-by: Jiri Olsa <jolsa@redhat.com>
Acked-by: Ingo Molnar <mingo@kernel.org>
---

Changelog[v2]
	All architectures may not use the "Family" to identify. So,
	assume first line is header.
---
 tools/perf/pmu-events/jevents.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c
index f550cad..9cdfbaa 100644
--- a/tools/perf/pmu-events/jevents.c
+++ b/tools/perf/pmu-events/jevents.c
@@ -492,7 +492,12 @@ static int process_mapfile(FILE *outfp, char *fpath)
 
 	print_mapping_table_prefix(outfp);
 
-	line_num = 0;
+	/* Skip first line (header) */
+	p = fgets(line, n, mapfp);
+	if (!p)
+		goto out;
+
+	line_num = 1;
 	while (1) {
 		char *cpuid, *version, *type, *fname;
 
@@ -536,8 +541,8 @@ static int process_mapfile(FILE *outfp, char *fpath)
 		fprintf(outfp, "},\n");
 	}
 
+out:
 	print_mapping_table_suffix(outfp);
-
 	return 0;
 }
 
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH v21 15/19] perf, tools: Add README for info on parsing JSON/map files
  2016-09-15 22:24 [PATCH v21 00/20] perf, tools: Add support for PMU events in JSON format Sukadev Bhattiprolu
                   ` (13 preceding siblings ...)
  2016-09-15 22:24 ` [PATCH v21 14/19] perf, tools, jevents: Handle header line in mapfile Sukadev Bhattiprolu
@ 2016-09-15 22:24 ` Sukadev Bhattiprolu
  2016-10-04  0:38   ` Arnaldo Carvalho de Melo
  2016-10-04  8:17   ` [tip:perf/urgent] perf " tip-bot for Sukadev Bhattiprolu
  2016-09-15 22:24 ` [PATCH v21 16/19] perf, tools: Make alias matching case-insensitive Sukadev Bhattiprolu
                   ` (5 subsequent siblings)
  20 siblings, 2 replies; 70+ messages in thread
From: Sukadev Bhattiprolu @ 2016-09-15 22:24 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo; +Cc: peterz, maddy, linuxppc-dev, linux-kernel

Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Acked-by: Jiri Olsa <jolsa@redhat.com>
Acked-by: Ingo Molnar <mingo@kernel.org>
---
Changelog[v21]
	- Update README to reflect the Topics.json directory tree layout.
---
 tools/perf/pmu-events/README | 148 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 148 insertions(+)
 create mode 100644 tools/perf/pmu-events/README

diff --git a/tools/perf/pmu-events/README b/tools/perf/pmu-events/README
new file mode 100644
index 0000000..c5ee208e
--- /dev/null
+++ b/tools/perf/pmu-events/README
@@ -0,0 +1,148 @@
+
+The contents of this directory allow users to specify PMU events in their
+CPUs by their symbolic names rather than raw event codes (see example below).
+
+The main program in this directory, is the 'jevents', which is built and
+executed _BEFORE_ the perf binary itself is built.
+
+The 'jevents' program tries to locate and process JSON files in the directory
+tree tools/perf/pmu-events/arch/foo.
+
+	- Regular files with '.json' extension in the name are assumed to be
+	  JSON files, each of which describes a set of PMU events.
+
+	- Regular files with basename starting with 'mapfile.csv' are assumed
+	  to be a CSV file that maps a specific CPU to its set of PMU events.
+	  (see below for mapfile format)
+
+	- Directories are traversed, but all other files are ignored.
+
+The PMU events supported by a CPU model are expected to grouped into topics
+such as Pipelining, Cache, Memory, Floating-point etc. All events for a topic
+should be placed in a separate JSON file - where the file name identifies
+the topic. Eg: "Floating-point.json".
+
+All the topic JSON files for a CPU model/family should be in a separate
+sub directory. Thus for the Silvermont X86 CPU:
+
+	$ ls tools/perf/pmu-events/arch/x86/Silvermont_core
+	Cache.json 	Memory.json 	Virtual-Memory.json
+	Frontend.json 	Pipeline.json
+
+Using the JSON files and the mapfile, 'jevents' generates the C source file,
+'pmu-events.c', which encodes the two sets of tables:
+
+	- Set of 'PMU events tables' for all known CPUs in the architecture,
+	  (one table like the following, per JSON file; table name 'pme_power8'
+	  is derived from JSON file name, 'power8.json').
+
+		struct pmu_event pme_power8[] = {
+
+			...
+
+			{
+				.name = "pm_1plus_ppc_cmpl",
+				.event = "event=0x100f2",
+				.desc = "1 or more ppc insts finished,",
+			},
+
+			...
+		}
+
+	- A 'mapping table' that maps each CPU of the architecture, to its
+	  'PMU events table'
+
+		struct pmu_events_map pmu_events_map[] = {
+		{
+			.cpuid = "004b0000",
+			.version = "1",
+			.type = "core",
+			.table = pme_power8
+		},
+			...
+
+		};
+
+After the 'pmu-events.c' is generated, it is compiled and the resulting
+'pmu-events.o' is added to 'libperf.a' which is then used to build perf.
+
+NOTES:
+	1. Several CPUs can support same set of events and hence use a common
+	   JSON file. Hence several entries in the pmu_events_map[] could map
+	   to a single 'PMU events table'.
+
+	2. The 'pmu-events.h' has an extern declaration for the mapping table
+	   and the generated 'pmu-events.c' defines this table.
+
+	3. _All_ known CPU tables for architecture are included in the perf
+	   binary.
+
+At run time, perf determines the actual CPU it is running on, finds the
+matching events table and builds aliases for those events. This allows
+users to specify events by their name:
+
+	$ perf stat -e pm_1plus_ppc_cmpl sleep 1
+
+where 'pm_1plus_ppc_cmpl' is a Power8 PMU event.
+
+In case of errors when processing files in the tools/perf/pmu-events/arch
+directory, 'jevents' tries to create an empty mapping file to allow the perf
+build to succeed even if the PMU event aliases cannot be used.
+
+However some errors in processing may cause the perf build to fail.
+
+Mapfile format
+===============
+
+The mapfile enables multiple CPU models to share a single set of PMU events.
+It is required even if such mapping is 1:1.
+
+The mapfile.csv format is expected to be:
+
+	Header line
+	CPUID,Version,Dir/path/name,Type
+
+where:
+
+	Comma:
+		is the required field delimiter (i.e other fields cannot
+		have commas within them).
+
+	Comments:
+		Lines in which the first character is either '\n' or '#'
+		are ignored.
+
+	Header line
+		The header line is the first line in the file, which is
+		always _IGNORED_. It can empty.
+
+	CPUID:
+		CPUID is an arch-specific char string, that can be used
+		to identify CPU (and associate it with a set of PMU events
+		it supports). Multiple CPUIDS can point to the same
+		File/path/name.json.
+
+		Example:
+			CPUID == 'GenuineIntel-6-2E' (on x86).
+			CPUID == '004b0100' (PVR value in Powerpc)
+	Version:
+		is the Version of the mapfile.
+
+	Dir/path/name:
+		is the pathname to the directory containing the CPU's JSON
+		files, relative to the directory containing the mapfile.csv
+
+	Type:
+		indicates whether the events or "core" or "uncore" events.
+
+
+	Eg:
+
+	$ grep Silvermont tools/perf/pmu-events/arch/x86/mapfile.csv
+	GenuineIntel-6-37,V13,Silvermont_core,core
+	GenuineIntel-6-4D,V13,Silvermont_core,core
+	GenuineIntel-6-4C,V13,Silvermont_core,core
+
+	i.e the three CPU models use the JSON files (i.e PMU events) listed
+	in the directory 'tools/perf/pmu-events/arch/x86/Silvermont_core'.
+
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH v21 16/19] perf, tools: Make alias matching case-insensitive
  2016-09-15 22:24 [PATCH v21 00/20] perf, tools: Add support for PMU events in JSON format Sukadev Bhattiprolu
                   ` (14 preceding siblings ...)
  2016-09-15 22:24 ` [PATCH v21 15/19] perf, tools: Add README for info on parsing JSON/map files Sukadev Bhattiprolu
@ 2016-09-15 22:24 ` Sukadev Bhattiprolu
  2016-10-04  0:47   ` Arnaldo Carvalho de Melo
  2016-10-04  8:18   ` [tip:perf/urgent] perf " tip-bot for Andi Kleen
  2016-09-15 22:24 ` [PATCH v21 17/19] perf, tools, pmu-events: Fix fixed counters on Intel Sukadev Bhattiprolu
                   ` (4 subsequent siblings)
  20 siblings, 2 replies; 70+ messages in thread
From: Sukadev Bhattiprolu @ 2016-09-15 22:24 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo; +Cc: peterz, maddy, linuxppc-dev, linux-kernel

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

Make alias matching the events parser case-insensitive. This is useful
with the JSON events. perf uses lower case events, but the CPU manuals
generally use upper case event names. The JSON files use lower
case by default too. But if we search case insensitively then
users can cut-n-paste the upper case event names.

So the following works:

% perf stat -e BR_INST_EXEC.TAKEN_INDIRECT_NEAR_CALL true

 Performance counter stats for 'true':

               305      BR_INST_EXEC.TAKEN_INDIRECT_NEAR_CALL

       0.000492799 seconds time elapsed

Signed-off-by: Andi Kleen <ak@linux.intel.com>
Acked-by: Ingo Molnar <mingo@kernel.org>
---
 tools/perf/util/parse-events.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 9abd60d..1abda10 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -1453,7 +1453,7 @@ comp_pmu(const void *p1, const void *p2)
 	struct perf_pmu_event_symbol *pmu1 = (struct perf_pmu_event_symbol *) p1;
 	struct perf_pmu_event_symbol *pmu2 = (struct perf_pmu_event_symbol *) p2;
 
-	return strcmp(pmu1->symbol, pmu2->symbol);
+	return strcasecmp(pmu1->symbol, pmu2->symbol);
 }
 
 static void perf_pmu__parse_cleanup(void)
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH v21 17/19] perf, tools, pmu-events: Fix fixed counters on Intel
  2016-09-15 22:24 [PATCH v21 00/20] perf, tools: Add support for PMU events in JSON format Sukadev Bhattiprolu
                   ` (15 preceding siblings ...)
  2016-09-15 22:24 ` [PATCH v21 16/19] perf, tools: Make alias matching case-insensitive Sukadev Bhattiprolu
@ 2016-09-15 22:24 ` Sukadev Bhattiprolu
  2016-10-04  8:18   ` [tip:perf/urgent] perf " tip-bot for Andi Kleen
  2016-09-15 22:24 ` [PATCH v21 18/19] perf, tools, pmu-events: Add Skylake frontend MSR support Sukadev Bhattiprolu
                   ` (3 subsequent siblings)
  20 siblings, 1 reply; 70+ messages in thread
From: Sukadev Bhattiprolu @ 2016-09-15 22:24 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo; +Cc: peterz, maddy, linuxppc-dev, linux-kernel

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

The JSON event lists use a different encoding for fixed counters
than perf for instructions and cycles (ref-cycles is ok)

This lead to some common events like inst_retired.any
or cpu_clk_unhalted.thread not counting, when specified with their
JSON name.

Special case these events in the jevents conversion process.
I prefer to not touch the JSON files for this, as it's intended
that standard JSON files can be just dropped into the perf
build without changes.

Signed-off-by: Andi Kleen <ak@linux.intel.com>
Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
[Fix minor compile error]
Acked-by: Ingo Molnar <mingo@kernel.org>
---
Changelog[v21]:
	Fix minor conflict in tools/perf/pmu-events/jevents.c
---
 tools/perf/pmu-events/jevents.c | 25 ++++++++++++++++++++++++-
 1 file changed, 24 insertions(+), 1 deletion(-)

diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c
index 9cdfbaa..e8e2a87 100644
--- a/tools/perf/pmu-events/jevents.c
+++ b/tools/perf/pmu-events/jevents.c
@@ -305,6 +305,29 @@ static void print_events_table_suffix(FILE *outfp)
 	close_table = 0;
 }
 
+static struct fixed {
+	const char *name;
+	const char *event;
+} fixed[] = {
+	{ "inst_retired.any", "event=0xc0" },
+	{ "cpu_clk_unhalted.thread", "event=0x3c" },
+	{ "cpu_clk_unhalted.thread_any", "event=0x3c,any=1" },
+	{ NULL, NULL},
+};
+
+/*
+ * Handle different fixed counter encodings between JSON and perf.
+ */
+static char *real_event(const char *name, char *event)
+{
+	int i;
+
+	for (i = 0; fixed[i].name; i++)
+		if (!strcasecmp(name, fixed[i].name))
+			return (char *)fixed[i].event;
+	return event;
+}
+
 /* 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,
@@ -391,7 +414,7 @@ int json_events(const char *fn,
 			addfield(map, &event, ",", msr->pname, msrval);
 		fixname(name);
 
-		err = func(data, name, event, desc, long_desc);
+		err = func(data, name, real_event(name, event), desc, long_desc);
 		free(event);
 		free(desc);
 		free(name);
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH v21 18/19] perf, tools, pmu-events: Add Skylake frontend MSR support
  2016-09-15 22:24 [PATCH v21 00/20] perf, tools: Add support for PMU events in JSON format Sukadev Bhattiprolu
                   ` (16 preceding siblings ...)
  2016-09-15 22:24 ` [PATCH v21 17/19] perf, tools, pmu-events: Fix fixed counters on Intel Sukadev Bhattiprolu
@ 2016-09-15 22:24 ` Sukadev Bhattiprolu
  2016-10-04  8:19   ` [tip:perf/urgent] perf " tip-bot for Andi Kleen
  2016-09-15 22:24 ` [PATCH v21 19/19] perf, tools: Allow period= in perf stat CPU event descriptions Sukadev Bhattiprolu
                   ` (2 subsequent siblings)
  20 siblings, 1 reply; 70+ messages in thread
From: Sukadev Bhattiprolu @ 2016-09-15 22:24 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo; +Cc: peterz, maddy, linuxppc-dev, linux-kernel

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

Add support for the "frontend" extra MSR on Skylake in the JSON
conversion.

Signed-off-by: Andi Kleen <ak@linux.intel.com>
Acked-by: Ingo Molnar <mingo@kernel.org>
---
 tools/perf/pmu-events/jevents.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c
index e8e2a87..5846057 100644
--- a/tools/perf/pmu-events/jevents.c
+++ b/tools/perf/pmu-events/jevents.c
@@ -126,6 +126,7 @@ static struct msrmap {
 	{ "0x3F6", "ldlat=" },
 	{ "0x1A6", "offcore_rsp=" },
 	{ "0x1A7", "offcore_rsp=" },
+	{ "0x3F7", "frontend=" },
 	{ NULL, NULL }
 };
 
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH v21 19/19] perf, tools: Allow period= in perf stat CPU event descriptions.
  2016-09-15 22:24 [PATCH v21 00/20] perf, tools: Add support for PMU events in JSON format Sukadev Bhattiprolu
                   ` (17 preceding siblings ...)
  2016-09-15 22:24 ` [PATCH v21 18/19] perf, tools, pmu-events: Add Skylake frontend MSR support Sukadev Bhattiprolu
@ 2016-09-15 22:24 ` Sukadev Bhattiprolu
  2016-10-04  8:17   ` [tip:perf/urgent] perf " tip-bot for Sukadev Bhattiprolu
  2016-09-19 16:58 ` [PATCH v21 00/20] perf, tools: Add support for PMU events in JSON format Sukadev Bhattiprolu
  2016-09-19 21:20 ` Arnaldo Carvalho de Melo
  20 siblings, 1 reply; 70+ messages in thread
From: Sukadev Bhattiprolu @ 2016-09-15 22:24 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo; +Cc: peterz, maddy, linuxppc-dev, linux-kernel

This avoids the JSON PMU events parser having to know whether its aliases
are for perf stat or perf record.

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>
---
 tools/perf/util/parse-events.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 1abda10..b675273 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -923,6 +923,7 @@ config_term_avail(int term_type, struct parse_events_error *err)
 	case PARSE_EVENTS__TERM_TYPE_CONFIG1:
 	case PARSE_EVENTS__TERM_TYPE_CONFIG2:
 	case PARSE_EVENTS__TERM_TYPE_NAME:
+	case PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD:
 		return true;
 	default:
 		if (!err)
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* Re: [PATCH v21 00/20] perf, tools: Add support for PMU events in JSON format
  2016-09-15 22:24 [PATCH v21 00/20] perf, tools: Add support for PMU events in JSON format Sukadev Bhattiprolu
                   ` (18 preceding siblings ...)
  2016-09-15 22:24 ` [PATCH v21 19/19] perf, tools: Allow period= in perf stat CPU event descriptions Sukadev Bhattiprolu
@ 2016-09-19 16:58 ` Sukadev Bhattiprolu
  2016-09-19 21:20 ` Arnaldo Carvalho de Melo
  20 siblings, 0 replies; 70+ messages in thread
From: Sukadev Bhattiprolu @ 2016-09-19 16:58 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: peterz, maddy, linuxppc-dev, linux-kernel, Michael Ellerman,
	Jiri Olsa, mingo, ak, namhyung

I messed up the Cc list. Fixing it now.

Sukadev Bhattiprolu [sukadev@linux.vnet.ibm.com] wrote:
> CPUs support a large number of performance monitoring events (PMU events)
> and often these events are very specific to an architecture/model of the
> CPU. To use most of these PMU events with perf, we currently have to identify
> them by their raw codes:
> 
> 	perf stat -e r100f2 sleep 1
> 
> This patchset allows architectures to specify these PMU events in JSON
> files located in 'tools/perf/pmu-events/arch/' of the mainline tree.
> The events from the JSON files for the architecture are then built into
> the perf binary.
> 
> At run time, perf identifies the specific set of events for the CPU and
> creates "event aliases". These aliases allow users to specify events by
> "name" as:
> 
> 	perf stat -e pm_1plus_ppc_cmpl sleep 1
> 
> The file, 'tools/perf/pmu-events/README' in [PATCH 15/19] gives more
> details.
> 
> Note:
> 	- All known events tables for the architecture are included in the
> 	  perf binary.
> 
> 	- For architectures that don't have any JSON files, an empty mapping
> 	  table is created and they should continue to build.
> 
> Thanks to input from Andi Kleen, Jiri Olsa, Namhyung Kim and Ingo Molnar.
> 
> These patches are available from:
> 
> 	https://github.com/sukadev/linux.git 
> 	
> 	Branch			Description
> 	------------------------------------------------------
> 	json-code-v21		Source Code only 
> 	json-code+data-v21	Both code and data (for build/test/pull)
> 	
> NOTE: 	Only "source code" patches (i.e those in json-code-v21) are being
> 	emailed. Please pull the json-code+data-v21 branch for build/test.
> 
> Changelog[v21]
> 	- Rebase to recent perf/core
> 	- Group the PMU events supported by a CPU model into topics and
> 	  create a separate JSON file for each topic for each CPU (code
> 	  and input from Jiri Olsa).
> 
> Changelog[v20]
> 	- Rebase to recent perf/core
> 	- Add Patch 20/20 to allow perf-stat to work with the period= field
> 
> Changelog[v19]
> 	Rebase to recent perf/core; fix couple lines >80 chars.
> 
> Changelog[v18]
> 	Rebase to recent perf/core; fix minor merge conflicts.
> 
> Changelog[v17]
> 	Rebase to recent perf/core; couple of small fixes to processing Intel
> 	JSON files; allow case-insensitive PMU event names.
> 
> Changelog[v16]
> 	Rebase to recent perf/core; fix minor merge conflicts; drop 3 patches
> 	that were merged into perf/core.
> 
> Changelog[v15]
> 	Code changes:
> 	- Fix 'perf list' usage string and update man page.
> 	- Remove a redundant __maybe_unused tag.
> 	- Rebase to recent perf/core branch.
> 
> 	Data files updates: json-files-5 branch
> 	- Rebase to perf/intel-json-files-5 from Andi Kleen
> 	- Add patch from Madhavan Srinivasan for couple more Powerpc models
> 
> Changelog[v14]
> 	Comments from Jiri Olsa:
> 	- Change parameter name/type for pmu_add_cpu_aliases (from void *data
> 	  to list_head *head)
> 	- Use asprintf() in file_name_to_tablename() and simplify/reorg code.
> 	- Use __weak definition from <linux/compile.h>
> 	- Use fopen() with mode "w" and eliminate unlink()
> 	- Remove minor TODO.
> 	- Add error check for return value from strdup() in print_pmu_events().
> 	- Move independent changes from patches 3,11,12 .. to separate patches
> 	  for easier review/backport.
> 	- Clarify mapfile's "header line support" in patch description.
> 	- Fix build failure with DEBUG=1
> 
> 	Comment from Andi Kleen:
> 	- In tools/perf/pmu-events/Build, check for 'mapfile.csv' rather than
> 	  'mapfile*'
> 
> 	Misc:
> 	- Minor changes/clarifications to tools/perf/pmu-events/README.
> 
> 
> Changelog[v13]
> 	Version: Individual patches have their own history :-) that I am
> 	preserving. Patchset version (v13) is for overall patchset and is
> 	somewhat arbitrary.
> 
> 	- Added support for "categories" of events to perf
> 	- Add mapfile, jevents build dependency on pmu-events.c
> 	- Silence jevents when parsing JSON files unless V=1 is specified
> 	- Cleanup error messages
> 	- Fix memory leak with ->cpuid
> 	- Rebase to Arnaldo's tree
> 	- Allow overriding CPUID via environment variable
> 	- Support long descriptions for events
> 	- Handle header line in mapfile.csv
> 	- Cleanup JSON files (trim PublicDescription if identical to/prefix of
> 	  BriefDescription field)
> 
> 
> Andi Kleen (12):
>   perf, tools: Add jsmn `jasmine' JSON parser
>   perf, tools, jevents: Program to convert JSON file to C style file
>   perf, tools: Support CPU id matching for x86 v2
>   perf, tools: Support alias descriptions
>   perf, tools: Query terminal width and use in perf list
>   perf, tools: Add a --no-desc flag to perf list
>   perf, tools: Add override support for event list CPUID
>   perf, tools: Add support for event list topics
>   perf, tools, jevents: Handle header line in mapfile
>   perf, tools: Make alias matching case-insensitive
>   perf, tools, pmu-events: Fix fixed counters on Intel
>   perf, tools, pmu-events: Add Skylake frontend MSR support
> 
> Sukadev Bhattiprolu (7):
>   perf, tools: Use pmu_events table to create aliases
>   perf, tools: Support CPU ID matching for Powerpc
>   perf, tools, jevents: Add support for long descriptions
>   perf, tools: Add alias support for long descriptions
>   perf, tools: Support long descriptions with perf list
>   perf, tools: Add README for info on parsing JSON/map files
>   Allow period= in perf stat CPU event descriptions.
> 
>  tools/lib/subcmd/pager.c               |  16 +
>  tools/lib/subcmd/pager.h               |   1 +
>  tools/perf/Documentation/perf-list.txt |  12 +-
>  tools/perf/Makefile.perf               |  28 +-
>  tools/perf/arch/powerpc/util/header.c  |  11 +
>  tools/perf/arch/x86/util/header.c      |  24 +-
>  tools/perf/builtin-list.c              |  20 +-
>  tools/perf/pmu-events/Build            |  11 +
>  tools/perf/pmu-events/README           | 148 ++++++
>  tools/perf/pmu-events/jevents.c        | 811 +++++++++++++++++++++++++++++++++
>  tools/perf/pmu-events/jevents.h        |  18 +
>  tools/perf/pmu-events/jsmn.c           | 313 +++++++++++++
>  tools/perf/pmu-events/jsmn.h           |  67 +++
>  tools/perf/pmu-events/json.c           | 162 +++++++
>  tools/perf/pmu-events/json.h           |  42 ++
>  tools/perf/pmu-events/pmu-events.h     |  37 ++
>  tools/perf/util/header.h               |   1 +
>  tools/perf/util/parse-events.c         |   8 +-
>  tools/perf/util/parse-events.h         |   3 +-
>  tools/perf/util/pmu.c                  | 177 ++++++-
>  tools/perf/util/pmu.h                  |   6 +-
>  21 files changed, 1880 insertions(+), 36 deletions(-)
>  create mode 100644 tools/perf/pmu-events/Build
>  create mode 100644 tools/perf/pmu-events/README
>  create mode 100644 tools/perf/pmu-events/jevents.c
>  create mode 100644 tools/perf/pmu-events/jevents.h
>  create mode 100644 tools/perf/pmu-events/jsmn.c
>  create mode 100644 tools/perf/pmu-events/jsmn.h
>  create mode 100644 tools/perf/pmu-events/json.c
>  create mode 100644 tools/perf/pmu-events/json.h
>  create mode 100644 tools/perf/pmu-events/pmu-events.h
> 
> -- 
> 1.8.3.1

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH v21 00/20] perf, tools: Add support for PMU events in JSON format
  2016-09-15 22:24 [PATCH v21 00/20] perf, tools: Add support for PMU events in JSON format Sukadev Bhattiprolu
                   ` (19 preceding siblings ...)
  2016-09-19 16:58 ` [PATCH v21 00/20] perf, tools: Add support for PMU events in JSON format Sukadev Bhattiprolu
@ 2016-09-19 21:20 ` Arnaldo Carvalho de Melo
  2016-09-19 23:31   ` Arnaldo Carvalho de Melo
  20 siblings, 1 reply; 70+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-09-19 21:20 UTC (permalink / raw)
  To: Sukadev Bhattiprolu; +Cc: peterz, maddy, linuxppc-dev, linux-kernel

Em Thu, Sep 15, 2016 at 03:24:37PM -0700, Sukadev Bhattiprolu escreveu:
> CPUs support a large number of performance monitoring events (PMU events)
> and often these events are very specific to an architecture/model of the
> CPU. To use most of these PMU events with perf, we currently have to identify
> them by their raw codes:
> 
> 	perf stat -e r100f2 sleep 1

So, trying to build this with my set of containers I get lots of failures,
double checking running on another machine with those containers for the
segfault cases, changing sys/fcntl.h to fcntl.h cures the build on alpine:3.4
(musl libc), will try to fix all of them.

The list is incomplete, lots of other systems failed as well.

- Arnaldo

 1 alpine:3.4: FAIL
  CC       /tmp/build/perf/pmu-events/jsmn.o
In file included from pmu-events/json.c:35:0:
/usr/include/sys/fcntl.h:1:2: error: #warning redirecting incorrect
#include <sys/fcntl.h> to <fcntl.h> [-Werror=cpp]
 #warning redirecting incorrect #include <sys/fcntl.h> to <fcntl.h>
-----------------------------------------------------------------------
android-ndk:r12b-arm: FAIL

  CC       /tmp/build/perf/event-plugin.o
pmu-events/json.c:35:23: fatal error: sys/fcntl.h: No such file or
directory
 #include <sys/fcntl.h>
                       ^
compilation terminated.
-----------------------------------------------------------------------
archlinux:latest: FAIL
/bin/sh: line 1:  1408 Segmentation fault      (core dumped) /tmp/build/perf/pmu-events/jevents x86 pmu-events/arch /tmp/build/perf/pmu-events/pmu-events.c
make[2]: *** [pmu-events/Build:11: /tmp/build/perf/pmu-events/pmu-events.c] Error 139
make[1]: *** [Makefile.perf:461: /tmp/build/perf/pmu-events/pmu-events-in.o] Error 2
make[1]: *** Waiting for unfinished jobs....
-----------------------------------------------------------------------
centos:5: FAIL
/bin/sh: line 1:  1336 Segmentation fault      (core dumped) /tmp/build/perf/pmu-events/jevents x86 pmu-events/arch /tmp/build/perf/pmu-events/pmu-events.c
make[2]: *** [/tmp/build/perf/pmu-events/pmu-events.c] Error 139
make[1]: *** [/tmp/build/perf/pmu-events/pmu-events-in.o] Error 2
make[1]: *** Waiting for unfinished jobs....
-----------------------------------------------------------------------
centos:6: FAIL
/bin/sh: line 1:  1633 Segmentation fault      (core dumped) /tmp/build/perf/pmu-events/jevents x86 pmu-events/arch /tmp/build/perf/pmu-events/pmu-events.c
make[2]: *** [/tmp/build/perf/pmu-events/pmu-events.c] Error 139
make[1]: *** [/tmp/build/perf/pmu-events/pmu-events-in.o] Error 2
make[1]: *** Waiting for unfinished jobs....
-----------------------------------------------------------------------
centos:7: FAIL
  GEN      /tmp/build/perf/pmu-events/pmu-events.c
/bin/sh: line 1:  1548 Segmentation fault      (core dumped) /tmp/build/perf/pmu-events/jevents x86 pmu-events/arch /tmp/build/perf/pmu-events/pmu-events.c
make[2]: *** [/tmp/build/perf/pmu-events/pmu-events.c] Error 139
make[1]: *** [/tmp/build/perf/pmu-events/pmu-events-in.o] Error 2
make[1]: *** Waiting for unfinished jobs....
-----------------------------------------------------------------------
debian:7: Ok
-----------------------------------------------------------------------
debian:8: FAIL
  GEN      /tmp/build/perf/pmu-events/pmu-events.c
Segmentation fault (core dumped)
pmu-events/Build:11: recipe for target '/tmp/build/perf/pmu-events/pmu-events.c' failed
make[2]: *** [/tmp/build/perf/pmu-events/pmu-events.c] Error 139
Makefile.perf:461: recipe for target '/tmp/build/perf/pmu-events/pmu-events-in.o' failed
make[1]: *** [/tmp/build/perf/pmu-events/pmu-events-in.o] Error 2
make[1]: *** Waiting for unfinished jobs....
-----------------------------------------------------------------------
debian:experimental: FAIL
  GEN      /tmp/build/perf/pmu-events/pmu-events.c
Segmentation fault (core dumped)
pmu-events/Build:11: recipe for target '/tmp/build/perf/pmu-events/pmu-events.c' failed
make[2]: *** [/tmp/build/perf/pmu-events/pmu-events.c] Error 139
Makefile.perf:461: recipe for target '/tmp/build/perf/pmu-events/pmu-events-in.o' failed
make[1]: *** [/tmp/build/perf/pmu-events/pmu-events-in.o] Error 2
-----------------------------------------------------------------------
fedora:20: FAIL
/bin/sh: line 1:  1460 Segmentation fault      (core dumped) /tmp/build/perf/pmu-events/jevents x86 pmu-events/arch /tmp/build/perf/pmu-events/pmu-events.c
make[2]: *** [/tmp/build/perf/pmu-events/pmu-events.c] Error 139
make[1]: *** [/tmp/build/perf/pmu-events/pmu-events-in.o] Error 2
make[1]: *** Waiting for unfinished jobs....
-----------------------------------------------------------------------

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH v21 00/20] perf, tools: Add support for PMU events in JSON format
  2016-09-19 21:20 ` Arnaldo Carvalho de Melo
@ 2016-09-19 23:31   ` Arnaldo Carvalho de Melo
  2016-09-19 23:37     ` Arnaldo Carvalho de Melo
  0 siblings, 1 reply; 70+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-09-19 23:31 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Sukadev Bhattiprolu, peterz, maddy, linuxppc-dev, linux-kernel

Em Mon, Sep 19, 2016 at 06:20:17PM -0300, Arnaldo Carvalho de Melo escreveu:
> Em Thu, Sep 15, 2016 at 03:24:37PM -0700, Sukadev Bhattiprolu escreveu:
> > CPUs support a large number of performance monitoring events (PMU events)
> > and often these events are very specific to an architecture/model of the
> > CPU. To use most of these PMU events with perf, we currently have to identify
> > them by their raw codes:
> > 
> > 	perf stat -e r100f2 sleep 1
> 
> So, trying to build this with my set of containers I get lots of failures,
> double checking running on another machine with those containers for the
> segfault cases, changing sys/fcntl.h to fcntl.h cures the build on alpine:3.4
> (musl libc), will try to fix all of them.
> 
> The list is incomplete, lots of other systems failed as well.
> 
> - Arnaldo
> 
 1 alpine:3.4: Ok

Fixed with fcntl.h + capping the maxfds parameter to nftw to avoid it
exploding on alloca() in environments where rlim_max is set to a high
value, like in docker.

Now looking at:

  CC       /tmp/build/perf/fs/tracing_path.o
In file included from /git/linux/tools/include/linux/types.h:4:0,
                 from /opt/android-ndk-r12b/platforms/android-24/arch-arm/usr/include/sys/types.h:35,
                 from /opt/android-ndk-r12b/platforms/android-24/arch-arm/usr/include/strings.h:42,
                 from /opt/android-ndk-r12b/platforms/android-24/arch-arm/usr/include/stdlib.h:36,
                 from pmu-events/json.c:31:
pmu-events/json.h:15:22: error: two or more data types in declaration specifiers
 typedef unsigned int bool;


Which looks like clashing with stdbool.h...

- Arnaldo


> android-ndk:r12b-arm: FAIL
> 
>   CC       /tmp/build/perf/event-plugin.o
> pmu-events/json.c:35:23: fatal error: sys/fcntl.h: No such file or
> directory
>  #include <sys/fcntl.h>
>                        ^
> compilation terminated.
> -----------------------------------------------------------------------
> archlinux:latest: FAIL
> /bin/sh: line 1:  1408 Segmentation fault      (core dumped) /tmp/build/perf/pmu-events/jevents x86 pmu-events/arch /tmp/build/perf/pmu-events/pmu-events.c
> make[2]: *** [pmu-events/Build:11: /tmp/build/perf/pmu-events/pmu-events.c] Error 139
> make[1]: *** [Makefile.perf:461: /tmp/build/perf/pmu-events/pmu-events-in.o] Error 2
> make[1]: *** Waiting for unfinished jobs....
> -----------------------------------------------------------------------
> centos:5: FAIL
> /bin/sh: line 1:  1336 Segmentation fault      (core dumped) /tmp/build/perf/pmu-events/jevents x86 pmu-events/arch /tmp/build/perf/pmu-events/pmu-events.c
> make[2]: *** [/tmp/build/perf/pmu-events/pmu-events.c] Error 139
> make[1]: *** Waiting for unfinished jobs....
> -----------------------------------------------------------------------
> centos:6: FAIL
> /bin/sh: line 1:  1633 Segmentation fault      (core dumped) /tmp/build/perf/pmu-events/jevents x86 pmu-events/arch /tmp/build/perf/pmu-events/pmu-events.c
> make[2]: *** [/tmp/build/perf/pmu-events/pmu-events.c] Error 139
> make[1]: *** [/tmp/build/perf/pmu-events/pmu-events-in.o] Error 2
> make[1]: *** Waiting for unfinished jobs....
> -----------------------------------------------------------------------
> centos:7: FAIL
>   GEN      /tmp/build/perf/pmu-events/pmu-events.c
> /bin/sh: line 1:  1548 Segmentation fault      (core dumped) /tmp/build/perf/pmu-events/jevents x86 pmu-events/arch /tmp/build/perf/pmu-events/pmu-events.c
> make[2]: *** [/tmp/build/perf/pmu-events/pmu-events.c] Error 139
> make[1]: *** [/tmp/build/perf/pmu-events/pmu-events-in.o] Error 2
> make[1]: *** Waiting for unfinished jobs....
> -----------------------------------------------------------------------
> debian:7: Ok
> -----------------------------------------------------------------------
> debian:8: FAIL
>   GEN      /tmp/build/perf/pmu-events/pmu-events.c
> Segmentation fault (core dumped)
> pmu-events/Build:11: recipe for target '/tmp/build/perf/pmu-events/pmu-events.c' failed
> make[2]: *** [/tmp/build/perf/pmu-events/pmu-events.c] Error 139
> Makefile.perf:461: recipe for target '/tmp/build/perf/pmu-events/pmu-events-in.o' failed
> make[1]: *** [/tmp/build/perf/pmu-events/pmu-events-in.o] Error 2
> make[1]: *** Waiting for unfinished jobs....
> -----------------------------------------------------------------------
> debian:experimental: FAIL
>   GEN      /tmp/build/perf/pmu-events/pmu-events.c
> Segmentation fault (core dumped)
> pmu-events/Build:11: recipe for target '/tmp/build/perf/pmu-events/pmu-events.c' failed
> make[2]: *** [/tmp/build/perf/pmu-events/pmu-events.c] Error 139
> Makefile.perf:461: recipe for target '/tmp/build/perf/pmu-events/pmu-events-in.o' failed
> make[1]: *** [/tmp/build/perf/pmu-events/pmu-events-in.o] Error 2
> -----------------------------------------------------------------------
> fedora:20: FAIL
> /bin/sh: line 1:  1460 Segmentation fault      (core dumped) /tmp/build/perf/pmu-events/jevents x86 pmu-events/arch /tmp/build/perf/pmu-events/pmu-events.c
> make[2]: *** [/tmp/build/perf/pmu-events/pmu-events.c] Error 139
> make[1]: *** [/tmp/build/perf/pmu-events/pmu-events-in.o] Error 2
> make[1]: *** Waiting for unfinished jobs....
> -----------------------------------------------------------------------

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH v21 00/20] perf, tools: Add support for PMU events in JSON format
  2016-09-19 23:31   ` Arnaldo Carvalho de Melo
@ 2016-09-19 23:37     ` Arnaldo Carvalho de Melo
  2016-09-20  0:02       ` Arnaldo Carvalho de Melo
  0 siblings, 1 reply; 70+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-09-19 23:37 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Sukadev Bhattiprolu, peterz, maddy, linuxppc-dev, linux-kernel

Em Mon, Sep 19, 2016 at 08:31:13PM -0300, Arnaldo Carvalho de Melo escreveu:
> Em Mon, Sep 19, 2016 at 06:20:17PM -0300, Arnaldo Carvalho de Melo escreveu:
> > Em Thu, Sep 15, 2016 at 03:24:37PM -0700, Sukadev Bhattiprolu escreveu:
> > > CPUs support a large number of performance monitoring events (PMU events)
> > > and often these events are very specific to an architecture/model of the
> > > CPU. To use most of these PMU events with perf, we currently have to identify
> > > them by their raw codes:
> > > 
> > > 	perf stat -e r100f2 sleep 1
> > 
> > So, trying to build this with my set of containers I get lots of failures,
> > double checking running on another machine with those containers for the
> > segfault cases, changing sys/fcntl.h to fcntl.h cures the build on alpine:3.4
> > (musl libc), will try to fix all of them.
> > 
> > The list is incomplete, lots of other systems failed as well.
> > 
> > - Arnaldo
> > 
>  1 alpine:3.4: Ok
> 
> Fixed with fcntl.h + capping the maxfds parameter to nftw to avoid it
> exploding on alloca() in environments where rlim_max is set to a high
> value, like in docker.
> 
> Now looking at:
> 
>   CC       /tmp/build/perf/fs/tracing_path.o
> In file included from /git/linux/tools/include/linux/types.h:4:0,
>                  from /opt/android-ndk-r12b/platforms/android-24/arch-arm/usr/include/sys/types.h:35,
>                  from /opt/android-ndk-r12b/platforms/android-24/arch-arm/usr/include/strings.h:42,
>                  from /opt/android-ndk-r12b/platforms/android-24/arch-arm/usr/include/stdlib.h:36,
>                  from pmu-events/json.c:31:
> pmu-events/json.h:15:22: error: two or more data types in declaration specifiers
>  typedef unsigned int bool;
> 
> 
> Which looks like clashing with stdbool.h...

yeah, changing that typedef + true def to plain include <stdbool.h>
makes it progress to the next failure, which is in cross compilation
environments, such as using fedora 24 + the Android NDK to try to build
a ARM android binary.

On the bright side, in addition to alpine:3.4 now these are building ok:

 3 archlinux:latest: Ok
 4 centos:5: Ok
 5 centos:6: Ok
 6 centos:7: Ok
 7 debian:7: Ok
 8 debian:8: Ok
 9 fedora:20: Ok

Waiting for some extra cross compilation envs to check that hunch...

- Arnaldo

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH v21 00/20] perf, tools: Add support for PMU events in JSON format
  2016-09-19 23:37     ` Arnaldo Carvalho de Melo
@ 2016-09-20  0:02       ` Arnaldo Carvalho de Melo
  2016-09-20  0:28         ` Arnaldo Carvalho de Melo
  0 siblings, 1 reply; 70+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-09-20  0:02 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Sukadev Bhattiprolu, peterz, maddy, linuxppc-dev, linux-kernel

Em Mon, Sep 19, 2016 at 08:37:53PM -0300, Arnaldo Carvalho de Melo escreveu:
> yeah, changing that typedef + true def to plain include <stdbool.h>
> makes it progress to the next failure, which is in cross compilation
> environments, such as using fedora 24 + the Android NDK to try to build
> a ARM android binary.
> 
> On the bright side, in addition to alpine:3.4 now these are building ok:
> 
>  3 archlinux:latest: Ok
>  4 centos:5: Ok
>  5 centos:6: Ok
>  6 centos:7: Ok
>  7 debian:7: Ok
>  8 debian:8: Ok
>  9 fedora:20: Ok
> 
> Waiting for some extra cross compilation envs to check that hunch...

Yeap:

10 fedora:21: Ok
11 fedora:22: Ok
12 fedora:23: Ok
13 fedora:24: Ok
14 fedora:24-x-ARC-uClibc: FAIL
  GEN      /tmp/build/perf/pmu-events/pmu-events.c
/bin/sh: /tmp/build/perf/pmu-events/jevents: cannot execute binary file: Exec format error
pmu-events/Build:11: recipe for target '/tmp/build/perf/pmu-events/pmu-events.c' failed
make[2]: *** [/tmp/build/perf/pmu-events/pmu-events.c] Error 126
Makefile.perf:461: recipe for target '/tmp/build/perf/pmu-events/pmu-events-in.o' failed
make[1]: *** [/tmp/build/perf/pmu-events/pmu-events-in.o] Error 2
make[1]: *** Waiting for unfinished jobs....
15 fedora:rawhide: Ok
16 mageia:5: Ok
17 opensuse:13.2: Ok
18 opensuse:42.1: Ok
19 86.364838418 opensuse:tumbleweed: Ok
20 62.414227297 ubuntu:12.04.5: Ok
21 41.172970676 ubuntu:14.04: Ok
22 74.243049939 ubuntu:14.04.4: Ok
23 75.634449405 ubuntu:15.10: Ok
24 70.487913217 ubuntu:16.04: Ok
25 33.938554395 ubuntu:16.04-x-arm: FAIL
26 31.902507224 ubuntu:16.04-x-arm64: FAIL
27 32.903876355 ubuntu:16.04-x-powerpc64: FAIL
28 32.849412876 ubuntu:16.04-x-powerpc64el: FAIL
29 79.446950856 ubuntu:16.10: Ok
30 33.443948539 ubuntu:16.10-x-arm64: FAIL
31 33.801496151 ubuntu:16.10-x-powerpc: FAIL
32 32.860975730 ubuntu:16.10-x-s390: FAIL

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH v21 00/20] perf, tools: Add support for PMU events in JSON format
  2016-09-20  0:02       ` Arnaldo Carvalho de Melo
@ 2016-09-20  0:28         ` Arnaldo Carvalho de Melo
  2016-09-22 14:56           ` Arnaldo Carvalho de Melo
  2016-09-22 15:00           ` Jiri Olsa
  0 siblings, 2 replies; 70+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-09-20  0:28 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Sukadev Bhattiprolu, peterz, maddy, linuxppc-dev, linux-kernel

Em Mon, Sep 19, 2016 at 09:02:58PM -0300, Arnaldo Carvalho de Melo escreveu:
> Em Mon, Sep 19, 2016 at 08:37:53PM -0300, Arnaldo Carvalho de Melo escreveu:
> > yeah, changing that typedef + true def to plain include <stdbool.h>
> > makes it progress to the next failure, which is in cross compilation
> > environments, such as using fedora 24 + the Android NDK to try to build
> > a ARM android binary.

> 14 fedora:24-x-ARC-uClibc: FAIL
>   GEN      /tmp/build/perf/pmu-events/pmu-events.c
> /bin/sh: /tmp/build/perf/pmu-events/jevents: cannot execute binary file: Exec format error
> pmu-events/Build:11: recipe for target '/tmp/build/perf/pmu-events/pmu-events.c' failed
> make[2]: *** [/tmp/build/perf/pmu-events/pmu-events.c] Error 126
> Makefile.perf:461: recipe for target '/tmp/build/perf/pmu-events/pmu-events-in.o' failed
> make[1]: *** [/tmp/build/perf/pmu-events/pmu-events-in.o] Error 2
> make[1]: *** Waiting for unfinished jobs....

Jiri, we need something similar to scripts/Makefile.host :-\

Calling it a day, perhaps, for now, we should just detect that it is a
corss compile env (CROSS_COMPILE is set) and exclude all this code from
the build, emitting a warning.

I left what I did at the tmp.perf/core branch of my repo at
git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git.

- Arnaldo

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH v21 00/20] perf, tools: Add support for PMU events in JSON format
  2016-09-20  0:28         ` Arnaldo Carvalho de Melo
@ 2016-09-22 14:56           ` Arnaldo Carvalho de Melo
  2016-09-22 15:00           ` Jiri Olsa
  1 sibling, 0 replies; 70+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-09-22 14:56 UTC (permalink / raw)
  To: Jiri Olsa; +Cc: Sukadev Bhattiprolu, peterz, maddy, linuxppc-dev, linux-kernel

oops, Jiri wasn't CCed, fixing it...

Em Mon, Sep 19, 2016 at 09:28:20PM -0300, Arnaldo Carvalho de Melo escreveu:
> Em Mon, Sep 19, 2016 at 09:02:58PM -0300, Arnaldo Carvalho de Melo escreveu:
> > Em Mon, Sep 19, 2016 at 08:37:53PM -0300, Arnaldo Carvalho de Melo escreveu:
> > > yeah, changing that typedef + true def to plain include <stdbool.h>
> > > makes it progress to the next failure, which is in cross compilation
> > > environments, such as using fedora 24 + the Android NDK to try to build
> > > a ARM android binary.
> 
> > 14 fedora:24-x-ARC-uClibc: FAIL
> >   GEN      /tmp/build/perf/pmu-events/pmu-events.c
> > /bin/sh: /tmp/build/perf/pmu-events/jevents: cannot execute binary file: Exec format error
> > pmu-events/Build:11: recipe for target '/tmp/build/perf/pmu-events/pmu-events.c' failed
> > make[2]: *** [/tmp/build/perf/pmu-events/pmu-events.c] Error 126
> > Makefile.perf:461: recipe for target '/tmp/build/perf/pmu-events/pmu-events-in.o' failed
> > make[1]: *** [/tmp/build/perf/pmu-events/pmu-events-in.o] Error 2
> > make[1]: *** Waiting for unfinished jobs....
> 
> Jiri, we need something similar to scripts/Makefile.host :-\
> 
> Calling it a day, perhaps, for now, we should just detect that it is a
> corss compile env (CROSS_COMPILE is set) and exclude all this code from
> the build, emitting a warning.
> 
> I left what I did at the tmp.perf/core branch of my repo at
> git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git.
> 
> - Arnaldo

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH v21 00/20] perf, tools: Add support for PMU events in JSON format
  2016-09-20  0:28         ` Arnaldo Carvalho de Melo
  2016-09-22 14:56           ` Arnaldo Carvalho de Melo
@ 2016-09-22 15:00           ` Jiri Olsa
  2016-09-22 16:27             ` Jiri Olsa
  1 sibling, 1 reply; 70+ messages in thread
From: Jiri Olsa @ 2016-09-22 15:00 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Arnaldo Carvalho de Melo, Sukadev Bhattiprolu, peterz, maddy,
	linuxppc-dev, linux-kernel

On Mon, Sep 19, 2016 at 09:28:20PM -0300, Arnaldo Carvalho de Melo wrote:
> Em Mon, Sep 19, 2016 at 09:02:58PM -0300, Arnaldo Carvalho de Melo escreveu:
> > Em Mon, Sep 19, 2016 at 08:37:53PM -0300, Arnaldo Carvalho de Melo escreveu:
> > > yeah, changing that typedef + true def to plain include <stdbool.h>
> > > makes it progress to the next failure, which is in cross compilation
> > > environments, such as using fedora 24 + the Android NDK to try to build
> > > a ARM android binary.
> 
> > 14 fedora:24-x-ARC-uClibc: FAIL
> >   GEN      /tmp/build/perf/pmu-events/pmu-events.c
> > /bin/sh: /tmp/build/perf/pmu-events/jevents: cannot execute binary file: Exec format error
> > pmu-events/Build:11: recipe for target '/tmp/build/perf/pmu-events/pmu-events.c' failed
> > make[2]: *** [/tmp/build/perf/pmu-events/pmu-events.c] Error 126
> > Makefile.perf:461: recipe for target '/tmp/build/perf/pmu-events/pmu-events-in.o' failed
> > make[1]: *** [/tmp/build/perf/pmu-events/pmu-events-in.o] Error 2
> > make[1]: *** Waiting for unfinished jobs....
> 
> Jiri, we need something similar to scripts/Makefile.host :-\
> 
> Calling it a day, perhaps, for now, we should just detect that it is a
> corss compile env (CROSS_COMPILE is set) and exclude all this code from
> the build, emitting a warning.
> 
> I left what I did at the tmp.perf/core branch of my repo at
> git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git.

as discussed on irc we will disable it for cross builds now,
because we dont have good solution at the moment.. it's
similar case as for fixdep tool:

    3a70fcd3a4db tools build: Fix cross compile build
    ...
    We need to add support for host side tools build, meanwhile
    disabling fixdep usage for cross arch builds.

I'll make a change to disable this for crossbuild and
work on common solution later

thanks,
jirka

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH v21 00/20] perf, tools: Add support for PMU events in JSON format
  2016-09-22 15:00           ` Jiri Olsa
@ 2016-09-22 16:27             ` Jiri Olsa
  2016-09-26  8:35               ` Jiri Olsa
  0 siblings, 1 reply; 70+ messages in thread
From: Jiri Olsa @ 2016-09-22 16:27 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Arnaldo Carvalho de Melo, Sukadev Bhattiprolu, peterz, maddy,
	linuxppc-dev, linux-kernel

On Thu, Sep 22, 2016 at 05:00:22PM +0200, Jiri Olsa wrote:
> On Mon, Sep 19, 2016 at 09:28:20PM -0300, Arnaldo Carvalho de Melo wrote:
> > Em Mon, Sep 19, 2016 at 09:02:58PM -0300, Arnaldo Carvalho de Melo escreveu:
> > > Em Mon, Sep 19, 2016 at 08:37:53PM -0300, Arnaldo Carvalho de Melo escreveu:
> > > > yeah, changing that typedef + true def to plain include <stdbool.h>
> > > > makes it progress to the next failure, which is in cross compilation
> > > > environments, such as using fedora 24 + the Android NDK to try to build
> > > > a ARM android binary.
> > 
> > > 14 fedora:24-x-ARC-uClibc: FAIL
> > >   GEN      /tmp/build/perf/pmu-events/pmu-events.c
> > > /bin/sh: /tmp/build/perf/pmu-events/jevents: cannot execute binary file: Exec format error
> > > pmu-events/Build:11: recipe for target '/tmp/build/perf/pmu-events/pmu-events.c' failed
> > > make[2]: *** [/tmp/build/perf/pmu-events/pmu-events.c] Error 126
> > > Makefile.perf:461: recipe for target '/tmp/build/perf/pmu-events/pmu-events-in.o' failed
> > > make[1]: *** [/tmp/build/perf/pmu-events/pmu-events-in.o] Error 2
> > > make[1]: *** Waiting for unfinished jobs....
> > 
> > Jiri, we need something similar to scripts/Makefile.host :-\
> > 
> > Calling it a day, perhaps, for now, we should just detect that it is a
> > corss compile env (CROSS_COMPILE is set) and exclude all this code from
> > the build, emitting a warning.
> > 
> > I left what I did at the tmp.perf/core branch of my repo at
> > git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git.
> 
> as discussed on irc we will disable it for cross builds now,
> because we dont have good solution at the moment.. it's
> similar case as for fixdep tool:
> 
>     3a70fcd3a4db tools build: Fix cross compile build
>     ...
>     We need to add support for host side tools build, meanwhile
>     disabling fixdep usage for cross arch builds.
> 
> I'll make a change to disable this for crossbuild and
> work on common solution later

could you please give it a try with patch below?
I tested but not with properly cross building...

also,  did you want some message during the cross build that pmu-events are not included?

thanks,
jirka


---
diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index 24803c58049a..ec3a59d9a56b 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -755,6 +755,10 @@ ifndef NO_AUXTRACE
   endif
 endif
 
+ifndef CROSS_COMPILE
+  CFLAGS += -DHAVE_PMU_EVENTS_SUPPORT
+endif
+
 # Among the variables below, these:
 #   perfexecdir
 #   template_dir
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 0abebcba849f..85257c49d5ab 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -349,7 +349,14 @@ include $(srctree)/tools/build/Makefile.include
 
 JEVENTS       := $(OUTPUT)pmu-events/jevents
 JEVENTS_IN    := $(OUTPUT)pmu-events/jevents-in.o
+
+#
+# Disabling pmu-events for cross compile, as
+# we dont support host CC tools building yet.
+#
+ifndef CROSS_COMPILE
 PMU_EVENTS_IN := $(OUTPUT)pmu-events/pmu-events-in.o
+endif
 
 export JEVENTS
 
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index ac097fcaba7b..21a3f21a6f6f 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -482,6 +482,8 @@ static struct cpu_map *pmu_cpumask(const char *name)
 	return cpus;
 }
 
+#ifdef HAVE_PMU_EVENTS_SUPPORT
+
 /*
  * Return the CPU id as a raw string.
  *
@@ -545,6 +547,13 @@ out:
 	return 0;
 }
 
+#else
+static int pmu_add_cpu_aliases(struct list_head *head __maybe_unused)
+{
+	return 0;
+}
+#endif /* HAVE_PMU_EVENTS_SUPPORT */
+
 struct perf_event_attr * __weak
 perf_pmu__get_default_config(struct perf_pmu *pmu __maybe_unused)
 {

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* Re: [PATCH v21 00/20] perf, tools: Add support for PMU events in JSON format
  2016-09-22 16:27             ` Jiri Olsa
@ 2016-09-26  8:35               ` Jiri Olsa
  2016-09-26 15:03                 ` Arnaldo Carvalho de Melo
  0 siblings, 1 reply; 70+ messages in thread
From: Jiri Olsa @ 2016-09-26  8:35 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Arnaldo Carvalho de Melo, Sukadev Bhattiprolu, peterz, maddy,
	linuxppc-dev, linux-kernel, Andi Kleen

On Thu, Sep 22, 2016 at 06:27:13PM +0200, Jiri Olsa wrote:
> On Thu, Sep 22, 2016 at 05:00:22PM +0200, Jiri Olsa wrote:
> > On Mon, Sep 19, 2016 at 09:28:20PM -0300, Arnaldo Carvalho de Melo wrote:
> > > Em Mon, Sep 19, 2016 at 09:02:58PM -0300, Arnaldo Carvalho de Melo escreveu:
> > > > Em Mon, Sep 19, 2016 at 08:37:53PM -0300, Arnaldo Carvalho de Melo escreveu:
> > > > > yeah, changing that typedef + true def to plain include <stdbool.h>
> > > > > makes it progress to the next failure, which is in cross compilation
> > > > > environments, such as using fedora 24 + the Android NDK to try to build
> > > > > a ARM android binary.
> > > 
> > > > 14 fedora:24-x-ARC-uClibc: FAIL
> > > >   GEN      /tmp/build/perf/pmu-events/pmu-events.c
> > > > /bin/sh: /tmp/build/perf/pmu-events/jevents: cannot execute binary file: Exec format error
> > > > pmu-events/Build:11: recipe for target '/tmp/build/perf/pmu-events/pmu-events.c' failed
> > > > make[2]: *** [/tmp/build/perf/pmu-events/pmu-events.c] Error 126
> > > > Makefile.perf:461: recipe for target '/tmp/build/perf/pmu-events/pmu-events-in.o' failed
> > > > make[1]: *** [/tmp/build/perf/pmu-events/pmu-events-in.o] Error 2
> > > > make[1]: *** Waiting for unfinished jobs....
> > > 
> > > Jiri, we need something similar to scripts/Makefile.host :-\
> > > 
> > > Calling it a day, perhaps, for now, we should just detect that it is a
> > > corss compile env (CROSS_COMPILE is set) and exclude all this code from
> > > the build, emitting a warning.
> > > 
> > > I left what I did at the tmp.perf/core branch of my repo at
> > > git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git.
> > 
> > as discussed on irc we will disable it for cross builds now,
> > because we dont have good solution at the moment.. it's
> > similar case as for fixdep tool:
> > 
> >     3a70fcd3a4db tools build: Fix cross compile build
> >     ...
> >     We need to add support for host side tools build, meanwhile
> >     disabling fixdep usage for cross arch builds.
> > 
> > I'll make a change to disable this for crossbuild and
> > work on common solution later
> 
> could you please give it a try with patch below?
> I tested but not with properly cross building...
> 
> also,  did you want some message during the cross build that pmu-events are not included?

ping.. is that working for you? IMO we can include this
as additional patch to the set..

thanks,
jirka

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH v21 00/20] perf, tools: Add support for PMU events in JSON format
  2016-09-26  8:35               ` Jiri Olsa
@ 2016-09-26 15:03                 ` Arnaldo Carvalho de Melo
  2016-09-26 16:59                   ` Andi Kleen
  0 siblings, 1 reply; 70+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-09-26 15:03 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: Arnaldo Carvalho de Melo, Sukadev Bhattiprolu, peterz, maddy,
	linuxppc-dev, linux-kernel, Andi Kleen

Em Mon, Sep 26, 2016 at 10:35:33AM +0200, Jiri Olsa escreveu:
> ping.. is that working for you? IMO we can include this
> as additional patch to the set..

No, it doesn't fails to build on the first cross env I tried, fixing it
now, resulting patch:

diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index 72edf83d76b7..9365c155c6f3 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -758,6 +758,10 @@ ifndef NO_AUXTRACE
   endif
 endif
 
+ifndef CROSS_COMPILE
+  CFLAGS += -DHAVE_PMU_EVENTS_SUPPORT
+endif
+
 # Among the variables below, these:
 #   perfexecdir
 #   template_dir
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 26dbee50b36c..ee86dbf2814e 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -349,7 +349,14 @@ include $(srctree)/tools/build/Makefile.include
 
 JEVENTS       := $(OUTPUT)pmu-events/jevents
 JEVENTS_IN    := $(OUTPUT)pmu-events/jevents-in.o
+
+#
+# Disabling pmu-events for cross compile, as
+# we dont support host CC tools building yet.
+#
+ifndef CROSS_COMPILE
 PMU_EVENTS_IN := $(OUTPUT)pmu-events/pmu-events-in.o
+endif
 
 export JEVENTS
 
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index 2babcdf62839..37f74fcc9ca2 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -377,6 +377,8 @@ static int pmu_alias_terms(struct perf_pmu_alias *alias,
 	return 0;
 }
 
+#ifdef HAVE_PMU_EVENTS_SUPPORT
+
 /*
  * Reading/parsing the default pmu type value, which should be
  * located at:
@@ -473,6 +475,23 @@ static struct cpu_map *pmu_cpumask(const char *name)
 	return cpus;
 }
 
+#else
+static int pmu_type(const char *name __maybe_unused, __u32 *type)
+{
+	*type = 0;
+	return 0;
+}
+
+static void pmu_read_sysfs(void)
+{
+}
+
+static struct cpu_map *pmu_cpumask(const char *name __maybe_unused)
+{
+	return NULL;
+}
+#endif /* HAVE_PMU_EVENTS_SUPPORT */
+
 struct perf_event_attr * __weak
 perf_pmu__get_default_config(struct perf_pmu *pmu __maybe_unused)
 {

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* Re: [PATCH v21 00/20] perf, tools: Add support for PMU events in JSON format
  2016-09-26 15:03                 ` Arnaldo Carvalho de Melo
@ 2016-09-26 16:59                   ` Andi Kleen
  2016-09-27 14:18                     ` Jiri Olsa
  0 siblings, 1 reply; 70+ messages in thread
From: Andi Kleen @ 2016-09-26 16:59 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Jiri Olsa, Arnaldo Carvalho de Melo, Sukadev Bhattiprolu, peterz,
	maddy, linuxppc-dev, linux-kernel, Andi Kleen

On Mon, Sep 26, 2016 at 12:03:43PM -0300, Arnaldo Carvalho de Melo wrote:
> Em Mon, Sep 26, 2016 at 10:35:33AM +0200, Jiri Olsa escreveu:
> > ping.. is that working for you? IMO we can include this
> > as additional patch to the set..
> 
> No, it doesn't fails to build on the first cross env I tried, fixing it
> now, resulting patch:

Yes it shouldn't be difficult to fix cross building. I don't think
there are any fundamental problems.

-Andi

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH v21 03/19] perf, tools: Use pmu_events table to create aliases
  2016-09-15 22:24 ` [PATCH v21 03/19] perf, tools: Use pmu_events table to create aliases Sukadev Bhattiprolu
@ 2016-09-27 13:16   ` Arnaldo Carvalho de Melo
  2016-10-04  8:12   ` [tip:perf/urgent] perf pmu: " tip-bot for Sukadev Bhattiprolu
  1 sibling, 0 replies; 70+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-09-27 13:16 UTC (permalink / raw)
  To: Sukadev Bhattiprolu; +Cc: peterz, maddy, linuxppc-dev, linux-kernel

Em Thu, Sep 15, 2016 at 03:24:40PM -0700, Sukadev Bhattiprolu escreveu:
> At run time (when 'perf' is starting up), locate the specific table
> of PMU events that corresponds to the current CPU. Using that table,
> create aliases for the each of the PMU events in the CPU. The use
> these aliases to parse the user specified perf event.
> 
> In short this would allow the user to specify events using their
> aliases rather than raw event codes.
> 
> Based on input and some earlier patches from Andi Kleen, Jiri Olsa.

this took a long time so I'll try to go chainsawing some stuff along the
way, like why introduce a function that returns an error just to ignore
it, even more using a ugly (void) cast?

- Arnaldo
 
> Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
> Acked-by: Jiri Olsa <jolsa@redhat.com>
> Acked-by: Ingo Molnar <mingo@kernel.org>
> ---
> 
> Changelog[v4]
> 	- Split off unrelated code into separate patches.
> Changelog[v3]
> 	- [Jiri Olsa] Fix memory leak in cpuid
> Changelog[v2]
> 	- [Andi Kleen] Replace pmu_events_map->vfm with a generic "cpuid".
> ---
>  tools/perf/util/header.h |  1 +
>  tools/perf/util/pmu.c    | 61 ++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 62 insertions(+)
> 
> diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h
> index d306ca1..d30109b 100644
> --- a/tools/perf/util/header.h
> +++ b/tools/perf/util/header.h
> @@ -151,4 +151,5 @@ int write_padded(int fd, const void *bf, size_t count, size_t count_aligned);
>   */
>  int get_cpuid(char *buffer, size_t sz);
>  
> +char *get_cpuid_str(void);
>  #endif /* __PERF_HEADER_H */
> diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
> index 2babcdf..c842886 100644
> --- a/tools/perf/util/pmu.c
> +++ b/tools/perf/util/pmu.c
> @@ -12,6 +12,8 @@
>  #include "pmu.h"
>  #include "parse-events.h"
>  #include "cpumap.h"
> +#include "header.h"
> +#include "pmu-events/pmu-events.h"
>  
>  struct perf_pmu_format {
>  	char *name;
> @@ -473,6 +475,62 @@ static struct cpu_map *pmu_cpumask(const char *name)
>  	return cpus;
>  }
>  
> +/*
> + * Return the CPU id as a raw string.
> + *
> + * Each architecture should provide a more precise id string that
> + * can be use to match the architecture's "mapfile".
> + */
> +char * __weak get_cpuid_str(void)
> +{
> +	return NULL;
> +}
> +
> +/*
> + * From the pmu_events_map, find the table of PMU events that corresponds
> + * to the current running CPU. Then, add all PMU events from that table
> + * as aliases.
> + */
> +static int pmu_add_cpu_aliases(struct list_head *head)
> +{
> +	int i;
> +	struct pmu_events_map *map;
> +	struct pmu_event *pe;
> +	char *cpuid;
> +
> +	cpuid = get_cpuid_str();
> +	if (!cpuid)
> +		return 0;
> +
> +	i = 0;
> +	while (1) {
> +		map = &pmu_events_map[i++];
> +		if (!map->table)
> +			goto out;
> +
> +		if (!strcmp(map->cpuid, cpuid))
> +			break;
> +	}
> +
> +	/*
> +	 * Found a matching PMU events table. Create aliases
> +	 */
> +	i = 0;
> +	while (1) {
> +		pe = &map->table[i++];
> +		if (!pe->name)
> +			break;
> +
> +		/* need type casts to override 'const' */
> +		__perf_pmu__new_alias(head, NULL, (char *)pe->name,
> +				(char *)pe->desc, (char *)pe->event);
> +	}
> +
> +out:
> +	free(cpuid);
> +	return 0;
> +}
> +
>  struct perf_event_attr * __weak
>  perf_pmu__get_default_config(struct perf_pmu *pmu __maybe_unused)
>  {
> @@ -497,6 +555,9 @@ static struct perf_pmu *pmu_lookup(const char *name)
>  	if (pmu_aliases(name, &aliases))
>  		return NULL;
>  
> +	if (!strcmp(name, "cpu"))
> +		(void)pmu_add_cpu_aliases(&aliases);
> +
>  	if (pmu_type(name, &type))
>  		return NULL;
>  
> -- 
> 1.8.3.1

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH v21 00/20] perf, tools: Add support for PMU events in JSON format
  2016-09-26 16:59                   ` Andi Kleen
@ 2016-09-27 14:18                     ` Jiri Olsa
  2016-09-29 22:19                       ` Arnaldo Carvalho de Melo
                                         ` (3 more replies)
  0 siblings, 4 replies; 70+ messages in thread
From: Jiri Olsa @ 2016-09-27 14:18 UTC (permalink / raw)
  To: Andi Kleen, Arnaldo Carvalho de Melo
  Cc: Arnaldo Carvalho de Melo, Sukadev Bhattiprolu, peterz, maddy,
	linuxppc-dev, linux-kernel

On Mon, Sep 26, 2016 at 09:59:54AM -0700, Andi Kleen wrote:
> On Mon, Sep 26, 2016 at 12:03:43PM -0300, Arnaldo Carvalho de Melo wrote:
> > Em Mon, Sep 26, 2016 at 10:35:33AM +0200, Jiri Olsa escreveu:
> > > ping.. is that working for you? IMO we can include this
> > > as additional patch to the set..
> > 
> > No, it doesn't fails to build on the first cross env I tried, fixing it
> > now, resulting patch:
> 
> Yes it shouldn't be difficult to fix cross building. I don't think
> there are any fundamental problems.

right, how about attached patch

Arnaldo,
could you please try it on cross build.. I still dont have setup for that :-\

thanks,
jirka


---
diff --git a/tools/build/Build b/tools/build/Build
index 63a6c34c0c88..76d1a4960973 100644
--- a/tools/build/Build
+++ b/tools/build/Build
@@ -1 +1,3 @@
+hostprogs := fixdep
+
 fixdep-y := fixdep.o
diff --git a/tools/build/Makefile b/tools/build/Makefile
index 0d5a0e3a8fa9..653faee2a055 100644
--- a/tools/build/Makefile
+++ b/tools/build/Makefile
@@ -14,6 +14,12 @@ endef
 $(call allow-override,CC,$(CROSS_COMPILE)gcc)
 $(call allow-override,LD,$(CROSS_COMPILE)ld)
 
+HOSTCC ?= gcc
+HOSTLD ?= ld
+HOSTAR ?= ar
+
+export HOSTCC HOSTLD HOSTAR
+
 ifeq ($(V),1)
   Q =
 else
diff --git a/tools/build/Makefile.build b/tools/build/Makefile.build
index 27f3583193e6..031c5631cc21 100644
--- a/tools/build/Makefile.build
+++ b/tools/build/Makefile.build
@@ -58,6 +58,9 @@ quiet_cmd_mkdir = MKDIR    $(dir $@)
 quiet_cmd_cc_o_c = CC       $@
       cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $<
 
+quiet_cmd_host_cc_o_c = HOSTCC   $@
+      cmd_host_cc_o_c = $(HOSTCC) $(c_flags) -c -o $@ $<
+
 quiet_cmd_cpp_i_c = CPP      $@
       cmd_cpp_i_c = $(CC) $(c_flags) -E -o $@ $<
 
@@ -70,16 +73,24 @@ quiet_cmd_gen = GEN      $@
 # If there's nothing to link, create empty $@ object.
 quiet_cmd_ld_multi = LD       $@
       cmd_ld_multi = $(if $(strip $(obj-y)),\
-		       $(LD) -r -o $@  $(filter $(obj-y),$^),rm -f $@; $(AR) rcs $@)
+                     $(LD) -r -o $@  $(filter $(obj-y),$^),rm -f $@; $(AR) rcs $@)
+
+quiet_cmd_host_ld_multi = HOSTLD   $@
+      cmd_host_ld_multi = $(if $(strip $(obj-y)),\
+                          $(HOSTLD) -r -o $@  $(filter $(obj-y),$^),rm -f $@; $(HOSTAR) rcs $@)
+
+ifneq ($(filter $(obj),$(hostprogs)),)
+  host = host_
+endif
 
 # Build rules
 $(OUTPUT)%.o: %.c FORCE
 	$(call rule_mkdir)
-	$(call if_changed_dep,cc_o_c)
+	$(call if_changed_dep,$(host)cc_o_c)
 
 $(OUTPUT)%.o: %.S FORCE
 	$(call rule_mkdir)
-	$(call if_changed_dep,cc_o_c)
+	$(call if_changed_dep,$(host)cc_o_c)
 
 $(OUTPUT)%.i: %.c FORCE
 	$(call rule_mkdir)
@@ -119,7 +130,7 @@ $(sort $(subdir-obj-y)): $(subdir-y) ;
 
 $(in-target): $(obj-y) FORCE
 	$(call rule_mkdir)
-	$(call if_changed,ld_multi)
+	$(call if_changed,$(host)ld_multi)
 
 __build: $(in-target)
 	@:
diff --git a/tools/build/Makefile.include b/tools/build/Makefile.include
index be630bed66d2..ad22e4e7bc59 100644
--- a/tools/build/Makefile.include
+++ b/tools/build/Makefile.include
@@ -1,10 +1,6 @@
 build := -f $(srctree)/tools/build/Makefile.build dir=. obj
 
-ifdef CROSS_COMPILE
-fixdep:
-else
 fixdep:
 	$(Q)$(MAKE) -C $(srctree)/tools/build CFLAGS= LDFLAGS= $(OUTPUT)fixdep
-endif
 
 .PHONY: fixdep
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 0abebcba849f..1347b5de3669 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -144,6 +144,10 @@ $(call allow-override,LD,$(CROSS_COMPILE)ld)
 
 LD += $(EXTRA_LDFLAGS)
 
+HOSTCC  ?= gcc
+HOSTLD  ?= ld
+HOSTAR  ?= ar
+
 PKG_CONFIG = $(CROSS_COMPILE)pkg-config
 
 RM      = rm -f
@@ -345,6 +349,7 @@ strip: $(PROGRAMS) $(OUTPUT)perf
 PERF_IN := $(OUTPUT)perf-in.o
 
 export srctree OUTPUT RM CC LD AR CFLAGS V BISON FLEX AWK
+export HOSTCC HOSTLD HOSTAR
 include $(srctree)/tools/build/Makefile.include
 
 JEVENTS       := $(OUTPUT)pmu-events/jevents
diff --git a/tools/perf/pmu-events/Build b/tools/perf/pmu-events/Build
index d2f34307ae79..9213a1273697 100644
--- a/tools/perf/pmu-events/Build
+++ b/tools/perf/pmu-events/Build
@@ -1,3 +1,5 @@
+hostprogs := jevents
+
 jevents-y	+= json.o jsmn.o jevents.o
 pmu-events-y	+= pmu-events.o
 JDIR		=  pmu-events/arch/$(ARCH)

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* Re: [PATCH v21 06/19] perf, tools: Support alias descriptions
  2016-09-15 22:24 ` [PATCH v21 06/19] perf, tools: Support alias descriptions Sukadev Bhattiprolu
@ 2016-09-27 17:41   ` Arnaldo Carvalho de Melo
  2016-09-27 18:11     ` Sukadev Bhattiprolu
  2016-10-04  8:14   ` [tip:perf/urgent] perf pmu: " tip-bot for Andi Kleen
  1 sibling, 1 reply; 70+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-09-27 17:41 UTC (permalink / raw)
  To: Sukadev Bhattiprolu; +Cc: peterz, maddy, linuxppc-dev, linux-kernel

Em Thu, Sep 15, 2016 at 03:24:43PM -0700, Sukadev Bhattiprolu escreveu:
> 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.

So, now I'm trying to reproduce the results below, but I couldn't find a
tarball with those .json files for me to use, can you provide me with
one?

I've put what I have at:

  git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git tmp.perf/json

Now testing Jiri's cross compiling patch...


Thanks,

- Arnaldo
 
> Example output:
> 
> % perf list
> ...
>   arith.fpu_div
>        [Divide operations executed]
>   arith.fpu_div_active
>        [Cycles when divider is busy executing divide operations]
> 
> Signed-off-by: Andi Kleen <ak@linux.intel.com>
> Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
> Acked-by: Jiri Olsa <jolsa@redhat.com>
> Acked-by: Ingo Molnar <mingo@kernel.org>
> ---
> 
> Changelog
> 	- Delete a redundant free()
> 
> Changelog[v14]
> 	- [Jiri Olsa] Fail, rather than continue if strdup() returns NULL;
> 	  remove unnecessary __maybe_unused.
> ---
>  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 c842886..af1a612 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;
> @@ -1044,11 +1046,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)
> @@ -1058,7 +1091,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;
> @@ -1068,14 +1103,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 &&
> @@ -1084,12 +1120,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 &&
> @@ -1097,25 +1140,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 5d7e844..11bda57 100644
> --- a/tools/perf/util/pmu.h
> +++ b/tools/perf/util/pmu.h
> @@ -38,6 +38,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];
> -- 
> 1.8.3.1

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH v21 06/19] perf, tools: Support alias descriptions
  2016-09-27 17:41   ` Arnaldo Carvalho de Melo
@ 2016-09-27 18:11     ` Sukadev Bhattiprolu
  2016-09-28 13:57       ` Arnaldo Carvalho de Melo
  0 siblings, 1 reply; 70+ messages in thread
From: Sukadev Bhattiprolu @ 2016-09-27 18:11 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo; +Cc: peterz, maddy, linuxppc-dev, linux-kernel

Arnaldo Carvalho de Melo [acme@kernel.org] wrote:
> Em Thu, Sep 15, 2016 at 03:24:43PM -0700, Sukadev Bhattiprolu escreveu:
> > 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.
> 
> So, now I'm trying to reproduce the results below, but I couldn't find a
> tarball with those .json files for me to use, can you provide me with
> one?

The data files are in my github, in the json-code+data-v21 branch
starting with 23bb101. They are individual commits rather than a
tarball though.

	>       https://github.com/sukadev/linux.git
	>
	>       Branch                  Description
	>       ------------------------------------------------------
	>       json-code-v21           Source Code only
	>       json-code+data-v21      Both code and data(for build/test/pull)
	> 

Sukadev

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH v21 06/19] perf, tools: Support alias descriptions
  2016-09-27 18:11     ` Sukadev Bhattiprolu
@ 2016-09-28 13:57       ` Arnaldo Carvalho de Melo
  2016-09-28 18:29         ` Sukadev Bhattiprolu
  0 siblings, 1 reply; 70+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-09-28 13:57 UTC (permalink / raw)
  To: Sukadev Bhattiprolu; +Cc: peterz, maddy, linuxppc-dev, linux-kernel

Em Tue, Sep 27, 2016 at 11:11:16AM -0700, Sukadev Bhattiprolu escreveu:
> Arnaldo Carvalho de Melo [acme@kernel.org] wrote:
> > Em Thu, Sep 15, 2016 at 03:24:43PM -0700, Sukadev Bhattiprolu escreveu:
> > > 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.
> > 
> > So, now I'm trying to reproduce the results below, but I couldn't find a
> > tarball with those .json files for me to use, can you provide me with
> > one?
> 
> The data files are in my github, in the json-code+data-v21 branch
> starting with 23bb101. They are individual commits rather than a
> tarball though.

Ok, I'll pick one for powerpc and another for x86_64 so that I can test
it and Jiri's x-compile support.

Refresh my mind, what is the plan on these files? Are we just going to
provide pointers to where to get them from vendors, ship it in the
kernel, auto-download them as part of the build process?

At least examples that allows to build and have a new 'perf test' entry
to check them automatically seems to be in order, no?

- Arnaldo
 
> 	>       https://github.com/sukadev/linux.git
> 	>
> 	>       Branch                  Description
> 	>       ------------------------------------------------------
> 	>       json-code-v21           Source Code only
> 	>       json-code+data-v21      Both code and data(for build/test/pull)
> 	> 
> 
> Sukadev

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH v21 06/19] perf, tools: Support alias descriptions
  2016-09-28 13:57       ` Arnaldo Carvalho de Melo
@ 2016-09-28 18:29         ` Sukadev Bhattiprolu
  2016-09-28 19:08           ` Arnaldo Carvalho de Melo
  2016-10-03 20:52           ` Arnaldo Carvalho de Melo
  0 siblings, 2 replies; 70+ messages in thread
From: Sukadev Bhattiprolu @ 2016-09-28 18:29 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo; +Cc: peterz, maddy, linuxppc-dev, linux-kernel

Arnaldo Carvalho de Melo [acme@kernel.org] wrote:
> Em Tue, Sep 27, 2016 at 11:11:16AM -0700, Sukadev Bhattiprolu escreveu:
> > Arnaldo Carvalho de Melo [acme@kernel.org] wrote:
> > > Em Thu, Sep 15, 2016 at 03:24:43PM -0700, Sukadev Bhattiprolu escreveu:
> > > > 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.
> > > 
> > > So, now I'm trying to reproduce the results below, but I couldn't find a
> > > tarball with those .json files for me to use, can you provide me with
> > > one?
> > 
> > The data files are in my github, in the json-code+data-v21 branch
> > starting with 23bb101. They are individual commits rather than a
> > tarball though.
> 
> Ok, I'll pick one for powerpc and another for x86_64 so that I can test
> it and Jiri's x-compile support.

Please pull all files if possible, specially on x86, _before_ building the
perf binary. If you are going to pull only one, you need to make sure that
the file you pull matches the CPU model on the system you are testing.(see
below). For Power, you need to test on Power8.

> 
> Refresh my mind, what is the plan on these files? Are we just going to
> provide pointers to where to get them from vendors, ship it in the
> kernel, auto-download them as part of the build process?

They are supposed to be committed into the linux kernel tree as shown
in the json-code+data-v21 tree and they will be picked up _during build_
of the perf binary. (We are just not mailing those data files as patches
since they are large and there is very little value in reviewing them).

When building perf on on say x86, event tables for all the different
x86 CPU models will be included in the perf binary. When perf is then
executed on an x86 box, it will detect the CPU model of that box and
use the set of events corresponding to that model.

If the CPU model does not match the models "known" to the perf binary,
then the symbolic names will not work on that system, but there should
be no other change in behavior.

Patch 15/19 tries to explain the process.

> 
> At least examples that allows to build and have a new 'perf test' entry
> to check them automatically seems to be in order, no?

Well, the hope was that build/usage will be transparent! but we did not
test in the cross-compile environment. Will think about a test case.
Please let me know if we can update the README in Patch 15/19 in any
way.

> 
> - Arnaldo
> 
> > 	>       https://github.com/sukadev/linux.git
> > 	>
> > 	>       Branch                  Description
> > 	>       ------------------------------------------------------
> > 	>       json-code-v21           Source Code only
> > 	>       json-code+data-v21      Both code and data(for build/test/pull)
> > 	> 
> > 
> > Sukadev

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH v21 06/19] perf, tools: Support alias descriptions
  2016-09-28 18:29         ` Sukadev Bhattiprolu
@ 2016-09-28 19:08           ` Arnaldo Carvalho de Melo
  2016-10-03 20:52           ` Arnaldo Carvalho de Melo
  1 sibling, 0 replies; 70+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-09-28 19:08 UTC (permalink / raw)
  To: Sukadev Bhattiprolu; +Cc: peterz, maddy, linuxppc-dev, linux-kernel

Em Wed, Sep 28, 2016 at 11:29:16AM -0700, Sukadev Bhattiprolu escreveu:
> Arnaldo Carvalho de Melo [acme@kernel.org] wrote:
> > Em Tue, Sep 27, 2016 at 11:11:16AM -0700, Sukadev Bhattiprolu escreveu:
> > > Arnaldo Carvalho de Melo [acme@kernel.org] wrote:
> > > > Em Thu, Sep 15, 2016 at 03:24:43PM -0700, Sukadev Bhattiprolu escreveu:
> > > > > 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.
> > > > 
> > > > So, now I'm trying to reproduce the results below, but I couldn't find a
> > > > tarball with those .json files for me to use, can you provide me with
> > > > one?
> > > 
> > > The data files are in my github, in the json-code+data-v21 branch
> > > starting with 23bb101. They are individual commits rather than a
> > > tarball though.
> > 
> > Ok, I'll pick one for powerpc and another for x86_64 so that I can test
> > it and Jiri's x-compile support.
> 
> Please pull all files if possible, specially on x86, _before_ building the
> perf binary. If you are going to pull only one, you need to make sure that
> the file you pull matches the CPU model on the system you are testing.(see
> below). For Power, you need to test on Power8.
> 
> > 
> > Refresh my mind, what is the plan on these files? Are we just going to
> > provide pointers to where to get them from vendors, ship it in the
> > kernel, auto-download them as part of the build process?
> 
> They are supposed to be committed into the linux kernel tree as shown
> in the json-code+data-v21 tree and they will be picked up _during build_
> of the perf binary. (We are just not mailing those data files as patches
> since they are large and there is very little value in reviewing them).
> 
> When building perf on on say x86, event tables for all the different
> x86 CPU models will be included in the perf binary. When perf is then
> executed on an x86 box, it will detect the CPU model of that box and
> use the set of events corresponding to that model.
> 
> If the CPU model does not match the models "known" to the perf binary,
> then the symbolic names will not work on that system, but there should
> be no other change in behavior.
> 
> Patch 15/19 tries to explain the process.

I didn't get to that one yet.
 
> > At least examples that allows to build and have a new 'perf test' entry
> > to check them automatically seems to be in order, no?
> 
> Well, the hope was that build/usage will be transparent! but we did not

the 'perf test' entry is to test the whole process of going from a json
file to a the perf binary and then asking for one such event and
checking if the resulting perf_event_attr is what we expect it to be,
see, for instance:

[root@jouet c]# perf test roundtrip
11: roundtrip evsel->name check                              : Ok

tools/perf/tests/evsel-roundtrip-name.c

> test in the cross-compile environment. Will think about a test case.
> Please let me know if we can update the README in Patch 15/19 in any
> way.

I'll let you know when I get to that patch, till then I'll follow the
instructions you gave me here.

I.e. I go on testing patch by patch, trying to use the documentation
that is available up to that point, trying to reproduce the results
described in the patch, to fully validate it.

- Arnaldo
 
> > > 	>       https://github.com/sukadev/linux.git
> > > 	>
> > > 	>       Branch                  Description
> > > 	>       ------------------------------------------------------
> > > 	>       json-code-v21           Source Code only
> > > 	>       json-code+data-v21      Both code and data(for build/test/pull)
> > > 	> 
> > > 
> > > Sukadev

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH v21 00/20] perf, tools: Add support for PMU events in JSON format
  2016-09-27 14:18                     ` Jiri Olsa
@ 2016-09-29 22:19                       ` Arnaldo Carvalho de Melo
  2016-09-30  9:10                         ` Jiri Olsa
  2016-10-04  8:10                       ` [tip:perf/urgent] tools build: Add support for host programs format tip-bot for Jiri Olsa
                                         ` (2 subsequent siblings)
  3 siblings, 1 reply; 70+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-09-29 22:19 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: Andi Kleen, Arnaldo Carvalho de Melo, Sukadev Bhattiprolu,
	peterz, maddy, linuxppc-dev, linux-kernel

Em Tue, Sep 27, 2016 at 04:18:46PM +0200, Jiri Olsa escreveu:
> On Mon, Sep 26, 2016 at 09:59:54AM -0700, Andi Kleen wrote:
> > On Mon, Sep 26, 2016 at 12:03:43PM -0300, Arnaldo Carvalho de Melo wrote:
> > > Em Mon, Sep 26, 2016 at 10:35:33AM +0200, Jiri Olsa escreveu:
> > > > ping.. is that working for you? IMO we can include this
> > > > as additional patch to the set..
> > > 
> > > No, it doesn't fails to build on the first cross env I tried, fixing it
> > > now, resulting patch:
> > 
> > Yes it shouldn't be difficult to fix cross building. I don't think
> > there are any fundamental problems.
> 
> right, how about attached patch
> 
> Arnaldo,
> could you please try it on cross build.. I still dont have setup for that :-\
> 
> thanks,
> jirka

So, this makes it work for me in one of the cross build envs I have (all
in https://hub.docker.com/r/acmel/) if I apply this patch on top:

diff --git a/tools/build/Makefile b/tools/build/Makefile
index 653faee2a055..8332959fbca4 100644
--- a/tools/build/Makefile
+++ b/tools/build/Makefile
@@ -42,7 +42,7 @@ $(OUTPUT)fixdep-in.o: FORCE
 	$(Q)$(MAKE) $(build)=fixdep
 
 $(OUTPUT)fixdep: $(OUTPUT)fixdep-in.o
-	$(QUIET_LINK)$(CC) $(LDFLAGS) -o $@ $<
+	$(QUIET_LINK)$(HOSTCC) $(LDFLAGS) -o $@ $<
 
 FORCE:
 
-------------------

I've broken up the patch into multiple ones, to get first fixdep
working, then to move to jevents, I'm putting this on a
tmp.perf/hostprog branch till I've tested it all.

- Arnaldo
 
> 
> ---
> diff --git a/tools/build/Build b/tools/build/Build
> index 63a6c34c0c88..76d1a4960973 100644
> --- a/tools/build/Build
> +++ b/tools/build/Build
> @@ -1 +1,3 @@
> +hostprogs := fixdep
> +
>  fixdep-y := fixdep.o
> diff --git a/tools/build/Makefile b/tools/build/Makefile
> index 0d5a0e3a8fa9..653faee2a055 100644
> --- a/tools/build/Makefile
> +++ b/tools/build/Makefile
> @@ -14,6 +14,12 @@ endef
>  $(call allow-override,CC,$(CROSS_COMPILE)gcc)
>  $(call allow-override,LD,$(CROSS_COMPILE)ld)
>  
> +HOSTCC ?= gcc
> +HOSTLD ?= ld
> +HOSTAR ?= ar
> +
> +export HOSTCC HOSTLD HOSTAR
> +
>  ifeq ($(V),1)
>    Q =
>  else
> diff --git a/tools/build/Makefile.build b/tools/build/Makefile.build
> index 27f3583193e6..031c5631cc21 100644
> --- a/tools/build/Makefile.build
> +++ b/tools/build/Makefile.build
> @@ -58,6 +58,9 @@ quiet_cmd_mkdir = MKDIR    $(dir $@)
>  quiet_cmd_cc_o_c = CC       $@
>        cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $<
>  
> +quiet_cmd_host_cc_o_c = HOSTCC   $@
> +      cmd_host_cc_o_c = $(HOSTCC) $(c_flags) -c -o $@ $<
> +
>  quiet_cmd_cpp_i_c = CPP      $@
>        cmd_cpp_i_c = $(CC) $(c_flags) -E -o $@ $<
>  
> @@ -70,16 +73,24 @@ quiet_cmd_gen = GEN      $@
>  # If there's nothing to link, create empty $@ object.
>  quiet_cmd_ld_multi = LD       $@
>        cmd_ld_multi = $(if $(strip $(obj-y)),\
> -		       $(LD) -r -o $@  $(filter $(obj-y),$^),rm -f $@; $(AR) rcs $@)
> +                     $(LD) -r -o $@  $(filter $(obj-y),$^),rm -f $@; $(AR) rcs $@)
> +
> +quiet_cmd_host_ld_multi = HOSTLD   $@
> +      cmd_host_ld_multi = $(if $(strip $(obj-y)),\
> +                          $(HOSTLD) -r -o $@  $(filter $(obj-y),$^),rm -f $@; $(HOSTAR) rcs $@)
> +
> +ifneq ($(filter $(obj),$(hostprogs)),)
> +  host = host_
> +endif
>  
>  # Build rules
>  $(OUTPUT)%.o: %.c FORCE
>  	$(call rule_mkdir)
> -	$(call if_changed_dep,cc_o_c)
> +	$(call if_changed_dep,$(host)cc_o_c)
>  
>  $(OUTPUT)%.o: %.S FORCE
>  	$(call rule_mkdir)
> -	$(call if_changed_dep,cc_o_c)
> +	$(call if_changed_dep,$(host)cc_o_c)
>  
>  $(OUTPUT)%.i: %.c FORCE
>  	$(call rule_mkdir)
> @@ -119,7 +130,7 @@ $(sort $(subdir-obj-y)): $(subdir-y) ;
>  
>  $(in-target): $(obj-y) FORCE
>  	$(call rule_mkdir)
> -	$(call if_changed,ld_multi)
> +	$(call if_changed,$(host)ld_multi)
>  
>  __build: $(in-target)
>  	@:
> diff --git a/tools/build/Makefile.include b/tools/build/Makefile.include
> index be630bed66d2..ad22e4e7bc59 100644
> --- a/tools/build/Makefile.include
> +++ b/tools/build/Makefile.include
> @@ -1,10 +1,6 @@
>  build := -f $(srctree)/tools/build/Makefile.build dir=. obj
>  
> -ifdef CROSS_COMPILE
> -fixdep:
> -else
>  fixdep:
>  	$(Q)$(MAKE) -C $(srctree)/tools/build CFLAGS= LDFLAGS= $(OUTPUT)fixdep
> -endif
>  
>  .PHONY: fixdep
> diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
> index 0abebcba849f..1347b5de3669 100644
> --- a/tools/perf/Makefile.perf
> +++ b/tools/perf/Makefile.perf
> @@ -144,6 +144,10 @@ $(call allow-override,LD,$(CROSS_COMPILE)ld)
>  
>  LD += $(EXTRA_LDFLAGS)
>  
> +HOSTCC  ?= gcc
> +HOSTLD  ?= ld
> +HOSTAR  ?= ar
> +
>  PKG_CONFIG = $(CROSS_COMPILE)pkg-config
>  
>  RM      = rm -f
> @@ -345,6 +349,7 @@ strip: $(PROGRAMS) $(OUTPUT)perf
>  PERF_IN := $(OUTPUT)perf-in.o
>  
>  export srctree OUTPUT RM CC LD AR CFLAGS V BISON FLEX AWK
> +export HOSTCC HOSTLD HOSTAR
>  include $(srctree)/tools/build/Makefile.include
>  
>  JEVENTS       := $(OUTPUT)pmu-events/jevents
> diff --git a/tools/perf/pmu-events/Build b/tools/perf/pmu-events/Build
> index d2f34307ae79..9213a1273697 100644
> --- a/tools/perf/pmu-events/Build
> +++ b/tools/perf/pmu-events/Build
> @@ -1,3 +1,5 @@
> +hostprogs := jevents
> +
>  jevents-y	+= json.o jsmn.o jevents.o
>  pmu-events-y	+= pmu-events.o
>  JDIR		=  pmu-events/arch/$(ARCH)

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* Re: [PATCH v21 00/20] perf, tools: Add support for PMU events in JSON format
  2016-09-29 22:19                       ` Arnaldo Carvalho de Melo
@ 2016-09-30  9:10                         ` Jiri Olsa
  0 siblings, 0 replies; 70+ messages in thread
From: Jiri Olsa @ 2016-09-30  9:10 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Andi Kleen, Arnaldo Carvalho de Melo, Sukadev Bhattiprolu,
	peterz, maddy, linuxppc-dev, linux-kernel

On Thu, Sep 29, 2016 at 07:19:48PM -0300, Arnaldo Carvalho de Melo wrote:
> Em Tue, Sep 27, 2016 at 04:18:46PM +0200, Jiri Olsa escreveu:
> > On Mon, Sep 26, 2016 at 09:59:54AM -0700, Andi Kleen wrote:
> > > On Mon, Sep 26, 2016 at 12:03:43PM -0300, Arnaldo Carvalho de Melo wrote:
> > > > Em Mon, Sep 26, 2016 at 10:35:33AM +0200, Jiri Olsa escreveu:
> > > > > ping.. is that working for you? IMO we can include this
> > > > > as additional patch to the set..
> > > > 
> > > > No, it doesn't fails to build on the first cross env I tried, fixing it
> > > > now, resulting patch:
> > > 
> > > Yes it shouldn't be difficult to fix cross building. I don't think
> > > there are any fundamental problems.
> > 
> > right, how about attached patch
> > 
> > Arnaldo,
> > could you please try it on cross build.. I still dont have setup for that :-\
> > 
> > thanks,
> > jirka
> 
> So, this makes it work for me in one of the cross build envs I have (all
> in https://hub.docker.com/r/acmel/) if I apply this patch on top:
> 
> diff --git a/tools/build/Makefile b/tools/build/Makefile
> index 653faee2a055..8332959fbca4 100644
> --- a/tools/build/Makefile
> +++ b/tools/build/Makefile
> @@ -42,7 +42,7 @@ $(OUTPUT)fixdep-in.o: FORCE
>  	$(Q)$(MAKE) $(build)=fixdep
>  
>  $(OUTPUT)fixdep: $(OUTPUT)fixdep-in.o
> -	$(QUIET_LINK)$(CC) $(LDFLAGS) -o $@ $<
> +	$(QUIET_LINK)$(HOSTCC) $(LDFLAGS) -o $@ $<
>  
>  FORCE:
>  
> -------------------
> 
> I've broken up the patch into multiple ones, to get first fixdep
> working, then to move to jevents, I'm putting this on a
> tmp.perf/hostprog branch till I've tested it all.

looks great, thanks

jirka

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH v21 06/19] perf, tools: Support alias descriptions
  2016-09-28 18:29         ` Sukadev Bhattiprolu
  2016-09-28 19:08           ` Arnaldo Carvalho de Melo
@ 2016-10-03 20:52           ` Arnaldo Carvalho de Melo
  1 sibling, 0 replies; 70+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-10-03 20:52 UTC (permalink / raw)
  To: Sukadev Bhattiprolu; +Cc: peterz, maddy, linuxppc-dev, linux-kernel

Em Wed, Sep 28, 2016 at 11:29:16AM -0700, Sukadev Bhattiprolu escreveu:
> Arnaldo Carvalho de Melo [acme@kernel.org] wrote:
> > Em Tue, Sep 27, 2016 at 11:11:16AM -0700, Sukadev Bhattiprolu escreveu:
> > > Arnaldo Carvalho de Melo [acme@kernel.org] wrote:
> > > > Em Thu, Sep 15, 2016 at 03:24:43PM -0700, Sukadev Bhattiprolu escreveu:
> > > > > 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.
> > > > 
> > > > So, now I'm trying to reproduce the results below, but I couldn't find a
> > > > tarball with those .json files for me to use, can you provide me with
> > > > one?
> > > 
> > > The data files are in my github, in the json-code+data-v21 branch
> > > starting with 23bb101. They are individual commits rather than a
> > > tarball though.
> > 
> > Ok, I'll pick one for powerpc and another for x86_64 so that I can test
> > it and Jiri's x-compile support.
> 
> Please pull all files if possible, specially on x86, _before_ building the

Nah, will leave this for a second step, i.e. you guys can send a pull
req after I finish the initial testing.

> perf binary. If you are going to pull only one, you need to make sure that
> the file you pull matches the CPU model on the system you are testing.(see

Right, right, that was the plan, and I actually did it now, got the
mapfile.csv, left only the entry for my test machine:

processor	: 3
vendor_id	: GenuineIntel
cpu family	: 6
model		: 61
model name	: Intel(R) Core(TM) i7-5600U CPU @ 2.60GHz

Which is 3D, i.e.:

[acme@jouet linux]$ cat tools/perf/pmu-events/arch/x86/mapfile.csv 
Family-model,Version,Filename,EventType
GenuineIntel-6-3D,V16,Broadwell,core
[acme@jouet linux]$ 

And copied the files in the directory this maps to:

[acme@jouet linux]$ ls -la tools/perf/pmu-events/arch/x86/Broadwell/
total 352
drwxrwxr-x. 2 acme acme   4096 Oct  3 17:23 .
drwxrwxr-x. 3 acme acme   4096 Oct  3 17:23 ..
-rw-r--r--. 1 acme acme 127294 Oct  3 17:20 Cache.json
-rw-r--r--. 1 acme acme  10100 Oct  3 17:21 Floating-point.json
-rw-r--r--. 1 acme acme  16319 Oct  3 17:21 Frontend.json
-rw-r--r--. 1 acme acme 106375 Oct  3 17:21 Memory.json
-rw-r--r--. 1 acme acme   2080 Oct  3 17:22 Other.json
-rw-r--r--. 1 acme acme  64972 Oct  3 17:22 Pipeline.json
-rw-r--r--. 1 acme acme  15356 Oct  3 17:23 Virtual-Memory.json
[acme@jouet linux]$ 

Then try to build it as usual, i.e. using O=:

  make O=/tmp/build/perf -C tools/perf install-bin

And it fails, not building the $(OUTPUT)pmu-events/pmu-events.c
somehow...

Ok, I decide to fall back to building it in the same directory as the
sources:

[acme@jouet linux]$ cd tools/perf
[acme@jouet perf]$ make

It gets a bit better, but fails as well:

[acme@jouet perf]$ make
  BUILD:   Doing 'make -j4' parallel build
  CC       pmu-events/pmu-events.o
pmu-events/pmu-events.c:4430:11: error: ‘pme_Filename’ undeclared here
(not in a function)
  .table = pme_Filename
           ^~~~~~~~~~~~
mv: cannot stat 'pmu-events/.pmu-events.o.tmp': No such file or
directory
/home/acme/git/linux/tools/build/Makefile.build:88: recipe for target
'pmu-events/pmu-events.o' failed
make[2]: *** [pmu-events/pmu-events.o] Error 1
Makefile.perf:467: recipe for target 'pmu-events/pmu-events-in.o' failed
make[1]: *** [pmu-events/pmu-events-in.o] Error 2
make[1]: *** Waiting for unfinished jobs....
Makefile:68: recipe for target 'all' failed
make: *** [all] Error 2
[acme@jouet perf]$ 

It finally builds if I ditch the header in

https://raw.githubusercontent.com/sukadev/linux/json-code%2Bdata-v21/tools/perf/pmu-events/arch/x86/mapfile.csv

[acme@jouet perf]$ cat pmu-events/arch/x86/mapfile.csv 
Family-model,Version,Filename,EventType
GenuineIntel-6-3D,V16,Broadwell,core
[acme@jouet perf]$ vim pmu-events/arch/x86/mapfile.csv 
[acme@jouet perf]$ cat pmu-events/arch/x86/mapfile.csv 
GenuineIntel-6-3D,V16,Broadwell,core
[acme@jouet perf]$ make
  BUILD:   Doing 'make -j4' parallel build
  GEN      pmu-events/pmu-events.c
Warning: tools/include/uapi/linux/bpf.h differs from kernel
  CC       pmu-events/pmu-events.o
  LD       pmu-events/pmu-events-in.o
  AR       libperf.a
  LINK     libperf-gtk.so
  LINK     perf
[acme@jouet perf]$

And then it seems to work, at least for 'perf list', still need to check
if reading events with the generic name so far used + the new one looks
sane, will be done after this:

[acme@jouet perf]$ perf list | grep arith
  arith.fpu_div_active                              
  fp_arith_inst_retired.128b_packed_double          
  fp_arith_inst_retired.128b_packed_single          
  fp_arith_inst_retired.256b_packed_double          
  fp_arith_inst_retired.256b_packed_single          
  fp_arith_inst_retired.double                      
  fp_arith_inst_retired.packed                      
  fp_arith_inst_retired.scalar                      
  fp_arith_inst_retired.scalar_double               
  fp_arith_inst_retired.scalar_single               
  fp_arith_inst_retired.single                      
[acme@jouet perf]$

Now trying to fix the O= part to continue processing...

- Arnaldo

> below). For Power, you need to test on Power8.
> > 
> > Refresh my mind, what is the plan on these files? Are we just going to
> > provide pointers to where to get them from vendors, ship it in the
> > kernel, auto-download them as part of the build process?
> 
> They are supposed to be committed into the linux kernel tree as shown
> in the json-code+data-v21 tree and they will be picked up _during build_
> of the perf binary. (We are just not mailing those data files as patches
> since they are large and there is very little value in reviewing them).
> 
> When building perf on on say x86, event tables for all the different
> x86 CPU models will be included in the perf binary. When perf is then
> executed on an x86 box, it will detect the CPU model of that box and
> use the set of events corresponding to that model.
> 
> If the CPU model does not match the models "known" to the perf binary,
> then the symbolic names will not work on that system, but there should
> be no other change in behavior.
> 
> Patch 15/19 tries to explain the process.
> 
> > 
> > At least examples that allows to build and have a new 'perf test' entry
> > to check them automatically seems to be in order, no?
> 
> Well, the hope was that build/usage will be transparent! but we did not
> test in the cross-compile environment. Will think about a test case.
> Please let me know if we can update the README in Patch 15/19 in any
> way.
> 
> > 
> > - Arnaldo
> > 
> > > 	>       https://github.com/sukadev/linux.git
> > > 	>
> > > 	>       Branch                  Description
> > > 	>       ------------------------------------------------------
> > > 	>       json-code-v21           Source Code only
> > > 	>       json-code+data-v21      Both code and data(for build/test/pull)
> > > 	> 
> > > 
> > > Sukadev

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH v21 11/19] perf, tools: Add alias support for long descriptions
  2016-09-15 22:24 ` [PATCH v21 11/19] perf, tools: Add alias " Sukadev Bhattiprolu
@ 2016-10-04  0:20   ` Arnaldo Carvalho de Melo
  0 siblings, 0 replies; 70+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-10-04  0:20 UTC (permalink / raw)
  To: Sukadev Bhattiprolu; +Cc: peterz, maddy, linuxppc-dev, linux-kernel

Em Thu, Sep 15, 2016 at 03:24:48PM -0700, Sukadev Bhattiprolu escreveu:
> Previously we were dropping the useful longer descriptions that some
> events have in the event list completely. Now that jevents provides
> support for longer descriptions (see previous patch), add support for
> parsing the long descriptions
> 
> Signed-off-by: Andi Kleen <ak@linux.intel.com>
> Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
> Acked-by: Jiri Olsa <jolsa@redhat.com>
> Acked-by: Ingo Molnar <mingo@kernel.org>
> ---

This patch doesn't build, fixing... probably needs stuff that is in a
following patch.

- Arnaldo
 
> Changelog[v14]
> 	- [Jiri Olsa] Break up independent parts of the patch into
> 	  separate patches.
> ---
>  tools/perf/util/parse-events.c |  5 +++--
>  tools/perf/util/parse-events.h |  3 ++-
>  tools/perf/util/pmu.c          | 15 ++++++++++-----
>  tools/perf/util/pmu.h          |  4 +++-
>  4 files changed, 18 insertions(+), 9 deletions(-)
> 
> diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
> index a3c7739..9abd60d 100644
> --- a/tools/perf/util/parse-events.c
> +++ b/tools/perf/util/parse-events.c
> @@ -2229,7 +2229,8 @@ 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);
> @@ -2239,7 +2240,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 795f2579..7efde4a 100644
> --- a/tools/perf/util/parse-events.h
> +++ b/tools/perf/util/parse-events.h
> @@ -171,7 +171,8 @@ 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 2291d2a..43838b3 100644
> --- a/tools/perf/util/pmu.c
> +++ b/tools/perf/util/pmu.c
> @@ -223,7 +223,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, char *val)
> +				 char *desc, char *val, char *long_desc)
>  {
>  	struct perf_pmu_alias *alias;
>  	int ret;
> @@ -257,6 +257,8 @@ static int __perf_pmu__new_alias(struct list_head *list, char *dir, char *name,
>  	}
>  
>  	alias->desc = desc ? strdup(desc) : NULL;
> +	alias->long_desc = long_desc ? strdup(long_desc) :
> +				desc ? strdup(desc) : NULL;
>  
>  	list_add_tail(&alias->list, list);
>  
> @@ -274,7 +276,7 @@ static int perf_pmu__new_alias(struct list_head *list, char *dir, char *name, FI
>  
>  	buf[ret] = 0;
>  
> -	return __perf_pmu__new_alias(list, dir, name, NULL, buf);
> +	return __perf_pmu__new_alias(list, dir, name, NULL, buf, NULL);
>  }
>  
>  static inline bool pmu_alias_info_file(char *name)
> @@ -532,7 +534,8 @@ static int pmu_add_cpu_aliases(struct list_head *head)
>  
>  		/* need type casts to override 'const' */
>  		__perf_pmu__new_alias(head, NULL, (char *)pe->name,
> -				(char *)pe->desc, (char *)pe->event);
> +				(char *)pe->desc, (char *)pe->event,
> +				(char *)pe->long_desc);
>  	}
>  
>  out:
> @@ -1091,7 +1094,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;
> @@ -1139,7 +1143,8 @@ void print_pmu_events(const char *event_glob, bool name_only, bool quiet_flag)
>  			if (!aliases[j].name)
>  				goto out_enomem;
>  
> -			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 42999c7..1aa614e 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];
> @@ -70,7 +71,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.8.3.1

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH v21 12/19] perf, tools: Support long descriptions with perf list
  2016-09-15 22:24 ` [PATCH v21 12/19] perf, tools: Support long descriptions with perf list Sukadev Bhattiprolu
@ 2016-10-04  0:26   ` Arnaldo Carvalho de Melo
  2016-10-04  8:16   ` [tip:perf/urgent] perf list: Support long jevents descriptions tip-bot for Sukadev Bhattiprolu
  1 sibling, 0 replies; 70+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-10-04  0:26 UTC (permalink / raw)
  To: Sukadev Bhattiprolu; +Cc: peterz, maddy, linuxppc-dev, linux-kernel

Em Thu, Sep 15, 2016 at 03:24:49PM -0700, Sukadev Bhattiprolu escreveu:
> 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.

Squashed this with 11/19 so that we don't break bisect.
 
> 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 <ak@linux.intel.com>
> Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
> Acked-by: Jiri Olsa <jolsa@redhat.com>
> Acked-by: Ingo Molnar <mingo@kernel.org>
> ---
> 
> Changelog[v15]
> 	- [Jir Olsa, Andi Kleen] Fix usage strings; update man page.
> 
> Changelog[v14]
> 	- [Jiri Olsa] Break up independent parts of the patch into
> 	  separate patches.
> 
> Changelog[v18]:
> 	- Fix minor conflict in tools/perf/builtin-list.c; add long_desc_flag
> 	  parameter to new print_pmu_events() call site.
> 
> Changelog[v21]
> 	- Fix minor conflicts in tools/perf/builtin-list.c
> ---
>  tools/perf/Documentation/perf-list.txt |  6 +++++-
>  tools/perf/builtin-list.c              | 16 +++++++++++-----
>  2 files changed, 16 insertions(+), 6 deletions(-)
> 
> diff --git a/tools/perf/Documentation/perf-list.txt b/tools/perf/Documentation/perf-list.txt
> index 72209bc..41857cc 100644
> --- a/tools/perf/Documentation/perf-list.txt
> +++ b/tools/perf/Documentation/perf-list.txt
> @@ -8,7 +8,7 @@ perf-list - List all symbolic event types
>  SYNOPSIS
>  --------
>  [verse]
> -'perf list' [--no-desc] [hw|sw|cache|tracepoint|pmu|event_glob]
> +'perf list' [--no-desc] [--long-desc] [hw|sw|cache|tracepoint|pmu|event_glob]
>  
>  DESCRIPTION
>  -----------
> @@ -20,6 +20,10 @@ OPTIONS
>  --no-desc::
>  Don't print descriptions.
>  
> +-v::
> +--long-desc::
> +Print longer event descriptions.
> +
>  
>  [[EVENT_MODIFIERS]]
>  EVENT MODIFIERS
> diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c
> index b14cb16..ba9322f 100644
> --- a/tools/perf/builtin-list.c
> +++ b/tools/perf/builtin-list.c
> @@ -22,14 +22,17 @@ 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[] = {
> -		"perf list [--no-desc] [hw|sw|cache|tracepoint|pmu|sdt|event_glob]",
> +		"perf list [<options>] [hw|sw|cache|tracepoint|pmu|sdt|event_glob]",
>  		NULL
>  	};
>  
> @@ -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;
>  	}
>  
> @@ -65,14 +68,16 @@ 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 if (strcmp(argv[i], "sdt") == 0)
>  			print_sdt_events(NULL, NULL, raw_dump);
>  		else if ((sep = strchr(argv[i], ':')) != NULL) {
>  			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];
> @@ -94,7 +99,8 @@ int cmd_list(int argc, const char **argv, const char *prefix __maybe_unused)
>  			print_symbol_events(s, PERF_TYPE_SOFTWARE,
>  					    event_symbols_sw, PERF_COUNT_SW_MAX, raw_dump);
>  			print_hwcache_events(s, raw_dump);
> -			print_pmu_events(s, raw_dump, !desc_flag);
> +			print_pmu_events(s, raw_dump, !desc_flag,
> +						long_desc_flag);
>  			print_tracepoint_events(NULL, s, raw_dump);
>  			print_sdt_events(NULL, s, raw_dump);
>  			free(s);
> -- 
> 1.8.3.1

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH v21 14/19] perf, tools, jevents: Handle header line in mapfile
  2016-09-15 22:24 ` [PATCH v21 14/19] perf, tools, jevents: Handle header line in mapfile Sukadev Bhattiprolu
@ 2016-10-04  0:36   ` Arnaldo Carvalho de Melo
  2016-10-04  8:13   ` [tip:perf/urgent] perf " tip-bot for Andi Kleen
  1 sibling, 0 replies; 70+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-10-04  0:36 UTC (permalink / raw)
  To: Sukadev Bhattiprolu; +Cc: peterz, maddy, linuxppc-dev, linux-kernel

Em Thu, Sep 15, 2016 at 03:24:51PM -0700, Sukadev Bhattiprolu escreveu:
> From: Andi Kleen <ak@linux.intel.com>
> 
> To work with existing mapfiles, assume that the first line in
> 'mapfile.csv' is a header line and skip over it.

Moved this more to the front of this patchkit so that when testing it,
reproducing the tests performed earlier, one don't have to remove the
header.

- Arnaldo
 
> Signed-off-by: Andi Kleen <ak@linux.intel.com>
> Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
> Acked-by: Jiri Olsa <jolsa@redhat.com>
> Acked-by: Ingo Molnar <mingo@kernel.org>
> ---
> 
> Changelog[v2]
> 	All architectures may not use the "Family" to identify. So,
> 	assume first line is header.
> ---
>  tools/perf/pmu-events/jevents.c | 9 +++++++--
>  1 file changed, 7 insertions(+), 2 deletions(-)
> 
> diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c
> index f550cad..9cdfbaa 100644
> --- a/tools/perf/pmu-events/jevents.c
> +++ b/tools/perf/pmu-events/jevents.c
> @@ -492,7 +492,12 @@ static int process_mapfile(FILE *outfp, char *fpath)
>  
>  	print_mapping_table_prefix(outfp);
>  
> -	line_num = 0;
> +	/* Skip first line (header) */
> +	p = fgets(line, n, mapfp);
> +	if (!p)
> +		goto out;
> +
> +	line_num = 1;
>  	while (1) {
>  		char *cpuid, *version, *type, *fname;
>  
> @@ -536,8 +541,8 @@ static int process_mapfile(FILE *outfp, char *fpath)
>  		fprintf(outfp, "},\n");
>  	}
>  
> +out:
>  	print_mapping_table_suffix(outfp);
> -
>  	return 0;
>  }
>  
> -- 
> 1.8.3.1

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH v21 15/19] perf, tools: Add README for info on parsing JSON/map files
  2016-09-15 22:24 ` [PATCH v21 15/19] perf, tools: Add README for info on parsing JSON/map files Sukadev Bhattiprolu
@ 2016-10-04  0:38   ` Arnaldo Carvalho de Melo
  2016-10-04  8:17   ` [tip:perf/urgent] perf " tip-bot for Sukadev Bhattiprolu
  1 sibling, 0 replies; 70+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-10-04  0:38 UTC (permalink / raw)
  To: Sukadev Bhattiprolu; +Cc: peterz, maddy, linuxppc-dev, linux-kernel

Em Thu, Sep 15, 2016 at 03:24:52PM -0700, Sukadev Bhattiprolu escreveu:
> Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
> Acked-by: Jiri Olsa <jolsa@redhat.com>
> Acked-by: Ingo Molnar <mingo@kernel.org>
> ---
> Changelog[v21]
> 	- Update README to reflect the Topics.json directory tree layout.

Fixed this:

[acme@jouet linux]$ am /wb/1.patch 
Applying: perf, tools: Add README for info on parsing JSON/map files
.git/rebase-apply/patch:162: new blank line at EOF.
+
warning: 1 line adds whitespace errors.
tools/perf/pmu-events/README:148: new blank line at EOF.
[acme@jouet linux]$

> ---
>  tools/perf/pmu-events/README | 148 +++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 148 insertions(+)
>  create mode 100644 tools/perf/pmu-events/README
> 
> diff --git a/tools/perf/pmu-events/README b/tools/perf/pmu-events/README
> new file mode 100644
> index 0000000..c5ee208e
> --- /dev/null
> +++ b/tools/perf/pmu-events/README
> @@ -0,0 +1,148 @@
> +
> +The contents of this directory allow users to specify PMU events in their
> +CPUs by their symbolic names rather than raw event codes (see example below).
> +
> +The main program in this directory, is the 'jevents', which is built and
> +executed _BEFORE_ the perf binary itself is built.
> +
> +The 'jevents' program tries to locate and process JSON files in the directory
> +tree tools/perf/pmu-events/arch/foo.
> +
> +	- Regular files with '.json' extension in the name are assumed to be
> +	  JSON files, each of which describes a set of PMU events.
> +
> +	- Regular files with basename starting with 'mapfile.csv' are assumed
> +	  to be a CSV file that maps a specific CPU to its set of PMU events.
> +	  (see below for mapfile format)
> +
> +	- Directories are traversed, but all other files are ignored.
> +
> +The PMU events supported by a CPU model are expected to grouped into topics
> +such as Pipelining, Cache, Memory, Floating-point etc. All events for a topic
> +should be placed in a separate JSON file - where the file name identifies
> +the topic. Eg: "Floating-point.json".
> +
> +All the topic JSON files for a CPU model/family should be in a separate
> +sub directory. Thus for the Silvermont X86 CPU:
> +
> +	$ ls tools/perf/pmu-events/arch/x86/Silvermont_core
> +	Cache.json 	Memory.json 	Virtual-Memory.json
> +	Frontend.json 	Pipeline.json
> +
> +Using the JSON files and the mapfile, 'jevents' generates the C source file,
> +'pmu-events.c', which encodes the two sets of tables:
> +
> +	- Set of 'PMU events tables' for all known CPUs in the architecture,
> +	  (one table like the following, per JSON file; table name 'pme_power8'
> +	  is derived from JSON file name, 'power8.json').
> +
> +		struct pmu_event pme_power8[] = {
> +
> +			...
> +
> +			{
> +				.name = "pm_1plus_ppc_cmpl",
> +				.event = "event=0x100f2",
> +				.desc = "1 or more ppc insts finished,",
> +			},
> +
> +			...
> +		}
> +
> +	- A 'mapping table' that maps each CPU of the architecture, to its
> +	  'PMU events table'
> +
> +		struct pmu_events_map pmu_events_map[] = {
> +		{
> +			.cpuid = "004b0000",
> +			.version = "1",
> +			.type = "core",
> +			.table = pme_power8
> +		},
> +			...
> +
> +		};
> +
> +After the 'pmu-events.c' is generated, it is compiled and the resulting
> +'pmu-events.o' is added to 'libperf.a' which is then used to build perf.
> +
> +NOTES:
> +	1. Several CPUs can support same set of events and hence use a common
> +	   JSON file. Hence several entries in the pmu_events_map[] could map
> +	   to a single 'PMU events table'.
> +
> +	2. The 'pmu-events.h' has an extern declaration for the mapping table
> +	   and the generated 'pmu-events.c' defines this table.
> +
> +	3. _All_ known CPU tables for architecture are included in the perf
> +	   binary.
> +
> +At run time, perf determines the actual CPU it is running on, finds the
> +matching events table and builds aliases for those events. This allows
> +users to specify events by their name:
> +
> +	$ perf stat -e pm_1plus_ppc_cmpl sleep 1
> +
> +where 'pm_1plus_ppc_cmpl' is a Power8 PMU event.
> +
> +In case of errors when processing files in the tools/perf/pmu-events/arch
> +directory, 'jevents' tries to create an empty mapping file to allow the perf
> +build to succeed even if the PMU event aliases cannot be used.
> +
> +However some errors in processing may cause the perf build to fail.
> +
> +Mapfile format
> +===============
> +
> +The mapfile enables multiple CPU models to share a single set of PMU events.
> +It is required even if such mapping is 1:1.
> +
> +The mapfile.csv format is expected to be:
> +
> +	Header line
> +	CPUID,Version,Dir/path/name,Type
> +
> +where:
> +
> +	Comma:
> +		is the required field delimiter (i.e other fields cannot
> +		have commas within them).
> +
> +	Comments:
> +		Lines in which the first character is either '\n' or '#'
> +		are ignored.
> +
> +	Header line
> +		The header line is the first line in the file, which is
> +		always _IGNORED_. It can empty.
> +
> +	CPUID:
> +		CPUID is an arch-specific char string, that can be used
> +		to identify CPU (and associate it with a set of PMU events
> +		it supports). Multiple CPUIDS can point to the same
> +		File/path/name.json.
> +
> +		Example:
> +			CPUID == 'GenuineIntel-6-2E' (on x86).
> +			CPUID == '004b0100' (PVR value in Powerpc)
> +	Version:
> +		is the Version of the mapfile.
> +
> +	Dir/path/name:
> +		is the pathname to the directory containing the CPU's JSON
> +		files, relative to the directory containing the mapfile.csv
> +
> +	Type:
> +		indicates whether the events or "core" or "uncore" events.
> +
> +
> +	Eg:
> +
> +	$ grep Silvermont tools/perf/pmu-events/arch/x86/mapfile.csv
> +	GenuineIntel-6-37,V13,Silvermont_core,core
> +	GenuineIntel-6-4D,V13,Silvermont_core,core
> +	GenuineIntel-6-4C,V13,Silvermont_core,core
> +
> +	i.e the three CPU models use the JSON files (i.e PMU events) listed
> +	in the directory 'tools/perf/pmu-events/arch/x86/Silvermont_core'.
> +
> -- 
> 1.8.3.1

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH v21 16/19] perf, tools: Make alias matching case-insensitive
  2016-09-15 22:24 ` [PATCH v21 16/19] perf, tools: Make alias matching case-insensitive Sukadev Bhattiprolu
@ 2016-10-04  0:47   ` Arnaldo Carvalho de Melo
  2016-10-04  0:54     ` Arnaldo Carvalho de Melo
  2016-10-04  8:19     ` Jiri Olsa
  2016-10-04  8:18   ` [tip:perf/urgent] perf " tip-bot for Andi Kleen
  1 sibling, 2 replies; 70+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-10-04  0:47 UTC (permalink / raw)
  To: Sukadev Bhattiprolu
  Cc: peterz, maddy, linuxppc-dev, linux-kernel, Jiri Olsa, Andi Kleen

Em Thu, Sep 15, 2016 at 03:24:53PM -0700, Sukadev Bhattiprolu escreveu:
> From: Andi Kleen <ak@linux.intel.com>
> 
> Make alias matching the events parser case-insensitive. This is useful
> with the JSON events. perf uses lower case events, but the CPU manuals
> generally use upper case event names. The JSON files use lower
> case by default too. But if we search case insensitively then
> users can cut-n-paste the upper case event names.
> 
> So the following works:
> 
> % perf stat -e BR_INST_EXEC.TAKEN_INDIRECT_NEAR_CALL true
> 
>  Performance counter stats for 'true':
> 
>                305      BR_INST_EXEC.TAKEN_INDIRECT_NEAR_CALL
> 
>        0.000492799 seconds time elapsed

So now trying to figure this out:

[acme@jouet linux]$ perf stat -e br_inst_exec.all_direct_near_call true
event syntax error: 'br_inst_exec.all_direct_near_call'
                     \___ 'period' is not usable in 'perf stat'
Run 'perf list' for a list of valid events

 Usage: perf stat [<options>] [<command>]

    -e, --event <event>   event selector. use 'perf list' to list available events
[acme@jouet linux]$ 

[acme@jouet linux]$ perf stat -e cycles true

 Performance counter stats for 'true':

           228,093      cycles:u                                                    

       0.002678362 seconds time elapsed

[acme@jouet linux]$


Who is setting period in that case?

For cycles we get in verbose mode:

[acme@jouet linux]$ perf stat -vv -e cycles true
Using CPUID GenuineIntel-6-3D
intel_pt default config: tsc
------------------------------------------------------------
perf_event_attr:
  size                             112
  sample_type                      IDENTIFIER
  read_format                      TOTAL_TIME_ENABLED|TOTAL_TIME_RUNNING
  disabled                         1
  inherit                          1
  enable_on_exec                   1
  exclude_guest                    1
------------------------------------------------------------
sys_perf_event_open: pid 13346  cpu -1  group_fd -1  flags 0x8
sys_perf_event_open failed, error -13
Warning:
kernel.perf_event_paranoid=2, trying to fall back to excluding kernel samples
------------------------------------------------------------
perf_event_attr:
  size                             112
  sample_type                      IDENTIFIER
  read_format                      TOTAL_TIME_ENABLED|TOTAL_TIME_RUNNING
  disabled                         1
  inherit                          1
  exclude_kernel                   1
  enable_on_exec                   1
  exclude_guest                    1
------------------------------------------------------------
sys_perf_event_open: pid 13346  cpu -1  group_fd -1  flags 0x8
cycles:u: 0: 322539 536424 536424
cycles:u: 322539 536424 536424

 Performance counter stats for 'true':

           322,539      cycles:u                                                    

       0.001061349 seconds time elapsed

And for br_inst_exec.all_direct_near_call:

Strange:

[acme@jouet linux]$ perf stat -vvv -e 'br_inst_exec.all_direct_near_call' true
Using CPUID GenuineIntel-6-3D
event syntax error: 'br_inst_exec.all_direct_near_call'
                     \___ 'period' is not usable in 'perf stat'
Run 'perf list' for a list of valid events

 Usage: perf stat [<options>] [<command>]

    -e, --event <event>   event selector. use 'perf list' to list available events
[acme@jouet linux]$ 
[acme@jouet linux]$ perf record -e 'br_inst_exec.all_direct_near_call' true
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.020 MB perf.data ]
[acme@jouet linux]$ perf evlist -v
br_inst_exec.all_direct_near_call:u: type: 4, size: 112, config: 0xd088, { sample_period, sample_freq }: 200003, sample_type: IP|TID|TIME|PERIOD, disabled: 1, inherit: 1, exclude_kernel: 1, mmap: 1, comm: 1, enable_on_exec: 1, task: 1, sample_id_all: 1, exclude_guest: 1, mmap2: 1, comm_exec: 1
[acme@jouet linux]$ 

I've put what I have on a tmp.perf/json branch, will run it thru my tests and
continue tomorrow, when I'll try to investigate this problem with 'perf stat' and
these events, unless someone does it while I'm asleep. :-)

- Arnaldo
 
> Signed-off-by: Andi Kleen <ak@linux.intel.com>
> Acked-by: Ingo Molnar <mingo@kernel.org>
> ---
>  tools/perf/util/parse-events.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
> index 9abd60d..1abda10 100644
> --- a/tools/perf/util/parse-events.c
> +++ b/tools/perf/util/parse-events.c
> @@ -1453,7 +1453,7 @@ comp_pmu(const void *p1, const void *p2)
>  	struct perf_pmu_event_symbol *pmu1 = (struct perf_pmu_event_symbol *) p1;
>  	struct perf_pmu_event_symbol *pmu2 = (struct perf_pmu_event_symbol *) p2;
>  
> -	return strcmp(pmu1->symbol, pmu2->symbol);
> +	return strcasecmp(pmu1->symbol, pmu2->symbol);
>  }
>  
>  static void perf_pmu__parse_cleanup(void)
> -- 
> 1.8.3.1

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH v21 16/19] perf, tools: Make alias matching case-insensitive
  2016-10-04  0:47   ` Arnaldo Carvalho de Melo
@ 2016-10-04  0:54     ` Arnaldo Carvalho de Melo
  2016-10-04  8:19       ` Jiri Olsa
  2016-10-04  8:19     ` Jiri Olsa
  1 sibling, 1 reply; 70+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-10-04  0:54 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Sukadev Bhattiprolu, peterz, maddy, linuxppc-dev, linux-kernel,
	Jiri Olsa, Andi Kleen

Em Mon, Oct 03, 2016 at 09:47:06PM -0300, Arnaldo Carvalho de Melo escreveu:
> Em Thu, Sep 15, 2016 at 03:24:53PM -0700, Sukadev Bhattiprolu escreveu:
> > From: Andi Kleen <ak@linux.intel.com>
> > 
> > Make alias matching the events parser case-insensitive. This is useful
> > with the JSON events. perf uses lower case events, but the CPU manuals
> > generally use upper case event names. The JSON files use lower
> > case by default too. But if we search case insensitively then
> > users can cut-n-paste the upper case event names.
> > 
> > So the following works:
> > 
> > % perf stat -e BR_INST_EXEC.TAKEN_INDIRECT_NEAR_CALL true
> > 
> >  Performance counter stats for 'true':
> > 
> >                305      BR_INST_EXEC.TAKEN_INDIRECT_NEAR_CALL
> > 
> >        0.000492799 seconds time elapsed
> 
> So now trying to figure this out:

Ok, so this is just another case of bad patch ordering: this uses 'perf
stat' as the example, but it doesn't work at this point, one needs to go
to the last patch, apply it and then test it again, when it will work.
So just moved the last patch to before this one, sigh.

- Arnaldo
 
> [acme@jouet linux]$ perf stat -e br_inst_exec.all_direct_near_call true
> event syntax error: 'br_inst_exec.all_direct_near_call'
>                      \___ 'period' is not usable in 'perf stat'
> Run 'perf list' for a list of valid events
> 
>  Usage: perf stat [<options>] [<command>]
> 
>     -e, --event <event>   event selector. use 'perf list' to list available events
> [acme@jouet linux]$ 
> 
> [acme@jouet linux]$ perf stat -e cycles true
> 
>  Performance counter stats for 'true':
> 
>            228,093      cycles:u                                                    
> 
>        0.002678362 seconds time elapsed
> 
> [acme@jouet linux]$
> 
> 
> Who is setting period in that case?
> 
> For cycles we get in verbose mode:
> 
> [acme@jouet linux]$ perf stat -vv -e cycles true
> Using CPUID GenuineIntel-6-3D
> intel_pt default config: tsc
> ------------------------------------------------------------
> perf_event_attr:
>   size                             112
>   sample_type                      IDENTIFIER
>   read_format                      TOTAL_TIME_ENABLED|TOTAL_TIME_RUNNING
>   disabled                         1
>   inherit                          1
>   enable_on_exec                   1
>   exclude_guest                    1
> ------------------------------------------------------------
> sys_perf_event_open: pid 13346  cpu -1  group_fd -1  flags 0x8
> sys_perf_event_open failed, error -13
> Warning:
> kernel.perf_event_paranoid=2, trying to fall back to excluding kernel samples
> ------------------------------------------------------------
> perf_event_attr:
>   size                             112
>   sample_type                      IDENTIFIER
>   read_format                      TOTAL_TIME_ENABLED|TOTAL_TIME_RUNNING
>   disabled                         1
>   inherit                          1
>   exclude_kernel                   1
>   enable_on_exec                   1
>   exclude_guest                    1
> ------------------------------------------------------------
> sys_perf_event_open: pid 13346  cpu -1  group_fd -1  flags 0x8
> cycles:u: 0: 322539 536424 536424
> cycles:u: 322539 536424 536424
> 
>  Performance counter stats for 'true':
> 
>            322,539      cycles:u                                                    
> 
>        0.001061349 seconds time elapsed
> 
> And for br_inst_exec.all_direct_near_call:
> 
> Strange:
> 
> [acme@jouet linux]$ perf stat -vvv -e 'br_inst_exec.all_direct_near_call' true
> Using CPUID GenuineIntel-6-3D
> event syntax error: 'br_inst_exec.all_direct_near_call'
>                      \___ 'period' is not usable in 'perf stat'
> Run 'perf list' for a list of valid events
> 
>  Usage: perf stat [<options>] [<command>]
> 
>     -e, --event <event>   event selector. use 'perf list' to list available events
> [acme@jouet linux]$ 
> [acme@jouet linux]$ perf record -e 'br_inst_exec.all_direct_near_call' true
> [ perf record: Woken up 1 times to write data ]
> [ perf record: Captured and wrote 0.020 MB perf.data ]
> [acme@jouet linux]$ perf evlist -v
> br_inst_exec.all_direct_near_call:u: type: 4, size: 112, config: 0xd088, { sample_period, sample_freq }: 200003, sample_type: IP|TID|TIME|PERIOD, disabled: 1, inherit: 1, exclude_kernel: 1, mmap: 1, comm: 1, enable_on_exec: 1, task: 1, sample_id_all: 1, exclude_guest: 1, mmap2: 1, comm_exec: 1
> [acme@jouet linux]$ 
> 
> I've put what I have on a tmp.perf/json branch, will run it thru my tests and
> continue tomorrow, when I'll try to investigate this problem with 'perf stat' and
> these events, unless someone does it while I'm asleep. :-)
> 
> - Arnaldo
>  
> > Signed-off-by: Andi Kleen <ak@linux.intel.com>
> > Acked-by: Ingo Molnar <mingo@kernel.org>
> > ---
> >  tools/perf/util/parse-events.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
> > index 9abd60d..1abda10 100644
> > --- a/tools/perf/util/parse-events.c
> > +++ b/tools/perf/util/parse-events.c
> > @@ -1453,7 +1453,7 @@ comp_pmu(const void *p1, const void *p2)
> >  	struct perf_pmu_event_symbol *pmu1 = (struct perf_pmu_event_symbol *) p1;
> >  	struct perf_pmu_event_symbol *pmu2 = (struct perf_pmu_event_symbol *) p2;
> >  
> > -	return strcmp(pmu1->symbol, pmu2->symbol);
> > +	return strcasecmp(pmu1->symbol, pmu2->symbol);
> >  }
> >  
> >  static void perf_pmu__parse_cleanup(void)
> > -- 
> > 1.8.3.1

^ permalink raw reply	[flat|nested] 70+ messages in thread

* [tip:perf/urgent] tools build: Add support for host programs format
  2016-09-27 14:18                     ` Jiri Olsa
  2016-09-29 22:19                       ` Arnaldo Carvalho de Melo
@ 2016-10-04  8:10                       ` tip-bot for Jiri Olsa
  2016-10-04  8:11                       ` [tip:perf/urgent] tools build: Make fixdep a hostprog tip-bot for Jiri Olsa
  2016-10-04  8:12                       ` [tip:perf/urgent] perf jevents: Program to convert JSON file tip-bot for Andi Kleen
  3 siblings, 0 replies; 70+ messages in thread
From: tip-bot for Jiri Olsa @ 2016-10-04  8:10 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: jolsa, acme, peterz, andi, sukadev, tglx, jolsa, mingo, maddy,
	hpa, linux-kernel

Commit-ID:  0c3b7e42616f1f6084cfeb0d443cbff0b2c424a9
Gitweb:     http://git.kernel.org/tip/0c3b7e42616f1f6084cfeb0d443cbff0b2c424a9
Author:     Jiri Olsa <jolsa@redhat.com>
AuthorDate: Tue, 27 Sep 2016 16:18:46 +0200
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Mon, 3 Oct 2016 11:39:09 -0300

tools build: Add support for host programs format

In some cases, like for fixdep and shortly for jevents, we need to build a tool
to run on the host that will be used in building a tool, such as perf, that is
being cross compiled, so do like the kernel and provide HOSTCC, HOSTLD and HOSTAR
to do that.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Requested-by: Andi Kleen <andi@firstfloor.org>
Requested-and-Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Cc: linuxppc-dev@lists.ozlabs.org
Link: http://lkml.kernel.org/r/20160927141846.GA6589@krava
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/build/Build.include  |  5 +++++
 tools/build/Makefile       |  6 ++++++
 tools/build/Makefile.build | 19 +++++++++++++++----
 3 files changed, 26 insertions(+), 4 deletions(-)

diff --git a/tools/build/Build.include b/tools/build/Build.include
index 4d000bc..0248938 100644
--- a/tools/build/Build.include
+++ b/tools/build/Build.include
@@ -90,3 +90,8 @@ if_changed = $(if $(strip $(any-prereq) $(arg-check)),             \
 # - per object C flags
 # - BUILD_STR macro to allow '-D"$(variable)"' constructs
 c_flags = -Wp,-MD,$(depfile),-MT,$@ $(CFLAGS) -D"BUILD_STR(s)=\#s" $(CFLAGS_$(basetarget).o) $(CFLAGS_$(obj))
+
+###
+## HOSTCC C flags
+
+host_c_flags = -Wp,-MD,$(depfile),-MT,$@ $(CHOSTFLAGS) -D"BUILD_STR(s)=\#s" $(CHOSTFLAGS_$(basetarget).o) $(CHOSTFLAGS_$(obj))
diff --git a/tools/build/Makefile b/tools/build/Makefile
index 0d5a0e3..653faee 100644
--- a/tools/build/Makefile
+++ b/tools/build/Makefile
@@ -14,6 +14,12 @@ endef
 $(call allow-override,CC,$(CROSS_COMPILE)gcc)
 $(call allow-override,LD,$(CROSS_COMPILE)ld)
 
+HOSTCC ?= gcc
+HOSTLD ?= ld
+HOSTAR ?= ar
+
+export HOSTCC HOSTLD HOSTAR
+
 ifeq ($(V),1)
   Q =
 else
diff --git a/tools/build/Makefile.build b/tools/build/Makefile.build
index 27f3583..190519a 100644
--- a/tools/build/Makefile.build
+++ b/tools/build/Makefile.build
@@ -58,6 +58,9 @@ quiet_cmd_mkdir = MKDIR    $(dir $@)
 quiet_cmd_cc_o_c = CC       $@
       cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $<
 
+quiet_cmd_host_cc_o_c = HOSTCC   $@
+      cmd_host_cc_o_c = $(HOSTCC) $(host_c_flags) -c -o $@ $<
+
 quiet_cmd_cpp_i_c = CPP      $@
       cmd_cpp_i_c = $(CC) $(c_flags) -E -o $@ $<
 
@@ -70,16 +73,24 @@ quiet_cmd_gen = GEN      $@
 # If there's nothing to link, create empty $@ object.
 quiet_cmd_ld_multi = LD       $@
       cmd_ld_multi = $(if $(strip $(obj-y)),\
-		       $(LD) -r -o $@  $(filter $(obj-y),$^),rm -f $@; $(AR) rcs $@)
+                     $(LD) -r -o $@  $(filter $(obj-y),$^),rm -f $@; $(AR) rcs $@)
+
+quiet_cmd_host_ld_multi = HOSTLD   $@
+      cmd_host_ld_multi = $(if $(strip $(obj-y)),\
+                          $(HOSTLD) -r -o $@  $(filter $(obj-y),$^),rm -f $@; $(HOSTAR) rcs $@)
+
+ifneq ($(filter $(obj),$(hostprogs)),)
+  host = host_
+endif
 
 # Build rules
 $(OUTPUT)%.o: %.c FORCE
 	$(call rule_mkdir)
-	$(call if_changed_dep,cc_o_c)
+	$(call if_changed_dep,$(host)cc_o_c)
 
 $(OUTPUT)%.o: %.S FORCE
 	$(call rule_mkdir)
-	$(call if_changed_dep,cc_o_c)
+	$(call if_changed_dep,$(host)cc_o_c)
 
 $(OUTPUT)%.i: %.c FORCE
 	$(call rule_mkdir)
@@ -119,7 +130,7 @@ $(sort $(subdir-obj-y)): $(subdir-y) ;
 
 $(in-target): $(obj-y) FORCE
 	$(call rule_mkdir)
-	$(call if_changed,ld_multi)
+	$(call if_changed,$(host)ld_multi)
 
 __build: $(in-target)
 	@:

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [tip:perf/urgent] tools build: Make fixdep a hostprog
  2016-09-27 14:18                     ` Jiri Olsa
  2016-09-29 22:19                       ` Arnaldo Carvalho de Melo
  2016-10-04  8:10                       ` [tip:perf/urgent] tools build: Add support for host programs format tip-bot for Jiri Olsa
@ 2016-10-04  8:11                       ` tip-bot for Jiri Olsa
  2016-10-04  8:12                       ` [tip:perf/urgent] perf jevents: Program to convert JSON file tip-bot for Andi Kleen
  3 siblings, 0 replies; 70+ messages in thread
From: tip-bot for Jiri Olsa @ 2016-10-04  8:11 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: tglx, jolsa, peterz, linux-kernel, sukadev, jolsa, andi, mingo,
	acme, maddy, hpa

Commit-ID:  6b3db6f9b970001b751a6cd001bc2ab581ce0fb3
Gitweb:     http://git.kernel.org/tip/6b3db6f9b970001b751a6cd001bc2ab581ce0fb3
Author:     Jiri Olsa <jolsa@redhat.com>
AuthorDate: Tue, 27 Sep 2016 16:18:46 +0200
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Mon, 3 Oct 2016 11:40:35 -0300

tools build: Make fixdep a hostprog

It is used in the build process, so stop suppressing its build in tools
cross builds.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Cc: linuxppc-dev@lists.ozlabs.org
Link: http://lkml.kernel.org/r/20160927141846.GA6589@krava
[ Use HOSTCC on the $(OUTPUT)fixdep target, it was using the x-compiler
  to link fixdep-in.o, that was correctly built with HOSTCC and thus failing ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/build/Build            | 2 ++
 tools/build/Makefile         | 2 +-
 tools/build/Makefile.include | 4 ----
 3 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/tools/build/Build b/tools/build/Build
index 63a6c34..76d1a49 100644
--- a/tools/build/Build
+++ b/tools/build/Build
@@ -1 +1,3 @@
+hostprogs := fixdep
+
 fixdep-y := fixdep.o
diff --git a/tools/build/Makefile b/tools/build/Makefile
index 653faee..8332959 100644
--- a/tools/build/Makefile
+++ b/tools/build/Makefile
@@ -42,7 +42,7 @@ $(OUTPUT)fixdep-in.o: FORCE
 	$(Q)$(MAKE) $(build)=fixdep
 
 $(OUTPUT)fixdep: $(OUTPUT)fixdep-in.o
-	$(QUIET_LINK)$(CC) $(LDFLAGS) -o $@ $<
+	$(QUIET_LINK)$(HOSTCC) $(LDFLAGS) -o $@ $<
 
 FORCE:
 
diff --git a/tools/build/Makefile.include b/tools/build/Makefile.include
index be630be..ad22e4e 100644
--- a/tools/build/Makefile.include
+++ b/tools/build/Makefile.include
@@ -1,10 +1,6 @@
 build := -f $(srctree)/tools/build/Makefile.build dir=. obj
 
-ifdef CROSS_COMPILE
-fixdep:
-else
 fixdep:
 	$(Q)$(MAKE) -C $(srctree)/tools/build CFLAGS= LDFLAGS= $(OUTPUT)fixdep
-endif
 
 .PHONY: fixdep

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [tip:perf/urgent] perf tools: Add jsmn `jasmine' JSON parser
  2016-09-15 22:24 ` [PATCH v21 01/19] perf, tools: Add jsmn `jasmine' JSON parser Sukadev Bhattiprolu
@ 2016-10-04  8:11   ` tip-bot for Andi Kleen
  0 siblings, 0 replies; 70+ messages in thread
From: tip-bot for Andi Kleen @ 2016-10-04  8:11 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: acme, peterz, ak, mingo, linux-kernel, hpa, jolsa, maddy, tglx,
	sukadev, namhyung

Commit-ID:  867a979a83d38fb82c4e7534a0281a02ef1700a3
Gitweb:     http://git.kernel.org/tip/867a979a83d38fb82c4e7534a0281a02ef1700a3
Author:     Andi Kleen <ak@linux.intel.com>
AuthorDate: Thu, 15 Sep 2016 15:24:38 -0700
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Mon, 3 Oct 2016 11:40:36 -0300

perf tools: Add jsmn `jasmine' JSON parser

I need a JSON parser. This adds the simplest JSON parser I could find --
Serge Zaitsev's jsmn `jasmine' -- to the perf library. I merely
converted it to (mostly) Linux style and added support for non 0
terminated input.

The parser is quite straight forward and does not copy any data, just
returns tokens with offsets into the input buffer. So it's relatively
efficient and simple to use.

The code is not fully checkpatch clean, but I didn't want to completely
fork the upstream code.

Original source: http://zserge.bitbucket.org/jsmn.html

In addition I added a simple wrapper that mmaps a json file and provides
some straight forward access functions.

Used in follow-on patches to parse event files.

Signed-off-by: Andi Kleen <ak@linux.intel.com>
Acked-by: Ingo Molnar <mingo@kernel.org>
Acked-by: Jiri Olsa <jolsa@redhat.com>
Acked-by: Namhyung Kim <namhyung@kernel.org>
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-2-git-send-email-sukadev@linux.vnet.ibm.com
Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
[ Use fcntl.h instead of sys/fcntl.h to fix the build on Alpine Linux 3.4/musl libc,
  use stdbool.h to avoid clashing with 'bool' typedef there ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/pmu-events/jsmn.c | 313 +++++++++++++++++++++++++++++++++++++++++++
 tools/perf/pmu-events/jsmn.h |  67 +++++++++
 tools/perf/pmu-events/json.c | 162 ++++++++++++++++++++++
 tools/perf/pmu-events/json.h |  32 +++++
 4 files changed, 574 insertions(+)

diff --git a/tools/perf/pmu-events/jsmn.c b/tools/perf/pmu-events/jsmn.c
new file mode 100644
index 0000000..11d1fa1
--- /dev/null
+++ b/tools/perf/pmu-events/jsmn.c
@@ -0,0 +1,313 @@
+/*
+ * Copyright (c) 2010 Serge A. Zaitsev
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * Slightly modified by AK to not assume 0 terminated input.
+ */
+
+#include <stdlib.h>
+#include "jsmn.h"
+
+/*
+ * Allocates a fresh unused token from the token pool.
+ */
+static jsmntok_t *jsmn_alloc_token(jsmn_parser *parser,
+				   jsmntok_t *tokens, size_t num_tokens)
+{
+	jsmntok_t *tok;
+
+	if ((unsigned)parser->toknext >= num_tokens)
+		return NULL;
+	tok = &tokens[parser->toknext++];
+	tok->start = tok->end = -1;
+	tok->size = 0;
+	return tok;
+}
+
+/*
+ * Fills token type and boundaries.
+ */
+static void jsmn_fill_token(jsmntok_t *token, jsmntype_t type,
+			    int start, int end)
+{
+	token->type = type;
+	token->start = start;
+	token->end = end;
+	token->size = 0;
+}
+
+/*
+ * Fills next available token with JSON primitive.
+ */
+static jsmnerr_t jsmn_parse_primitive(jsmn_parser *parser, const char *js,
+				      size_t len,
+				      jsmntok_t *tokens, size_t num_tokens)
+{
+	jsmntok_t *token;
+	int start;
+
+	start = parser->pos;
+
+	for (; parser->pos < len; parser->pos++) {
+		switch (js[parser->pos]) {
+#ifndef JSMN_STRICT
+		/*
+		 * In strict mode primitive must be followed by ","
+		 * or "}" or "]"
+		 */
+		case ':':
+#endif
+		case '\t':
+		case '\r':
+		case '\n':
+		case ' ':
+		case ',':
+		case ']':
+		case '}':
+			goto found;
+		default:
+			break;
+		}
+		if (js[parser->pos] < 32 || js[parser->pos] >= 127) {
+			parser->pos = start;
+			return JSMN_ERROR_INVAL;
+		}
+	}
+#ifdef JSMN_STRICT
+	/*
+	 * In strict mode primitive must be followed by a
+	 * comma/object/array.
+	 */
+	parser->pos = start;
+	return JSMN_ERROR_PART;
+#endif
+
+found:
+	token = jsmn_alloc_token(parser, tokens, num_tokens);
+	if (token == NULL) {
+		parser->pos = start;
+		return JSMN_ERROR_NOMEM;
+	}
+	jsmn_fill_token(token, JSMN_PRIMITIVE, start, parser->pos);
+	parser->pos--; /* parent sees closing brackets */
+	return JSMN_SUCCESS;
+}
+
+/*
+ * Fills next token with JSON string.
+ */
+static jsmnerr_t jsmn_parse_string(jsmn_parser *parser, const char *js,
+				   size_t len,
+				   jsmntok_t *tokens, size_t num_tokens)
+{
+	jsmntok_t *token;
+	int start = parser->pos;
+
+	/* Skip starting quote */
+	parser->pos++;
+
+	for (; parser->pos < len; parser->pos++) {
+		char c = js[parser->pos];
+
+		/* Quote: end of string */
+		if (c == '\"') {
+			token = jsmn_alloc_token(parser, tokens, num_tokens);
+			if (token == NULL) {
+				parser->pos = start;
+				return JSMN_ERROR_NOMEM;
+			}
+			jsmn_fill_token(token, JSMN_STRING, start+1,
+					parser->pos);
+			return JSMN_SUCCESS;
+		}
+
+		/* Backslash: Quoted symbol expected */
+		if (c == '\\') {
+			parser->pos++;
+			switch (js[parser->pos]) {
+				/* Allowed escaped symbols */
+			case '\"':
+			case '/':
+			case '\\':
+			case 'b':
+			case 'f':
+			case 'r':
+			case 'n':
+			case 't':
+				break;
+				/* Allows escaped symbol \uXXXX */
+			case 'u':
+				/* TODO */
+				break;
+				/* Unexpected symbol */
+			default:
+				parser->pos = start;
+				return JSMN_ERROR_INVAL;
+			}
+		}
+	}
+	parser->pos = start;
+	return JSMN_ERROR_PART;
+}
+
+/*
+ * Parse JSON string and fill tokens.
+ */
+jsmnerr_t jsmn_parse(jsmn_parser *parser, const char *js, size_t len,
+		     jsmntok_t *tokens, unsigned int num_tokens)
+{
+	jsmnerr_t r;
+	int i;
+	jsmntok_t *token;
+
+	for (; parser->pos < len; parser->pos++) {
+		char c;
+		jsmntype_t type;
+
+		c = js[parser->pos];
+		switch (c) {
+		case '{':
+		case '[':
+			token = jsmn_alloc_token(parser, tokens, num_tokens);
+			if (token == NULL)
+				return JSMN_ERROR_NOMEM;
+			if (parser->toksuper != -1)
+				tokens[parser->toksuper].size++;
+			token->type = (c == '{' ? JSMN_OBJECT : JSMN_ARRAY);
+			token->start = parser->pos;
+			parser->toksuper = parser->toknext - 1;
+			break;
+		case '}':
+		case ']':
+			type = (c == '}' ? JSMN_OBJECT : JSMN_ARRAY);
+			for (i = parser->toknext - 1; i >= 0; i--) {
+				token = &tokens[i];
+				if (token->start != -1 && token->end == -1) {
+					if (token->type != type)
+						return JSMN_ERROR_INVAL;
+					parser->toksuper = -1;
+					token->end = parser->pos + 1;
+					break;
+				}
+			}
+			/* Error if unmatched closing bracket */
+			if (i == -1)
+				return JSMN_ERROR_INVAL;
+			for (; i >= 0; i--) {
+				token = &tokens[i];
+				if (token->start != -1 && token->end == -1) {
+					parser->toksuper = i;
+					break;
+				}
+			}
+			break;
+		case '\"':
+			r = jsmn_parse_string(parser, js, len, tokens,
+					      num_tokens);
+			if (r < 0)
+				return r;
+			if (parser->toksuper != -1)
+				tokens[parser->toksuper].size++;
+			break;
+		case '\t':
+		case '\r':
+		case '\n':
+		case ':':
+		case ',':
+		case ' ':
+			break;
+#ifdef JSMN_STRICT
+			/*
+			 * In strict mode primitives are:
+			 * numbers and booleans.
+			 */
+		case '-':
+		case '0':
+		case '1':
+		case '2':
+		case '3':
+		case '4':
+		case '5':
+		case '6':
+		case '7':
+		case '8':
+		case '9':
+		case 't':
+		case 'f':
+		case 'n':
+#else
+			/*
+			 * In non-strict mode every unquoted value
+			 * is a primitive.
+			 */
+			/*FALL THROUGH */
+		default:
+#endif
+			r = jsmn_parse_primitive(parser, js, len, tokens,
+						 num_tokens);
+			if (r < 0)
+				return r;
+			if (parser->toksuper != -1)
+				tokens[parser->toksuper].size++;
+			break;
+
+#ifdef JSMN_STRICT
+			/* Unexpected char in strict mode */
+		default:
+			return JSMN_ERROR_INVAL;
+#endif
+		}
+	}
+
+	for (i = parser->toknext - 1; i >= 0; i--) {
+		/* Unmatched opened object or array */
+		if (tokens[i].start != -1 && tokens[i].end == -1)
+			return JSMN_ERROR_PART;
+	}
+
+	return JSMN_SUCCESS;
+}
+
+/*
+ * Creates a new parser based over a given  buffer with an array of tokens
+ * available.
+ */
+void jsmn_init(jsmn_parser *parser)
+{
+	parser->pos = 0;
+	parser->toknext = 0;
+	parser->toksuper = -1;
+}
+
+const char *jsmn_strerror(jsmnerr_t err)
+{
+	switch (err) {
+	case JSMN_ERROR_NOMEM:
+		return "No enough tokens";
+	case JSMN_ERROR_INVAL:
+		return "Invalid character inside JSON string";
+	case JSMN_ERROR_PART:
+		return "The string is not a full JSON packet, more bytes expected";
+	case JSMN_SUCCESS:
+		return "Success";
+	default:
+		return "Unknown json error";
+	}
+}
diff --git a/tools/perf/pmu-events/jsmn.h b/tools/perf/pmu-events/jsmn.h
new file mode 100644
index 0000000..d666b10
--- /dev/null
+++ b/tools/perf/pmu-events/jsmn.h
@@ -0,0 +1,67 @@
+#ifndef __JSMN_H_
+#define __JSMN_H_
+
+/*
+ * JSON type identifier. Basic types are:
+ *	o Object
+ *	o Array
+ *	o String
+ *	o Other primitive: number, boolean (true/false) or null
+ */
+typedef enum {
+	JSMN_PRIMITIVE = 0,
+	JSMN_OBJECT = 1,
+	JSMN_ARRAY = 2,
+	JSMN_STRING = 3
+} jsmntype_t;
+
+typedef enum {
+	/* Not enough tokens were provided */
+	JSMN_ERROR_NOMEM = -1,
+	/* Invalid character inside JSON string */
+	JSMN_ERROR_INVAL = -2,
+	/* The string is not a full JSON packet, more bytes expected */
+	JSMN_ERROR_PART = -3,
+	/* Everything was fine */
+	JSMN_SUCCESS = 0
+} jsmnerr_t;
+
+/*
+ * JSON token description.
+ * @param		type	type (object, array, string etc.)
+ * @param		start	start position in JSON data string
+ * @param		end		end position in JSON data string
+ */
+typedef struct {
+	jsmntype_t type;
+	int start;
+	int end;
+	int size;
+} jsmntok_t;
+
+/*
+ * JSON parser. Contains an array of token blocks available. Also stores
+ * the string being parsed now and current position in that string
+ */
+typedef struct {
+	unsigned int pos; /* offset in the JSON string */
+	int toknext; /* next token to allocate */
+	int toksuper; /* superior token node, e.g parent object or array */
+} jsmn_parser;
+
+/*
+ * Create JSON parser over an array of tokens
+ */
+void jsmn_init(jsmn_parser *parser);
+
+/*
+ * Run JSON parser. It parses a JSON data string into and array of tokens,
+ * each describing a single JSON object.
+ */
+jsmnerr_t jsmn_parse(jsmn_parser *parser, const char *js,
+		     size_t len,
+		     jsmntok_t *tokens, unsigned int num_tokens);
+
+const char *jsmn_strerror(jsmnerr_t err);
+
+#endif /* __JSMN_H_ */
diff --git a/tools/perf/pmu-events/json.c b/tools/perf/pmu-events/json.c
new file mode 100644
index 0000000..f67bbb0
--- /dev/null
+++ b/tools/perf/pmu-events/json.c
@@ -0,0 +1,162 @@
+/* Parse JSON files using the JSMN parser. */
+
+/*
+ * Copyright (c) 2014, Intel Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+#include "jsmn.h"
+#include "json.h"
+#include <linux/kernel.h>
+
+
+static char *mapfile(const char *fn, size_t *size)
+{
+	unsigned ps = sysconf(_SC_PAGESIZE);
+	struct stat st;
+	char *map = NULL;
+	int err;
+	int fd = open(fn, O_RDONLY);
+
+	if (fd < 0 && verbose && fn) {
+		pr_err("Error opening events file '%s': %s\n", fn,
+				strerror(errno));
+	}
+
+	if (fd < 0)
+		return NULL;
+	err = fstat(fd, &st);
+	if (err < 0)
+		goto out;
+	*size = st.st_size;
+	map = mmap(NULL,
+		   (st.st_size + ps - 1) & ~(ps - 1),
+		   PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
+	if (map == MAP_FAILED)
+		map = NULL;
+out:
+	close(fd);
+	return map;
+}
+
+static void unmapfile(char *map, size_t size)
+{
+	unsigned ps = sysconf(_SC_PAGESIZE);
+	munmap(map, roundup(size, ps));
+}
+
+/*
+ * Parse json file using jsmn. Return array of tokens,
+ * and mapped file. Caller needs to free array.
+ */
+jsmntok_t *parse_json(const char *fn, char **map, size_t *size, int *len)
+{
+	jsmn_parser parser;
+	jsmntok_t *tokens;
+	jsmnerr_t res;
+	unsigned sz;
+
+	*map = mapfile(fn, size);
+	if (!*map)
+		return NULL;
+	/* Heuristic */
+	sz = *size * 16;
+	tokens = malloc(sz);
+	if (!tokens)
+		goto error;
+	jsmn_init(&parser);
+	res = jsmn_parse(&parser, *map, *size, tokens,
+			 sz / sizeof(jsmntok_t));
+	if (res != JSMN_SUCCESS) {
+		pr_err("%s: json error %s\n", fn, jsmn_strerror(res));
+		goto error_free;
+	}
+	if (len)
+		*len = parser.toknext;
+	return tokens;
+error_free:
+	free(tokens);
+error:
+	unmapfile(*map, *size);
+	return NULL;
+}
+
+void free_json(char *map, size_t size, jsmntok_t *tokens)
+{
+	free(tokens);
+	unmapfile(map, size);
+}
+
+static int countchar(char *map, char c, int end)
+{
+	int i;
+	int count = 0;
+	for (i = 0; i < end; i++)
+		if (map[i] == c)
+			count++;
+	return count;
+}
+
+/* Return line number of a jsmn token */
+int json_line(char *map, jsmntok_t *t)
+{
+	return countchar(map, '\n', t->start) + 1;
+}
+
+static const char * const jsmn_types[] = {
+	[JSMN_PRIMITIVE] = "primitive",
+	[JSMN_ARRAY] = "array",
+	[JSMN_OBJECT] = "object",
+	[JSMN_STRING] = "string"
+};
+
+#define LOOKUP(a, i) ((i) < (sizeof(a)/sizeof(*(a))) ? ((a)[i]) : "?")
+
+/* Return type name of a jsmn token */
+const char *json_name(jsmntok_t *t)
+{
+	return LOOKUP(jsmn_types, t->type);
+}
+
+int json_len(jsmntok_t *t)
+{
+	return t->end - t->start;
+}
+
+/* Is string t equal to s? */
+int json_streq(char *map, jsmntok_t *t, const char *s)
+{
+	unsigned len = json_len(t);
+	return len == strlen(s) && !strncasecmp(map + t->start, s, len);
+}
diff --git a/tools/perf/pmu-events/json.h b/tools/perf/pmu-events/json.h
new file mode 100644
index 0000000..f2745c7
--- /dev/null
+++ b/tools/perf/pmu-events/json.h
@@ -0,0 +1,32 @@
+#ifndef JSON_H
+#define JSON_H 1
+
+#include "jsmn.h"
+
+jsmntok_t *parse_json(const char *fn, char **map, size_t *size, int *len);
+void free_json(char *map, size_t size, jsmntok_t *tokens);
+int json_line(char *map, jsmntok_t *t);
+const char *json_name(jsmntok_t *t);
+int json_streq(char *map, jsmntok_t *t, const char *s);
+int json_len(jsmntok_t *t);
+
+extern int verbose;
+
+#include <stdbool.h>
+
+extern int eprintf(int level, int var, const char *fmt, ...);
+#define pr_fmt(fmt)	fmt
+
+#define pr_err(fmt, ...) \
+	eprintf(0, verbose, pr_fmt(fmt), ##__VA_ARGS__)
+
+#ifndef roundup
+#define roundup(x, y) (                                \
+{                                                      \
+        const typeof(y) __y = y;                       \
+        (((x) + (__y - 1)) / __y) * __y;               \
+}                                                      \
+)
+#endif
+
+#endif

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [tip:perf/urgent] perf jevents: Program to convert JSON file
  2016-09-27 14:18                     ` Jiri Olsa
                                         ` (2 preceding siblings ...)
  2016-10-04  8:11                       ` [tip:perf/urgent] tools build: Make fixdep a hostprog tip-bot for Jiri Olsa
@ 2016-10-04  8:12                       ` tip-bot for Andi Kleen
  3 siblings, 0 replies; 70+ messages in thread
From: tip-bot for Andi Kleen @ 2016-10-04  8:12 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: ak, sukadev, acme, maddy, hpa, tglx, linux-kernel, mingo, peterz, jolsa

Commit-ID:  80eeb67fe577aa76b2d1bb5b029bca097f0f25bc
Gitweb:     http://git.kernel.org/tip/80eeb67fe577aa76b2d1bb5b029bca097f0f25bc
Author:     Andi Kleen <ak@linux.intel.com>
AuthorDate: Mon, 19 Sep 2016 17:39:33 -0300
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Mon, 3 Oct 2016 19:55:55 -0300

perf jevents: Program to convert JSON file

This is a modified version of an earlier patch by Andi Kleen.

We expect architectures to create JSON files describing the performance
monitoring (PMU) events that each CPU model/family of the architecture
supports.

Following is an example of the JSON file entry for an x86 event:

    	[
    	...
    	{
    	"EventCode": "0x00",
    	"UMask": "0x01",
    	"EventName": "INST_RETIRED.ANY",
    	"BriefDescription": "Instructions retired from execution.",
    	"PublicDescription": "Instructions retired from execution.",
    	"Counter": "Fixed counter 1",
    	"CounterHTOff": "Fixed counter 1",
    	"SampleAfterValue": "2000003",
    	"SampleAfterValue": "2000003",
    	"MSRIndex": "0",
    	"MSRValue": "0",
    	"TakenAlone": "0",
    	"CounterMask": "0",
    	"Invert": "0",
    	"AnyThread": "0",
    	"EdgeDetect": "0",
    	"PEBS": "0",
    	"PRECISE_STORE": "0",
    	"Errata": "null",
    	"Offcore": "0"
    	},
    	...

    	]

All the PMU events supported by a CPU model/family must be grouped into
"topics" such as "Pipelining", "Floating-point", "Virtual-memory" etc.

All events belonging to a topic must be placed in a separate JSON file
(eg: "Pipelining.json") and all the topic JSON files for a CPU model must
be in a separate directory.

	Eg: for the CPU model "Silvermont_core":

    	$ ls tools/perf/pmu-events/arch/x86/Silvermont_core
    	Floating-point.json
    	Memory.json
    	Other.json
    	Pipelining.json
    	Virtualmemory.json

Finally, to allow multiple CPU models to share a single set of JSON files,
architectures must provide a mapping between a model and its set of events:

    	$ grep Silvermont tools/perf/pmu-events/arch/x86/mapfile.csv
    	GenuineIntel-6-4D,V13,Silvermont_core,core
    	GenuineIntel-6-4C,V13,Silvermont_core,core

which maps each CPU, identified by [vendor, family, model, version, type]
to a directory of JSON files. Thus two (or more) CPU models support the
set of PMU events listed in the directory.

    	tools/perf/pmu-events/arch/x86/Silvermont_core/

Given this organization of files, the program, jevents:

	- locates all JSON files for each CPU-model of the architecture,

	- parses all JSON files for the CPU-model and generates a C-style
	  "PMU-events table" (pmu-events.c) for the model

	- locates a mapfile for the architecture

	- builds a global table, mapping each model of CPU to the corresponding
	  PMU-events table.

The 'pmu-events.c' is generated when building perf and added to libperf.a.
The global table pmu_events_map[] table in this pmu-events.c will be used
in perf in a follow-on patch.

If the architecture does not have any JSON files or there is an error in
processing them, an empty mapping file is created. This would allow the
build of perf to proceed even if we are not able to provide aliases for
events.

The parser for JSON files allows parsing Intel style JSON event files. This
allows to use an Intel event list directly with perf. The Intel event lists
can be quite large and are too big to store in unswappable kernel memory.

The conversion from JSON to C-style is straight forward.  The parser knows
(very little) Intel specific information, and can be easily extended to
handle fields for other CPUs.

The parser code is partially shared with an independent parsing library,
which is 2-clause BSD licensed. To avoid any conflicts I marked those
files as BSD licensed too. As part of perf they become GPLv2.

Committer notes:

Fixes:

1) Limit maxfds to 512 to avoid nftd() segfaulting on alloca() with a
   big rlim_max, as in docker containers - acme

2) Make jevents a hostprog, supporting cross compilation - jolsa

3) Use HOSTCC for jevents final step - acme

4) Define _GNU_SOURCE for asprintf, as we can't use CC's EXTRA_CFLAGS,
  that has to have --sysroot on the Android NDK 24 - acme

5) Removed $(srctree)/tools/perf/pmu-events/pmu-events.c from the
   'clean' target, it is generated on $(OUTPUT)pmu-events/pmu-events.c,
   which is already taken care of in the original patch - acme

Signed-off-by: Andi Kleen <ak@linux.intel.com>
Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Acked-by: Ingo Molnar <mingo@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
Cc: linuxppc-dev@lists.ozlabs.org
Link: http://lkml.kernel.org/r/1473978296-20712-3-git-send-email-sukadev@linux.vnet.ibm.com
Link: http://lkml.kernel.org/r/20160927141846.GA6589@krava
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/Makefile.perf           |  34 +-
 tools/perf/pmu-events/Build        |  13 +
 tools/perf/pmu-events/jevents.c    | 767 +++++++++++++++++++++++++++++++++++++
 tools/perf/pmu-events/jevents.h    |  17 +
 tools/perf/pmu-events/json.h       |   6 +
 tools/perf/pmu-events/pmu-events.h |  36 ++
 6 files changed, 869 insertions(+), 4 deletions(-)

diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index d710db1..982d643 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -144,6 +144,10 @@ $(call allow-override,LD,$(CROSS_COMPILE)ld)
 
 LD += $(EXTRA_LDFLAGS)
 
+HOSTCC  ?= gcc
+HOSTLD  ?= ld
+HOSTAR  ?= ar
+
 PKG_CONFIG = $(CROSS_COMPILE)pkg-config
 
 RM      = rm -f
@@ -345,8 +349,18 @@ strip: $(PROGRAMS) $(OUTPUT)perf
 PERF_IN := $(OUTPUT)perf-in.o
 
 export srctree OUTPUT RM CC LD AR CFLAGS V BISON FLEX AWK
+export HOSTCC HOSTLD HOSTAR
 include $(srctree)/tools/build/Makefile.include
 
+JEVENTS       := $(OUTPUT)pmu-events/jevents
+JEVENTS_IN    := $(OUTPUT)pmu-events/jevents-in.o
+
+PMU_EVENTS_IN := $(OUTPUT)pmu-events/pmu-events-in.o
+
+export JEVENTS
+
+build := -f $(srctree)/tools/build/Makefile.build dir=. obj
+
 $(PERF_IN): prepare FORCE
 	@(test -f ../../include/uapi/linux/perf_event.h && ( \
         (diff -B ../include/uapi/linux/perf_event.h ../../include/uapi/linux/perf_event.h >/dev/null) \
@@ -443,9 +457,18 @@ $(PERF_IN): prepare FORCE
 	|| echo "Warning: tools/include/uapi/linux/mman.h differs from kernel" >&2 )) || true
 	$(Q)$(MAKE) $(build)=perf
 
-$(OUTPUT)perf: $(PERFLIBS) $(PERF_IN) $(LIBTRACEEVENT_DYNAMIC_LIST)
+$(JEVENTS_IN): FORCE
+	$(Q)$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=pmu-events obj=jevents
+
+$(JEVENTS): $(JEVENTS_IN)
+	$(QUIET_LINK)$(HOSTCC) $(JEVENTS_IN) -o $@
+
+$(PMU_EVENTS_IN): $(JEVENTS) FORCE
+	$(Q)$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=pmu-events obj=pmu-events
+
+$(OUTPUT)perf: $(PERFLIBS) $(PERF_IN) $(PMU_EVENTS_IN) $(LIBTRACEEVENT_DYNAMIC_LIST)
 	$(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $(LIBTRACEEVENT_DYNAMIC_LIST_LDFLAGS) \
-		$(PERF_IN) $(LIBS) -o $@
+		$(PERF_IN) $(PMU_EVENTS_IN) $(LIBS) -o $@
 
 $(GTK_IN): fixdep FORCE
 	$(Q)$(MAKE) $(build)=gtk
@@ -474,6 +497,8 @@ perf.spec $(SCRIPTS) \
 ifneq ($(OUTPUT),)
 %.o: $(OUTPUT)%.o
 	@echo "    # Redirected target $@ => $(OUTPUT)$@"
+pmu-events/%.o: $(OUTPUT)pmu-events/%.o
+	@echo "    # Redirected target $@ => $(OUTPUT)$@"
 util/%.o: $(OUTPUT)util/%.o
 	@echo "    # Redirected target $@ => $(OUTPUT)$@"
 bench/%.o: $(OUTPUT)bench/%.o
@@ -729,10 +754,11 @@ clean:: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clea
 	$(call QUIET_CLEAN, core-objs)  $(RM) $(LIB_FILE) $(OUTPUT)perf-archive $(OUTPUT)perf-with-kcore $(LANG_BINDINGS)
 	$(Q)find $(if $(OUTPUT),$(OUTPUT),.) -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete
 	$(Q)$(RM) $(OUTPUT).config-detected
-	$(call QUIET_CLEAN, core-progs) $(RM) $(ALL_PROGRAMS) perf perf-read-vdso32 perf-read-vdsox32
+	$(call QUIET_CLEAN, core-progs) $(RM) $(ALL_PROGRAMS) perf perf-read-vdso32 perf-read-vdsox32 $(OUTPUT)pmu-events/jevents
 	$(call QUIET_CLEAN, core-gen)   $(RM)  *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope* $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)FEATURE-DUMP $(OUTPUT)util/*-bison* $(OUTPUT)util/*-flex* \
 		$(OUTPUT)util/intel-pt-decoder/inat-tables.c $(OUTPUT)fixdep \
-		$(OUTPUT)tests/llvm-src-{base,kbuild,prologue,relocation}.c
+		$(OUTPUT)tests/llvm-src-{base,kbuild,prologue,relocation}.c \
+		$(OUTPUT)pmu-events/pmu-events.c
 	$(QUIET_SUBDIR0)Documentation $(QUIET_SUBDIR1) clean
 	$(python-clean)
 
diff --git a/tools/perf/pmu-events/Build b/tools/perf/pmu-events/Build
new file mode 100644
index 0000000..9213a12
--- /dev/null
+++ b/tools/perf/pmu-events/Build
@@ -0,0 +1,13 @@
+hostprogs := jevents
+
+jevents-y	+= json.o jsmn.o jevents.o
+pmu-events-y	+= pmu-events.o
+JDIR		=  pmu-events/arch/$(ARCH)
+JSON		=  $(shell [ -d $(JDIR) ] &&				\
+			find $(JDIR) -name '*.json' -o -name 'mapfile.csv')
+#
+# Locate/process JSON files in pmu-events/arch/
+# directory and create tables in pmu-events.c.
+#
+$(OUTPUT)pmu-events/pmu-events.c: $(JSON) $(JEVENTS)
+	$(Q)$(call echo-cmd,gen)$(JEVENTS) $(ARCH) pmu-events/arch $(OUTPUT)pmu-events/pmu-events.c $(V)
diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c
new file mode 100644
index 0000000..c4c074a
--- /dev/null
+++ b/tools/perf/pmu-events/jevents.c
@@ -0,0 +1,767 @@
+#define  _XOPEN_SOURCE 500	/* needed for nftw() */
+#define  _GNU_SOURCE		/* needed for asprintf() */
+
+/* Parse event JSON files */
+
+/*
+ * Copyright (c) 2014, Intel Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <stdarg.h>
+#include <libgen.h>
+#include <dirent.h>
+#include <sys/time.h>			/* getrlimit */
+#include <sys/resource.h>		/* getrlimit */
+#include <ftw.h>
+#include <sys/stat.h>
+#include "jsmn.h"
+#include "json.h"
+#include "jevents.h"
+
+#ifndef __maybe_unused
+#define __maybe_unused                  __attribute__((unused))
+#endif
+
+int verbose;
+char *prog;
+
+int eprintf(int level, int var, const char *fmt, ...)
+{
+
+	int ret;
+	va_list args;
+
+	if (var < level)
+		return 0;
+
+	va_start(args, fmt);
+
+	ret = vfprintf(stderr, fmt, args);
+
+	va_end(args);
+
+	return ret;
+}
+
+__attribute__((weak)) char *get_cpu_str(void)
+{
+	return NULL;
+}
+
+static void addfield(char *map, char **dst, const char *sep,
+		     const char *a, jsmntok_t *bt)
+{
+	unsigned int len = strlen(a) + 1 + strlen(sep);
+	int olen = *dst ? strlen(*dst) : 0;
+	int blen = bt ? json_len(bt) : 0;
+	char *out;
+
+	out = realloc(*dst, len + olen + blen);
+	if (!out) {
+		/* Don't add field in this case */
+		return;
+	}
+	*dst = out;
+
+	if (!olen)
+		*(*dst) = 0;
+	else
+		strcat(*dst, sep);
+	strcat(*dst, a);
+	if (bt)
+		strncat(*dst, map + bt->start, blen);
+}
+
+static void fixname(char *s)
+{
+	for (; *s; s++)
+		*s = tolower(*s);
+}
+
+static void fixdesc(char *s)
+{
+	char *e = s + strlen(s);
+
+	/* Remove trailing dots that look ugly in perf list */
+	--e;
+	while (e >= s && isspace(*e))
+		--e;
+	if (*e == '.')
+		*e = 0;
+}
+
+static struct msrmap {
+	const char *num;
+	const char *pname;
+} msrmap[] = {
+	{ "0x3F6", "ldlat=" },
+	{ "0x1A6", "offcore_rsp=" },
+	{ "0x1A7", "offcore_rsp=" },
+	{ NULL, NULL }
+};
+
+static struct field {
+	const char *field;
+	const char *kernel;
+} fields[] = {
+	{ "EventCode",	"event=" },
+	{ "UMask",	"umask=" },
+	{ "CounterMask", "cmask=" },
+	{ "Invert",	"inv=" },
+	{ "AnyThread",	"any=" },
+	{ "EdgeDetect",	"edge=" },
+	{ "SampleAfterValue", "period=" },
+	{ NULL, NULL }
+};
+
+static void cut_comma(char *map, jsmntok_t *newval)
+{
+	int i;
+
+	/* Cut off everything after comma */
+	for (i = newval->start; i < newval->end; i++) {
+		if (map[i] == ',')
+			newval->end = i;
+	}
+}
+
+static int match_field(char *map, jsmntok_t *field, int nz,
+		       char **event, jsmntok_t *val)
+{
+	struct field *f;
+	jsmntok_t newval = *val;
+
+	for (f = fields; f->field; f++)
+		if (json_streq(map, field, f->field) && nz) {
+			cut_comma(map, &newval);
+			addfield(map, event, ",", f->kernel, &newval);
+			return 1;
+		}
+	return 0;
+}
+
+static struct msrmap *lookup_msr(char *map, jsmntok_t *val)
+{
+	jsmntok_t newval = *val;
+	static bool warned;
+	int i;
+
+	cut_comma(map, &newval);
+	for (i = 0; msrmap[i].num; i++)
+		if (json_streq(map, &newval, msrmap[i].num))
+			return &msrmap[i];
+	if (!warned) {
+		warned = true;
+		pr_err("%s: Unknown MSR in event file %.*s\n", prog,
+			json_len(val), map + val->start);
+	}
+	return NULL;
+}
+
+#define EXPECT(e, t, m) do { if (!(e)) {			\
+	jsmntok_t *loc = (t);					\
+	if (!(t)->start && (t) > tokens)			\
+		loc = (t) - 1;					\
+		pr_err("%s:%d: " m ", got %s\n", fn,		\
+			json_line(map, loc),			\
+			json_name(t));				\
+	goto out_free;						\
+} } while (0)
+
+#define TOPIC_DEPTH 256
+static char *topic_array[TOPIC_DEPTH];
+static int   topic_level;
+
+static char *get_topic(void)
+{
+	char *tp_old, *tp = NULL;
+	int i;
+
+	for (i = 0; i < topic_level + 1; i++) {
+		int n;
+
+		tp_old = tp;
+		n = asprintf(&tp, "%s%s", tp ?: "", topic_array[i]);
+		if (n < 0) {
+			pr_info("%s: asprintf() error %s\n", prog);
+			return NULL;
+		}
+		free(tp_old);
+	}
+
+	for (i = 0; i < (int) strlen(tp); i++) {
+		char c = tp[i];
+
+		if (c == '-')
+			tp[i] = ' ';
+		else if (c == '.') {
+			tp[i] = '\0';
+			break;
+		}
+	}
+
+	return tp;
+}
+
+static int add_topic(int level, char *bname)
+{
+	char *topic;
+
+	level -= 2;
+
+	if (level >= TOPIC_DEPTH)
+		return -EINVAL;
+
+	topic = strdup(bname);
+	if (!topic) {
+		pr_info("%s: strdup() error %s for file %s\n", prog,
+				strerror(errno), bname);
+		return -ENOMEM;
+	}
+
+	free(topic_array[topic_level]);
+	topic_array[topic_level] = topic;
+	topic_level              = level;
+	return 0;
+}
+
+struct perf_entry_data {
+	FILE *outfp;
+	char *topic;
+};
+
+static int close_table;
+
+static void print_events_table_prefix(FILE *fp, const char *tblname)
+{
+	fprintf(fp, "struct pmu_event %s[] = {\n", tblname);
+	close_table = 1;
+}
+
+static int print_events_table_entry(void *data, char *name, char *event,
+				    char *desc)
+{
+	struct perf_entry_data *pd = data;
+	FILE *outfp = pd->outfp;
+	char *topic = pd->topic;
+
+	/*
+	 * TODO: Remove formatting chars after debugging to reduce
+	 *	 string lengths.
+	 */
+	fprintf(outfp, "{\n");
+
+	fprintf(outfp, "\t.name = \"%s\",\n", name);
+	fprintf(outfp, "\t.event = \"%s\",\n", event);
+	fprintf(outfp, "\t.desc = \"%s\",\n", desc);
+	fprintf(outfp, "\t.topic = \"%s\",\n", topic);
+
+	fprintf(outfp, "},\n");
+
+	return 0;
+}
+
+static void print_events_table_suffix(FILE *outfp)
+{
+	fprintf(outfp, "{\n");
+
+	fprintf(outfp, "\t.name = 0,\n");
+	fprintf(outfp, "\t.event = 0,\n");
+	fprintf(outfp, "\t.desc = 0,\n");
+
+	fprintf(outfp, "},\n");
+	fprintf(outfp, "};\n");
+	close_table = 0;
+}
+
+/* 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),
+	  void *data)
+{
+	int err = -EIO;
+	size_t size;
+	jsmntok_t *tokens, *tok;
+	int i, j, len;
+	char *map;
+
+	if (!fn)
+		return -ENOENT;
+
+	tokens = parse_json(fn, &map, &size, &len);
+	if (!tokens)
+		return -EIO;
+	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;
+		struct msrmap *msr = NULL;
+		jsmntok_t *msrval = NULL;
+		jsmntok_t *precise = NULL;
+		jsmntok_t *obj = tok++;
+
+		EXPECT(obj->type == JSMN_OBJECT, obj, "expected object");
+		for (j = 0; j < obj->size; j += 2) {
+			jsmntok_t *field, *val;
+			int nz;
+
+			field = tok + j;
+			EXPECT(field->type == JSMN_STRING, tok + j,
+			       "Expected field name");
+			val = tok + j + 1;
+			EXPECT(val->type == JSMN_STRING, tok + j + 1,
+			       "Expected string value");
+
+			nz = !json_streq(map, val, "0");
+			if (match_field(map, field, nz, &event, val)) {
+				/* ok */
+			} else if (json_streq(map, field, "EventName")) {
+				addfield(map, &name, "", "", val);
+			} else if (json_streq(map, field, "BriefDescription")) {
+				addfield(map, &desc, "", "", val);
+				fixdesc(desc);
+			} else if (json_streq(map, field, "PEBS") && nz) {
+				precise = val;
+			} else if (json_streq(map, field, "MSRIndex") && nz) {
+				msr = lookup_msr(map, val);
+			} else if (json_streq(map, field, "MSRValue")) {
+				msrval = val;
+			} else if (json_streq(map, field, "Errata") &&
+				   !json_streq(map, val, "null")) {
+				addfield(map, &desc, ". ",
+					" Spec update: ", val);
+			} else if (json_streq(map, field, "Data_LA") && nz) {
+				addfield(map, &desc, ". ",
+					" Supports address when precise",
+					NULL);
+			}
+			/* ignore unknown fields */
+		}
+		if (precise && desc && !strstr(desc, "(Precise Event)")) {
+			if (json_streq(map, precise, "2"))
+				addfield(map, &desc, " ", "(Must be precise)",
+						NULL);
+			else
+				addfield(map, &desc, " ",
+						"(Precise event)", NULL);
+		}
+		if (msr != NULL)
+			addfield(map, &event, ",", msr->pname, msrval);
+		fixname(name);
+		err = func(data, name, event, desc);
+		free(event);
+		free(desc);
+		free(name);
+		if (err)
+			break;
+		tok += j;
+	}
+	EXPECT(tok - tokens == len, tok, "unexpected objects at end");
+	err = 0;
+out_free:
+	free_json(map, size, tokens);
+	return err;
+}
+
+static char *file_name_to_table_name(char *fname)
+{
+	unsigned int i;
+	int n;
+	int c;
+	char *tblname;
+
+	/*
+	 * Ensure tablename starts with alphabetic character.
+	 * Derive rest of table name from basename of the JSON file,
+	 * replacing hyphens and stripping out .json suffix.
+	 */
+	n = asprintf(&tblname, "pme_%s", basename(fname));
+	if (n < 0) {
+		pr_info("%s: asprintf() error %s for file %s\n", prog,
+				strerror(errno), fname);
+		return NULL;
+	}
+
+	for (i = 0; i < strlen(tblname); i++) {
+		c = tblname[i];
+
+		if (c == '-')
+			tblname[i] = '_';
+		else if (c == '.') {
+			tblname[i] = '\0';
+			break;
+		} else if (!isalnum(c) && c != '_') {
+			pr_err("%s: Invalid character '%c' in file name %s\n",
+					prog, c, basename(fname));
+			free(tblname);
+			tblname = NULL;
+			break;
+		}
+	}
+
+	return tblname;
+}
+
+static void print_mapping_table_prefix(FILE *outfp)
+{
+	fprintf(outfp, "struct pmu_events_map pmu_events_map[] = {\n");
+}
+
+static void print_mapping_table_suffix(FILE *outfp)
+{
+	/*
+	 * Print the terminating, NULL entry.
+	 */
+	fprintf(outfp, "{\n");
+	fprintf(outfp, "\t.cpuid = 0,\n");
+	fprintf(outfp, "\t.version = 0,\n");
+	fprintf(outfp, "\t.type = 0,\n");
+	fprintf(outfp, "\t.table = 0,\n");
+	fprintf(outfp, "},\n");
+
+	/* and finally, the closing curly bracket for the struct */
+	fprintf(outfp, "};\n");
+}
+
+static int process_mapfile(FILE *outfp, char *fpath)
+{
+	int n = 16384;
+	FILE *mapfp;
+	char *save = NULL;
+	char *line, *p;
+	int line_num;
+	char *tblname;
+
+	pr_info("%s: Processing mapfile %s\n", prog, fpath);
+
+	line = malloc(n);
+	if (!line)
+		return -1;
+
+	mapfp = fopen(fpath, "r");
+	if (!mapfp) {
+		pr_info("%s: Error %s opening %s\n", prog, strerror(errno),
+				fpath);
+		return -1;
+	}
+
+	print_mapping_table_prefix(outfp);
+
+	line_num = 0;
+	while (1) {
+		char *cpuid, *version, *type, *fname;
+
+		line_num++;
+		p = fgets(line, n, mapfp);
+		if (!p)
+			break;
+
+		if (line[0] == '#' || line[0] == '\n')
+			continue;
+
+		if (line[strlen(line)-1] != '\n') {
+			/* TODO Deal with lines longer than 16K */
+			pr_info("%s: Mapfile %s: line %d too long, aborting\n",
+					prog, fpath, line_num);
+			return -1;
+		}
+		line[strlen(line)-1] = '\0';
+
+		cpuid = strtok_r(p, ",", &save);
+		version = strtok_r(NULL, ",", &save);
+		fname = strtok_r(NULL, ",", &save);
+		type = strtok_r(NULL, ",", &save);
+
+		tblname = file_name_to_table_name(fname);
+		fprintf(outfp, "{\n");
+		fprintf(outfp, "\t.cpuid = \"%s\",\n", cpuid);
+		fprintf(outfp, "\t.version = \"%s\",\n", version);
+		fprintf(outfp, "\t.type = \"%s\",\n", type);
+
+		/*
+		 * CHECK: We can't use the type (eg "core") field in the
+		 * table name. For us to do that, we need to somehow tweak
+		 * the other caller of file_name_to_table(), process_json()
+		 * to determine the type. process_json() file has no way
+		 * of knowing these are "core" events unless file name has
+		 * core in it. If filename has core in it, we can safely
+		 * ignore the type field here also.
+		 */
+		fprintf(outfp, "\t.table = %s\n", tblname);
+		fprintf(outfp, "},\n");
+	}
+
+	print_mapping_table_suffix(outfp);
+
+	return 0;
+}
+
+/*
+ * If we fail to locate/process JSON and map files, create a NULL mapping
+ * table. This would at least allow perf to build even if we can't find/use
+ * the aliases.
+ */
+static void create_empty_mapping(const char *output_file)
+{
+	FILE *outfp;
+
+	pr_info("%s: Creating empty pmu_events_map[] table\n", prog);
+
+	/* Truncate file to clear any partial writes to it */
+	outfp = fopen(output_file, "w");
+	if (!outfp) {
+		perror("fopen()");
+		_Exit(1);
+	}
+
+	fprintf(outfp, "#include \"../../pmu-events/pmu-events.h\"\n");
+	print_mapping_table_prefix(outfp);
+	print_mapping_table_suffix(outfp);
+	fclose(outfp);
+}
+
+static int get_maxfds(void)
+{
+	struct rlimit rlim;
+
+	if (getrlimit(RLIMIT_NOFILE, &rlim) == 0)
+		return min((int)rlim.rlim_max / 2, 512);
+
+	return 512;
+}
+
+/*
+ * nftw() doesn't let us pass an argument to the processing function,
+ * so use a global variables.
+ */
+static FILE *eventsfp;
+static char *mapfile;
+
+static int process_one_file(const char *fpath, const struct stat *sb,
+			    int typeflag, struct FTW *ftwbuf)
+{
+	char *tblname, *bname  = (char *) fpath + ftwbuf->base;
+	int is_dir  = typeflag == FTW_D;
+	int is_file = typeflag == FTW_F;
+	int level   = ftwbuf->level;
+	int err = 0;
+
+	pr_debug("%s %d %7jd %-20s %s\n",
+		 is_file ? "f" : is_dir ? "d" : "x",
+		 level, sb->st_size, bname, fpath);
+
+	/* base dir */
+	if (level == 0)
+		return 0;
+
+	/* model directory, reset topic */
+	if (level == 1 && is_dir) {
+		if (close_table)
+			print_events_table_suffix(eventsfp);
+
+		/*
+		 * Drop file name suffix. Replace hyphens with underscores.
+		 * Fail if file name contains any alphanum characters besides
+		 * underscores.
+		 */
+		tblname = file_name_to_table_name(bname);
+		if (!tblname) {
+			pr_info("%s: Error determining table name for %s\n", prog,
+				bname);
+			return -1;
+		}
+
+		print_events_table_prefix(eventsfp, tblname);
+		return 0;
+	}
+
+	/*
+	 * Save the mapfile name for now. We will process mapfile
+	 * after processing all JSON files (so we can write out the
+	 * mapping table after all PMU events tables).
+	 *
+	 * TODO: Allow for multiple mapfiles? Punt for now.
+	 */
+	if (level == 1 && is_file) {
+		if (!strncmp(bname, "mapfile.csv", 11)) {
+			if (mapfile) {
+				pr_info("%s: Many mapfiles? Using %s, ignoring %s\n",
+						prog, mapfile, fpath);
+			} else {
+				mapfile = strdup(fpath);
+			}
+			return 0;
+		}
+
+		pr_info("%s: Ignoring file %s\n", prog, fpath);
+		return 0;
+	}
+
+	/*
+	 * If the file name does not have a .json extension,
+	 * ignore it. It could be a readme.txt for instance.
+	 */
+	if (is_file) {
+		char *suffix = bname + strlen(bname) - 5;
+
+		if (strncmp(suffix, ".json", 5)) {
+			pr_info("%s: Ignoring file without .json suffix %s\n", prog,
+				fpath);
+			return 0;
+		}
+	}
+
+	if (level > 1 && add_topic(level, bname))
+		return -ENOMEM;
+
+	/*
+	 * Assume all other files are JSON files.
+	 *
+	 * If mapfile refers to 'power7_core.json', we create a table
+	 * named 'power7_core'. Any inconsistencies between the mapfile
+	 * and directory tree could result in build failure due to table
+	 * names not being found.
+	 *
+	 * Atleast for now, be strict with processing JSON file names.
+	 * i.e. if JSON file name cannot be mapped to C-style table name,
+	 * fail.
+	 */
+	if (is_file) {
+		struct perf_entry_data data = {
+			.topic = get_topic(),
+			.outfp = eventsfp,
+		};
+
+		err = json_events(fpath, print_events_table_entry, &data);
+
+		free(data.topic);
+	}
+
+	return err;
+}
+
+#ifndef PATH_MAX
+#define PATH_MAX	4096
+#endif
+
+/*
+ * Starting in directory 'start_dirname', find the "mapfile.csv" and
+ * the set of JSON files for the architecture 'arch'.
+ *
+ * From each JSON file, create a C-style "PMU events table" from the
+ * JSON file (see struct pmu_event).
+ *
+ * From the mapfile, create a mapping between the CPU revisions and
+ * PMU event tables (see struct pmu_events_map).
+ *
+ * Write out the PMU events tables and the mapping table to pmu-event.c.
+ *
+ * If unable to process the JSON or arch files, create an empty mapping
+ * table so we can continue to build/use  perf even if we cannot use the
+ * PMU event aliases.
+ */
+int main(int argc, char *argv[])
+{
+	int rc;
+	int maxfds;
+	char ldirname[PATH_MAX];
+
+	const char *arch;
+	const char *output_file;
+	const char *start_dirname;
+
+	prog = basename(argv[0]);
+	if (argc < 4) {
+		pr_err("Usage: %s <arch> <starting_dir> <output_file>\n", prog);
+		return 1;
+	}
+
+	arch = argv[1];
+	start_dirname = argv[2];
+	output_file = argv[3];
+
+	if (argc > 4)
+		verbose = atoi(argv[4]);
+
+	eventsfp = fopen(output_file, "w");
+	if (!eventsfp) {
+		pr_err("%s Unable to create required file %s (%s)\n",
+				prog, output_file, strerror(errno));
+		return 2;
+	}
+
+	/* Include pmu-events.h first */
+	fprintf(eventsfp, "#include \"../../pmu-events/pmu-events.h\"\n");
+
+	sprintf(ldirname, "%s/%s", start_dirname, arch);
+
+	/*
+	 * The mapfile allows multiple CPUids to point to the same JSON file,
+	 * so, not sure if there is a need for symlinks within the pmu-events
+	 * directory.
+	 *
+	 * For now, treat symlinks of JSON files as regular files and create
+	 * separate tables for each symlink (presumably, each symlink refers
+	 * to specific version of the CPU).
+	 */
+
+	maxfds = get_maxfds();
+	mapfile = NULL;
+	rc = nftw(ldirname, process_one_file, maxfds, 0);
+	if (rc && verbose) {
+		pr_info("%s: Error walking file tree %s\n", prog, ldirname);
+		goto empty_map;
+	} else if (rc) {
+		goto empty_map;
+	}
+
+	if (close_table)
+		print_events_table_suffix(eventsfp);
+
+	if (!mapfile) {
+		pr_info("%s: No CPU->JSON mapping?\n", prog);
+		goto empty_map;
+	}
+
+	if (process_mapfile(eventsfp, mapfile)) {
+		pr_info("%s: Error processing mapfile %s\n", prog, mapfile);
+		goto empty_map;
+	}
+
+	return 0;
+
+empty_map:
+	fclose(eventsfp);
+	create_empty_mapping(output_file);
+	return 0;
+}
diff --git a/tools/perf/pmu-events/jevents.h b/tools/perf/pmu-events/jevents.h
new file mode 100644
index 0000000..996601f
--- /dev/null
+++ b/tools/perf/pmu-events/jevents.h
@@ -0,0 +1,17 @@
+#ifndef JEVENTS_H
+#define JEVENTS_H 1
+
+int json_events(const char *fn,
+		int (*func)(void *data, char *name, char *event, char *desc),
+		void *data);
+char *get_cpu_str(void);
+
+#ifndef min
+#define min(x, y) ({                            \
+	typeof(x) _min1 = (x);                  \
+	typeof(y) _min2 = (y);                  \
+	(void) (&_min1 == &_min2);              \
+	_min1 < _min2 ? _min1 : _min2; })
+#endif
+
+#endif
diff --git a/tools/perf/pmu-events/json.h b/tools/perf/pmu-events/json.h
index f2745c7..278ebd3 100644
--- a/tools/perf/pmu-events/json.h
+++ b/tools/perf/pmu-events/json.h
@@ -20,6 +20,12 @@ extern int eprintf(int level, int var, const char *fmt, ...);
 #define pr_err(fmt, ...) \
 	eprintf(0, verbose, pr_fmt(fmt), ##__VA_ARGS__)
 
+#define pr_info(fmt, ...) \
+	eprintf(1, verbose, pr_fmt(fmt), ##__VA_ARGS__)
+
+#define pr_debug(fmt, ...) \
+	eprintf(2, verbose, pr_fmt(fmt), ##__VA_ARGS__)
+
 #ifndef roundup
 #define roundup(x, y) (                                \
 {                                                      \
diff --git a/tools/perf/pmu-events/pmu-events.h b/tools/perf/pmu-events/pmu-events.h
new file mode 100644
index 0000000..70d5479
--- /dev/null
+++ b/tools/perf/pmu-events/pmu-events.h
@@ -0,0 +1,36 @@
+#ifndef PMU_EVENTS_H
+#define PMU_EVENTS_H
+
+/*
+ * Describe each PMU event. Each CPU has a table of PMU events.
+ */
+struct pmu_event {
+	const char *name;
+	const char *event;
+	const char *desc;
+	const char *topic;
+};
+
+/*
+ *
+ * Map a CPU to its table of PMU events. The CPU is identified by the
+ * cpuid field, which is an arch-specific identifier for the CPU.
+ * The identifier specified in tools/perf/pmu-events/arch/xxx/mapfile
+ * must match the get_cpustr() in tools/perf/arch/xxx/util/header.c)
+ *
+ * The  cpuid can contain any character other than the comma.
+ */
+struct pmu_events_map {
+	const char *cpuid;
+	const char *version;
+	const char *type;		/* core, uncore etc */
+	struct pmu_event *table;
+};
+
+/*
+ * Global table mapping each known CPU for the architecture to its
+ * table of PMU events.
+ */
+extern struct pmu_events_map pmu_events_map[];
+
+#endif

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [tip:perf/urgent] perf pmu: Use pmu_events table to create aliases
  2016-09-15 22:24 ` [PATCH v21 03/19] perf, tools: Use pmu_events table to create aliases Sukadev Bhattiprolu
  2016-09-27 13:16   ` Arnaldo Carvalho de Melo
@ 2016-10-04  8:12   ` tip-bot for Sukadev Bhattiprolu
  1 sibling, 0 replies; 70+ messages in thread
From: tip-bot for Sukadev Bhattiprolu @ 2016-10-04  8:12 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: maddy, peterz, mingo, hpa, acme, linux-kernel, sukadev, jolsa, tglx

Commit-ID:  933f82ff72d7d1641663462f61f3056ee1fe3f8b
Gitweb:     http://git.kernel.org/tip/933f82ff72d7d1641663462f61f3056ee1fe3f8b
Author:     Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
AuthorDate: Thu, 15 Sep 2016 15:24:40 -0700
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Mon, 3 Oct 2016 19:58:00 -0300

perf pmu: Use pmu_events table to create aliases

At run time (when 'perf' is starting up), locate the specific table of
PMU events that corresponds to the current CPU. Using that table, create
aliases for the each of the PMU events in the CPU. The use these aliases
to parse the user specified perf event.

In short this would allow the user to specify events using their aliases
rather than raw event codes.

Based on input and some earlier patches from Andi Kleen, Jiri Olsa.

Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Acked-by: Ingo Molnar <mingo@kernel.org>
Acked-by: Jiri Olsa <jolsa@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-4-git-send-email-sukadev@linux.vnet.ibm.com
[ Make pmu_add_cpu_aliases() return void, since it was returning just '0' and
  furthermore, even that was being discarded via an explicit (void) cast ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/header.h |  1 +
 tools/perf/util/pmu.c    | 60 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 61 insertions(+)

diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h
index d306ca1..d30109b 100644
--- a/tools/perf/util/header.h
+++ b/tools/perf/util/header.h
@@ -151,4 +151,5 @@ int write_padded(int fd, const void *bf, size_t count, size_t count_aligned);
  */
 int get_cpuid(char *buffer, size_t sz);
 
+char *get_cpuid_str(void);
 #endif /* __PERF_HEADER_H */
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index 2babcdf..10668b7 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -12,6 +12,8 @@
 #include "pmu.h"
 #include "parse-events.h"
 #include "cpumap.h"
+#include "header.h"
+#include "pmu-events/pmu-events.h"
 
 struct perf_pmu_format {
 	char *name;
@@ -473,6 +475,61 @@ static struct cpu_map *pmu_cpumask(const char *name)
 	return cpus;
 }
 
+/*
+ * Return the CPU id as a raw string.
+ *
+ * Each architecture should provide a more precise id string that
+ * can be use to match the architecture's "mapfile".
+ */
+char * __weak get_cpuid_str(void)
+{
+	return NULL;
+}
+
+/*
+ * From the pmu_events_map, find the table of PMU events that corresponds
+ * to the current running CPU. Then, add all PMU events from that table
+ * as aliases.
+ */
+static void pmu_add_cpu_aliases(struct list_head *head)
+{
+	int i;
+	struct pmu_events_map *map;
+	struct pmu_event *pe;
+	char *cpuid;
+
+	cpuid = get_cpuid_str();
+	if (!cpuid)
+		return;
+
+	i = 0;
+	while (1) {
+		map = &pmu_events_map[i++];
+		if (!map->table)
+			goto out;
+
+		if (!strcmp(map->cpuid, cpuid))
+			break;
+	}
+
+	/*
+	 * Found a matching PMU events table. Create aliases
+	 */
+	i = 0;
+	while (1) {
+		pe = &map->table[i++];
+		if (!pe->name)
+			break;
+
+		/* need type casts to override 'const' */
+		__perf_pmu__new_alias(head, NULL, (char *)pe->name,
+				(char *)pe->desc, (char *)pe->event);
+	}
+
+out:
+	free(cpuid);
+}
+
 struct perf_event_attr * __weak
 perf_pmu__get_default_config(struct perf_pmu *pmu __maybe_unused)
 {
@@ -497,6 +554,9 @@ static struct perf_pmu *pmu_lookup(const char *name)
 	if (pmu_aliases(name, &aliases))
 		return NULL;
 
+	if (!strcmp(name, "cpu"))
+		pmu_add_cpu_aliases(&aliases);
+
 	if (pmu_type(name, &type))
 		return NULL;
 

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [tip:perf/urgent] perf powerpc: Support CPU ID matching for Powerpc
  2016-09-15 22:24 ` [PATCH v21 04/19] perf, tools: Support CPU ID matching for Powerpc Sukadev Bhattiprolu
@ 2016-10-04  8:13   ` tip-bot for Sukadev Bhattiprolu
  0 siblings, 0 replies; 70+ messages in thread
From: tip-bot for Sukadev Bhattiprolu @ 2016-10-04  8:13 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: peterz, acme, sukadev, hpa, maddy, jolsa, tglx, mingo, linux-kernel

Commit-ID:  ce88f27ccc724fa8e6766fdd4140768931f42f88
Gitweb:     http://git.kernel.org/tip/ce88f27ccc724fa8e6766fdd4140768931f42f88
Author:     Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
AuthorDate: Thu, 15 Sep 2016 15:24:41 -0700
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Mon, 3 Oct 2016 19:58:01 -0300

perf powerpc: Support CPU ID matching for Powerpc

Implement code that returns the generic CPU ID string for Powerpc.  This
will be used to identify the specific table of PMU events to
parse/compare user specified events against.

Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Acked-by: Ingo Molnar <mingo@kernel.org>
Acked-by: Jiri Olsa <jolsa@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-5-git-send-email-sukadev@linux.vnet.ibm.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/arch/powerpc/util/header.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/tools/perf/arch/powerpc/util/header.c b/tools/perf/arch/powerpc/util/header.c
index f8ccee1..9aaa6f5 100644
--- a/tools/perf/arch/powerpc/util/header.c
+++ b/tools/perf/arch/powerpc/util/header.c
@@ -32,3 +32,14 @@ get_cpuid(char *buffer, size_t sz)
 	}
 	return -1;
 }
+
+char *
+get_cpuid_str(void)
+{
+	char *bufp;
+
+	if (asprintf(&bufp, "%.8lx", mfspr(SPRN_PVR)) < 0)
+		bufp = NULL;
+
+	return bufp;
+}

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [tip:perf/urgent] perf tools: Support CPU id matching for x86 v2
  2016-09-15 22:24 ` [PATCH v21 05/19] perf, tools: Support CPU id matching for x86 v2 Sukadev Bhattiprolu
@ 2016-10-04  8:13   ` tip-bot for Andi Kleen
  0 siblings, 0 replies; 70+ messages in thread
From: tip-bot for Andi Kleen @ 2016-10-04  8:13 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: hpa, acme, peterz, mingo, ak, tglx, linux-kernel, maddy, sukadev, jolsa

Commit-ID:  f33d1227197e0fe9d3682c5a766fdc74559da78e
Gitweb:     http://git.kernel.org/tip/f33d1227197e0fe9d3682c5a766fdc74559da78e
Author:     Andi Kleen <ak@linux.intel.com>
AuthorDate: Thu, 15 Sep 2016 15:24:42 -0700
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Mon, 3 Oct 2016 19:58:01 -0300

perf tools: Support CPU id matching for x86 v2

Implement the code to match CPU types to mapfile types for x86 based on
CPUID. This extends an existing similar function, but changes it to use
the x86 mapfile cpu description.  This allows to resolve event lists
generated by jevents.

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>
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-6-git-send-email-sukadev@linux.vnet.ibm.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/arch/x86/util/header.c | 24 +++++++++++++++++++++---
 1 file changed, 21 insertions(+), 3 deletions(-)

diff --git a/tools/perf/arch/x86/util/header.c b/tools/perf/arch/x86/util/header.c
index 146d12a..a74a48d 100644
--- a/tools/perf/arch/x86/util/header.c
+++ b/tools/perf/arch/x86/util/header.c
@@ -19,8 +19,8 @@ cpuid(unsigned int op, unsigned int *a, unsigned int *b, unsigned int *c,
 			: "a" (op));
 }
 
-int
-get_cpuid(char *buffer, size_t sz)
+static int
+__get_cpuid(char *buffer, size_t sz, const char *fmt)
 {
 	unsigned int a, b, c, d, lvl;
 	int family = -1, model = -1, step = -1;
@@ -48,7 +48,7 @@ get_cpuid(char *buffer, size_t sz)
 		if (family >= 0x6)
 			model += ((a >> 16) & 0xf) << 4;
 	}
-	nb = scnprintf(buffer, sz, "%s,%u,%u,%u$", vendor, family, model, step);
+	nb = scnprintf(buffer, sz, fmt, vendor, family, model, step);
 
 	/* look for end marker to ensure the entire data fit */
 	if (strchr(buffer, '$')) {
@@ -57,3 +57,21 @@ get_cpuid(char *buffer, size_t sz)
 	}
 	return -1;
 }
+
+int
+get_cpuid(char *buffer, size_t sz)
+{
+	return __get_cpuid(buffer, sz, "%s,%u,%u,%u$");
+}
+
+char *
+get_cpuid_str(void)
+{
+	char *buf = malloc(128);
+
+	if (__get_cpuid(buf, 128, "%s-%u-%X$") < 0) {
+		free(buf);
+		return NULL;
+	}
+	return buf;
+}

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [tip:perf/urgent] perf jevents: Handle header line in mapfile
  2016-09-15 22:24 ` [PATCH v21 14/19] perf, tools, jevents: Handle header line in mapfile Sukadev Bhattiprolu
  2016-10-04  0:36   ` Arnaldo Carvalho de Melo
@ 2016-10-04  8:13   ` tip-bot for Andi Kleen
  1 sibling, 0 replies; 70+ messages in thread
From: tip-bot for Andi Kleen @ 2016-10-04  8:13 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: ak, mingo, acme, sukadev, maddy, linux-kernel, tglx, peterz, jolsa, hpa

Commit-ID:  dc720ffc9863b618a192f5949234c54aad00ed24
Gitweb:     http://git.kernel.org/tip/dc720ffc9863b618a192f5949234c54aad00ed24
Author:     Andi Kleen <ak@linux.intel.com>
AuthorDate: Thu, 15 Sep 2016 15:24:51 -0700
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Mon, 3 Oct 2016 21:33:54 -0300

perf jevents: Handle header line in mapfile

To work with existing mapfiles, assume that the first line in
'mapfile.csv' is a header line and skip over it.

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

diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c
index c4c074a..c9bf9a7 100644
--- a/tools/perf/pmu-events/jevents.c
+++ b/tools/perf/pmu-events/jevents.c
@@ -477,7 +477,12 @@ static int process_mapfile(FILE *outfp, char *fpath)
 
 	print_mapping_table_prefix(outfp);
 
-	line_num = 0;
+	/* Skip first line (header) */
+	p = fgets(line, n, mapfp);
+	if (!p)
+		goto out;
+
+	line_num = 1;
 	while (1) {
 		char *cpuid, *version, *type, *fname;
 
@@ -521,8 +526,8 @@ static int process_mapfile(FILE *outfp, char *fpath)
 		fprintf(outfp, "},\n");
 	}
 
+out:
 	print_mapping_table_suffix(outfp);
-
 	return 0;
 }
 

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [tip:perf/urgent] perf pmu: Support alias descriptions
  2016-09-15 22:24 ` [PATCH v21 06/19] perf, tools: Support alias descriptions Sukadev Bhattiprolu
  2016-09-27 17:41   ` Arnaldo Carvalho de Melo
@ 2016-10-04  8:14   ` tip-bot for Andi Kleen
  1 sibling, 0 replies; 70+ messages in thread
From: tip-bot for Andi Kleen @ 2016-10-04  8:14 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: tglx, mingo, acme, ak, linux-kernel, hpa, peterz, jolsa, maddy, sukadev

Commit-ID:  08e60ed15d0483be38a87d17538ccf02acff5b1f
Gitweb:     http://git.kernel.org/tip/08e60ed15d0483be38a87d17538ccf02acff5b1f
Author:     Andi Kleen <ak@linux.intel.com>
AuthorDate: Thu, 15 Sep 2016 15:24:43 -0700
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Mon, 3 Oct 2016 21:34:54 -0300

perf pmu: Support alias descriptions

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 10668b7..9857fb1 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 743422a..51d8d0d 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];

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [tip:perf/urgent] perf tools: Query terminal width and use in perf list
  2016-09-15 22:24 ` [PATCH v21 07/19] perf, tools: Query terminal width and use in perf list Sukadev Bhattiprolu
@ 2016-10-04  8:14   ` tip-bot for Andi Kleen
  0 siblings, 0 replies; 70+ messages in thread
From: tip-bot for Andi Kleen @ 2016-10-04  8:14 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, ak, acme, namhyung, peterz, hpa, maddy, mingo,
	tglx, jolsa, sukadev

Commit-ID:  61eb2eb434b3430c6ef70536eb3d16b616b5ee52
Gitweb:     http://git.kernel.org/tip/61eb2eb434b3430c6ef70536eb3d16b616b5ee52
Author:     Andi Kleen <ak@linux.intel.com>
AuthorDate: Thu, 15 Sep 2016 15:24:44 -0700
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Mon, 3 Oct 2016 21:35:45 -0300

perf tools: Query terminal width and use in perf list

Automatically adapt the now wider and word wrapped perf list output to
wider terminals. This requires querying the terminal before the auto
pager takes over, and exporting this information from the pager
subsystem.

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>
Acked-by: Namhyung Kim <namhyung@kernel.org>
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-8-git-send-email-sukadev@linux.vnet.ibm.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/lib/subcmd/pager.c | 16 ++++++++++++++++
 tools/lib/subcmd/pager.h |  1 +
 tools/perf/util/pmu.c    |  3 ++-
 3 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/tools/lib/subcmd/pager.c b/tools/lib/subcmd/pager.c
index d50f3b58..6518bea 100644
--- a/tools/lib/subcmd/pager.c
+++ b/tools/lib/subcmd/pager.c
@@ -3,6 +3,7 @@
 #include <stdio.h>
 #include <string.h>
 #include <signal.h>
+#include <sys/ioctl.h>
 #include "pager.h"
 #include "run-command.h"
 #include "sigchain.h"
@@ -14,6 +15,7 @@
  */
 
 static int spawned_pager;
+static int pager_columns;
 
 void pager_init(const char *pager_env)
 {
@@ -58,9 +60,12 @@ static void wait_for_pager_signal(int signo)
 void setup_pager(void)
 {
 	const char *pager = getenv(subcmd_config.pager_env);
+	struct winsize sz;
 
 	if (!isatty(1))
 		return;
+	if (ioctl(1, TIOCGWINSZ, &sz) == 0)
+		pager_columns = sz.ws_col;
 	if (!pager)
 		pager = getenv("PAGER");
 	if (!(pager || access("/usr/bin/pager", X_OK)))
@@ -98,3 +103,14 @@ int pager_in_use(void)
 {
 	return spawned_pager;
 }
+
+int pager_get_columns(void)
+{
+	char *s;
+
+	s = getenv("COLUMNS");
+	if (s)
+		return atoi(s);
+
+	return (pager_columns ? pager_columns : 80) - 2;
+}
diff --git a/tools/lib/subcmd/pager.h b/tools/lib/subcmd/pager.h
index 8b83714..623f554 100644
--- a/tools/lib/subcmd/pager.h
+++ b/tools/lib/subcmd/pager.h
@@ -5,5 +5,6 @@ extern void pager_init(const char *pager_env);
 
 extern void setup_pager(void);
 extern int pager_in_use(void);
+extern int pager_get_columns(void);
 
 #endif /* __SUBCMD_PAGER_H */
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index 9857fb1..7b46e77 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -14,6 +14,7 @@
 #include "cpumap.h"
 #include "header.h"
 #include "pmu-events/pmu-events.h"
+#include "cache.h"
 
 struct perf_pmu_format {
 	char *name;
@@ -1092,7 +1093,7 @@ void print_pmu_events(const char *event_glob, bool name_only)
 	int len, j;
 	struct pair *aliases;
 	int numdesc = 0;
-	int columns = 78;
+	int columns = pager_get_columns();
 
 	pmu = NULL;
 	len = 0;

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [tip:perf/urgent] perf list: Add a --no-desc flag
  2016-09-15 22:24 ` [PATCH v21 08/19] perf, tools: Add a --no-desc flag to " Sukadev Bhattiprolu
@ 2016-10-04  8:15   ` tip-bot for Andi Kleen
  0 siblings, 0 replies; 70+ messages in thread
From: tip-bot for Andi Kleen @ 2016-10-04  8:15 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: mingo, peterz, jolsa, sukadev, maddy, acme, tglx, ak, hpa, linux-kernel

Commit-ID:  1c5f01fe8660fc48625a94a5ed10e4dbaea95d5f
Gitweb:     http://git.kernel.org/tip/1c5f01fe8660fc48625a94a5ed10e4dbaea95d5f
Author:     Andi Kleen <ak@linux.intel.com>
AuthorDate: Thu, 15 Sep 2016 15:24:45 -0700
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Mon, 3 Oct 2016 21:35:45 -0300

perf list: Add a --no-desc flag

Add a --no-desc flag to 'perf list' to not print the event descriptions
that were earlier added for JSON events. This may be useful to get a
less crowded listing.

It's still default to print descriptions as that is the more useful
default for most users.

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: linuxppc-dev@lists.ozlabs.org
Cc: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/1473978296-20712-9-git-send-email-sukadev@linux.vnet.ibm.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/Documentation/perf-list.txt |  8 +++++++-
 tools/perf/builtin-list.c              | 14 +++++++++-----
 tools/perf/util/parse-events.c         |  4 ++--
 tools/perf/util/parse-events.h         |  2 +-
 tools/perf/util/pmu.c                  |  4 ++--
 tools/perf/util/pmu.h                  |  2 +-
 6 files changed, 22 insertions(+), 12 deletions(-)

diff --git a/tools/perf/Documentation/perf-list.txt b/tools/perf/Documentation/perf-list.txt
index a126e97..72209bc 100644
--- a/tools/perf/Documentation/perf-list.txt
+++ b/tools/perf/Documentation/perf-list.txt
@@ -8,13 +8,19 @@ perf-list - List all symbolic event types
 SYNOPSIS
 --------
 [verse]
-'perf list' [hw|sw|cache|tracepoint|pmu|event_glob]
+'perf list' [--no-desc] [hw|sw|cache|tracepoint|pmu|event_glob]
 
 DESCRIPTION
 -----------
 This command displays the symbolic event types which can be selected in the
 various perf commands with the -e option.
 
+OPTIONS
+-------
+--no-desc::
+Don't print descriptions.
+
+
 [[EVENT_MODIFIERS]]
 EVENT MODIFIERS
 ---------------
diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c
index 88ee419..b14cb16 100644
--- a/tools/perf/builtin-list.c
+++ b/tools/perf/builtin-list.c
@@ -16,16 +16,20 @@
 #include "util/pmu.h"
 #include <subcmd/parse-options.h>
 
+static bool desc_flag = true;
+
 int cmd_list(int argc, const char **argv, const char *prefix __maybe_unused)
 {
 	int i;
 	bool raw_dump = 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_END()
 	};
 	const char * const list_usage[] = {
-		"perf list [hw|sw|cache|tracepoint|pmu|sdt|event_glob]",
+		"perf list [--no-desc] [hw|sw|cache|tracepoint|pmu|sdt|event_glob]",
 		NULL
 	};
 
@@ -40,7 +44,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);
+		print_events(NULL, raw_dump, !desc_flag);
 		return 0;
 	}
 
@@ -61,14 +65,14 @@ 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);
+			print_pmu_events(NULL, raw_dump, !desc_flag);
 		else if (strcmp(argv[i], "sdt") == 0)
 			print_sdt_events(NULL, NULL, raw_dump);
 		else if ((sep = strchr(argv[i], ':')) != NULL) {
 			int sep_idx;
 
 			if (sep == NULL) {
-				print_events(argv[i], raw_dump);
+				print_events(argv[i], raw_dump, !desc_flag);
 				continue;
 			}
 			sep_idx = sep - argv[i];
@@ -90,7 +94,7 @@ int cmd_list(int argc, const char **argv, const char *prefix __maybe_unused)
 			print_symbol_events(s, PERF_TYPE_SOFTWARE,
 					    event_symbols_sw, PERF_COUNT_SW_MAX, raw_dump);
 			print_hwcache_events(s, raw_dump);
-			print_pmu_events(s, raw_dump);
+			print_pmu_events(s, raw_dump, !desc_flag);
 			print_tracepoint_events(NULL, s, raw_dump);
 			print_sdt_events(NULL, s, raw_dump);
 			free(s);
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 33546c3..3966ad7 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -2263,7 +2263,7 @@ out_enomem:
 /*
  * Print the help text for the event symbols:
  */
-void print_events(const char *event_glob, bool name_only)
+void print_events(const char *event_glob, bool name_only, bool quiet_flag)
 {
 	print_symbol_events(event_glob, PERF_TYPE_HARDWARE,
 			    event_symbols_hw, PERF_COUNT_HW_MAX, name_only);
@@ -2273,7 +2273,7 @@ void print_events(const char *event_glob, bool name_only)
 
 	print_hwcache_events(event_glob, name_only);
 
-	print_pmu_events(event_glob, name_only);
+	print_pmu_events(event_glob, name_only, quiet_flag);
 
 	if (event_glob != NULL)
 		return;
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
index 8d09a97..3bf376b 100644
--- a/tools/perf/util/parse-events.h
+++ b/tools/perf/util/parse-events.h
@@ -172,7 +172,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);
+void print_events(const char *event_glob, bool name_only, bool quiet);
 
 struct event_symbol {
 	const char	*symbol;
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index 7b46e77..9dc3506 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -1084,7 +1084,7 @@ static void wordwrap(char *s, int start, int max, int corr)
 	}
 }
 
-void print_pmu_events(const char *event_glob, bool name_only)
+void print_pmu_events(const char *event_glob, bool name_only, bool quiet_flag)
 {
 	struct perf_pmu *pmu;
 	struct perf_pmu_alias *alias;
@@ -1151,7 +1151,7 @@ void print_pmu_events(const char *event_glob, bool name_only)
 			printf("%s ", aliases[j].name);
 			continue;
 		}
-		if (aliases[j].desc) {
+		if (aliases[j].desc && !quiet_flag) {
 			if (numdesc++ == 0)
 				printf("\n");
 			printf("  %-50s\n", aliases[j].name);
diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h
index 51d8d0d..7b47192 100644
--- a/tools/perf/util/pmu.h
+++ b/tools/perf/util/pmu.h
@@ -72,7 +72,7 @@ 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);
+void print_pmu_events(const char *event_glob, bool name_only, bool quiet);
 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,

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [tip:perf/urgent] perf pmu: Add override support for event list CPUID
  2016-09-15 22:24 ` [PATCH v21 09/19] perf, tools: Add override support for event list CPUID Sukadev Bhattiprolu
@ 2016-10-04  8:15   ` tip-bot for Andi Kleen
  0 siblings, 0 replies; 70+ messages in thread
From: tip-bot for Andi Kleen @ 2016-10-04  8:15 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: ak, linux-kernel, jolsa, peterz, mingo, acme, maddy, sukadev, tglx, hpa

Commit-ID:  fc06e2a5aad9fcf7efaabd7550ac31f648d2f2bc
Gitweb:     http://git.kernel.org/tip/fc06e2a5aad9fcf7efaabd7550ac31f648d2f2bc
Author:     Andi Kleen <ak@linux.intel.com>
AuthorDate: Thu, 15 Sep 2016 15:24:46 -0700
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Mon, 3 Oct 2016 21:35:46 -0300

perf pmu: Add override support for event list CPUID

Add a PERF_CPUID variable to override the CPUID of the current CPU
(within the current architecture). This is useful for testing, so that
all event lists can be tested on a single system.

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>
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-10-git-send-email-sukadev@linux.vnet.ibm.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/pmu.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index 9dc3506..79242cf 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -501,10 +501,16 @@ static void pmu_add_cpu_aliases(struct list_head *head)
 	struct pmu_event *pe;
 	char *cpuid;
 
-	cpuid = get_cpuid_str();
+	cpuid = getenv("PERF_CPUID");
+	if (cpuid)
+		cpuid = strdup(cpuid);
+	if (!cpuid)
+		cpuid = get_cpuid_str();
 	if (!cpuid)
 		return;
 
+	pr_debug("Using CPUID %s\n", cpuid);
+
 	i = 0;
 	while (1) {
 		map = &pmu_events_map[i++];

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [tip:perf/urgent] perf jevents: Add support for long descriptions
  2016-09-15 22:24 ` [PATCH v21 10/19] perf, tools, jevents: Add support for long descriptions Sukadev Bhattiprolu
@ 2016-10-04  8:16   ` tip-bot for Sukadev Bhattiprolu
  0 siblings, 0 replies; 70+ messages in thread
From: tip-bot for Sukadev Bhattiprolu @ 2016-10-04  8:16 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: mingo, hpa, jolsa, sukadev, acme, ak, tglx, maddy, linux-kernel, peterz

Commit-ID:  794ba54a8393456d503958d6217874e455b6a771
Gitweb:     http://git.kernel.org/tip/794ba54a8393456d503958d6217874e455b6a771
Author:     Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
AuthorDate: Thu, 15 Sep 2016 15:24:47 -0700
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Mon, 3 Oct 2016 21:35:46 -0300

perf jevents: Add support for long descriptions

Implement support in jevents to parse long descriptions for events that
may have them in the JSON files. A follow on patch will make this long
description available to user through the 'perf list' command.

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>
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-11-git-send-email-sukadev@linux.vnet.ibm.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/pmu-events/jevents.c    | 32 ++++++++++++++++++++++++--------
 tools/perf/pmu-events/jevents.h    |  3 ++-
 tools/perf/pmu-events/pmu-events.h |  1 +
 3 files changed, 27 insertions(+), 9 deletions(-)

diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c
index c9bf9a7..13f4284 100644
--- a/tools/perf/pmu-events/jevents.c
+++ b/tools/perf/pmu-events/jevents.c
@@ -269,7 +269,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)
 {
 	struct perf_entry_data *pd = data;
 	FILE *outfp = pd->outfp;
@@ -285,6 +285,8 @@ static int print_events_table_entry(void *data, char *name, char *event,
 	fprintf(outfp, "\t.event = \"%s\",\n", event);
 	fprintf(outfp, "\t.desc = \"%s\",\n", desc);
 	fprintf(outfp, "\t.topic = \"%s\",\n", topic);
+	if (long_desc && long_desc[0])
+		fprintf(outfp, "\t.long_desc = \"%s\",\n", long_desc);
 
 	fprintf(outfp, "},\n");
 
@@ -306,7 +308,8 @@ 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;
@@ -325,6 +328,8 @@ int json_events(const char *fn,
 	tok = tokens + 1;
 	for (i = 0; i < tokens->size; i++) {
 		char *event = NULL, *desc = NULL, *name = NULL;
+		char *long_desc = NULL;
+		char *extra_desc = NULL;
 		struct msrmap *msr = NULL;
 		jsmntok_t *msrval = NULL;
 		jsmntok_t *precise = NULL;
@@ -350,6 +355,10 @@ 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) {
@@ -358,10 +367,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);
 			}
@@ -369,19 +378,26 @@ int json_events(const char *fn,
 		}
 		if (precise && desc && !strstr(desc, "(Precise Event)")) {
 			if (json_streq(map, precise, "2"))
-				addfield(map, &desc, " ", "(Must be precise)",
-						NULL);
+				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(long_desc);
+		free(extra_desc);
 		if (err)
 			break;
 		tok += j;
diff --git a/tools/perf/pmu-events/jevents.h b/tools/perf/pmu-events/jevents.h
index 996601f..b0eb274 100644
--- a/tools/perf/pmu-events/jevents.h
+++ b/tools/perf/pmu-events/jevents.h
@@ -2,7 +2,8 @@
 #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 70d5479..2eaef59 100644
--- a/tools/perf/pmu-events/pmu-events.h
+++ b/tools/perf/pmu-events/pmu-events.h
@@ -9,6 +9,7 @@ struct pmu_event {
 	const char *event;
 	const char *desc;
 	const char *topic;
+	const char *long_desc;
 };
 
 /*

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [tip:perf/urgent] perf list: Support long jevents descriptions
  2016-09-15 22:24 ` [PATCH v21 12/19] perf, tools: Support long descriptions with perf list Sukadev Bhattiprolu
  2016-10-04  0:26   ` Arnaldo Carvalho de Melo
@ 2016-10-04  8:16   ` tip-bot for Sukadev Bhattiprolu
  1 sibling, 0 replies; 70+ messages in thread
From: tip-bot for Sukadev Bhattiprolu @ 2016-10-04  8:16 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: jolsa, mingo, peterz, linux-kernel, maddy, sukadev, tglx, hpa, ak, acme

Commit-ID:  c8d6828a6510c9363180ebf662b51d032e0eb85a
Gitweb:     http://git.kernel.org/tip/c8d6828a6510c9363180ebf662b51d032e0eb85a
Author:     Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
AuthorDate: Thu, 15 Sep 2016 15:24:48 -0700
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Mon, 3 Oct 2016 21:35:47 -0300

perf list: Support long jevents descriptions

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 <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>
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-13-git-send-email-sukadev@linux.vnet.ibm.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/Documentation/perf-list.txt |  6 +++++-
 tools/perf/builtin-list.c              | 16 +++++++++++-----
 tools/perf/util/parse-events.c         |  5 +++--
 tools/perf/util/parse-events.h         |  3 ++-
 tools/perf/util/pmu.c                  | 15 ++++++++++-----
 tools/perf/util/pmu.h                  |  4 +++-
 6 files changed, 34 insertions(+), 15 deletions(-)

diff --git a/tools/perf/Documentation/perf-list.txt b/tools/perf/Documentation/perf-list.txt
index 72209bc..41857cc 100644
--- a/tools/perf/Documentation/perf-list.txt
+++ b/tools/perf/Documentation/perf-list.txt
@@ -8,7 +8,7 @@ perf-list - List all symbolic event types
 SYNOPSIS
 --------
 [verse]
-'perf list' [--no-desc] [hw|sw|cache|tracepoint|pmu|event_glob]
+'perf list' [--no-desc] [--long-desc] [hw|sw|cache|tracepoint|pmu|event_glob]
 
 DESCRIPTION
 -----------
@@ -20,6 +20,10 @@ OPTIONS
 --no-desc::
 Don't print descriptions.
 
+-v::
+--long-desc::
+Print longer event descriptions.
+
 
 [[EVENT_MODIFIERS]]
 EVENT MODIFIERS
diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c
index b14cb16..ba9322f 100644
--- a/tools/perf/builtin-list.c
+++ b/tools/perf/builtin-list.c
@@ -22,14 +22,17 @@ 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[] = {
-		"perf list [--no-desc] [hw|sw|cache|tracepoint|pmu|sdt|event_glob]",
+		"perf list [<options>] [hw|sw|cache|tracepoint|pmu|sdt|event_glob]",
 		NULL
 	};
 
@@ -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;
 	}
 
@@ -65,14 +68,16 @@ 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 if (strcmp(argv[i], "sdt") == 0)
 			print_sdt_events(NULL, NULL, raw_dump);
 		else if ((sep = strchr(argv[i], ':')) != NULL) {
 			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];
@@ -94,7 +99,8 @@ int cmd_list(int argc, const char **argv, const char *prefix __maybe_unused)
 			print_symbol_events(s, PERF_TYPE_SOFTWARE,
 					    event_symbols_sw, PERF_COUNT_SW_MAX, raw_dump);
 			print_hwcache_events(s, raw_dump);
-			print_pmu_events(s, raw_dump, !desc_flag);
+			print_pmu_events(s, raw_dump, !desc_flag,
+						long_desc_flag);
 			print_tracepoint_events(NULL, s, raw_dump);
 			print_sdt_events(NULL, s, raw_dump);
 			free(s);
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 3966ad7..8f88f63 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -2263,7 +2263,8 @@ 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);
@@ -2273,7 +2274,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 3bf376b..da246a3 100644
--- a/tools/perf/util/parse-events.h
+++ b/tools/perf/util/parse-events.h
@@ -172,7 +172,8 @@ 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 79242cf..8ff382c 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -223,7 +223,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, char *val)
+				 char *desc, char *val, char *long_desc)
 {
 	struct perf_pmu_alias *alias;
 	int ret;
@@ -257,6 +257,8 @@ static int __perf_pmu__new_alias(struct list_head *list, char *dir, char *name,
 	}
 
 	alias->desc = desc ? strdup(desc) : NULL;
+	alias->long_desc = long_desc ? strdup(long_desc) :
+				desc ? strdup(desc) : NULL;
 
 	list_add_tail(&alias->list, list);
 
@@ -274,7 +276,7 @@ static int perf_pmu__new_alias(struct list_head *list, char *dir, char *name, FI
 
 	buf[ret] = 0;
 
-	return __perf_pmu__new_alias(list, dir, name, NULL, buf);
+	return __perf_pmu__new_alias(list, dir, name, NULL, buf, NULL);
 }
 
 static inline bool pmu_alias_info_file(char *name)
@@ -532,7 +534,8 @@ static void pmu_add_cpu_aliases(struct list_head *head)
 
 		/* need type casts to override 'const' */
 		__perf_pmu__new_alias(head, NULL, (char *)pe->name,
-				(char *)pe->desc, (char *)pe->event);
+				(char *)pe->desc, (char *)pe->event,
+				(char *)pe->long_desc);
 	}
 
 out:
@@ -1090,7 +1093,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;
@@ -1138,7 +1142,8 @@ void print_pmu_events(const char *event_glob, bool name_only, bool quiet_flag)
 			if (!aliases[j].name)
 				goto out_enomem;
 
-			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 7b47192..2fb8aa0 100644
--- a/tools/perf/util/pmu.h
+++ b/tools/perf/util/pmu.h
@@ -41,6 +41,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];
@@ -72,7 +73,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,

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [tip:perf/urgent] perf list jevents: Add support for event list topics
  2016-09-15 22:24 ` [PATCH v21 13/19] perf, tools: Add support for event list topics Sukadev Bhattiprolu
@ 2016-10-04  8:16   ` tip-bot for Andi Kleen
  0 siblings, 0 replies; 70+ messages in thread
From: tip-bot for Andi Kleen @ 2016-10-04  8:16 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: tglx, mingo, acme, maddy, linux-kernel, sukadev, hpa, ak, peterz, jolsa

Commit-ID:  dd5f10368a5f27ec926395056d959513ca4578cc
Gitweb:     http://git.kernel.org/tip/dd5f10368a5f27ec926395056d959513ca4578cc
Author:     Andi Kleen <ak@linux.intel.com>
AuthorDate: Thu, 15 Sep 2016 15:24:50 -0700
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Mon, 3 Oct 2016 21:35:47 -0300

perf list jevents: Add support for event list topics

Add support to group the output of perf list by the Topic field in the
JSON file.

Example output:

% perf list
...
Cache:
  l1d.replacement
       [L1D data line replacements]
  l1d_pend_miss.pending
       [L1D miss oustandings duration in cycles]
  l1d_pend_miss.pending_cycles
       [Cycles with L1D load Misses outstanding]
  l2_l1d_wb_rqsts.all
       [Not rejected writebacks from L1D to L2 cache lines in any state]
  l2_l1d_wb_rqsts.hit_e
       [Not rejected writebacks from L1D to L2 cache lines in E state]
  l2_l1d_wb_rqsts.hit_m
       [Not rejected writebacks from L1D to L2 cache lines in M state]

...
Pipeline:
  arith.fpu_div
       [Divide operations executed]
  arith.fpu_div_active
       [Cycles when divider is busy executing divide operations]
  baclears.any
       [Counts the total number when the front end is resteered, mainly
       when the BPU cannot provide a correct prediction and this is
       corrected by other branch handling mechanisms at the front end]
  br_inst_exec.all_branches
       [Speculative and retired branches]
  br_inst_exec.all_conditional
       [Speculative and retired macro-conditional branches]
  br_inst_exec.all_direct_jmp
       [Speculative and retired macro-unconditional branches excluding
       calls and indirects]
  br_inst_exec.all_direct_near_call
       [Speculative and retired direct near calls]
  br_inst_exec.all_indirect_jump_non_call_ret

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-14-git-send-email-sukadev@linux.vnet.ibm.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/pmu.c | 37 +++++++++++++++++++++++++++----------
 tools/perf/util/pmu.h |  1 +
 2 files changed, 28 insertions(+), 10 deletions(-)

diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index 8ff382c..b1474dc 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -223,7 +223,8 @@ 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, char *val, char *long_desc)
+				 char *desc, char *val, char *long_desc,
+				 char *topic)
 {
 	struct perf_pmu_alias *alias;
 	int ret;
@@ -259,6 +260,7 @@ static int __perf_pmu__new_alias(struct list_head *list, char *dir, char *name,
 	alias->desc = desc ? strdup(desc) : NULL;
 	alias->long_desc = long_desc ? strdup(long_desc) :
 				desc ? strdup(desc) : NULL;
+	alias->topic = topic ? strdup(topic) : NULL;
 
 	list_add_tail(&alias->list, list);
 
@@ -276,7 +278,7 @@ static int perf_pmu__new_alias(struct list_head *list, char *dir, char *name, FI
 
 	buf[ret] = 0;
 
-	return __perf_pmu__new_alias(list, dir, name, NULL, buf, NULL);
+	return __perf_pmu__new_alias(list, dir, name, NULL, buf, NULL, NULL);
 }
 
 static inline bool pmu_alias_info_file(char *name)
@@ -535,7 +537,7 @@ static void pmu_add_cpu_aliases(struct list_head *head)
 		/* need type casts to override 'const' */
 		__perf_pmu__new_alias(head, NULL, (char *)pe->name,
 				(char *)pe->desc, (char *)pe->event,
-				(char *)pe->long_desc);
+				(char *)pe->long_desc, (char *)pe->topic);
 	}
 
 out:
@@ -1055,19 +1057,26 @@ static char *format_alias_or(char *buf, int len, struct perf_pmu *pmu,
 	return buf;
 }
 
-struct pair {
+struct sevent {
 	char *name;
 	char *desc;
+	char *topic;
 };
 
-static int cmp_pair(const void *a, const void *b)
+static int cmp_sevent(const void *a, const void *b)
 {
-	const struct pair *as = a;
-	const struct pair *bs = b;
+	const struct sevent *as = a;
+	const struct sevent *bs = b;
 
 	/* Put extra events last */
 	if (!!as->desc != !!bs->desc)
 		return !!as->desc - !!bs->desc;
+	if (as->topic && bs->topic) {
+		int n = strcmp(as->topic, bs->topic);
+
+		if (n)
+			return n;
+	}
 	return strcmp(as->name, bs->name);
 }
 
@@ -1101,9 +1110,10 @@ void print_pmu_events(const char *event_glob, bool name_only, bool quiet_flag,
 	char buf[1024];
 	int printed = 0;
 	int len, j;
-	struct pair *aliases;
+	struct sevent *aliases;
 	int numdesc = 0;
 	int columns = pager_get_columns();
+	char *topic = NULL;
 
 	pmu = NULL;
 	len = 0;
@@ -1113,7 +1123,7 @@ void print_pmu_events(const char *event_glob, bool name_only, bool quiet_flag,
 		if (pmu->selectable)
 			len++;
 	}
-	aliases = zalloc(sizeof(struct pair) * len);
+	aliases = zalloc(sizeof(struct sevent) * len);
 	if (!aliases)
 		goto out_enomem;
 	pmu = NULL;
@@ -1144,6 +1154,7 @@ void print_pmu_events(const char *event_glob, bool name_only, bool quiet_flag,
 
 			aliases[j].desc = long_desc ? alias->long_desc :
 						alias->desc;
+			aliases[j].topic = alias->topic;
 			j++;
 		}
 		if (pmu->selectable &&
@@ -1156,7 +1167,7 @@ void print_pmu_events(const char *event_glob, bool name_only, bool quiet_flag,
 		}
 	}
 	len = j;
-	qsort(aliases, len, sizeof(struct pair), cmp_pair);
+	qsort(aliases, len, sizeof(struct sevent), cmp_sevent);
 	for (j = 0; j < len; j++) {
 		if (name_only) {
 			printf("%s ", aliases[j].name);
@@ -1165,6 +1176,12 @@ void print_pmu_events(const char *event_glob, bool name_only, bool quiet_flag,
 		if (aliases[j].desc && !quiet_flag) {
 			if (numdesc++ == 0)
 				printf("\n");
+			if (aliases[j].topic && (!topic ||
+					strcmp(topic, aliases[j].topic))) {
+				printf("%s%s:\n", topic ? "\n" : "",
+						aliases[j].topic);
+				topic = aliases[j].topic;
+			}
 			printf("  %-50s\n", aliases[j].name);
 			printf("%*s", 8, "[");
 			wordwrap(aliases[j].desc, 8, columns, 0);
diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h
index 2fb8aa0..2571203 100644
--- a/tools/perf/util/pmu.h
+++ b/tools/perf/util/pmu.h
@@ -42,6 +42,7 @@ struct perf_pmu_alias {
 	char *name;
 	char *desc;
 	char *long_desc;
+	char *topic;
 	struct list_head terms; /* HEAD struct parse_events_term -> list */
 	struct list_head list;  /* ELEM */
 	char unit[UNIT_MAX_LEN+1];

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [tip:perf/urgent] perf tools: Add README for info on parsing JSON/map files
  2016-09-15 22:24 ` [PATCH v21 15/19] perf, tools: Add README for info on parsing JSON/map files Sukadev Bhattiprolu
  2016-10-04  0:38   ` Arnaldo Carvalho de Melo
@ 2016-10-04  8:17   ` tip-bot for Sukadev Bhattiprolu
  1 sibling, 0 replies; 70+ messages in thread
From: tip-bot for Sukadev Bhattiprolu @ 2016-10-04  8:17 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: tglx, linux-kernel, mingo, acme, maddy, sukadev, peterz, hpa, jolsa

Commit-ID:  06d839b4f712065d76cba92e7e10e9d771771c5a
Gitweb:     http://git.kernel.org/tip/06d839b4f712065d76cba92e7e10e9d771771c5a
Author:     Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
AuthorDate: Thu, 15 Sep 2016 15:24:52 -0700
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Mon, 3 Oct 2016 21:37:48 -0300

perf tools: Add README for info on parsing JSON/map files

Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Acked-by: Ingo Molnar <mingo@kernel.org>
Acked-by: Jiri Olsa <jolsa@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-16-git-send-email-sukadev@linux.vnet.ibm.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/pmu-events/README | 147 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 147 insertions(+)

diff --git a/tools/perf/pmu-events/README b/tools/perf/pmu-events/README
new file mode 100644
index 0000000..1408ade
--- /dev/null
+++ b/tools/perf/pmu-events/README
@@ -0,0 +1,147 @@
+
+The contents of this directory allow users to specify PMU events in their
+CPUs by their symbolic names rather than raw event codes (see example below).
+
+The main program in this directory, is the 'jevents', which is built and
+executed _BEFORE_ the perf binary itself is built.
+
+The 'jevents' program tries to locate and process JSON files in the directory
+tree tools/perf/pmu-events/arch/foo.
+
+	- Regular files with '.json' extension in the name are assumed to be
+	  JSON files, each of which describes a set of PMU events.
+
+	- Regular files with basename starting with 'mapfile.csv' are assumed
+	  to be a CSV file that maps a specific CPU to its set of PMU events.
+	  (see below for mapfile format)
+
+	- Directories are traversed, but all other files are ignored.
+
+The PMU events supported by a CPU model are expected to grouped into topics
+such as Pipelining, Cache, Memory, Floating-point etc. All events for a topic
+should be placed in a separate JSON file - where the file name identifies
+the topic. Eg: "Floating-point.json".
+
+All the topic JSON files for a CPU model/family should be in a separate
+sub directory. Thus for the Silvermont X86 CPU:
+
+	$ ls tools/perf/pmu-events/arch/x86/Silvermont_core
+	Cache.json 	Memory.json 	Virtual-Memory.json
+	Frontend.json 	Pipeline.json
+
+Using the JSON files and the mapfile, 'jevents' generates the C source file,
+'pmu-events.c', which encodes the two sets of tables:
+
+	- Set of 'PMU events tables' for all known CPUs in the architecture,
+	  (one table like the following, per JSON file; table name 'pme_power8'
+	  is derived from JSON file name, 'power8.json').
+
+		struct pmu_event pme_power8[] = {
+
+			...
+
+			{
+				.name = "pm_1plus_ppc_cmpl",
+				.event = "event=0x100f2",
+				.desc = "1 or more ppc insts finished,",
+			},
+
+			...
+		}
+
+	- A 'mapping table' that maps each CPU of the architecture, to its
+	  'PMU events table'
+
+		struct pmu_events_map pmu_events_map[] = {
+		{
+			.cpuid = "004b0000",
+			.version = "1",
+			.type = "core",
+			.table = pme_power8
+		},
+			...
+
+		};
+
+After the 'pmu-events.c' is generated, it is compiled and the resulting
+'pmu-events.o' is added to 'libperf.a' which is then used to build perf.
+
+NOTES:
+	1. Several CPUs can support same set of events and hence use a common
+	   JSON file. Hence several entries in the pmu_events_map[] could map
+	   to a single 'PMU events table'.
+
+	2. The 'pmu-events.h' has an extern declaration for the mapping table
+	   and the generated 'pmu-events.c' defines this table.
+
+	3. _All_ known CPU tables for architecture are included in the perf
+	   binary.
+
+At run time, perf determines the actual CPU it is running on, finds the
+matching events table and builds aliases for those events. This allows
+users to specify events by their name:
+
+	$ perf stat -e pm_1plus_ppc_cmpl sleep 1
+
+where 'pm_1plus_ppc_cmpl' is a Power8 PMU event.
+
+In case of errors when processing files in the tools/perf/pmu-events/arch
+directory, 'jevents' tries to create an empty mapping file to allow the perf
+build to succeed even if the PMU event aliases cannot be used.
+
+However some errors in processing may cause the perf build to fail.
+
+Mapfile format
+===============
+
+The mapfile enables multiple CPU models to share a single set of PMU events.
+It is required even if such mapping is 1:1.
+
+The mapfile.csv format is expected to be:
+
+	Header line
+	CPUID,Version,Dir/path/name,Type
+
+where:
+
+	Comma:
+		is the required field delimiter (i.e other fields cannot
+		have commas within them).
+
+	Comments:
+		Lines in which the first character is either '\n' or '#'
+		are ignored.
+
+	Header line
+		The header line is the first line in the file, which is
+		always _IGNORED_. It can empty.
+
+	CPUID:
+		CPUID is an arch-specific char string, that can be used
+		to identify CPU (and associate it with a set of PMU events
+		it supports). Multiple CPUIDS can point to the same
+		File/path/name.json.
+
+		Example:
+			CPUID == 'GenuineIntel-6-2E' (on x86).
+			CPUID == '004b0100' (PVR value in Powerpc)
+	Version:
+		is the Version of the mapfile.
+
+	Dir/path/name:
+		is the pathname to the directory containing the CPU's JSON
+		files, relative to the directory containing the mapfile.csv
+
+	Type:
+		indicates whether the events or "core" or "uncore" events.
+
+
+	Eg:
+
+	$ grep Silvermont tools/perf/pmu-events/arch/x86/mapfile.csv
+	GenuineIntel-6-37,V13,Silvermont_core,core
+	GenuineIntel-6-4D,V13,Silvermont_core,core
+	GenuineIntel-6-4C,V13,Silvermont_core,core
+
+	i.e the three CPU models use the JSON files (i.e PMU events) listed
+	in the directory 'tools/perf/pmu-events/arch/x86/Silvermont_core'.

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [tip:perf/urgent] perf tools: Allow period= in perf stat CPU event descriptions.
  2016-09-15 22:24 ` [PATCH v21 19/19] perf, tools: Allow period= in perf stat CPU event descriptions Sukadev Bhattiprolu
@ 2016-10-04  8:17   ` tip-bot for Sukadev Bhattiprolu
  0 siblings, 0 replies; 70+ messages in thread
From: tip-bot for Sukadev Bhattiprolu @ 2016-10-04  8:17 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: sukadev, acme, peterz, ak, tglx, hpa, maddy, linux-kernel, mingo

Commit-ID:  06835545b144cab6e7748748576145ea15f68dff
Gitweb:     http://git.kernel.org/tip/06835545b144cab6e7748748576145ea15f68dff
Author:     Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
AuthorDate: Thu, 15 Sep 2016 15:24:56 -0700
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Mon, 3 Oct 2016 21:50:56 -0300

perf tools: Allow period= in perf stat CPU event descriptions.

This avoids the JSON PMU events parser having to know whether its
aliases are for perf stat or perf record.

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>
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-20-git-send-email-sukadev@linux.vnet.ibm.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/parse-events.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 8f88f63..d445b11 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -924,6 +924,7 @@ config_term_avail(int term_type, struct parse_events_error *err)
 	case PARSE_EVENTS__TERM_TYPE_CONFIG1:
 	case PARSE_EVENTS__TERM_TYPE_CONFIG2:
 	case PARSE_EVENTS__TERM_TYPE_NAME:
+	case PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD:
 		return true;
 	default:
 		if (!err)

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [tip:perf/urgent] perf tools: Make alias matching case-insensitive
  2016-09-15 22:24 ` [PATCH v21 16/19] perf, tools: Make alias matching case-insensitive Sukadev Bhattiprolu
  2016-10-04  0:47   ` Arnaldo Carvalho de Melo
@ 2016-10-04  8:18   ` tip-bot for Andi Kleen
  1 sibling, 0 replies; 70+ messages in thread
From: tip-bot for Andi Kleen @ 2016-10-04  8:18 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: acme, maddy, linux-kernel, peterz, mingo, tglx, ak, hpa

Commit-ID:  e312bcf13053970c0f07ec2c02d7d9be1a036ce0
Gitweb:     http://git.kernel.org/tip/e312bcf13053970c0f07ec2c02d7d9be1a036ce0
Author:     Andi Kleen <ak@linux.intel.com>
AuthorDate: Thu, 15 Sep 2016 15:24:53 -0700
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Mon, 3 Oct 2016 21:51:48 -0300

perf tools: Make alias matching case-insensitive

Make alias matching the events parser case-insensitive. This is useful
with the JSON events. perf uses lower case events, but the CPU manuals
generally use upper case event names. The JSON files use lower case by
default too. But if we search case insensitively then users can
cut-n-paste the upper case event names.

So the following works:

% perf stat -e BR_INST_EXEC.TAKEN_INDIRECT_NEAR_CALL true

 Performance counter stats for 'true':

               305      BR_INST_EXEC.TAKEN_INDIRECT_NEAR_CALL

       0.000492799 seconds time elapsed

Signed-off-by: Andi Kleen <ak@linux.intel.com>
Acked-by: Ingo Molnar <mingo@kernel.org>
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-17-git-send-email-sukadev@linux.vnet.ibm.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/parse-events.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index d445b11..4e778ea 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -1459,7 +1459,7 @@ comp_pmu(const void *p1, const void *p2)
 	struct perf_pmu_event_symbol *pmu1 = (struct perf_pmu_event_symbol *) p1;
 	struct perf_pmu_event_symbol *pmu2 = (struct perf_pmu_event_symbol *) p2;
 
-	return strcmp(pmu1->symbol, pmu2->symbol);
+	return strcasecmp(pmu1->symbol, pmu2->symbol);
 }
 
 static void perf_pmu__parse_cleanup(void)

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [tip:perf/urgent] perf pmu-events: Fix fixed counters on Intel
  2016-09-15 22:24 ` [PATCH v21 17/19] perf, tools, pmu-events: Fix fixed counters on Intel Sukadev Bhattiprolu
@ 2016-10-04  8:18   ` tip-bot for Andi Kleen
  0 siblings, 0 replies; 70+ messages in thread
From: tip-bot for Andi Kleen @ 2016-10-04  8:18 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: ak, tglx, sukadev, hpa, linux-kernel, maddy, mingo, acme, peterz

Commit-ID:  0b1db474314c883d0bfc6720278667a6155e995a
Gitweb:     http://git.kernel.org/tip/0b1db474314c883d0bfc6720278667a6155e995a
Author:     Andi Kleen <ak@linux.intel.com>
AuthorDate: Thu, 15 Sep 2016 15:24:54 -0700
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Mon, 3 Oct 2016 21:52:00 -0300

perf pmu-events: Fix fixed counters on Intel

The JSON event lists use a different encoding for fixed counters than
perf for instructions and cycles (ref-cycles is ok)

This lead to some common events like inst_retired.any or
cpu_clk_unhalted.thread not counting, when specified with their JSON
name.

Special case these events in the jevents conversion process.  I prefer
to not touch the JSON files for this, as it's intended that standard
JSON files can be just dropped into the perf build without changes.

Signed-off-by: Andi Kleen <ak@linux.intel.com>
Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
[Fix minor compile error]
Acked-by: Ingo Molnar <mingo@kernel.org>
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-18-git-send-email-sukadev@linux.vnet.ibm.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/pmu-events/jevents.c | 25 ++++++++++++++++++++++++-
 1 file changed, 24 insertions(+), 1 deletion(-)

diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c
index 13f4284..04e106e 100644
--- a/tools/perf/pmu-events/jevents.c
+++ b/tools/perf/pmu-events/jevents.c
@@ -306,6 +306,29 @@ static void print_events_table_suffix(FILE *outfp)
 	close_table = 0;
 }
 
+static struct fixed {
+	const char *name;
+	const char *event;
+} fixed[] = {
+	{ "inst_retired.any", "event=0xc0" },
+	{ "cpu_clk_unhalted.thread", "event=0x3c" },
+	{ "cpu_clk_unhalted.thread_any", "event=0x3c,any=1" },
+	{ NULL, NULL},
+};
+
+/*
+ * Handle different fixed counter encodings between JSON and perf.
+ */
+static char *real_event(const char *name, char *event)
+{
+	int i;
+
+	for (i = 0; fixed[i].name; i++)
+		if (!strcasecmp(name, fixed[i].name))
+			return (char *)fixed[i].event;
+	return event;
+}
+
 /* 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,
@@ -392,7 +415,7 @@ int json_events(const char *fn,
 			addfield(map, &event, ",", msr->pname, msrval);
 		fixname(name);
 
-		err = func(data, name, event, desc, long_desc);
+		err = func(data, name, real_event(name, event), desc, long_desc);
 		free(event);
 		free(desc);
 		free(name);

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* Re: [PATCH v21 16/19] perf, tools: Make alias matching case-insensitive
  2016-10-04  0:47   ` Arnaldo Carvalho de Melo
  2016-10-04  0:54     ` Arnaldo Carvalho de Melo
@ 2016-10-04  8:19     ` Jiri Olsa
  1 sibling, 0 replies; 70+ messages in thread
From: Jiri Olsa @ 2016-10-04  8:19 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Sukadev Bhattiprolu, peterz, maddy, linuxppc-dev, linux-kernel,
	Jiri Olsa, Andi Kleen

On Mon, Oct 03, 2016 at 09:47:06PM -0300, Arnaldo Carvalho de Melo wrote:
> Em Thu, Sep 15, 2016 at 03:24:53PM -0700, Sukadev Bhattiprolu escreveu:
> > From: Andi Kleen <ak@linux.intel.com>
> > 
> > Make alias matching the events parser case-insensitive. This is useful
> > with the JSON events. perf uses lower case events, but the CPU manuals
> > generally use upper case event names. The JSON files use lower
> > case by default too. But if we search case insensitively then
> > users can cut-n-paste the upper case event names.
> > 
> > So the following works:
> > 
> > % perf stat -e BR_INST_EXEC.TAKEN_INDIRECT_NEAR_CALL true
> > 
> >  Performance counter stats for 'true':
> > 
> >                305      BR_INST_EXEC.TAKEN_INDIRECT_NEAR_CALL
> > 
> >        0.000492799 seconds time elapsed
> 
> So now trying to figure this out:
> 
> [acme@jouet linux]$ perf stat -e br_inst_exec.all_direct_near_call true
> event syntax error: 'br_inst_exec.all_direct_near_call'
>                      \___ 'period' is not usable in 'perf stat'
> Run 'perf list' for a list of valid events

looks like you need also this one:
  155128eaa62f Allow period= in perf stat CPU event descriptions.

jirka

^ permalink raw reply	[flat|nested] 70+ messages in thread

* [tip:perf/urgent] perf pmu-events: Add Skylake frontend MSR support
  2016-09-15 22:24 ` [PATCH v21 18/19] perf, tools, pmu-events: Add Skylake frontend MSR support Sukadev Bhattiprolu
@ 2016-10-04  8:19   ` tip-bot for Andi Kleen
  0 siblings, 0 replies; 70+ messages in thread
From: tip-bot for Andi Kleen @ 2016-10-04  8:19 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: peterz, maddy, mingo, linux-kernel, hpa, ak, acme, tglx

Commit-ID:  b42c7369e3f451e22c2b0be5d193955498d37546
Gitweb:     http://git.kernel.org/tip/b42c7369e3f451e22c2b0be5d193955498d37546
Author:     Andi Kleen <ak@linux.intel.com>
AuthorDate: Thu, 15 Sep 2016 15:24:55 -0700
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Mon, 3 Oct 2016 21:52:01 -0300

perf pmu-events: Add Skylake frontend MSR support

Add support for the "frontend" extra MSR on Skylake in the JSON
conversion.

Signed-off-by: Andi Kleen <ak@linux.intel.com>
Acked-by: Ingo Molnar <mingo@kernel.org>
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-19-git-send-email-sukadev@linux.vnet.ibm.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/pmu-events/jevents.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c
index 04e106e..79c2133 100644
--- a/tools/perf/pmu-events/jevents.c
+++ b/tools/perf/pmu-events/jevents.c
@@ -127,6 +127,7 @@ static struct msrmap {
 	{ "0x3F6", "ldlat=" },
 	{ "0x1A6", "offcore_rsp=" },
 	{ "0x1A7", "offcore_rsp=" },
+	{ "0x3F7", "frontend=" },
 	{ NULL, NULL }
 };
 

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* Re: [PATCH v21 16/19] perf, tools: Make alias matching case-insensitive
  2016-10-04  0:54     ` Arnaldo Carvalho de Melo
@ 2016-10-04  8:19       ` Jiri Olsa
  0 siblings, 0 replies; 70+ messages in thread
From: Jiri Olsa @ 2016-10-04  8:19 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Arnaldo Carvalho de Melo, Sukadev Bhattiprolu, peterz, maddy,
	linuxppc-dev, linux-kernel, Jiri Olsa, Andi Kleen

On Mon, Oct 03, 2016 at 09:54:48PM -0300, Arnaldo Carvalho de Melo wrote:
> Em Mon, Oct 03, 2016 at 09:47:06PM -0300, Arnaldo Carvalho de Melo escreveu:
> > Em Thu, Sep 15, 2016 at 03:24:53PM -0700, Sukadev Bhattiprolu escreveu:
> > > From: Andi Kleen <ak@linux.intel.com>
> > > 
> > > Make alias matching the events parser case-insensitive. This is useful
> > > with the JSON events. perf uses lower case events, but the CPU manuals
> > > generally use upper case event names. The JSON files use lower
> > > case by default too. But if we search case insensitively then
> > > users can cut-n-paste the upper case event names.
> > > 
> > > So the following works:
> > > 
> > > % perf stat -e BR_INST_EXEC.TAKEN_INDIRECT_NEAR_CALL true
> > > 
> > >  Performance counter stats for 'true':
> > > 
> > >                305      BR_INST_EXEC.TAKEN_INDIRECT_NEAR_CALL
> > > 
> > >        0.000492799 seconds time elapsed
> > 
> > So now trying to figure this out:
> 
> Ok, so this is just another case of bad patch ordering: this uses 'perf
> stat' as the example, but it doesn't work at this point, one needs to go
> to the last patch, apply it and then test it again, when it will work.
> So just moved the last patch to before this one, sigh.

ok, you found it.. sry ;-)

jirka

^ permalink raw reply	[flat|nested] 70+ messages in thread

end of thread, other threads:[~2016-10-04  8:20 UTC | newest]

Thread overview: 70+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-09-15 22:24 [PATCH v21 00/20] perf, tools: Add support for PMU events in JSON format Sukadev Bhattiprolu
2016-09-15 22:24 ` [PATCH v21 01/19] perf, tools: Add jsmn `jasmine' JSON parser Sukadev Bhattiprolu
2016-10-04  8:11   ` [tip:perf/urgent] perf " tip-bot for Andi Kleen
2016-09-15 22:24 ` [PATCH v21 02/19] perf, tools, jevents: Program to convert JSON file to C style file Sukadev Bhattiprolu
2016-09-15 22:24 ` [PATCH v21 03/19] perf, tools: Use pmu_events table to create aliases Sukadev Bhattiprolu
2016-09-27 13:16   ` Arnaldo Carvalho de Melo
2016-10-04  8:12   ` [tip:perf/urgent] perf pmu: " tip-bot for Sukadev Bhattiprolu
2016-09-15 22:24 ` [PATCH v21 04/19] perf, tools: Support CPU ID matching for Powerpc Sukadev Bhattiprolu
2016-10-04  8:13   ` [tip:perf/urgent] perf powerpc: " tip-bot for Sukadev Bhattiprolu
2016-09-15 22:24 ` [PATCH v21 05/19] perf, tools: Support CPU id matching for x86 v2 Sukadev Bhattiprolu
2016-10-04  8:13   ` [tip:perf/urgent] perf " tip-bot for Andi Kleen
2016-09-15 22:24 ` [PATCH v21 06/19] perf, tools: Support alias descriptions Sukadev Bhattiprolu
2016-09-27 17:41   ` Arnaldo Carvalho de Melo
2016-09-27 18:11     ` Sukadev Bhattiprolu
2016-09-28 13:57       ` Arnaldo Carvalho de Melo
2016-09-28 18:29         ` Sukadev Bhattiprolu
2016-09-28 19:08           ` Arnaldo Carvalho de Melo
2016-10-03 20:52           ` Arnaldo Carvalho de Melo
2016-10-04  8:14   ` [tip:perf/urgent] perf pmu: " tip-bot for Andi Kleen
2016-09-15 22:24 ` [PATCH v21 07/19] perf, tools: Query terminal width and use in perf list Sukadev Bhattiprolu
2016-10-04  8:14   ` [tip:perf/urgent] perf " tip-bot for Andi Kleen
2016-09-15 22:24 ` [PATCH v21 08/19] perf, tools: Add a --no-desc flag to " Sukadev Bhattiprolu
2016-10-04  8:15   ` [tip:perf/urgent] perf list: Add a --no-desc flag tip-bot for Andi Kleen
2016-09-15 22:24 ` [PATCH v21 09/19] perf, tools: Add override support for event list CPUID Sukadev Bhattiprolu
2016-10-04  8:15   ` [tip:perf/urgent] perf pmu: " tip-bot for Andi Kleen
2016-09-15 22:24 ` [PATCH v21 10/19] perf, tools, jevents: Add support for long descriptions Sukadev Bhattiprolu
2016-10-04  8:16   ` [tip:perf/urgent] perf " tip-bot for Sukadev Bhattiprolu
2016-09-15 22:24 ` [PATCH v21 11/19] perf, tools: Add alias " Sukadev Bhattiprolu
2016-10-04  0:20   ` Arnaldo Carvalho de Melo
2016-09-15 22:24 ` [PATCH v21 12/19] perf, tools: Support long descriptions with perf list Sukadev Bhattiprolu
2016-10-04  0:26   ` Arnaldo Carvalho de Melo
2016-10-04  8:16   ` [tip:perf/urgent] perf list: Support long jevents descriptions tip-bot for Sukadev Bhattiprolu
2016-09-15 22:24 ` [PATCH v21 13/19] perf, tools: Add support for event list topics Sukadev Bhattiprolu
2016-10-04  8:16   ` [tip:perf/urgent] perf list jevents: " tip-bot for Andi Kleen
2016-09-15 22:24 ` [PATCH v21 14/19] perf, tools, jevents: Handle header line in mapfile Sukadev Bhattiprolu
2016-10-04  0:36   ` Arnaldo Carvalho de Melo
2016-10-04  8:13   ` [tip:perf/urgent] perf " tip-bot for Andi Kleen
2016-09-15 22:24 ` [PATCH v21 15/19] perf, tools: Add README for info on parsing JSON/map files Sukadev Bhattiprolu
2016-10-04  0:38   ` Arnaldo Carvalho de Melo
2016-10-04  8:17   ` [tip:perf/urgent] perf " tip-bot for Sukadev Bhattiprolu
2016-09-15 22:24 ` [PATCH v21 16/19] perf, tools: Make alias matching case-insensitive Sukadev Bhattiprolu
2016-10-04  0:47   ` Arnaldo Carvalho de Melo
2016-10-04  0:54     ` Arnaldo Carvalho de Melo
2016-10-04  8:19       ` Jiri Olsa
2016-10-04  8:19     ` Jiri Olsa
2016-10-04  8:18   ` [tip:perf/urgent] perf " tip-bot for Andi Kleen
2016-09-15 22:24 ` [PATCH v21 17/19] perf, tools, pmu-events: Fix fixed counters on Intel Sukadev Bhattiprolu
2016-10-04  8:18   ` [tip:perf/urgent] perf " tip-bot for Andi Kleen
2016-09-15 22:24 ` [PATCH v21 18/19] perf, tools, pmu-events: Add Skylake frontend MSR support Sukadev Bhattiprolu
2016-10-04  8:19   ` [tip:perf/urgent] perf " tip-bot for Andi Kleen
2016-09-15 22:24 ` [PATCH v21 19/19] perf, tools: Allow period= in perf stat CPU event descriptions Sukadev Bhattiprolu
2016-10-04  8:17   ` [tip:perf/urgent] perf " tip-bot for Sukadev Bhattiprolu
2016-09-19 16:58 ` [PATCH v21 00/20] perf, tools: Add support for PMU events in JSON format Sukadev Bhattiprolu
2016-09-19 21:20 ` Arnaldo Carvalho de Melo
2016-09-19 23:31   ` Arnaldo Carvalho de Melo
2016-09-19 23:37     ` Arnaldo Carvalho de Melo
2016-09-20  0:02       ` Arnaldo Carvalho de Melo
2016-09-20  0:28         ` Arnaldo Carvalho de Melo
2016-09-22 14:56           ` Arnaldo Carvalho de Melo
2016-09-22 15:00           ` Jiri Olsa
2016-09-22 16:27             ` Jiri Olsa
2016-09-26  8:35               ` Jiri Olsa
2016-09-26 15:03                 ` Arnaldo Carvalho de Melo
2016-09-26 16:59                   ` Andi Kleen
2016-09-27 14:18                     ` Jiri Olsa
2016-09-29 22:19                       ` Arnaldo Carvalho de Melo
2016-09-30  9:10                         ` Jiri Olsa
2016-10-04  8:10                       ` [tip:perf/urgent] tools build: Add support for host programs format tip-bot for Jiri Olsa
2016-10-04  8:11                       ` [tip:perf/urgent] tools build: Make fixdep a hostprog tip-bot for Jiri Olsa
2016-10-04  8:12                       ` [tip:perf/urgent] perf jevents: Program to convert JSON file tip-bot for Andi Kleen

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).