mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Andi Kleen <andi@firstfloor.org>
To: sukadev@linux.vnet.ibm.com
Cc: jolsa@redhat.com, acme@kernel.org, linux-kernel@vger.kernel.org,
	Andi Kleen <ak@linux.intel.com>
Subject: [PATCH 1/5] perf, tools: Add support for parsing uncore json files
Date: Fri,  5 Jun 2015 14:14:34 -0700	[thread overview]
Message-ID: <1433538878-13321-2-git-send-email-andi@firstfloor.org> (raw)
In-Reply-To: <1433538878-13321-1-git-send-email-andi@firstfloor.org>

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

Handle the Unit field, which is needed to find the right PMU for
an event.

Handle the ExtSel field.

Handle the Filter field.

Filter out zero fields, except for the event itself.

Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
 tools/perf/pmu-events/jevents.c    | 130 +++++++++++++++++++++++++++++++++++--
 tools/perf/pmu-events/jevents.h    |   2 +-
 tools/perf/pmu-events/pmu-events.h |   1 +
 3 files changed, 126 insertions(+), 7 deletions(-)

diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c
index 7347cca..63ade38 100644
--- a/tools/perf/pmu-events/jevents.c
+++ b/tools/perf/pmu-events/jevents.c
@@ -133,7 +133,6 @@ static struct field {
 	const char *field;
 	const char *kernel;
 } fields[] = {
-	{ "EventCode",	"event=" },
 	{ "UMask",	"umask=" },
 	{ "CounterMask", "cmask=" },
 	{ "Invert",	"inv=" },
@@ -162,6 +161,9 @@ static int match_field(char *map, jsmntok_t *field, int nz,
 
 	for (f = fields; f->field; f++)
 		if (json_streq(map, field, f->field) && nz) {
+			if (json_streq(map, val, "0x00") ||
+			     json_streq(map, val, "0x0"))
+				return 1;
 			cut_comma(map, &newval);
 			addfield(map, event, ",", f->kernel, &newval);
 			return 1;
@@ -187,6 +189,62 @@ static struct msrmap *lookup_msr(char *map, jsmntok_t *val)
 	return NULL;
 }
 
+static struct map {
+	const char *json;
+	const char *perf;
+} unit_to_perf[] = {
+	{ "CBO", "cbox" },
+	{ "QPI LL", "qpi" },
+	{ "SBO", "sbox" },
+	{}
+};
+
+static struct map filter_to_perf[] = {
+#if 0
+	{ "QPIMatch0[17:0]", "match0"},
+	{ "QPIMask0[17:0]", "mask0"},
+	{ "QPIMatch0[12:0]", "match0"},
+	{ "QPIMask0[12:0]", "mask_mc, match_opc, match_vnw"},
+	{ "QPIMatch0[12:0]", "match_mc, match_opc, match_vnw"},
+#endif
+	{ "CBoFilter0[22:18]", "filter_state"},
+	{ "CBoFilter1[17:10]", "filter_nid"},
+	{ "CBoFilter[17:10]", "filter_nid"},
+	{ "PCUFilter[7:0]", "filter_band0"},
+	{ "PCUFilter[15:8]", "filter_band1"},
+	{ "PCUFilter[23:16]", "filter_band2"},
+	{ "PCUFilter[31:24]", "filter_band3"},
+	{ "QPIMask0[17:0]", "mask0"},
+	{ "QPIMask1[19:16]", "mask_rds"},
+	{ "QPIMatch0[17:0]", "match_mc, match_opc, match_vnw, match_dnid"},
+	{ "QPIMatch1[19:16]", "match_rds"},
+	{ "CBoFilter[31:23]", "filter_opc"},
+	{ "CBoFilter0[23:17]", "filter_state" },
+#if 0
+	/* Missing in uncore driver currently? */
+	CBoFilter1[15:0]
+	CBoFilter1[28:20]
+	HA_AddrMatch0[31:6]
+	HA_AddrMatch1[13:0]
+	HA_Opcod
+	HA_OpcodeMatch[5:0]
+	IRPFilter[4:0]
+	UBoxFilter[3:0]
+#endif
+	{}
+};
+
+static const char *field_to_perf(struct map *table, char *map, jsmntok_t *val)
+{
+	int i;
+
+	for (i = 0; table[i].json; i++) {
+		if (json_streq(map, val, table[i].json))
+			return table[i].perf;
+	}
+	return NULL;
+}
+
 #define EXPECT(e, t, m) do { if (!(e)) {			\
 	jsmntok_t *loc = (t);					\
 	if (!(t)->start && (t) > tokens)			\
@@ -203,7 +261,8 @@ 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 *long_desc, char *topic)
+				    char *desc, char *long_desc, char *topic,
+				    char *unit)
 {
 	FILE *outfp = data;
 	/*
@@ -219,7 +278,8 @@ static int print_events_table_entry(void *data, char *name, char *event,
 		fprintf(outfp, "\t.long_desc = \"%s\",\n", long_desc);
 	if (topic)
 		fprintf(outfp, "\t.topic = \"%s\",\n", topic);
-
+	if (unit)
+		fprintf(outfp, "\t.unit = \"%s\",\n", unit);
 	fprintf(outfp, "},\n");
 
 	return 0;
@@ -240,7 +300,7 @@ static void print_events_table_suffix(FILE *outfp)
 /* Call func with each event in the json file */
 int json_events(const char *fn,
 	  int (*func)(void *data, char *name, char *event, char *desc,
-		      char *long_desc, char *topic),
+		      char *long_desc, char *topic, char *unit),
 	  void *data)
 {
 	int err = -EIO;
@@ -248,6 +308,7 @@ int json_events(const char *fn,
 	jsmntok_t *tokens, *tok;
 	int i, j, len;
 	char *map;
+	char buf[128];
 
 	if (!fn)
 		return -ENOENT;
@@ -262,6 +323,9 @@ int json_events(const char *fn,
 		char *long_desc = NULL;
 		char *extra_desc = NULL;
 		char *topic = NULL;
+		char *unit = NULL;
+		char *filter = NULL;
+		unsigned long long eventcode = 0;
 		struct msrmap *msr = NULL;
 		jsmntok_t *msrval = NULL;
 		jsmntok_t *precise = NULL;
@@ -282,6 +346,16 @@ int json_events(const char *fn,
 			nz = !json_streq(map, val, "0");
 			if (match_field(map, field, nz, &event, val)) {
 				/* ok */
+			} else if (json_streq(map, field, "EventCode")) {
+				char *code = NULL;
+				addfield(map, &code, "", "", val);
+				eventcode |= strtoul(code, NULL, 0);
+				free(code);
+			} else if (json_streq(map, field, "ExtSel")) {
+				char *code = NULL;
+				addfield(map, &code, "", "", val);
+				eventcode |= strtoul(code, NULL, 0) << 21;
+				free(code);
 			} else if (json_streq(map, field, "EventName")) {
 				addfield(map, &name, "", "", val);
 			} else if (json_streq(map, field, "BriefDescription")) {
@@ -306,9 +380,46 @@ int json_events(const char *fn,
 				addfield(map, &extra_desc, ". ",
 					" Supports address when precise",
 					NULL);
+			} else if (json_streq(map, field, "Unit")) {
+				const char *punit;
+				char *s;
+
+				addfield(map, &topic, " ", "Uncore ", val);
+
+				punit = field_to_perf(unit_to_perf, map, val);
+				if (punit) {
+					unit = strdup(punit);
+				} else {
+					addfield(map, &unit, "", "", val);
+					for (s = unit; *s; s++)
+						*s = tolower(*s);
+				}
+				addfield(map, &desc, ". ", "Unit: ", NULL);
+				addfield(map, &desc, "", unit, NULL);
+			} else if (json_streq(map, field, "Filter")) {
+				jsmntok_t nt = *val;
+				const char *nf;
+
+				do {
+					cut_comma(map, &nt);
+					while (nt.start < val->end && isspace(map[nt.start]))
+						nt.start++;
+					nf = field_to_perf(filter_to_perf, map, &nt);
+					if (!nf) {
+						if (verbose > 1)
+							printf("no filter match %.*s\n",
+							  json_len(&nt), map + nt.start);
+						addfield(map, &filter, " ", "", &nt);
+					} else
+						addfield(map, &filter, " ", nf, NULL);
+					nt.start = nt.end + 1;
+					nt.end = val->end;
+				} while (nt.start < val->end);
 			}
 			/* ignore unknown fields */
 		}
+		if (verbose > 1 && filter && strchr(filter, '['))
+			printf("%s\n", name);
 		if (precise && !strstr(desc, "(Precise Event)")) {
 			if (json_streq(map, precise, "2"))
 				addfield(map, &extra_desc, " ",
@@ -317,21 +428,28 @@ int json_events(const char *fn,
 				addfield(map, &extra_desc, " ",
 						"(Precise event)", NULL);
 		}
+		snprintf(buf, sizeof buf, "event=%#llx", eventcode);
+		addfield(map, &event, ",", buf, NULL);
 		if (desc && extra_desc)
 			addfield(map, &desc, " ", extra_desc, NULL);
 		if (long_desc && extra_desc)
 			addfield(map, &long_desc, " ", extra_desc, NULL);
+		if (filter) {
+			addfield(map, &desc, ". ", "Filter: ", NULL);
+			addfield(map, &desc, "", filter, NULL);
+		}
 		if (msr != NULL)
 			addfield(map, &event, ",", msr->pname, msrval);
 		fixname(name);
-
-		err = func(data, name, event, desc, long_desc, topic);
+		err = func(data, name, event, desc, long_desc, topic, unit);
 		free(event);
 		free(desc);
 		free(name);
 		free(long_desc);
 		free(extra_desc);
 		free(topic);
+		free(unit);
+		free(filter);
 		if (err)
 			break;
 		tok += j;
diff --git a/tools/perf/pmu-events/jevents.h b/tools/perf/pmu-events/jevents.h
index 9ffcb89..bf6cf79 100644
--- a/tools/perf/pmu-events/jevents.h
+++ b/tools/perf/pmu-events/jevents.h
@@ -3,7 +3,7 @@
 
 int json_events(const char *fn,
 		int (*func)(void *data, char *name, char *event, char *desc,
-				char *long_desc, char *topic),
+				char *long_desc, char *topic, char *unit),
 		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 6b69f4b..cafea50 100644
--- a/tools/perf/pmu-events/pmu-events.h
+++ b/tools/perf/pmu-events/pmu-events.h
@@ -10,6 +10,7 @@ struct pmu_event {
 	const char *desc;
 	const char *long_desc;
 	const char *topic;
+	const char *unit;
 };
 
 /*
-- 
2.4.2


  reply	other threads:[~2015-06-05 21:15 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-06-05 21:14 perf, tools: Add support for uncore events and updated Intel events Andi Kleen
2015-06-05 21:14 ` Andi Kleen [this message]
2015-06-05 21:14 ` [PATCH 2/5] perf, tools: Support per pmu json aliases Andi Kleen
2015-06-05 21:14 ` [PATCH 3/5] perf, tools: Support event aliases for non cpu// pmus Andi Kleen
2015-06-05 21:14 ` [PATCH 4/5] perf, tools: Add debug support for outputing alias string Andi Kleen
2015-06-05 21:14 ` [PATCH 5/5] perf, tools: Expand PMU events by prefetch match Andi Kleen

Reply instructions:

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

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

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

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

  git send-email \
    --in-reply-to=1433538878-13321-2-git-send-email-andi@firstfloor.org \
    --to=andi@firstfloor.org \
    --cc=acme@kernel.org \
    --cc=ak@linux.intel.com \
    --cc=jolsa@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=sukadev@linux.vnet.ibm.com \
    /path/to/YOUR_REPLY

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

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

all inboxes | Powered by JetHome®