linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* perf: Improve support for uncore JSON event lists
@ 2017-03-01  6:49 Andi Kleen
  2017-03-01  6:49 ` [PATCH 01/10] perf, tools, stat: Factor out callback for collecting event values Andi Kleen
                   ` (10 more replies)
  0 siblings, 11 replies; 21+ messages in thread
From: Andi Kleen @ 2017-03-01  6:49 UTC (permalink / raw)
  To: acme; +Cc: jolsa, linux-kernel

This patch kit further improves support for Intel uncore events in
the Linux perf user tool. The basic support has been already
merged earlier, but this makes it nicer to use.

- Collapse counts from duplicated boxes to make the output
easier to read.
- Support specifying events for multiple duplicated boxes
in an abbreviated format to shorten event specifiers
- Add support for computing Metrics defined in the event lists,
so that the event lists can extend the metrics in perf stat.
This allows to represent many events in an easier to understand
format.

Available from

git://git.kernel.org/pub/scm/linux/kernel/git/ak/linux-misc.git perf/builtin-json-28

v1: Initial post after being split off to own patchkit
Adding MetricName support and support for more than two events
in expressions.

v2: Address review comments. Move new hunk from refactor
patchkit to patch adding new features. Improve changelogs
slightly.

^ permalink raw reply	[flat|nested] 21+ messages in thread
* [PATCH 01/10] perf, tools, stat: Factor out callback for collecting event values
@ 2017-02-24  0:10 Andi Kleen
  2017-02-24  0:10 ` [PATCH 08/10] perf, tools, stat: Output JSON MetricExpr metric Andi Kleen
  0 siblings, 1 reply; 21+ messages in thread
From: Andi Kleen @ 2017-02-24  0:10 UTC (permalink / raw)
  To: acme; +Cc: jolsa, linux-kernel, Andi Kleen

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

To be used in next patch to support automatic summing of alias
events.

Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
 tools/perf/builtin-stat.c | 114 ++++++++++++++++++++++++++++++++++++----------
 1 file changed, 91 insertions(+), 23 deletions(-)

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index f28719178b51..43a7ef3d71ed 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -1178,11 +1178,57 @@ static void aggr_update_shadow(void)
 	}
 }
 
+static void collect_data(struct perf_evsel *counter,
+			    void (*cb)(struct perf_evsel *counter, void *data,
+				       bool first),
+			    void *data)
+{
+	cb(counter, data, true);
+}
+
+struct aggr_data {
+	u64 ena, run, val;
+	int id;
+	int nr;
+	int cpu;
+};
+
+static void aggr_cb(struct perf_evsel *counter, void *data, bool first)
+{
+	struct aggr_data *ad = data;
+	int cpu, cpu2, s2;
+
+	for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) {
+		struct perf_counts_values *counts;
+
+		cpu2 = perf_evsel__cpus(counter)->map[cpu];
+		s2 = aggr_get_id(evsel_list->cpus, cpu2);
+		if (s2 != ad->id)
+			continue;
+		if (first)
+			ad->nr++;
+		counts = perf_counts(counter->counts, cpu, 0);
+		/*
+		 * When any result is bad, make them all to give
+		 * consistent output in interval mode.
+		 */
+		if (counts->ena == 0 || counts->run == 0 ||
+		    counter->counts->scaled == -1) {
+			ad->ena = 0;
+			ad->run = 0;
+			break;
+		}
+		ad->val += counts->val;
+		ad->ena += counts->ena;
+		ad->run += counts->run;
+	}
+}
+
 static void print_aggr(char *prefix)
 {
 	FILE *output = stat_config.output;
 	struct perf_evsel *counter;
-	int cpu, s, s2, id, nr;
+	int s, id, nr;
 	double uval;
 	u64 ena, run, val;
 	bool first;
@@ -1197,23 +1243,20 @@ static void print_aggr(char *prefix)
 	 * Without each counter has its own line.
 	 */
 	for (s = 0; s < aggr_map->nr; s++) {
+		struct aggr_data ad;
 		if (prefix && metric_only)
 			fprintf(output, "%s", prefix);
 
-		id = aggr_map->map[s];
+		ad.id = id = aggr_map->map[s];
 		first = true;
 		evlist__for_each_entry(evsel_list, counter) {
-			val = ena = run = 0;
-			nr = 0;
-			for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) {
-				s2 = aggr_get_id(perf_evsel__cpus(counter), cpu);
-				if (s2 != id)
-					continue;
-				val += perf_counts(counter->counts, cpu, 0)->val;
-				ena += perf_counts(counter->counts, cpu, 0)->ena;
-				run += perf_counts(counter->counts, cpu, 0)->run;
-				nr++;
-			}
+			ad.val = ad.ena = ad.run = 0;
+			ad.nr = 0;
+			collect_data(counter, aggr_cb, &ad);
+			nr = ad.nr;
+			ena = ad.ena;
+			run = ad.run;
+			val = ad.val;
 			if (first && metric_only) {
 				first = false;
 				aggr_printout(counter, id, nr);
@@ -1257,6 +1300,21 @@ static void print_aggr_thread(struct perf_evsel *counter, char *prefix)
 	}
 }
 
+struct caggr_data {
+	double avg, avg_enabled, avg_running;
+};
+
+static void counter_aggr_cb(struct perf_evsel *counter, void *data,
+			    bool first __maybe_unused)
+{
+	struct caggr_data *cd = data;
+	struct perf_stat_evsel *ps = counter->priv;
+
+	cd->avg += avg_stats(&ps->res_stats[0]);
+	cd->avg_enabled += avg_stats(&ps->res_stats[1]);
+	cd->avg_running += avg_stats(&ps->res_stats[2]);
+}
+
 /*
  * Print out the results of a single counter:
  * aggregated counts in system-wide mode
@@ -1264,23 +1322,30 @@ static void print_aggr_thread(struct perf_evsel *counter, char *prefix)
 static void print_counter_aggr(struct perf_evsel *counter, char *prefix)
 {
 	FILE *output = stat_config.output;
-	struct perf_stat_evsel *ps = counter->priv;
-	double avg = avg_stats(&ps->res_stats[0]);
 	double uval;
-	double avg_enabled, avg_running;
+	struct caggr_data cd = { .avg = 0.0 };
 
-	avg_enabled = avg_stats(&ps->res_stats[1]);
-	avg_running = avg_stats(&ps->res_stats[2]);
+	collect_data(counter, counter_aggr_cb, &cd);
 
 	if (prefix && !metric_only)
 		fprintf(output, "%s", prefix);
 
-	uval = avg * counter->scale;
-	printout(-1, 0, counter, uval, prefix, avg_running, avg_enabled, avg);
+	uval = cd.avg * counter->scale;
+	printout(-1, 0, counter, uval, prefix, cd.avg_running, cd.avg_enabled, cd.avg);
 	if (!metric_only)
 		fprintf(output, "\n");
 }
 
+static void counter_cb(struct perf_evsel *counter, void *data,
+		       bool first __maybe_unused)
+{
+	struct aggr_data *ad = data;
+
+	ad->val += perf_counts(counter->counts, ad->cpu, 0)->val;
+	ad->ena += perf_counts(counter->counts, ad->cpu, 0)->ena;
+	ad->run += perf_counts(counter->counts, ad->cpu, 0)->run;
+}
+
 /*
  * Print out the results of a single counter:
  * does not use aggregated count in system-wide
@@ -1293,9 +1358,12 @@ static void print_counter(struct perf_evsel *counter, char *prefix)
 	int cpu;
 
 	for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) {
-		val = perf_counts(counter->counts, cpu, 0)->val;
-		ena = perf_counts(counter->counts, cpu, 0)->ena;
-		run = perf_counts(counter->counts, cpu, 0)->run;
+		struct aggr_data ad = { .cpu = cpu };
+
+		collect_data(counter, counter_cb, &ad);
+		val = ad.val;
+		ena = ad.ena;
+		run = ad.run;
 
 		if (prefix)
 			fprintf(output, "%s", prefix);
-- 
2.9.3

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

end of thread, other threads:[~2017-03-07 10:05 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-03-01  6:49 perf: Improve support for uncore JSON event lists Andi Kleen
2017-03-01  6:49 ` [PATCH 01/10] perf, tools, stat: Factor out callback for collecting event values Andi Kleen
2017-03-03 10:33   ` Jiri Olsa
2017-03-03 23:16     ` Andi Kleen
2017-03-05 17:01       ` Jiri Olsa
2017-03-01  6:49 ` [PATCH 02/10] perf, tools, stat: Collapse identically named events Andi Kleen
2017-03-05 17:55   ` Jiri Olsa
2017-03-07 10:02   ` Jiri Olsa
2017-03-01  6:49 ` [PATCH 03/10] perf, tools: Factor out PMU matching in parser Andi Kleen
2017-03-07 10:03   ` Jiri Olsa
2017-03-01  6:49 ` [PATCH 04/10] perf, tools: Expand PMU events by prefix match Andi Kleen
2017-03-01  6:49 ` [PATCH 05/10] perf, tools: Special case uncore_ prefix Andi Kleen
2017-03-01  6:49 ` [PATCH 06/10] perf, tools: Add a simple expression parser for JSON Andi Kleen
2017-03-01  6:49 ` [PATCH 07/10] perf, tools: Support MetricExpr header in JSON event list Andi Kleen
2017-03-01  6:49 ` [PATCH 08/10] perf, tools, stat: Output JSON MetricExpr metric Andi Kleen
2017-03-07 10:03   ` Jiri Olsa
2017-03-01  6:49 ` [PATCH 09/10] perf, tools, list: Support printing MetricExpr with -v Andi Kleen
2017-03-01  6:49 ` [PATCH 10/10] perf, tools: Add support for MetricName JSON attribute Andi Kleen
2017-03-07 10:03   ` Jiri Olsa
2017-03-07 10:04 ` perf: Improve support for uncore JSON event lists Jiri Olsa
  -- strict thread matches above, loose matches on Subject: below --
2017-02-24  0:10 [PATCH 01/10] perf, tools, stat: Factor out callback for collecting event values Andi Kleen
2017-02-24  0:10 ` [PATCH 08/10] perf, tools, stat: Output JSON MetricExpr metric 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).