All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCHv2 0/9] perf stat: Separate shadow counters code
@ 2015-06-03 14:25 Jiri Olsa
  2015-06-03 14:25 ` [PATCH 1/9] perf stat: Add id into perf_stat struct Jiri Olsa
                   ` (9 more replies)
  0 siblings, 10 replies; 30+ messages in thread
From: Jiri Olsa @ 2015-06-03 14:25 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Peter Zijlstra, Paul Mackerras, David Ahern, Namhyung Kim,
	Ingo Molnar, Andi Kleen, Stephane Eranian

hi,
sending cleanup/move of shadow counters. I need it
for my other changes of stat scripting, but I think
it can stand alone as a cleanup.

v2 changes:
  - move evsel id into 'struct perf_stat'
    and change the id functions namespace

Also in:
  git://git.kernel.org/pub/scm/linux/kernel/git/jolsa/perf.git
  perf/shadow

I tested on Haswel with limited set of transaction events,
but all seemed ok.

thanks,
jirka
---
Jiri Olsa (9):
      perf stat: Add id into perf_stat struct
      perf stat: Replace transaction event possition check with id check
      perf stat: Remove setup_events function
      perf stat: Remove transaction_run from shadow update/print code
      perf stat: Introduce reset_shadow_stats function
      perf stat: Introduce print_shadow_stats function
      perf stat: Add output file argument to print_shadow_stats function
      perf stat: Add aggr_mode argument to print_shadow_stats function
      perf stat: Move shadow stat counters into separate object

 tools/perf/builtin-stat.c     | 506 ++------------------------------------------------------------------------
 tools/perf/util/Build         |   1 +
 tools/perf/util/stat-shadow.c | 434 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 tools/perf/util/stat.c        |  35 +++++-
 tools/perf/util/stat.h        |  40 ++++++
 5 files changed, 522 insertions(+), 494 deletions(-)
 create mode 100644 tools/perf/util/stat-shadow.c

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

* [PATCH 1/9] perf stat: Add id into perf_stat struct
  2015-06-03 14:25 [PATCHv2 0/9] perf stat: Separate shadow counters code Jiri Olsa
@ 2015-06-03 14:25 ` Jiri Olsa
  2015-06-04 13:50   ` [PATCHv3] " Jiri Olsa
  2015-06-03 14:25 ` [PATCH 2/9] perf stat: Replace transaction event possition check with id check Jiri Olsa
                   ` (8 subsequent siblings)
  9 siblings, 1 reply; 30+ messages in thread
From: Jiri Olsa @ 2015-06-03 14:25 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Peter Zijlstra, Paul Mackerras, David Ahern, Namhyung Kim,
	Ingo Molnar, Andi Kleen, Stephane Eranian

We need fast way to identify evsel as transaction event
for shadow counters computation. Currently we are using
possition (in evlist) based way.

Adding 'id' into 'struct perf_stat' so it can carry transaction
event ID and we can use it for shadow counters computations.

Link: http://lkml.kernel.org/n/tip-9lnvjksibrs0flhkpix2qkm9@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/builtin-stat.c |  6 ++----
 tools/perf/util/stat.c    | 31 ++++++++++++++++++++++++++++++-
 tools/perf/util/stat.h    | 20 ++++++++++++++++++++
 3 files changed, 52 insertions(+), 5 deletions(-)

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index fd577f725d23..a6ae1007f1f9 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -147,10 +147,6 @@ static int			(*aggr_get_id)(struct cpu_map *m, int cpu);
 
 static volatile int done = 0;
 
-struct perf_stat {
-	struct stats	  res_stats[3];
-};
-
 static inline void diff_timespec(struct timespec *r, struct timespec *a,
 				 struct timespec *b)
 {
@@ -180,6 +176,8 @@ static void perf_evsel__reset_stat_priv(struct perf_evsel *evsel)
 
 	for (i = 0; i < 3; i++)
 		init_stats(&ps->res_stats[i]);
+
+	perf_stat_evsel_id_init(evsel);
 }
 
 static int perf_evsel__alloc_stat_priv(struct perf_evsel *evsel)
diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c
index 6506b3dfb605..873d07607937 100644
--- a/tools/perf/util/stat.c
+++ b/tools/perf/util/stat.c
@@ -1,6 +1,6 @@
 #include <math.h>
-
 #include "stat.h"
+#include "evsel.h"
 
 void update_stats(struct stats *stats, u64 val)
 {
@@ -61,3 +61,32 @@ double rel_stddev_stats(double stddev, double avg)
 
 	return pct;
 }
+
+bool __perf_evsel_stat__is(struct perf_evsel *evsel,
+			   enum perf_stat_evsel_id id)
+{
+	struct perf_stat *ps = evsel->priv;
+
+	return ps->id == id;
+}
+
+#define ID(id, name) [PERF_STAT_EVSEL_ID__##id] = #name
+static const char *id_str[PERF_STAT_EVSEL_ID__MAX] = {
+	ID(NONE, x),
+};
+#undef ID
+
+void perf_stat_evsel_id_init(struct perf_evsel *evsel)
+{
+	struct perf_stat *ps = evsel->priv;
+	int i;
+
+	/* ps->id is 0 hence PERF_STAT_EVSEL_ID__NONE by default */
+
+	for (i = 0; i < PERF_STAT_EVSEL_ID__MAX; i++) {
+		if (!strcmp(evsel->name, id_str[i])) {
+			ps->id = i;
+			break;
+		}
+	}
+}
diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h
index 5667fc3e39cf..f4136cfd3cc9 100644
--- a/tools/perf/util/stat.h
+++ b/tools/perf/util/stat.h
@@ -9,6 +9,16 @@ struct stats
 	u64 max, min;
 };
 
+enum perf_stat_evsel_id {
+	PERF_STAT_EVSEL_ID__NONE = 0,
+	PERF_STAT_EVSEL_ID__MAX,
+};
+
+struct perf_stat {
+	struct stats		res_stats[3];
+	enum perf_stat_evsel_id	id;
+};
+
 void update_stats(struct stats *stats, u64 val);
 double avg_stats(struct stats *stats);
 double stddev_stats(struct stats *stats);
@@ -22,4 +32,14 @@ static inline void init_stats(struct stats *stats)
 	stats->min  = (u64) -1;
 	stats->max  = 0;
 }
+
+struct perf_evsel;
+bool __perf_evsel_stat__is(struct perf_evsel *evsel,
+			   enum perf_stat_evsel_id id);
+
+#define perf_stat_evsel__is(evsel, id) \
+	__perf_evsel_stat__is(evsel, PERF_STAT_EVSEL_ID__ ## id)
+
+void perf_stat_evsel_id_init(struct perf_evsel *evsel);
+
 #endif
-- 
1.9.3


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

* [PATCH 2/9] perf stat: Replace transaction event possition check with id check
  2015-06-03 14:25 [PATCHv2 0/9] perf stat: Separate shadow counters code Jiri Olsa
  2015-06-03 14:25 ` [PATCH 1/9] perf stat: Add id into perf_stat struct Jiri Olsa
@ 2015-06-03 14:25 ` Jiri Olsa
  2015-06-09  9:49   ` [tip:perf/core] " tip-bot for Jiri Olsa
  2015-06-03 14:25 ` [PATCH 3/9] perf stat: Remove setup_events function Jiri Olsa
                   ` (7 subsequent siblings)
  9 siblings, 1 reply; 30+ messages in thread
From: Jiri Olsa @ 2015-06-03 14:25 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Peter Zijlstra, Paul Mackerras, David Ahern, Namhyung Kim,
	Ingo Molnar, Andi Kleen, Stephane Eranian

Using perf_stat::id to check for transaction events,
instead of current possition based way.

Link: http://lkml.kernel.org/n/tip-ewc81hslqwhaljvlock51zyv@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/builtin-stat.c | 55 ++++++-----------------------------------------
 tools/perf/util/stat.c    |  6 +++++-
 tools/perf/util/stat.h    |  4 ++++
 3 files changed, 16 insertions(+), 49 deletions(-)

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index a6ae1007f1f9..514493d703da 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -96,17 +96,6 @@ static const char * const transaction_limited_attrs[] = {
 	"}"
 };
 
-/* must match transaction_attrs and the beginning limited_attrs */
-enum {
-	T_TASK_CLOCK,
-	T_INSTRUCTIONS,
-	T_CYCLES,
-	T_CYCLES_IN_TX,
-	T_TRANSACTION_START,
-	T_ELISION_START,
-	T_CYCLES_IN_TX_CP,
-};
-
 static struct perf_evlist	*evsel_list;
 
 static struct target target = {
@@ -352,29 +341,6 @@ static inline int nsec_counter(struct perf_evsel *evsel)
 	return 0;
 }
 
-static struct perf_evsel *nth_evsel(int n)
-{
-	static struct perf_evsel **array;
-	static int array_len;
-	struct perf_evsel *ev;
-	int j;
-
-	/* Assumes this only called when evsel_list does not change anymore. */
-	if (!array) {
-		evlist__for_each(evsel_list, ev)
-			array_len++;
-		array = malloc(array_len * sizeof(void *));
-		if (!array)
-			exit(ENOMEM);
-		j = 0;
-		evlist__for_each(evsel_list, ev)
-			array[j++] = ev;
-	}
-	if (n < array_len)
-		return array[n];
-	return NULL;
-}
-
 /*
  * Update various tracking values we maintain to print
  * more semantic information such as miss/hit ratios,
@@ -389,14 +355,11 @@ static void update_shadow_stats(struct perf_evsel *counter, u64 *count,
 		update_stats(&runtime_nsecs_stats[cpu], count[0]);
 	else if (perf_evsel__match(counter, HARDWARE, HW_CPU_CYCLES))
 		update_stats(&runtime_cycles_stats[ctx][cpu], count[0]);
-	else if (transaction_run &&
-		 perf_evsel__cmp(counter, nth_evsel(T_CYCLES_IN_TX)))
+	else if (transaction_run && perf_stat_evsel__is(counter, CYCLES_IN_TX))
 		update_stats(&runtime_transaction_stats[ctx][cpu], count[0]);
-	else if (transaction_run &&
-		 perf_evsel__cmp(counter, nth_evsel(T_TRANSACTION_START)))
+	else if (transaction_run && perf_stat_evsel__is(counter, TRANSACTION_START))
 		update_stats(&runtime_transaction_stats[ctx][cpu], count[0]);
-	else if (transaction_run &&
-		 perf_evsel__cmp(counter, nth_evsel(T_ELISION_START)))
+	else if (transaction_run && perf_stat_evsel__is(counter, ELISION_START))
 		update_stats(&runtime_elision_stats[ctx][cpu], count[0]);
 	else if (perf_evsel__match(counter, HARDWARE, HW_STALLED_CYCLES_FRONTEND))
 		update_stats(&runtime_stalled_cycles_front_stats[ctx][cpu], count[0]);
@@ -1207,15 +1170,13 @@ static void abs_printout(int id, int nr, struct perf_evsel *evsel, double avg)
 		} else {
 			fprintf(output, "                                   ");
 		}
-	} else if (transaction_run &&
-		   perf_evsel__cmp(evsel, nth_evsel(T_CYCLES_IN_TX))) {
+	} else if (transaction_run && perf_stat_evsel__is(evsel, CYCLES_IN_TX)) {
 		total = avg_stats(&runtime_cycles_stats[ctx][cpu]);
 		if (total)
 			fprintf(output,
 				" #   %5.2f%% transactional cycles   ",
 				100.0 * (avg / total));
-	} else if (transaction_run &&
-		   perf_evsel__cmp(evsel, nth_evsel(T_CYCLES_IN_TX_CP))) {
+	} else if (transaction_run && perf_stat_evsel__is(evsel, CYCLES_IN_TX_CP)) {
 		total = avg_stats(&runtime_cycles_stats[ctx][cpu]);
 		total2 = avg_stats(&runtime_cycles_in_tx_stats[ctx][cpu]);
 		if (total2 < avg)
@@ -1224,8 +1185,7 @@ static void abs_printout(int id, int nr, struct perf_evsel *evsel, double avg)
 			fprintf(output,
 				" #   %5.2f%% aborted cycles         ",
 				100.0 * ((total2-avg) / total));
-	} else if (transaction_run &&
-		   perf_evsel__cmp(evsel, nth_evsel(T_TRANSACTION_START)) &&
+	} else if (transaction_run && perf_stat_evsel__is(evsel, TRANSACTION_START) &&
 		   avg > 0 &&
 		   runtime_cycles_in_tx_stats[ctx][cpu].n != 0) {
 		total = avg_stats(&runtime_cycles_in_tx_stats[ctx][cpu]);
@@ -1234,8 +1194,7 @@ static void abs_printout(int id, int nr, struct perf_evsel *evsel, double avg)
 			ratio = total / avg;
 
 		fprintf(output, " # %8.0f cycles / transaction   ", ratio);
-	} else if (transaction_run &&
-		   perf_evsel__cmp(evsel, nth_evsel(T_ELISION_START)) &&
+	} else if (transaction_run && perf_stat_evsel__is(evsel, ELISION_START) &&
 		   avg > 0 &&
 		   runtime_cycles_in_tx_stats[ctx][cpu].n != 0) {
 		total = avg_stats(&runtime_cycles_in_tx_stats[ctx][cpu]);
diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c
index 873d07607937..d22791d02db0 100644
--- a/tools/perf/util/stat.c
+++ b/tools/perf/util/stat.c
@@ -72,7 +72,11 @@ bool __perf_evsel_stat__is(struct perf_evsel *evsel,
 
 #define ID(id, name) [PERF_STAT_EVSEL_ID__##id] = #name
 static const char *id_str[PERF_STAT_EVSEL_ID__MAX] = {
-	ID(NONE, x),
+	ID(NONE,		x),
+	ID(CYCLES_IN_TX,	cpu/cycles-t/),
+	ID(TRANSACTION_START,	cpu/tx-start/),
+	ID(ELISION_START,	cpu/el-start/),
+	ID(CYCLES_IN_TX_CP,	cpu/cycles-ct/),
 };
 #undef ID
 
diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h
index f4136cfd3cc9..3df529bd0774 100644
--- a/tools/perf/util/stat.h
+++ b/tools/perf/util/stat.h
@@ -11,6 +11,10 @@ struct stats
 
 enum perf_stat_evsel_id {
 	PERF_STAT_EVSEL_ID__NONE = 0,
+	PERF_STAT_EVSEL_ID__CYCLES_IN_TX,
+	PERF_STAT_EVSEL_ID__TRANSACTION_START,
+	PERF_STAT_EVSEL_ID__ELISION_START,
+	PERF_STAT_EVSEL_ID__CYCLES_IN_TX_CP,
 	PERF_STAT_EVSEL_ID__MAX,
 };
 
-- 
1.9.3


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

* [PATCH 3/9] perf stat: Remove setup_events function
  2015-06-03 14:25 [PATCHv2 0/9] perf stat: Separate shadow counters code Jiri Olsa
  2015-06-03 14:25 ` [PATCH 1/9] perf stat: Add id into perf_stat struct Jiri Olsa
  2015-06-03 14:25 ` [PATCH 2/9] perf stat: Replace transaction event possition check with id check Jiri Olsa
@ 2015-06-03 14:25 ` Jiri Olsa
  2015-06-09  9:49   ` [tip:perf/core] " tip-bot for Jiri Olsa
  2015-06-03 14:25 ` [PATCH 4/9] perf stat: Remove transaction_run from shadow update/print code Jiri Olsa
                   ` (6 subsequent siblings)
  9 siblings, 1 reply; 30+ messages in thread
From: Jiri Olsa @ 2015-06-03 14:25 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Peter Zijlstra, Paul Mackerras, David Ahern, Namhyung Kim,
	Ingo Molnar, Andi Kleen, Stephane Eranian

We can use already existing parse_events interface.

Both transaction_attrs and transaction_limited_attrs are
changed to be single strings.

Link: http://lkml.kernel.org/n/tip-9r37hrfb81v16xthafgxtppk@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/builtin-stat.c | 27 +++++++--------------------
 1 file changed, 7 insertions(+), 20 deletions(-)

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 514493d703da..0c0071cf4fba 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -73,8 +73,8 @@ static void print_counter(struct perf_evsel *counter, char *prefix);
 static void print_aggr(char *prefix);
 
 /* Default events used for perf stat -T */
-static const char * const transaction_attrs[] = {
-	"task-clock",
+static const char *transaction_attrs = {
+	"task-clock,"
 	"{"
 	"instructions,"
 	"cycles,"
@@ -86,8 +86,8 @@ static const char * const transaction_attrs[] = {
 };
 
 /* More limited version when the CPU does not have all events. */
-static const char * const transaction_limited_attrs[] = {
-	"task-clock",
+static const char * transaction_limited_attrs = {
+	"task-clock,"
 	"{"
 	"instructions,"
 	"cycles,"
@@ -1533,17 +1533,6 @@ static int perf_stat_init_aggr_mode(void)
 	return 0;
 }
 
-static int setup_events(const char * const *attrs, unsigned len)
-{
-	unsigned i;
-
-	for (i = 0; i < len; i++) {
-		if (parse_events(evsel_list, attrs[i], NULL))
-			return -1;
-	}
-	return 0;
-}
-
 /*
  * Add default attributes, if there were no attributes specified or
  * if -d/--detailed, -d -d or -d -d -d is used:
@@ -1665,12 +1654,10 @@ static int add_default_attributes(void)
 		int err;
 		if (pmu_have_event("cpu", "cycles-ct") &&
 		    pmu_have_event("cpu", "el-start"))
-			err = setup_events(transaction_attrs,
-					ARRAY_SIZE(transaction_attrs));
+			err = parse_events(evsel_list, transaction_attrs, NULL);
 		else
-			err = setup_events(transaction_limited_attrs,
-				 ARRAY_SIZE(transaction_limited_attrs));
-		if (err < 0) {
+			err = parse_events(evsel_list, transaction_limited_attrs, NULL);
+		if (err) {
 			fprintf(stderr, "Cannot set up transaction events\n");
 			return -1;
 		}
-- 
1.9.3


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

* [PATCH 4/9] perf stat: Remove transaction_run from shadow update/print code
  2015-06-03 14:25 [PATCHv2 0/9] perf stat: Separate shadow counters code Jiri Olsa
                   ` (2 preceding siblings ...)
  2015-06-03 14:25 ` [PATCH 3/9] perf stat: Remove setup_events function Jiri Olsa
@ 2015-06-03 14:25 ` Jiri Olsa
  2015-06-03 15:10   ` Arnaldo Carvalho de Melo
  2015-06-09  9:49   ` [tip:perf/core] " tip-bot for Jiri Olsa
  2015-06-03 14:25 ` [PATCH 5/9] perf stat: Introduce reset_shadow_stats function Jiri Olsa
                   ` (5 subsequent siblings)
  9 siblings, 2 replies; 30+ messages in thread
From: Jiri Olsa @ 2015-06-03 14:25 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Peter Zijlstra, Paul Mackerras, David Ahern, Namhyung Kim,
	Ingo Molnar, Andi Kleen, Stephane Eranian

It's no longer needed, because we use nameid to recognize
transaction events.

Keeping it only in stat code to initialize transaction events.

Link: http://lkml.kernel.org/n/tip-eo93tek7cjy8zqdvfd6f5a4x@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/builtin-stat.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 0c0071cf4fba..b3e08ce2c564 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -355,11 +355,11 @@ static void update_shadow_stats(struct perf_evsel *counter, u64 *count,
 		update_stats(&runtime_nsecs_stats[cpu], count[0]);
 	else if (perf_evsel__match(counter, HARDWARE, HW_CPU_CYCLES))
 		update_stats(&runtime_cycles_stats[ctx][cpu], count[0]);
-	else if (transaction_run && perf_stat_evsel__is(counter, CYCLES_IN_TX))
+	else if (perf_stat_evsel__is(counter, CYCLES_IN_TX))
 		update_stats(&runtime_transaction_stats[ctx][cpu], count[0]);
-	else if (transaction_run && perf_stat_evsel__is(counter, TRANSACTION_START))
+	else if (perf_stat_evsel__is(counter, TRANSACTION_START))
 		update_stats(&runtime_transaction_stats[ctx][cpu], count[0]);
-	else if (transaction_run && perf_stat_evsel__is(counter, ELISION_START))
+	else if (perf_stat_evsel__is(counter, ELISION_START))
 		update_stats(&runtime_elision_stats[ctx][cpu], count[0]);
 	else if (perf_evsel__match(counter, HARDWARE, HW_STALLED_CYCLES_FRONTEND))
 		update_stats(&runtime_stalled_cycles_front_stats[ctx][cpu], count[0]);
@@ -1170,13 +1170,13 @@ static void abs_printout(int id, int nr, struct perf_evsel *evsel, double avg)
 		} else {
 			fprintf(output, "                                   ");
 		}
-	} else if (transaction_run && perf_stat_evsel__is(evsel, CYCLES_IN_TX)) {
+	} else if (perf_stat_evsel__is(evsel, CYCLES_IN_TX)) {
 		total = avg_stats(&runtime_cycles_stats[ctx][cpu]);
 		if (total)
 			fprintf(output,
 				" #   %5.2f%% transactional cycles   ",
 				100.0 * (avg / total));
-	} else if (transaction_run && perf_stat_evsel__is(evsel, CYCLES_IN_TX_CP)) {
+	} else if (perf_stat_evsel__is(evsel, CYCLES_IN_TX_CP)) {
 		total = avg_stats(&runtime_cycles_stats[ctx][cpu]);
 		total2 = avg_stats(&runtime_cycles_in_tx_stats[ctx][cpu]);
 		if (total2 < avg)
@@ -1185,7 +1185,7 @@ static void abs_printout(int id, int nr, struct perf_evsel *evsel, double avg)
 			fprintf(output,
 				" #   %5.2f%% aborted cycles         ",
 				100.0 * ((total2-avg) / total));
-	} else if (transaction_run && perf_stat_evsel__is(evsel, TRANSACTION_START) &&
+	} else if (perf_stat_evsel__is(evsel, TRANSACTION_START) &&
 		   avg > 0 &&
 		   runtime_cycles_in_tx_stats[ctx][cpu].n != 0) {
 		total = avg_stats(&runtime_cycles_in_tx_stats[ctx][cpu]);
@@ -1194,7 +1194,7 @@ static void abs_printout(int id, int nr, struct perf_evsel *evsel, double avg)
 			ratio = total / avg;
 
 		fprintf(output, " # %8.0f cycles / transaction   ", ratio);
-	} else if (transaction_run && perf_stat_evsel__is(evsel, ELISION_START) &&
+	} else if (perf_stat_evsel__is(evsel, ELISION_START) &&
 		   avg > 0 &&
 		   runtime_cycles_in_tx_stats[ctx][cpu].n != 0) {
 		total = avg_stats(&runtime_cycles_in_tx_stats[ctx][cpu]);
-- 
1.9.3


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

* [PATCH 5/9] perf stat: Introduce reset_shadow_stats function
  2015-06-03 14:25 [PATCHv2 0/9] perf stat: Separate shadow counters code Jiri Olsa
                   ` (3 preceding siblings ...)
  2015-06-03 14:25 ` [PATCH 4/9] perf stat: Remove transaction_run from shadow update/print code Jiri Olsa
@ 2015-06-03 14:25 ` Jiri Olsa
  2015-06-09  9:50   ` [tip:perf/core] " tip-bot for Jiri Olsa
  2015-06-03 14:25 ` [PATCH 6/9] perf stat: Introduce print_shadow_stats function Jiri Olsa
                   ` (4 subsequent siblings)
  9 siblings, 1 reply; 30+ messages in thread
From: Jiri Olsa @ 2015-06-03 14:25 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Peter Zijlstra, Paul Mackerras, David Ahern, Namhyung Kim,
	Ingo Molnar, Andi Kleen, Stephane Eranian

Move shadow counters reset code into separate function
as preparation for moving it into its own object.

Link: http://lkml.kernel.org/n/tip-0i8ssz8kj0rpp5r699srqity@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/builtin-stat.c | 21 +++++++++++++--------
 1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index b3e08ce2c564..fc85e6b9bd13 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -279,15 +279,8 @@ static int evsel_context(struct perf_evsel *evsel)
 	return ctx;
 }
 
-static void perf_stat__reset_stats(struct perf_evlist *evlist)
+static void reset_shadow_stats(void)
 {
-	struct perf_evsel *evsel;
-
-	evlist__for_each(evlist, evsel) {
-		perf_evsel__reset_stat_priv(evsel);
-		perf_evsel__reset_counts(evsel, perf_evsel__nr_cpus(evsel));
-	}
-
 	memset(runtime_nsecs_stats, 0, sizeof(runtime_nsecs_stats));
 	memset(runtime_cycles_stats, 0, sizeof(runtime_cycles_stats));
 	memset(runtime_stalled_cycles_front_stats, 0, sizeof(runtime_stalled_cycles_front_stats));
@@ -307,6 +300,18 @@ static void perf_stat__reset_stats(struct perf_evlist *evlist)
 	memset(&walltime_nsecs_stats, 0, sizeof(walltime_nsecs_stats));
 }
 
+static void perf_stat__reset_stats(struct perf_evlist *evlist)
+{
+	struct perf_evsel *evsel;
+
+	evlist__for_each(evlist, evsel) {
+		perf_evsel__reset_stat_priv(evsel);
+		perf_evsel__reset_counts(evsel, perf_evsel__nr_cpus(evsel));
+	}
+
+	reset_shadow_stats();
+}
+
 static int create_perf_stat_counter(struct perf_evsel *evsel)
 {
 	struct perf_event_attr *attr = &evsel->attr;
-- 
1.9.3


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

* [PATCH 6/9] perf stat: Introduce print_shadow_stats function
  2015-06-03 14:25 [PATCHv2 0/9] perf stat: Separate shadow counters code Jiri Olsa
                   ` (4 preceding siblings ...)
  2015-06-03 14:25 ` [PATCH 5/9] perf stat: Introduce reset_shadow_stats function Jiri Olsa
@ 2015-06-03 14:25 ` Jiri Olsa
  2015-06-09  9:50   ` [tip:perf/core] " tip-bot for Jiri Olsa
  2015-06-03 14:25 ` [PATCH 7/9] perf stat: Add output file argument to " Jiri Olsa
                   ` (3 subsequent siblings)
  9 siblings, 1 reply; 30+ messages in thread
From: Jiri Olsa @ 2015-06-03 14:25 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Peter Zijlstra, Paul Mackerras, David Ahern, Namhyung Kim,
	Ingo Molnar, Andi Kleen, Stephane Eranian

Move shadow counters display code into separate function
as preparation for moving it into its own object.

Link: http://lkml.kernel.org/n/tip-loph8qgefq6664yqko3jg2tc@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/builtin-stat.c | 72 +++++++++++++++++++++++++----------------------
 1 file changed, 39 insertions(+), 33 deletions(-)

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index fc85e6b9bd13..2ff2e22aa140 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -1059,43 +1059,11 @@ static void print_ll_cache_misses(int cpu,
 	fprintf(output, " of all LL-cache hits   ");
 }
 
-static void abs_printout(int id, int nr, struct perf_evsel *evsel, double avg)
+static void print_shadow_stats(struct perf_evsel *evsel, double avg, int cpu)
 {
 	double total, ratio = 0.0, total2;
-	double sc =  evsel->scale;
-	const char *fmt;
-	int cpu = cpu_map__id_to_cpu(id);
 	int ctx = evsel_context(evsel);
 
-	if (csv_output) {
-		fmt = sc != 1.0 ?  "%.2f%s" : "%.0f%s";
-	} else {
-		if (big_num)
-			fmt = sc != 1.0 ? "%'18.2f%s" : "%'18.0f%s";
-		else
-			fmt = sc != 1.0 ? "%18.2f%s" : "%18.0f%s";
-	}
-
-	aggr_printout(evsel, id, nr);
-
-	if (aggr_mode == AGGR_GLOBAL)
-		cpu = 0;
-
-	fprintf(output, fmt, avg, csv_sep);
-
-	if (evsel->unit)
-		fprintf(output, "%-*s%s",
-			csv_output ? 0 : unit_width,
-			evsel->unit, csv_sep);
-
-	fprintf(output, "%-*s", csv_output ? 0 : 25, perf_evsel__name(evsel));
-
-	if (evsel->cgrp)
-		fprintf(output, "%s%s", csv_sep, evsel->cgrp->name);
-
-	if (csv_output || interval)
-		return;
-
 	if (perf_evsel__match(evsel, HARDWARE, HW_INSTRUCTIONS)) {
 		total = avg_stats(&runtime_cycles_stats[ctx][cpu]);
 		if (total) {
@@ -1226,6 +1194,44 @@ static void abs_printout(int id, int nr, struct perf_evsel *evsel, double avg)
 	}
 }
 
+static void abs_printout(int id, int nr, struct perf_evsel *evsel, double avg)
+{
+	double sc =  evsel->scale;
+	const char *fmt;
+	int cpu = cpu_map__id_to_cpu(id);
+
+	if (csv_output) {
+		fmt = sc != 1.0 ?  "%.2f%s" : "%.0f%s";
+	} else {
+		if (big_num)
+			fmt = sc != 1.0 ? "%'18.2f%s" : "%'18.0f%s";
+		else
+			fmt = sc != 1.0 ? "%18.2f%s" : "%18.0f%s";
+	}
+
+	aggr_printout(evsel, id, nr);
+
+	if (aggr_mode == AGGR_GLOBAL)
+		cpu = 0;
+
+	fprintf(output, fmt, avg, csv_sep);
+
+	if (evsel->unit)
+		fprintf(output, "%-*s%s",
+			csv_output ? 0 : unit_width,
+			evsel->unit, csv_sep);
+
+	fprintf(output, "%-*s", csv_output ? 0 : 25, perf_evsel__name(evsel));
+
+	if (evsel->cgrp)
+		fprintf(output, "%s%s", csv_sep, evsel->cgrp->name);
+
+	if (csv_output || interval)
+		return;
+
+	print_shadow_stats(evsel, avg, cpu);
+}
+
 static void print_aggr(char *prefix)
 {
 	struct perf_evsel *counter;
-- 
1.9.3


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

* [PATCH 7/9] perf stat: Add output file argument to print_shadow_stats function
  2015-06-03 14:25 [PATCHv2 0/9] perf stat: Separate shadow counters code Jiri Olsa
                   ` (5 preceding siblings ...)
  2015-06-03 14:25 ` [PATCH 6/9] perf stat: Introduce print_shadow_stats function Jiri Olsa
@ 2015-06-03 14:25 ` Jiri Olsa
  2015-06-09  9:50   ` [tip:perf/core] " tip-bot for Jiri Olsa
  2015-06-03 14:25 ` [PATCH 8/9] perf stat: Add aggr_mode " Jiri Olsa
                   ` (2 subsequent siblings)
  9 siblings, 1 reply; 30+ messages in thread
From: Jiri Olsa @ 2015-06-03 14:25 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Peter Zijlstra, Paul Mackerras, David Ahern, Namhyung Kim,
	Ingo Molnar, Andi Kleen, Stephane Eranian

As preparation for moving shadow counters code into its own object.

Link: http://lkml.kernel.org/n/tip-uhx2opot7qtd3xdq9pvx4z8v@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/builtin-stat.c | 112 +++++++++++++++++++++++-----------------------
 1 file changed, 56 insertions(+), 56 deletions(-)

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 2ff2e22aa140..14a75ddb60c7 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -899,7 +899,7 @@ static const char *get_ratio_color(enum grc_type type, double ratio)
 	return color;
 }
 
-static void print_stalled_cycles_frontend(int cpu,
+static void print_stalled_cycles_frontend(FILE *out, int cpu,
 					  struct perf_evsel *evsel
 					  __maybe_unused, double avg)
 {
@@ -914,12 +914,12 @@ static void print_stalled_cycles_frontend(int cpu,
 
 	color = get_ratio_color(GRC_STALLED_CYCLES_FE, ratio);
 
-	fprintf(output, " #  ");
-	color_fprintf(output, color, "%6.2f%%", ratio);
-	fprintf(output, " frontend cycles idle   ");
+	fprintf(out, " #  ");
+	color_fprintf(out, color, "%6.2f%%", ratio);
+	fprintf(out, " frontend cycles idle   ");
 }
 
-static void print_stalled_cycles_backend(int cpu,
+static void print_stalled_cycles_backend(FILE *out, int cpu,
 					 struct perf_evsel *evsel
 					 __maybe_unused, double avg)
 {
@@ -934,12 +934,12 @@ static void print_stalled_cycles_backend(int cpu,
 
 	color = get_ratio_color(GRC_STALLED_CYCLES_BE, ratio);
 
-	fprintf(output, " #  ");
-	color_fprintf(output, color, "%6.2f%%", ratio);
-	fprintf(output, " backend  cycles idle   ");
+	fprintf(out, " #  ");
+	color_fprintf(out, color, "%6.2f%%", ratio);
+	fprintf(out, " backend  cycles idle   ");
 }
 
-static void print_branch_misses(int cpu,
+static void print_branch_misses(FILE *out, int cpu,
 				struct perf_evsel *evsel __maybe_unused,
 				double avg)
 {
@@ -954,12 +954,12 @@ static void print_branch_misses(int cpu,
 
 	color = get_ratio_color(GRC_CACHE_MISSES, ratio);
 
-	fprintf(output, " #  ");
-	color_fprintf(output, color, "%6.2f%%", ratio);
-	fprintf(output, " of all branches        ");
+	fprintf(out, " #  ");
+	color_fprintf(out, color, "%6.2f%%", ratio);
+	fprintf(out, " of all branches        ");
 }
 
-static void print_l1_dcache_misses(int cpu,
+static void print_l1_dcache_misses(FILE *out, int cpu,
 				   struct perf_evsel *evsel __maybe_unused,
 				   double avg)
 {
@@ -974,12 +974,12 @@ static void print_l1_dcache_misses(int cpu,
 
 	color = get_ratio_color(GRC_CACHE_MISSES, ratio);
 
-	fprintf(output, " #  ");
-	color_fprintf(output, color, "%6.2f%%", ratio);
-	fprintf(output, " of all L1-dcache hits  ");
+	fprintf(out, " #  ");
+	color_fprintf(out, color, "%6.2f%%", ratio);
+	fprintf(out, " of all L1-dcache hits  ");
 }
 
-static void print_l1_icache_misses(int cpu,
+static void print_l1_icache_misses(FILE *out, int cpu,
 				   struct perf_evsel *evsel __maybe_unused,
 				   double avg)
 {
@@ -994,12 +994,12 @@ static void print_l1_icache_misses(int cpu,
 
 	color = get_ratio_color(GRC_CACHE_MISSES, ratio);
 
-	fprintf(output, " #  ");
-	color_fprintf(output, color, "%6.2f%%", ratio);
-	fprintf(output, " of all L1-icache hits  ");
+	fprintf(out, " #  ");
+	color_fprintf(out, color, "%6.2f%%", ratio);
+	fprintf(out, " of all L1-icache hits  ");
 }
 
-static void print_dtlb_cache_misses(int cpu,
+static void print_dtlb_cache_misses(FILE *out, int cpu,
 				    struct perf_evsel *evsel __maybe_unused,
 				    double avg)
 {
@@ -1014,12 +1014,12 @@ static void print_dtlb_cache_misses(int cpu,
 
 	color = get_ratio_color(GRC_CACHE_MISSES, ratio);
 
-	fprintf(output, " #  ");
-	color_fprintf(output, color, "%6.2f%%", ratio);
-	fprintf(output, " of all dTLB cache hits ");
+	fprintf(out, " #  ");
+	color_fprintf(out, color, "%6.2f%%", ratio);
+	fprintf(out, " of all dTLB cache hits ");
 }
 
-static void print_itlb_cache_misses(int cpu,
+static void print_itlb_cache_misses(FILE *out, int cpu,
 				    struct perf_evsel *evsel __maybe_unused,
 				    double avg)
 {
@@ -1034,12 +1034,12 @@ static void print_itlb_cache_misses(int cpu,
 
 	color = get_ratio_color(GRC_CACHE_MISSES, ratio);
 
-	fprintf(output, " #  ");
-	color_fprintf(output, color, "%6.2f%%", ratio);
-	fprintf(output, " of all iTLB cache hits ");
+	fprintf(out, " #  ");
+	color_fprintf(out, color, "%6.2f%%", ratio);
+	fprintf(out, " of all iTLB cache hits ");
 }
 
-static void print_ll_cache_misses(int cpu,
+static void print_ll_cache_misses(FILE *out, int cpu,
 				  struct perf_evsel *evsel __maybe_unused,
 				  double avg)
 {
@@ -1054,12 +1054,12 @@ static void print_ll_cache_misses(int cpu,
 
 	color = get_ratio_color(GRC_CACHE_MISSES, ratio);
 
-	fprintf(output, " #  ");
-	color_fprintf(output, color, "%6.2f%%", ratio);
-	fprintf(output, " of all LL-cache hits   ");
+	fprintf(out, " #  ");
+	color_fprintf(out, color, "%6.2f%%", ratio);
+	fprintf(out, " of all LL-cache hits   ");
 }
 
-static void print_shadow_stats(struct perf_evsel *evsel, double avg, int cpu)
+static void print_shadow_stats(FILE *out, struct perf_evsel *evsel, double avg, int cpu)
 {
 	double total, ratio = 0.0, total2;
 	int ctx = evsel_context(evsel);
@@ -1068,59 +1068,59 @@ static void print_shadow_stats(struct perf_evsel *evsel, double avg, int cpu)
 		total = avg_stats(&runtime_cycles_stats[ctx][cpu]);
 		if (total) {
 			ratio = avg / total;
-			fprintf(output, " #   %5.2f  insns per cycle        ", ratio);
+			fprintf(out, " #   %5.2f  insns per cycle        ", ratio);
 		} else {
-			fprintf(output, "                                   ");
+			fprintf(out, "                                   ");
 		}
 		total = avg_stats(&runtime_stalled_cycles_front_stats[ctx][cpu]);
 		total = max(total, avg_stats(&runtime_stalled_cycles_back_stats[ctx][cpu]));
 
 		if (total && avg) {
 			ratio = total / avg;
-			fprintf(output, "\n");
+			fprintf(out, "\n");
 			if (aggr_mode == AGGR_NONE)
-				fprintf(output, "        ");
-			fprintf(output, "                                                  #   %5.2f  stalled cycles per insn", ratio);
+				fprintf(out, "        ");
+			fprintf(out, "                                                  #   %5.2f  stalled cycles per insn", ratio);
 		}
 
 	} else if (perf_evsel__match(evsel, HARDWARE, HW_BRANCH_MISSES) &&
 			runtime_branches_stats[ctx][cpu].n != 0) {
-		print_branch_misses(cpu, evsel, avg);
+		print_branch_misses(out, cpu, evsel, avg);
 	} else if (
 		evsel->attr.type == PERF_TYPE_HW_CACHE &&
 		evsel->attr.config ==  ( PERF_COUNT_HW_CACHE_L1D |
 					((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
 					((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) &&
 			runtime_l1_dcache_stats[ctx][cpu].n != 0) {
-		print_l1_dcache_misses(cpu, evsel, avg);
+		print_l1_dcache_misses(out, cpu, evsel, avg);
 	} else if (
 		evsel->attr.type == PERF_TYPE_HW_CACHE &&
 		evsel->attr.config ==  ( PERF_COUNT_HW_CACHE_L1I |
 					((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
 					((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) &&
 			runtime_l1_icache_stats[ctx][cpu].n != 0) {
-		print_l1_icache_misses(cpu, evsel, avg);
+		print_l1_icache_misses(out, cpu, evsel, avg);
 	} else if (
 		evsel->attr.type == PERF_TYPE_HW_CACHE &&
 		evsel->attr.config ==  ( PERF_COUNT_HW_CACHE_DTLB |
 					((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
 					((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) &&
 			runtime_dtlb_cache_stats[ctx][cpu].n != 0) {
-		print_dtlb_cache_misses(cpu, evsel, avg);
+		print_dtlb_cache_misses(out, cpu, evsel, avg);
 	} else if (
 		evsel->attr.type == PERF_TYPE_HW_CACHE &&
 		evsel->attr.config ==  ( PERF_COUNT_HW_CACHE_ITLB |
 					((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
 					((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) &&
 			runtime_itlb_cache_stats[ctx][cpu].n != 0) {
-		print_itlb_cache_misses(cpu, evsel, avg);
+		print_itlb_cache_misses(out, cpu, evsel, avg);
 	} else if (
 		evsel->attr.type == PERF_TYPE_HW_CACHE &&
 		evsel->attr.config ==  ( PERF_COUNT_HW_CACHE_LL |
 					((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
 					((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) &&
 			runtime_ll_cache_stats[ctx][cpu].n != 0) {
-		print_ll_cache_misses(cpu, evsel, avg);
+		print_ll_cache_misses(out, cpu, evsel, avg);
 	} else if (perf_evsel__match(evsel, HARDWARE, HW_CACHE_MISSES) &&
 			runtime_cacherefs_stats[ctx][cpu].n != 0) {
 		total = avg_stats(&runtime_cacherefs_stats[ctx][cpu]);
@@ -1128,25 +1128,25 @@ static void print_shadow_stats(struct perf_evsel *evsel, double avg, int cpu)
 		if (total)
 			ratio = avg * 100 / total;
 
-		fprintf(output, " # %8.3f %% of all cache refs    ", ratio);
+		fprintf(out, " # %8.3f %% of all cache refs    ", ratio);
 
 	} else if (perf_evsel__match(evsel, HARDWARE, HW_STALLED_CYCLES_FRONTEND)) {
-		print_stalled_cycles_frontend(cpu, evsel, avg);
+		print_stalled_cycles_frontend(out, cpu, evsel, avg);
 	} else if (perf_evsel__match(evsel, HARDWARE, HW_STALLED_CYCLES_BACKEND)) {
-		print_stalled_cycles_backend(cpu, evsel, avg);
+		print_stalled_cycles_backend(out, cpu, evsel, avg);
 	} else if (perf_evsel__match(evsel, HARDWARE, HW_CPU_CYCLES)) {
 		total = avg_stats(&runtime_nsecs_stats[cpu]);
 
 		if (total) {
 			ratio = avg / total;
-			fprintf(output, " # %8.3f GHz                    ", ratio);
+			fprintf(out, " # %8.3f GHz                    ", ratio);
 		} else {
-			fprintf(output, "                                   ");
+			fprintf(out, "                                   ");
 		}
 	} else if (perf_stat_evsel__is(evsel, CYCLES_IN_TX)) {
 		total = avg_stats(&runtime_cycles_stats[ctx][cpu]);
 		if (total)
-			fprintf(output,
+			fprintf(out,
 				" #   %5.2f%% transactional cycles   ",
 				100.0 * (avg / total));
 	} else if (perf_stat_evsel__is(evsel, CYCLES_IN_TX_CP)) {
@@ -1155,7 +1155,7 @@ static void print_shadow_stats(struct perf_evsel *evsel, double avg, int cpu)
 		if (total2 < avg)
 			total2 = avg;
 		if (total)
-			fprintf(output,
+			fprintf(out,
 				" #   %5.2f%% aborted cycles         ",
 				100.0 * ((total2-avg) / total));
 	} else if (perf_stat_evsel__is(evsel, TRANSACTION_START) &&
@@ -1166,7 +1166,7 @@ static void print_shadow_stats(struct perf_evsel *evsel, double avg, int cpu)
 		if (total)
 			ratio = total / avg;
 
-		fprintf(output, " # %8.0f cycles / transaction   ", ratio);
+		fprintf(out, " # %8.0f cycles / transaction   ", ratio);
 	} else if (perf_stat_evsel__is(evsel, ELISION_START) &&
 		   avg > 0 &&
 		   runtime_cycles_in_tx_stats[ctx][cpu].n != 0) {
@@ -1175,7 +1175,7 @@ static void print_shadow_stats(struct perf_evsel *evsel, double avg, int cpu)
 		if (total)
 			ratio = total / avg;
 
-		fprintf(output, " # %8.0f cycles / elision       ", ratio);
+		fprintf(out, " # %8.0f cycles / elision       ", ratio);
 	} else if (runtime_nsecs_stats[cpu].n != 0) {
 		char unit = 'M';
 
@@ -1188,9 +1188,9 @@ static void print_shadow_stats(struct perf_evsel *evsel, double avg, int cpu)
 			unit = 'K';
 		}
 
-		fprintf(output, " # %8.3f %c/sec                  ", ratio, unit);
+		fprintf(out, " # %8.3f %c/sec                  ", ratio, unit);
 	} else {
-		fprintf(output, "                                   ");
+		fprintf(out, "                                   ");
 	}
 }
 
@@ -1229,7 +1229,7 @@ static void abs_printout(int id, int nr, struct perf_evsel *evsel, double avg)
 	if (csv_output || interval)
 		return;
 
-	print_shadow_stats(evsel, avg, cpu);
+	print_shadow_stats(output, evsel, avg, cpu);
 }
 
 static void print_aggr(char *prefix)
-- 
1.9.3


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

* [PATCH 8/9] perf stat: Add aggr_mode argument to print_shadow_stats function
  2015-06-03 14:25 [PATCHv2 0/9] perf stat: Separate shadow counters code Jiri Olsa
                   ` (6 preceding siblings ...)
  2015-06-03 14:25 ` [PATCH 7/9] perf stat: Add output file argument to " Jiri Olsa
@ 2015-06-03 14:25 ` Jiri Olsa
  2015-06-09  9:51   ` [tip:perf/core] " tip-bot for Jiri Olsa
  2015-06-03 14:25 ` [PATCH 9/9] perf stat: Move shadow stat counters into separate object Jiri Olsa
  2015-06-03 22:07 ` [PATCHv2 0/9] perf stat: Separate shadow counters code Arnaldo Carvalho de Melo
  9 siblings, 1 reply; 30+ messages in thread
From: Jiri Olsa @ 2015-06-03 14:25 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Peter Zijlstra, Paul Mackerras, David Ahern, Namhyung Kim,
	Ingo Molnar, Andi Kleen, Stephane Eranian

As preparation for moving shadow counters code into its own object.

Link: http://lkml.kernel.org/n/tip-kdgryri2kahing584g5is35b@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/builtin-stat.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 14a75ddb60c7..50918dc9fb31 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -1059,7 +1059,8 @@ static void print_ll_cache_misses(FILE *out, int cpu,
 	fprintf(out, " of all LL-cache hits   ");
 }
 
-static void print_shadow_stats(FILE *out, struct perf_evsel *evsel, double avg, int cpu)
+static void print_shadow_stats(FILE *out, struct perf_evsel *evsel,
+			       double avg, int cpu, enum aggr_mode aggr)
 {
 	double total, ratio = 0.0, total2;
 	int ctx = evsel_context(evsel);
@@ -1078,7 +1079,7 @@ static void print_shadow_stats(FILE *out, struct perf_evsel *evsel, double avg,
 		if (total && avg) {
 			ratio = total / avg;
 			fprintf(out, "\n");
-			if (aggr_mode == AGGR_NONE)
+			if (aggr == AGGR_NONE)
 				fprintf(out, "        ");
 			fprintf(out, "                                                  #   %5.2f  stalled cycles per insn", ratio);
 		}
@@ -1229,7 +1230,7 @@ static void abs_printout(int id, int nr, struct perf_evsel *evsel, double avg)
 	if (csv_output || interval)
 		return;
 
-	print_shadow_stats(output, evsel, avg, cpu);
+	print_shadow_stats(output, evsel, avg, cpu, aggr_mode);
 }
 
 static void print_aggr(char *prefix)
-- 
1.9.3


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

* [PATCH 9/9] perf stat: Move shadow stat counters into separate object
  2015-06-03 14:25 [PATCHv2 0/9] perf stat: Separate shadow counters code Jiri Olsa
                   ` (7 preceding siblings ...)
  2015-06-03 14:25 ` [PATCH 8/9] perf stat: Add aggr_mode " Jiri Olsa
@ 2015-06-03 14:25 ` Jiri Olsa
  2015-06-09  9:51   ` [tip:perf/core] " tip-bot for Jiri Olsa
  2015-06-03 22:07 ` [PATCHv2 0/9] perf stat: Separate shadow counters code Arnaldo Carvalho de Melo
  9 siblings, 1 reply; 30+ messages in thread
From: Jiri Olsa @ 2015-06-03 14:25 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Peter Zijlstra, Paul Mackerras, David Ahern, Namhyung Kim,
	Ingo Molnar, Andi Kleen, Stephane Eranian

Separating shadow counters code into separate object
as a cleanup, but mainly for upcomming changes, so
could use it from script command context.

Link: http://lkml.kernel.org/n/tip-ic34l55jem02kx4h3wodn7ql@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/builtin-stat.c     | 444 +-----------------------------------------
 tools/perf/util/Build         |   1 +
 tools/perf/util/stat-shadow.c | 434 +++++++++++++++++++++++++++++++++++++++++
 tools/perf/util/stat.h        |  16 ++
 4 files changed, 455 insertions(+), 440 deletions(-)
 create mode 100644 tools/perf/util/stat-shadow.c

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 50918dc9fb31..ff3d25803400 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -102,13 +102,6 @@ static struct target target = {
 	.uid	= UINT_MAX,
 };
 
-enum aggr_mode {
-	AGGR_NONE,
-	AGGR_GLOBAL,
-	AGGR_SOCKET,
-	AGGR_CORE,
-};
-
 static int			run_count			=  1;
 static bool			no_inherit			= false;
 static bool			scale				=  true;
@@ -234,72 +227,6 @@ out_free:
 	return -1;
 }
 
-enum {
-	CTX_BIT_USER	= 1 << 0,
-	CTX_BIT_KERNEL	= 1 << 1,
-	CTX_BIT_HV	= 1 << 2,
-	CTX_BIT_HOST	= 1 << 3,
-	CTX_BIT_IDLE	= 1 << 4,
-	CTX_BIT_MAX	= 1 << 5,
-};
-
-#define NUM_CTX CTX_BIT_MAX
-
-static struct stats runtime_nsecs_stats[MAX_NR_CPUS];
-static struct stats runtime_cycles_stats[NUM_CTX][MAX_NR_CPUS];
-static struct stats runtime_stalled_cycles_front_stats[NUM_CTX][MAX_NR_CPUS];
-static struct stats runtime_stalled_cycles_back_stats[NUM_CTX][MAX_NR_CPUS];
-static struct stats runtime_branches_stats[NUM_CTX][MAX_NR_CPUS];
-static struct stats runtime_cacherefs_stats[NUM_CTX][MAX_NR_CPUS];
-static struct stats runtime_l1_dcache_stats[NUM_CTX][MAX_NR_CPUS];
-static struct stats runtime_l1_icache_stats[NUM_CTX][MAX_NR_CPUS];
-static struct stats runtime_ll_cache_stats[NUM_CTX][MAX_NR_CPUS];
-static struct stats runtime_itlb_cache_stats[NUM_CTX][MAX_NR_CPUS];
-static struct stats runtime_dtlb_cache_stats[NUM_CTX][MAX_NR_CPUS];
-static struct stats runtime_cycles_in_tx_stats[NUM_CTX][MAX_NR_CPUS];
-static struct stats walltime_nsecs_stats;
-static struct stats runtime_transaction_stats[NUM_CTX][MAX_NR_CPUS];
-static struct stats runtime_elision_stats[NUM_CTX][MAX_NR_CPUS];
-
-static int evsel_context(struct perf_evsel *evsel)
-{
-	int ctx = 0;
-
-	if (evsel->attr.exclude_kernel)
-		ctx |= CTX_BIT_KERNEL;
-	if (evsel->attr.exclude_user)
-		ctx |= CTX_BIT_USER;
-	if (evsel->attr.exclude_hv)
-		ctx |= CTX_BIT_HV;
-	if (evsel->attr.exclude_host)
-		ctx |= CTX_BIT_HOST;
-	if (evsel->attr.exclude_idle)
-		ctx |= CTX_BIT_IDLE;
-
-	return ctx;
-}
-
-static void reset_shadow_stats(void)
-{
-	memset(runtime_nsecs_stats, 0, sizeof(runtime_nsecs_stats));
-	memset(runtime_cycles_stats, 0, sizeof(runtime_cycles_stats));
-	memset(runtime_stalled_cycles_front_stats, 0, sizeof(runtime_stalled_cycles_front_stats));
-	memset(runtime_stalled_cycles_back_stats, 0, sizeof(runtime_stalled_cycles_back_stats));
-	memset(runtime_branches_stats, 0, sizeof(runtime_branches_stats));
-	memset(runtime_cacherefs_stats, 0, sizeof(runtime_cacherefs_stats));
-	memset(runtime_l1_dcache_stats, 0, sizeof(runtime_l1_dcache_stats));
-	memset(runtime_l1_icache_stats, 0, sizeof(runtime_l1_icache_stats));
-	memset(runtime_ll_cache_stats, 0, sizeof(runtime_ll_cache_stats));
-	memset(runtime_itlb_cache_stats, 0, sizeof(runtime_itlb_cache_stats));
-	memset(runtime_dtlb_cache_stats, 0, sizeof(runtime_dtlb_cache_stats));
-	memset(runtime_cycles_in_tx_stats, 0,
-			sizeof(runtime_cycles_in_tx_stats));
-	memset(runtime_transaction_stats, 0,
-		sizeof(runtime_transaction_stats));
-	memset(runtime_elision_stats, 0, sizeof(runtime_elision_stats));
-	memset(&walltime_nsecs_stats, 0, sizeof(walltime_nsecs_stats));
-}
-
 static void perf_stat__reset_stats(struct perf_evlist *evlist)
 {
 	struct perf_evsel *evsel;
@@ -309,7 +236,7 @@ static void perf_stat__reset_stats(struct perf_evlist *evlist)
 		perf_evsel__reset_counts(evsel, perf_evsel__nr_cpus(evsel));
 	}
 
-	reset_shadow_stats();
+	perf_stat__reset_shadow_stats();
 }
 
 static int create_perf_stat_counter(struct perf_evsel *evsel)
@@ -346,46 +273,6 @@ static inline int nsec_counter(struct perf_evsel *evsel)
 	return 0;
 }
 
-/*
- * Update various tracking values we maintain to print
- * more semantic information such as miss/hit ratios,
- * instruction rates, etc:
- */
-static void update_shadow_stats(struct perf_evsel *counter, u64 *count,
-				int cpu)
-{
-	int ctx = evsel_context(counter);
-
-	if (perf_evsel__match(counter, SOFTWARE, SW_TASK_CLOCK))
-		update_stats(&runtime_nsecs_stats[cpu], count[0]);
-	else if (perf_evsel__match(counter, HARDWARE, HW_CPU_CYCLES))
-		update_stats(&runtime_cycles_stats[ctx][cpu], count[0]);
-	else if (perf_stat_evsel__is(counter, CYCLES_IN_TX))
-		update_stats(&runtime_transaction_stats[ctx][cpu], count[0]);
-	else if (perf_stat_evsel__is(counter, TRANSACTION_START))
-		update_stats(&runtime_transaction_stats[ctx][cpu], count[0]);
-	else if (perf_stat_evsel__is(counter, ELISION_START))
-		update_stats(&runtime_elision_stats[ctx][cpu], count[0]);
-	else if (perf_evsel__match(counter, HARDWARE, HW_STALLED_CYCLES_FRONTEND))
-		update_stats(&runtime_stalled_cycles_front_stats[ctx][cpu], count[0]);
-	else if (perf_evsel__match(counter, HARDWARE, HW_STALLED_CYCLES_BACKEND))
-		update_stats(&runtime_stalled_cycles_back_stats[ctx][cpu], count[0]);
-	else if (perf_evsel__match(counter, HARDWARE, HW_BRANCH_INSTRUCTIONS))
-		update_stats(&runtime_branches_stats[ctx][cpu], count[0]);
-	else if (perf_evsel__match(counter, HARDWARE, HW_CACHE_REFERENCES))
-		update_stats(&runtime_cacherefs_stats[ctx][cpu], count[0]);
-	else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_L1D))
-		update_stats(&runtime_l1_dcache_stats[ctx][cpu], count[0]);
-	else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_L1I))
-		update_stats(&runtime_ll_cache_stats[ctx][cpu], count[0]);
-	else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_LL))
-		update_stats(&runtime_ll_cache_stats[ctx][cpu], count[0]);
-	else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_DTLB))
-		update_stats(&runtime_dtlb_cache_stats[ctx][cpu], count[0]);
-	else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_ITLB))
-		update_stats(&runtime_itlb_cache_stats[ctx][cpu], count[0]);
-}
-
 static void zero_per_pkg(struct perf_evsel *counter)
 {
 	if (counter->per_pkg_mask)
@@ -446,7 +333,7 @@ static int read_cb(struct perf_evsel *evsel, int cpu, int thread __maybe_unused,
 		perf_counts_values__scale(count, scale, NULL);
 		evsel->counts->cpu[cpu] = *count;
 		if (aggr_mode == AGGR_NONE)
-			update_shadow_stats(evsel, count->values, cpu);
+			perf_stat__update_shadow_stats(evsel, count->values, cpu);
 		break;
 	case AGGR_GLOBAL:
 		aggr->val += count->val;
@@ -494,7 +381,7 @@ static int read_counter_aggr(struct perf_evsel *counter)
 	/*
 	 * Save the full runtime - to allow normalization during printout:
 	 */
-	update_shadow_stats(counter, count, 0);
+	perf_stat__update_shadow_stats(counter, count, 0);
 
 	return 0;
 }
@@ -872,329 +759,6 @@ static void nsec_printout(int id, int nr, struct perf_evsel *evsel, double avg)
 		fprintf(output, "                                   ");
 }
 
-/* used for get_ratio_color() */
-enum grc_type {
-	GRC_STALLED_CYCLES_FE,
-	GRC_STALLED_CYCLES_BE,
-	GRC_CACHE_MISSES,
-	GRC_MAX_NR
-};
-
-static const char *get_ratio_color(enum grc_type type, double ratio)
-{
-	static const double grc_table[GRC_MAX_NR][3] = {
-		[GRC_STALLED_CYCLES_FE] = { 50.0, 30.0, 10.0 },
-		[GRC_STALLED_CYCLES_BE] = { 75.0, 50.0, 20.0 },
-		[GRC_CACHE_MISSES] 	= { 20.0, 10.0, 5.0 },
-	};
-	const char *color = PERF_COLOR_NORMAL;
-
-	if (ratio > grc_table[type][0])
-		color = PERF_COLOR_RED;
-	else if (ratio > grc_table[type][1])
-		color = PERF_COLOR_MAGENTA;
-	else if (ratio > grc_table[type][2])
-		color = PERF_COLOR_YELLOW;
-
-	return color;
-}
-
-static void print_stalled_cycles_frontend(FILE *out, int cpu,
-					  struct perf_evsel *evsel
-					  __maybe_unused, double avg)
-{
-	double total, ratio = 0.0;
-	const char *color;
-	int ctx = evsel_context(evsel);
-
-	total = avg_stats(&runtime_cycles_stats[ctx][cpu]);
-
-	if (total)
-		ratio = avg / total * 100.0;
-
-	color = get_ratio_color(GRC_STALLED_CYCLES_FE, ratio);
-
-	fprintf(out, " #  ");
-	color_fprintf(out, color, "%6.2f%%", ratio);
-	fprintf(out, " frontend cycles idle   ");
-}
-
-static void print_stalled_cycles_backend(FILE *out, int cpu,
-					 struct perf_evsel *evsel
-					 __maybe_unused, double avg)
-{
-	double total, ratio = 0.0;
-	const char *color;
-	int ctx = evsel_context(evsel);
-
-	total = avg_stats(&runtime_cycles_stats[ctx][cpu]);
-
-	if (total)
-		ratio = avg / total * 100.0;
-
-	color = get_ratio_color(GRC_STALLED_CYCLES_BE, ratio);
-
-	fprintf(out, " #  ");
-	color_fprintf(out, color, "%6.2f%%", ratio);
-	fprintf(out, " backend  cycles idle   ");
-}
-
-static void print_branch_misses(FILE *out, int cpu,
-				struct perf_evsel *evsel __maybe_unused,
-				double avg)
-{
-	double total, ratio = 0.0;
-	const char *color;
-	int ctx = evsel_context(evsel);
-
-	total = avg_stats(&runtime_branches_stats[ctx][cpu]);
-
-	if (total)
-		ratio = avg / total * 100.0;
-
-	color = get_ratio_color(GRC_CACHE_MISSES, ratio);
-
-	fprintf(out, " #  ");
-	color_fprintf(out, color, "%6.2f%%", ratio);
-	fprintf(out, " of all branches        ");
-}
-
-static void print_l1_dcache_misses(FILE *out, int cpu,
-				   struct perf_evsel *evsel __maybe_unused,
-				   double avg)
-{
-	double total, ratio = 0.0;
-	const char *color;
-	int ctx = evsel_context(evsel);
-
-	total = avg_stats(&runtime_l1_dcache_stats[ctx][cpu]);
-
-	if (total)
-		ratio = avg / total * 100.0;
-
-	color = get_ratio_color(GRC_CACHE_MISSES, ratio);
-
-	fprintf(out, " #  ");
-	color_fprintf(out, color, "%6.2f%%", ratio);
-	fprintf(out, " of all L1-dcache hits  ");
-}
-
-static void print_l1_icache_misses(FILE *out, int cpu,
-				   struct perf_evsel *evsel __maybe_unused,
-				   double avg)
-{
-	double total, ratio = 0.0;
-	const char *color;
-	int ctx = evsel_context(evsel);
-
-	total = avg_stats(&runtime_l1_icache_stats[ctx][cpu]);
-
-	if (total)
-		ratio = avg / total * 100.0;
-
-	color = get_ratio_color(GRC_CACHE_MISSES, ratio);
-
-	fprintf(out, " #  ");
-	color_fprintf(out, color, "%6.2f%%", ratio);
-	fprintf(out, " of all L1-icache hits  ");
-}
-
-static void print_dtlb_cache_misses(FILE *out, int cpu,
-				    struct perf_evsel *evsel __maybe_unused,
-				    double avg)
-{
-	double total, ratio = 0.0;
-	const char *color;
-	int ctx = evsel_context(evsel);
-
-	total = avg_stats(&runtime_dtlb_cache_stats[ctx][cpu]);
-
-	if (total)
-		ratio = avg / total * 100.0;
-
-	color = get_ratio_color(GRC_CACHE_MISSES, ratio);
-
-	fprintf(out, " #  ");
-	color_fprintf(out, color, "%6.2f%%", ratio);
-	fprintf(out, " of all dTLB cache hits ");
-}
-
-static void print_itlb_cache_misses(FILE *out, int cpu,
-				    struct perf_evsel *evsel __maybe_unused,
-				    double avg)
-{
-	double total, ratio = 0.0;
-	const char *color;
-	int ctx = evsel_context(evsel);
-
-	total = avg_stats(&runtime_itlb_cache_stats[ctx][cpu]);
-
-	if (total)
-		ratio = avg / total * 100.0;
-
-	color = get_ratio_color(GRC_CACHE_MISSES, ratio);
-
-	fprintf(out, " #  ");
-	color_fprintf(out, color, "%6.2f%%", ratio);
-	fprintf(out, " of all iTLB cache hits ");
-}
-
-static void print_ll_cache_misses(FILE *out, int cpu,
-				  struct perf_evsel *evsel __maybe_unused,
-				  double avg)
-{
-	double total, ratio = 0.0;
-	const char *color;
-	int ctx = evsel_context(evsel);
-
-	total = avg_stats(&runtime_ll_cache_stats[ctx][cpu]);
-
-	if (total)
-		ratio = avg / total * 100.0;
-
-	color = get_ratio_color(GRC_CACHE_MISSES, ratio);
-
-	fprintf(out, " #  ");
-	color_fprintf(out, color, "%6.2f%%", ratio);
-	fprintf(out, " of all LL-cache hits   ");
-}
-
-static void print_shadow_stats(FILE *out, struct perf_evsel *evsel,
-			       double avg, int cpu, enum aggr_mode aggr)
-{
-	double total, ratio = 0.0, total2;
-	int ctx = evsel_context(evsel);
-
-	if (perf_evsel__match(evsel, HARDWARE, HW_INSTRUCTIONS)) {
-		total = avg_stats(&runtime_cycles_stats[ctx][cpu]);
-		if (total) {
-			ratio = avg / total;
-			fprintf(out, " #   %5.2f  insns per cycle        ", ratio);
-		} else {
-			fprintf(out, "                                   ");
-		}
-		total = avg_stats(&runtime_stalled_cycles_front_stats[ctx][cpu]);
-		total = max(total, avg_stats(&runtime_stalled_cycles_back_stats[ctx][cpu]));
-
-		if (total && avg) {
-			ratio = total / avg;
-			fprintf(out, "\n");
-			if (aggr == AGGR_NONE)
-				fprintf(out, "        ");
-			fprintf(out, "                                                  #   %5.2f  stalled cycles per insn", ratio);
-		}
-
-	} else if (perf_evsel__match(evsel, HARDWARE, HW_BRANCH_MISSES) &&
-			runtime_branches_stats[ctx][cpu].n != 0) {
-		print_branch_misses(out, cpu, evsel, avg);
-	} else if (
-		evsel->attr.type == PERF_TYPE_HW_CACHE &&
-		evsel->attr.config ==  ( PERF_COUNT_HW_CACHE_L1D |
-					((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
-					((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) &&
-			runtime_l1_dcache_stats[ctx][cpu].n != 0) {
-		print_l1_dcache_misses(out, cpu, evsel, avg);
-	} else if (
-		evsel->attr.type == PERF_TYPE_HW_CACHE &&
-		evsel->attr.config ==  ( PERF_COUNT_HW_CACHE_L1I |
-					((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
-					((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) &&
-			runtime_l1_icache_stats[ctx][cpu].n != 0) {
-		print_l1_icache_misses(out, cpu, evsel, avg);
-	} else if (
-		evsel->attr.type == PERF_TYPE_HW_CACHE &&
-		evsel->attr.config ==  ( PERF_COUNT_HW_CACHE_DTLB |
-					((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
-					((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) &&
-			runtime_dtlb_cache_stats[ctx][cpu].n != 0) {
-		print_dtlb_cache_misses(out, cpu, evsel, avg);
-	} else if (
-		evsel->attr.type == PERF_TYPE_HW_CACHE &&
-		evsel->attr.config ==  ( PERF_COUNT_HW_CACHE_ITLB |
-					((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
-					((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) &&
-			runtime_itlb_cache_stats[ctx][cpu].n != 0) {
-		print_itlb_cache_misses(out, cpu, evsel, avg);
-	} else if (
-		evsel->attr.type == PERF_TYPE_HW_CACHE &&
-		evsel->attr.config ==  ( PERF_COUNT_HW_CACHE_LL |
-					((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
-					((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) &&
-			runtime_ll_cache_stats[ctx][cpu].n != 0) {
-		print_ll_cache_misses(out, cpu, evsel, avg);
-	} else if (perf_evsel__match(evsel, HARDWARE, HW_CACHE_MISSES) &&
-			runtime_cacherefs_stats[ctx][cpu].n != 0) {
-		total = avg_stats(&runtime_cacherefs_stats[ctx][cpu]);
-
-		if (total)
-			ratio = avg * 100 / total;
-
-		fprintf(out, " # %8.3f %% of all cache refs    ", ratio);
-
-	} else if (perf_evsel__match(evsel, HARDWARE, HW_STALLED_CYCLES_FRONTEND)) {
-		print_stalled_cycles_frontend(out, cpu, evsel, avg);
-	} else if (perf_evsel__match(evsel, HARDWARE, HW_STALLED_CYCLES_BACKEND)) {
-		print_stalled_cycles_backend(out, cpu, evsel, avg);
-	} else if (perf_evsel__match(evsel, HARDWARE, HW_CPU_CYCLES)) {
-		total = avg_stats(&runtime_nsecs_stats[cpu]);
-
-		if (total) {
-			ratio = avg / total;
-			fprintf(out, " # %8.3f GHz                    ", ratio);
-		} else {
-			fprintf(out, "                                   ");
-		}
-	} else if (perf_stat_evsel__is(evsel, CYCLES_IN_TX)) {
-		total = avg_stats(&runtime_cycles_stats[ctx][cpu]);
-		if (total)
-			fprintf(out,
-				" #   %5.2f%% transactional cycles   ",
-				100.0 * (avg / total));
-	} else if (perf_stat_evsel__is(evsel, CYCLES_IN_TX_CP)) {
-		total = avg_stats(&runtime_cycles_stats[ctx][cpu]);
-		total2 = avg_stats(&runtime_cycles_in_tx_stats[ctx][cpu]);
-		if (total2 < avg)
-			total2 = avg;
-		if (total)
-			fprintf(out,
-				" #   %5.2f%% aborted cycles         ",
-				100.0 * ((total2-avg) / total));
-	} else if (perf_stat_evsel__is(evsel, TRANSACTION_START) &&
-		   avg > 0 &&
-		   runtime_cycles_in_tx_stats[ctx][cpu].n != 0) {
-		total = avg_stats(&runtime_cycles_in_tx_stats[ctx][cpu]);
-
-		if (total)
-			ratio = total / avg;
-
-		fprintf(out, " # %8.0f cycles / transaction   ", ratio);
-	} else if (perf_stat_evsel__is(evsel, ELISION_START) &&
-		   avg > 0 &&
-		   runtime_cycles_in_tx_stats[ctx][cpu].n != 0) {
-		total = avg_stats(&runtime_cycles_in_tx_stats[ctx][cpu]);
-
-		if (total)
-			ratio = total / avg;
-
-		fprintf(out, " # %8.0f cycles / elision       ", ratio);
-	} else if (runtime_nsecs_stats[cpu].n != 0) {
-		char unit = 'M';
-
-		total = avg_stats(&runtime_nsecs_stats[cpu]);
-
-		if (total)
-			ratio = 1000.0 * avg / total;
-		if (ratio < 0.001) {
-			ratio *= 1000;
-			unit = 'K';
-		}
-
-		fprintf(out, " # %8.3f %c/sec                  ", ratio, unit);
-	} else {
-		fprintf(out, "                                   ");
-	}
-}
-
 static void abs_printout(int id, int nr, struct perf_evsel *evsel, double avg)
 {
 	double sc =  evsel->scale;
@@ -1230,7 +794,7 @@ static void abs_printout(int id, int nr, struct perf_evsel *evsel, double avg)
 	if (csv_output || interval)
 		return;
 
-	print_shadow_stats(output, evsel, avg, cpu, aggr_mode);
+	perf_stat__print_shadow_stats(output, evsel, avg, cpu, aggr_mode);
 }
 
 static void print_aggr(char *prefix)
diff --git a/tools/perf/util/Build b/tools/perf/util/Build
index e4b676de2f64..586a59d46022 100644
--- a/tools/perf/util/Build
+++ b/tools/perf/util/Build
@@ -68,6 +68,7 @@ libperf-y += rblist.o
 libperf-y += intlist.o
 libperf-y += vdso.o
 libperf-y += stat.o
+libperf-y += stat-shadow.o
 libperf-y += record.o
 libperf-y += srcline.o
 libperf-y += data.o
diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c
new file mode 100644
index 000000000000..53e8bb7bc852
--- /dev/null
+++ b/tools/perf/util/stat-shadow.c
@@ -0,0 +1,434 @@
+#include <stdio.h>
+#include "evsel.h"
+#include "stat.h"
+#include "color.h"
+
+enum {
+	CTX_BIT_USER	= 1 << 0,
+	CTX_BIT_KERNEL	= 1 << 1,
+	CTX_BIT_HV	= 1 << 2,
+	CTX_BIT_HOST	= 1 << 3,
+	CTX_BIT_IDLE	= 1 << 4,
+	CTX_BIT_MAX	= 1 << 5,
+};
+
+#define NUM_CTX CTX_BIT_MAX
+
+static struct stats runtime_nsecs_stats[MAX_NR_CPUS];
+static struct stats runtime_cycles_stats[NUM_CTX][MAX_NR_CPUS];
+static struct stats runtime_stalled_cycles_front_stats[NUM_CTX][MAX_NR_CPUS];
+static struct stats runtime_stalled_cycles_back_stats[NUM_CTX][MAX_NR_CPUS];
+static struct stats runtime_branches_stats[NUM_CTX][MAX_NR_CPUS];
+static struct stats runtime_cacherefs_stats[NUM_CTX][MAX_NR_CPUS];
+static struct stats runtime_l1_dcache_stats[NUM_CTX][MAX_NR_CPUS];
+static struct stats runtime_l1_icache_stats[NUM_CTX][MAX_NR_CPUS];
+static struct stats runtime_ll_cache_stats[NUM_CTX][MAX_NR_CPUS];
+static struct stats runtime_itlb_cache_stats[NUM_CTX][MAX_NR_CPUS];
+static struct stats runtime_dtlb_cache_stats[NUM_CTX][MAX_NR_CPUS];
+static struct stats runtime_cycles_in_tx_stats[NUM_CTX][MAX_NR_CPUS];
+static struct stats runtime_transaction_stats[NUM_CTX][MAX_NR_CPUS];
+static struct stats runtime_elision_stats[NUM_CTX][MAX_NR_CPUS];
+
+struct stats walltime_nsecs_stats;
+
+static int evsel_context(struct perf_evsel *evsel)
+{
+	int ctx = 0;
+
+	if (evsel->attr.exclude_kernel)
+		ctx |= CTX_BIT_KERNEL;
+	if (evsel->attr.exclude_user)
+		ctx |= CTX_BIT_USER;
+	if (evsel->attr.exclude_hv)
+		ctx |= CTX_BIT_HV;
+	if (evsel->attr.exclude_host)
+		ctx |= CTX_BIT_HOST;
+	if (evsel->attr.exclude_idle)
+		ctx |= CTX_BIT_IDLE;
+
+	return ctx;
+}
+
+void perf_stat__reset_shadow_stats(void)
+{
+	memset(runtime_nsecs_stats, 0, sizeof(runtime_nsecs_stats));
+	memset(runtime_cycles_stats, 0, sizeof(runtime_cycles_stats));
+	memset(runtime_stalled_cycles_front_stats, 0, sizeof(runtime_stalled_cycles_front_stats));
+	memset(runtime_stalled_cycles_back_stats, 0, sizeof(runtime_stalled_cycles_back_stats));
+	memset(runtime_branches_stats, 0, sizeof(runtime_branches_stats));
+	memset(runtime_cacherefs_stats, 0, sizeof(runtime_cacherefs_stats));
+	memset(runtime_l1_dcache_stats, 0, sizeof(runtime_l1_dcache_stats));
+	memset(runtime_l1_icache_stats, 0, sizeof(runtime_l1_icache_stats));
+	memset(runtime_ll_cache_stats, 0, sizeof(runtime_ll_cache_stats));
+	memset(runtime_itlb_cache_stats, 0, sizeof(runtime_itlb_cache_stats));
+	memset(runtime_dtlb_cache_stats, 0, sizeof(runtime_dtlb_cache_stats));
+	memset(runtime_cycles_in_tx_stats, 0,
+			sizeof(runtime_cycles_in_tx_stats));
+	memset(runtime_transaction_stats, 0,
+		sizeof(runtime_transaction_stats));
+	memset(runtime_elision_stats, 0, sizeof(runtime_elision_stats));
+	memset(&walltime_nsecs_stats, 0, sizeof(walltime_nsecs_stats));
+}
+
+/*
+ * Update various tracking values we maintain to print
+ * more semantic information such as miss/hit ratios,
+ * instruction rates, etc:
+ */
+void perf_stat__update_shadow_stats(struct perf_evsel *counter, u64 *count,
+				    int cpu)
+{
+	int ctx = evsel_context(counter);
+
+	if (perf_evsel__match(counter, SOFTWARE, SW_TASK_CLOCK))
+		update_stats(&runtime_nsecs_stats[cpu], count[0]);
+	else if (perf_evsel__match(counter, HARDWARE, HW_CPU_CYCLES))
+		update_stats(&runtime_cycles_stats[ctx][cpu], count[0]);
+	else if (perf_stat_evsel__is(counter, CYCLES_IN_TX))
+		update_stats(&runtime_transaction_stats[ctx][cpu], count[0]);
+	else if (perf_stat_evsel__is(counter, TRANSACTION_START))
+		update_stats(&runtime_transaction_stats[ctx][cpu], count[0]);
+	else if (perf_stat_evsel__is(counter, ELISION_START))
+		update_stats(&runtime_elision_stats[ctx][cpu], count[0]);
+	else if (perf_evsel__match(counter, HARDWARE, HW_STALLED_CYCLES_FRONTEND))
+		update_stats(&runtime_stalled_cycles_front_stats[ctx][cpu], count[0]);
+	else if (perf_evsel__match(counter, HARDWARE, HW_STALLED_CYCLES_BACKEND))
+		update_stats(&runtime_stalled_cycles_back_stats[ctx][cpu], count[0]);
+	else if (perf_evsel__match(counter, HARDWARE, HW_BRANCH_INSTRUCTIONS))
+		update_stats(&runtime_branches_stats[ctx][cpu], count[0]);
+	else if (perf_evsel__match(counter, HARDWARE, HW_CACHE_REFERENCES))
+		update_stats(&runtime_cacherefs_stats[ctx][cpu], count[0]);
+	else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_L1D))
+		update_stats(&runtime_l1_dcache_stats[ctx][cpu], count[0]);
+	else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_L1I))
+		update_stats(&runtime_ll_cache_stats[ctx][cpu], count[0]);
+	else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_LL))
+		update_stats(&runtime_ll_cache_stats[ctx][cpu], count[0]);
+	else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_DTLB))
+		update_stats(&runtime_dtlb_cache_stats[ctx][cpu], count[0]);
+	else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_ITLB))
+		update_stats(&runtime_itlb_cache_stats[ctx][cpu], count[0]);
+}
+
+/* used for get_ratio_color() */
+enum grc_type {
+	GRC_STALLED_CYCLES_FE,
+	GRC_STALLED_CYCLES_BE,
+	GRC_CACHE_MISSES,
+	GRC_MAX_NR
+};
+
+static const char *get_ratio_color(enum grc_type type, double ratio)
+{
+	static const double grc_table[GRC_MAX_NR][3] = {
+		[GRC_STALLED_CYCLES_FE] = { 50.0, 30.0, 10.0 },
+		[GRC_STALLED_CYCLES_BE] = { 75.0, 50.0, 20.0 },
+		[GRC_CACHE_MISSES] 	= { 20.0, 10.0, 5.0 },
+	};
+	const char *color = PERF_COLOR_NORMAL;
+
+	if (ratio > grc_table[type][0])
+		color = PERF_COLOR_RED;
+	else if (ratio > grc_table[type][1])
+		color = PERF_COLOR_MAGENTA;
+	else if (ratio > grc_table[type][2])
+		color = PERF_COLOR_YELLOW;
+
+	return color;
+}
+
+static void print_stalled_cycles_frontend(FILE *out, int cpu,
+					  struct perf_evsel *evsel
+					  __maybe_unused, double avg)
+{
+	double total, ratio = 0.0;
+	const char *color;
+	int ctx = evsel_context(evsel);
+
+	total = avg_stats(&runtime_cycles_stats[ctx][cpu]);
+
+	if (total)
+		ratio = avg / total * 100.0;
+
+	color = get_ratio_color(GRC_STALLED_CYCLES_FE, ratio);
+
+	fprintf(out, " #  ");
+	color_fprintf(out, color, "%6.2f%%", ratio);
+	fprintf(out, " frontend cycles idle   ");
+}
+
+static void print_stalled_cycles_backend(FILE *out, int cpu,
+					 struct perf_evsel *evsel
+					 __maybe_unused, double avg)
+{
+	double total, ratio = 0.0;
+	const char *color;
+	int ctx = evsel_context(evsel);
+
+	total = avg_stats(&runtime_cycles_stats[ctx][cpu]);
+
+	if (total)
+		ratio = avg / total * 100.0;
+
+	color = get_ratio_color(GRC_STALLED_CYCLES_BE, ratio);
+
+	fprintf(out, " #  ");
+	color_fprintf(out, color, "%6.2f%%", ratio);
+	fprintf(out, " backend  cycles idle   ");
+}
+
+static void print_branch_misses(FILE *out, int cpu,
+				struct perf_evsel *evsel __maybe_unused,
+				double avg)
+{
+	double total, ratio = 0.0;
+	const char *color;
+	int ctx = evsel_context(evsel);
+
+	total = avg_stats(&runtime_branches_stats[ctx][cpu]);
+
+	if (total)
+		ratio = avg / total * 100.0;
+
+	color = get_ratio_color(GRC_CACHE_MISSES, ratio);
+
+	fprintf(out, " #  ");
+	color_fprintf(out, color, "%6.2f%%", ratio);
+	fprintf(out, " of all branches        ");
+}
+
+static void print_l1_dcache_misses(FILE *out, int cpu,
+				   struct perf_evsel *evsel __maybe_unused,
+				   double avg)
+{
+	double total, ratio = 0.0;
+	const char *color;
+	int ctx = evsel_context(evsel);
+
+	total = avg_stats(&runtime_l1_dcache_stats[ctx][cpu]);
+
+	if (total)
+		ratio = avg / total * 100.0;
+
+	color = get_ratio_color(GRC_CACHE_MISSES, ratio);
+
+	fprintf(out, " #  ");
+	color_fprintf(out, color, "%6.2f%%", ratio);
+	fprintf(out, " of all L1-dcache hits  ");
+}
+
+static void print_l1_icache_misses(FILE *out, int cpu,
+				   struct perf_evsel *evsel __maybe_unused,
+				   double avg)
+{
+	double total, ratio = 0.0;
+	const char *color;
+	int ctx = evsel_context(evsel);
+
+	total = avg_stats(&runtime_l1_icache_stats[ctx][cpu]);
+
+	if (total)
+		ratio = avg / total * 100.0;
+
+	color = get_ratio_color(GRC_CACHE_MISSES, ratio);
+
+	fprintf(out, " #  ");
+	color_fprintf(out, color, "%6.2f%%", ratio);
+	fprintf(out, " of all L1-icache hits  ");
+}
+
+static void print_dtlb_cache_misses(FILE *out, int cpu,
+				    struct perf_evsel *evsel __maybe_unused,
+				    double avg)
+{
+	double total, ratio = 0.0;
+	const char *color;
+	int ctx = evsel_context(evsel);
+
+	total = avg_stats(&runtime_dtlb_cache_stats[ctx][cpu]);
+
+	if (total)
+		ratio = avg / total * 100.0;
+
+	color = get_ratio_color(GRC_CACHE_MISSES, ratio);
+
+	fprintf(out, " #  ");
+	color_fprintf(out, color, "%6.2f%%", ratio);
+	fprintf(out, " of all dTLB cache hits ");
+}
+
+static void print_itlb_cache_misses(FILE *out, int cpu,
+				    struct perf_evsel *evsel __maybe_unused,
+				    double avg)
+{
+	double total, ratio = 0.0;
+	const char *color;
+	int ctx = evsel_context(evsel);
+
+	total = avg_stats(&runtime_itlb_cache_stats[ctx][cpu]);
+
+	if (total)
+		ratio = avg / total * 100.0;
+
+	color = get_ratio_color(GRC_CACHE_MISSES, ratio);
+
+	fprintf(out, " #  ");
+	color_fprintf(out, color, "%6.2f%%", ratio);
+	fprintf(out, " of all iTLB cache hits ");
+}
+
+static void print_ll_cache_misses(FILE *out, int cpu,
+				  struct perf_evsel *evsel __maybe_unused,
+				  double avg)
+{
+	double total, ratio = 0.0;
+	const char *color;
+	int ctx = evsel_context(evsel);
+
+	total = avg_stats(&runtime_ll_cache_stats[ctx][cpu]);
+
+	if (total)
+		ratio = avg / total * 100.0;
+
+	color = get_ratio_color(GRC_CACHE_MISSES, ratio);
+
+	fprintf(out, " #  ");
+	color_fprintf(out, color, "%6.2f%%", ratio);
+	fprintf(out, " of all LL-cache hits   ");
+}
+
+void perf_stat__print_shadow_stats(FILE *out, struct perf_evsel *evsel,
+				   double avg, int cpu, enum aggr_mode aggr)
+{
+	double total, ratio = 0.0, total2;
+	int ctx = evsel_context(evsel);
+
+	if (perf_evsel__match(evsel, HARDWARE, HW_INSTRUCTIONS)) {
+		total = avg_stats(&runtime_cycles_stats[ctx][cpu]);
+		if (total) {
+			ratio = avg / total;
+			fprintf(out, " #   %5.2f  insns per cycle        ", ratio);
+		} else {
+			fprintf(out, "                                   ");
+		}
+		total = avg_stats(&runtime_stalled_cycles_front_stats[ctx][cpu]);
+		total = max(total, avg_stats(&runtime_stalled_cycles_back_stats[ctx][cpu]));
+
+		if (total && avg) {
+			ratio = total / avg;
+			fprintf(out, "\n");
+			if (aggr == AGGR_NONE)
+				fprintf(out, "        ");
+			fprintf(out, "                                                  #   %5.2f  stalled cycles per insn", ratio);
+		}
+
+	} else if (perf_evsel__match(evsel, HARDWARE, HW_BRANCH_MISSES) &&
+			runtime_branches_stats[ctx][cpu].n != 0) {
+		print_branch_misses(out, cpu, evsel, avg);
+	} else if (
+		evsel->attr.type == PERF_TYPE_HW_CACHE &&
+		evsel->attr.config ==  ( PERF_COUNT_HW_CACHE_L1D |
+					((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
+					((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) &&
+			runtime_l1_dcache_stats[ctx][cpu].n != 0) {
+		print_l1_dcache_misses(out, cpu, evsel, avg);
+	} else if (
+		evsel->attr.type == PERF_TYPE_HW_CACHE &&
+		evsel->attr.config ==  ( PERF_COUNT_HW_CACHE_L1I |
+					((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
+					((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) &&
+			runtime_l1_icache_stats[ctx][cpu].n != 0) {
+		print_l1_icache_misses(out, cpu, evsel, avg);
+	} else if (
+		evsel->attr.type == PERF_TYPE_HW_CACHE &&
+		evsel->attr.config ==  ( PERF_COUNT_HW_CACHE_DTLB |
+					((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
+					((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) &&
+			runtime_dtlb_cache_stats[ctx][cpu].n != 0) {
+		print_dtlb_cache_misses(out, cpu, evsel, avg);
+	} else if (
+		evsel->attr.type == PERF_TYPE_HW_CACHE &&
+		evsel->attr.config ==  ( PERF_COUNT_HW_CACHE_ITLB |
+					((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
+					((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) &&
+			runtime_itlb_cache_stats[ctx][cpu].n != 0) {
+		print_itlb_cache_misses(out, cpu, evsel, avg);
+	} else if (
+		evsel->attr.type == PERF_TYPE_HW_CACHE &&
+		evsel->attr.config ==  ( PERF_COUNT_HW_CACHE_LL |
+					((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
+					((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) &&
+			runtime_ll_cache_stats[ctx][cpu].n != 0) {
+		print_ll_cache_misses(out, cpu, evsel, avg);
+	} else if (perf_evsel__match(evsel, HARDWARE, HW_CACHE_MISSES) &&
+			runtime_cacherefs_stats[ctx][cpu].n != 0) {
+		total = avg_stats(&runtime_cacherefs_stats[ctx][cpu]);
+
+		if (total)
+			ratio = avg * 100 / total;
+
+		fprintf(out, " # %8.3f %% of all cache refs    ", ratio);
+
+	} else if (perf_evsel__match(evsel, HARDWARE, HW_STALLED_CYCLES_FRONTEND)) {
+		print_stalled_cycles_frontend(out, cpu, evsel, avg);
+	} else if (perf_evsel__match(evsel, HARDWARE, HW_STALLED_CYCLES_BACKEND)) {
+		print_stalled_cycles_backend(out, cpu, evsel, avg);
+	} else if (perf_evsel__match(evsel, HARDWARE, HW_CPU_CYCLES)) {
+		total = avg_stats(&runtime_nsecs_stats[cpu]);
+
+		if (total) {
+			ratio = avg / total;
+			fprintf(out, " # %8.3f GHz                    ", ratio);
+		} else {
+			fprintf(out, "                                   ");
+		}
+	} else if (perf_stat_evsel__is(evsel, CYCLES_IN_TX)) {
+		total = avg_stats(&runtime_cycles_stats[ctx][cpu]);
+		if (total)
+			fprintf(out,
+				" #   %5.2f%% transactional cycles   ",
+				100.0 * (avg / total));
+	} else if (perf_stat_evsel__is(evsel, CYCLES_IN_TX_CP)) {
+		total = avg_stats(&runtime_cycles_stats[ctx][cpu]);
+		total2 = avg_stats(&runtime_cycles_in_tx_stats[ctx][cpu]);
+		if (total2 < avg)
+			total2 = avg;
+		if (total)
+			fprintf(out,
+				" #   %5.2f%% aborted cycles         ",
+				100.0 * ((total2-avg) / total));
+	} else if (perf_stat_evsel__is(evsel, TRANSACTION_START) &&
+		   avg > 0 &&
+		   runtime_cycles_in_tx_stats[ctx][cpu].n != 0) {
+		total = avg_stats(&runtime_cycles_in_tx_stats[ctx][cpu]);
+
+		if (total)
+			ratio = total / avg;
+
+		fprintf(out, " # %8.0f cycles / transaction   ", ratio);
+	} else if (perf_stat_evsel__is(evsel, ELISION_START) &&
+		   avg > 0 &&
+		   runtime_cycles_in_tx_stats[ctx][cpu].n != 0) {
+		total = avg_stats(&runtime_cycles_in_tx_stats[ctx][cpu]);
+
+		if (total)
+			ratio = total / avg;
+
+		fprintf(out, " # %8.0f cycles / elision       ", ratio);
+	} else if (runtime_nsecs_stats[cpu].n != 0) {
+		char unit = 'M';
+
+		total = avg_stats(&runtime_nsecs_stats[cpu]);
+
+		if (total)
+			ratio = 1000.0 * avg / total;
+		if (ratio < 0.001) {
+			ratio *= 1000;
+			unit = 'K';
+		}
+
+		fprintf(out, " # %8.3f %c/sec                  ", ratio, unit);
+	} else {
+		fprintf(out, "                                   ");
+	}
+}
diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h
index 3df529bd0774..615c779eb42a 100644
--- a/tools/perf/util/stat.h
+++ b/tools/perf/util/stat.h
@@ -2,6 +2,7 @@
 #define __PERF_STATS_H
 
 #include <linux/types.h>
+#include <stdio.h>
 
 struct stats
 {
@@ -23,6 +24,13 @@ struct perf_stat {
 	enum perf_stat_evsel_id	id;
 };
 
+enum aggr_mode {
+	AGGR_NONE,
+	AGGR_GLOBAL,
+	AGGR_SOCKET,
+	AGGR_CORE,
+};
+
 void update_stats(struct stats *stats, u64 val);
 double avg_stats(struct stats *stats);
 double stddev_stats(struct stats *stats);
@@ -46,4 +54,12 @@ bool __perf_evsel_stat__is(struct perf_evsel *evsel,
 
 void perf_stat_evsel_id_init(struct perf_evsel *evsel);
 
+extern struct stats walltime_nsecs_stats;
+
+void perf_stat__reset_shadow_stats(void);
+void perf_stat__update_shadow_stats(struct perf_evsel *counter, u64 *count,
+				    int cpu);
+void perf_stat__print_shadow_stats(FILE *out, struct perf_evsel *evsel,
+				   double avg, int cpu, enum aggr_mode aggr);
+
 #endif
-- 
1.9.3


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

* Re: [PATCH 4/9] perf stat: Remove transaction_run from shadow update/print code
  2015-06-03 14:25 ` [PATCH 4/9] perf stat: Remove transaction_run from shadow update/print code Jiri Olsa
@ 2015-06-03 15:10   ` Arnaldo Carvalho de Melo
  2015-06-03 15:14     ` Jiri Olsa
  2015-06-09  9:49   ` [tip:perf/core] " tip-bot for Jiri Olsa
  1 sibling, 1 reply; 30+ messages in thread
From: Arnaldo Carvalho de Melo @ 2015-06-03 15:10 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: lkml, Peter Zijlstra, Paul Mackerras, David Ahern, Namhyung Kim,
	Ingo Molnar, Andi Kleen, Stephane Eranian

Em Wed, Jun 03, 2015 at 04:25:54PM +0200, Jiri Olsa escreveu:
> It's no longer needed, because we use nameid to recognize
> transaction events.
> 
> Keeping it only in stat code to initialize transaction events.

Lemme see if I understand this correctly, this update_shadow_stats() is
called only for transaction runs?

It doesn't seem so, so now we will update those stats all the time?

- Arnaldo
 
> Link: http://lkml.kernel.org/n/tip-eo93tek7cjy8zqdvfd6f5a4x@git.kernel.org
> Signed-off-by: Jiri Olsa <jolsa@kernel.org>
> ---
>  tools/perf/builtin-stat.c | 14 +++++++-------
>  1 file changed, 7 insertions(+), 7 deletions(-)
> 
> diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
> index 0c0071cf4fba..b3e08ce2c564 100644
> --- a/tools/perf/builtin-stat.c
> +++ b/tools/perf/builtin-stat.c
> @@ -355,11 +355,11 @@ static void update_shadow_stats(struct perf_evsel *counter, u64 *count,
>  		update_stats(&runtime_nsecs_stats[cpu], count[0]);
>  	else if (perf_evsel__match(counter, HARDWARE, HW_CPU_CYCLES))
>  		update_stats(&runtime_cycles_stats[ctx][cpu], count[0]);
> -	else if (transaction_run && perf_stat_evsel__is(counter, CYCLES_IN_TX))
> +	else if (perf_stat_evsel__is(counter, CYCLES_IN_TX))
>  		update_stats(&runtime_transaction_stats[ctx][cpu], count[0]);
> -	else if (transaction_run && perf_stat_evsel__is(counter, TRANSACTION_START))
> +	else if (perf_stat_evsel__is(counter, TRANSACTION_START))
>  		update_stats(&runtime_transaction_stats[ctx][cpu], count[0]);
> -	else if (transaction_run && perf_stat_evsel__is(counter, ELISION_START))
> +	else if (perf_stat_evsel__is(counter, ELISION_START))
>  		update_stats(&runtime_elision_stats[ctx][cpu], count[0]);
>  	else if (perf_evsel__match(counter, HARDWARE, HW_STALLED_CYCLES_FRONTEND))
>  		update_stats(&runtime_stalled_cycles_front_stats[ctx][cpu], count[0]);
> @@ -1170,13 +1170,13 @@ static void abs_printout(int id, int nr, struct perf_evsel *evsel, double avg)
>  		} else {
>  			fprintf(output, "                                   ");
>  		}
> -	} else if (transaction_run && perf_stat_evsel__is(evsel, CYCLES_IN_TX)) {
> +	} else if (perf_stat_evsel__is(evsel, CYCLES_IN_TX)) {
>  		total = avg_stats(&runtime_cycles_stats[ctx][cpu]);
>  		if (total)
>  			fprintf(output,
>  				" #   %5.2f%% transactional cycles   ",
>  				100.0 * (avg / total));
> -	} else if (transaction_run && perf_stat_evsel__is(evsel, CYCLES_IN_TX_CP)) {
> +	} else if (perf_stat_evsel__is(evsel, CYCLES_IN_TX_CP)) {
>  		total = avg_stats(&runtime_cycles_stats[ctx][cpu]);
>  		total2 = avg_stats(&runtime_cycles_in_tx_stats[ctx][cpu]);
>  		if (total2 < avg)
> @@ -1185,7 +1185,7 @@ static void abs_printout(int id, int nr, struct perf_evsel *evsel, double avg)
>  			fprintf(output,
>  				" #   %5.2f%% aborted cycles         ",
>  				100.0 * ((total2-avg) / total));
> -	} else if (transaction_run && perf_stat_evsel__is(evsel, TRANSACTION_START) &&
> +	} else if (perf_stat_evsel__is(evsel, TRANSACTION_START) &&
>  		   avg > 0 &&
>  		   runtime_cycles_in_tx_stats[ctx][cpu].n != 0) {
>  		total = avg_stats(&runtime_cycles_in_tx_stats[ctx][cpu]);
> @@ -1194,7 +1194,7 @@ static void abs_printout(int id, int nr, struct perf_evsel *evsel, double avg)
>  			ratio = total / avg;
>  
>  		fprintf(output, " # %8.0f cycles / transaction   ", ratio);
> -	} else if (transaction_run && perf_stat_evsel__is(evsel, ELISION_START) &&
> +	} else if (perf_stat_evsel__is(evsel, ELISION_START) &&
>  		   avg > 0 &&
>  		   runtime_cycles_in_tx_stats[ctx][cpu].n != 0) {
>  		total = avg_stats(&runtime_cycles_in_tx_stats[ctx][cpu]);
> -- 
> 1.9.3

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

* Re: [PATCH 4/9] perf stat: Remove transaction_run from shadow update/print code
  2015-06-03 15:10   ` Arnaldo Carvalho de Melo
@ 2015-06-03 15:14     ` Jiri Olsa
  2015-06-03 15:55       ` Arnaldo Carvalho de Melo
  0 siblings, 1 reply; 30+ messages in thread
From: Jiri Olsa @ 2015-06-03 15:14 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Jiri Olsa, lkml, Peter Zijlstra, Paul Mackerras, David Ahern,
	Namhyung Kim, Ingo Molnar, Andi Kleen, Stephane Eranian

On Wed, Jun 03, 2015 at 12:10:38PM -0300, Arnaldo Carvalho de Melo wrote:
> Em Wed, Jun 03, 2015 at 04:25:54PM +0200, Jiri Olsa escreveu:
> > It's no longer needed, because we use nameid to recognize
> > transaction events.
> > 
> > Keeping it only in stat code to initialize transaction events.
> 
> Lemme see if I understand this correctly, this update_shadow_stats() is
> called only for transaction runs?
> 
> It doesn't seem so, so now we will update those stats all the time?

update_shadow_stats is called on currently read/processed
counter and based on its 'type' we update various other
counters - shadow counters - which are the base for things
like IPC in the stat output

jirka

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

* Re: [PATCH 4/9] perf stat: Remove transaction_run from shadow update/print code
  2015-06-03 15:14     ` Jiri Olsa
@ 2015-06-03 15:55       ` Arnaldo Carvalho de Melo
  0 siblings, 0 replies; 30+ messages in thread
From: Arnaldo Carvalho de Melo @ 2015-06-03 15:55 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: Jiri Olsa, lkml, Peter Zijlstra, Paul Mackerras, David Ahern,
	Namhyung Kim, Ingo Molnar, Andi Kleen, Stephane Eranian

Em Wed, Jun 03, 2015 at 05:14:50PM +0200, Jiri Olsa escreveu:
> On Wed, Jun 03, 2015 at 12:10:38PM -0300, Arnaldo Carvalho de Melo wrote:
> > Em Wed, Jun 03, 2015 at 04:25:54PM +0200, Jiri Olsa escreveu:
> > > It's no longer needed, because we use nameid to recognize
> > > transaction events.
> > > 
> > > Keeping it only in stat code to initialize transaction events.
> > 
> > Lemme see if I understand this correctly, this update_shadow_stats() is
> > called only for transaction runs?
> > 
> > It doesn't seem so, so now we will update those stats all the time?
> 
> update_shadow_stats is called on currently read/processed
> counter and based on its 'type' we update various other
> counters - shadow counters - which are the base for things
> like IPC in the stat output


So:

-       else if (transaction_run && perf_stat_evsel__is(counter, CYCLES_IN_TX))
+       else if (perf_stat_evsel__is(counter, CYCLES_IN_TX))
                update_stats(&runtime_transaction_stats[ctx][cpu], count[0]);


Before we were going to check this _only_ when transaction_run was set,
now we are doing it always, or are you saying that
perf_stat_evsel__is(counter, CYCLES_IN_TX) will only return true for
transaction 'perf stat' usage?

Let me take a look:

Yes, in all cases we, start doing:

   perf_evlist__alloc_stats()
     perf_evsel__alloc_stat_priv()
       perf_evsel__reset_stat_priv()
         perf_stat_evsel_id_init();
           struct perf_stat *ps = evsel->priv;
           ps->id = one of the entries below:

static const char *id_str[PERF_STAT_EVSEL_ID__MAX] = {
        ID(NONE,                x),
        ID(CYCLES_IN_TX,        cpu/cycles-t/),
        ID(TRANSACTION_START,   cpu/tx-start/),
        ID(ELISION_START,       cpu/el-start/),
        ID(CYCLES_IN_TX_CP,     cpu/cycles-ct/),
};


Ok, guess I understood now, all the events above are transaction events,
so if one of them is present, then, yes, this is a transaction run, and
we don't need to look at the 'transaction_run' variable to update the
shadow stats, got it right?

I.e. we _never_ needed to look at 'transaction_id', just noticing that
ps->id is not zero, ok.

- Arnaldo

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

* Re: [PATCHv2 0/9] perf stat: Separate shadow counters code
  2015-06-03 14:25 [PATCHv2 0/9] perf stat: Separate shadow counters code Jiri Olsa
                   ` (8 preceding siblings ...)
  2015-06-03 14:25 ` [PATCH 9/9] perf stat: Move shadow stat counters into separate object Jiri Olsa
@ 2015-06-03 22:07 ` Arnaldo Carvalho de Melo
  2015-06-03 22:24   ` Arnaldo Carvalho de Melo
  9 siblings, 1 reply; 30+ messages in thread
From: Arnaldo Carvalho de Melo @ 2015-06-03 22:07 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: lkml, Peter Zijlstra, Paul Mackerras, David Ahern, Namhyung Kim,
	Ingo Molnar, Andi Kleen, Stephane Eranian

Em Wed, Jun 03, 2015 at 04:25:50PM +0200, Jiri Olsa escreveu:
> hi,
> sending cleanup/move of shadow counters. I need it
> for my other changes of stat scripting, but I think
> it can stand alone as a cleanup.
> 
> v2 changes:
>   - move evsel id into 'struct perf_stat'
>     and change the id functions namespace

Thanks, applied.

- Arnaldo

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

* Re: [PATCHv2 0/9] perf stat: Separate shadow counters code
  2015-06-03 22:07 ` [PATCHv2 0/9] perf stat: Separate shadow counters code Arnaldo Carvalho de Melo
@ 2015-06-03 22:24   ` Arnaldo Carvalho de Melo
  2015-06-03 22:38     ` Jiri Olsa
  0 siblings, 1 reply; 30+ messages in thread
From: Arnaldo Carvalho de Melo @ 2015-06-03 22:24 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: lkml, Peter Zijlstra, Paul Mackerras, David Ahern, Namhyung Kim,
	Ingo Molnar, Andi Kleen, Stephane Eranian

Em Wed, Jun 03, 2015 at 07:07:05PM -0300, Arnaldo Carvalho de Melo escreveu:
> Em Wed, Jun 03, 2015 at 04:25:50PM +0200, Jiri Olsa escreveu:
> > hi,
> > sending cleanup/move of shadow counters. I need it
> > for my other changes of stat scripting, but I think
> > it can stand alone as a cleanup.
> > 
> > v2 changes:
> >   - move evsel id into 'struct perf_stat'
> >     and change the id functions namespace
> 
> Thanks, applied.

15: struct perf_event_attr setup                             :sh: line 1: 27101 Segmentation fault      (core dumped) PERF_TEST_ATTR=/tmp/tmptb9pWi /home/acme/bin/perf stat -o /tmp/tmptb9pWi/perf.data kill > /dev/null 2>&1
sh: line 1: 27104 Segmentation fault      (core dumped) PERF_TEST_ATTR=/tmp/tmpWgRK9D /home/acme/bin/perf stat -o /tmp/tmpWgRK9D/perf.data -d kill > /dev/null 2>&1
sh: line 1: 27107 Segmentation fault      (core dumped) PERF_TEST_ATTR=/tmp/tmpmCOyBe /home/acme/bin/perf stat -o /tmp/tmpmCOyBe/perf.data -dd kill > /dev/null 2>&1
sh: line 1: 27110 Segmentation fault      (core dumped) PERF_TEST_ATTR=/tmp/tmpJP9x2e /home/acme/bin/perf stat -o /tmp/tmpJP9x2e/perf.data -ddd kill > /dev/null 2>&1
 Ok

Can you please check?

- Arnaldo

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

* Re: [PATCHv2 0/9] perf stat: Separate shadow counters code
  2015-06-03 22:24   ` Arnaldo Carvalho de Melo
@ 2015-06-03 22:38     ` Jiri Olsa
  2015-06-03 22:42       ` Arnaldo Carvalho de Melo
  0 siblings, 1 reply; 30+ messages in thread
From: Jiri Olsa @ 2015-06-03 22:38 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Jiri Olsa, lkml, Peter Zijlstra, Paul Mackerras, David Ahern,
	Namhyung Kim, Ingo Molnar, Andi Kleen, Stephane Eranian

On Wed, Jun 03, 2015 at 07:24:53PM -0300, Arnaldo Carvalho de Melo wrote:
> Em Wed, Jun 03, 2015 at 07:07:05PM -0300, Arnaldo Carvalho de Melo escreveu:
> > Em Wed, Jun 03, 2015 at 04:25:50PM +0200, Jiri Olsa escreveu:
> > > hi,
> > > sending cleanup/move of shadow counters. I need it
> > > for my other changes of stat scripting, but I think
> > > it can stand alone as a cleanup.
> > > 
> > > v2 changes:
> > >   - move evsel id into 'struct perf_stat'
> > >     and change the id functions namespace
> > 
> > Thanks, applied.
> 
> 15: struct perf_event_attr setup                             :sh: line 1: 27101 Segmentation fault      (core dumped) PERF_TEST_ATTR=/tmp/tmptb9pWi /home/acme/bin/perf stat -o /tmp/tmptb9pWi/perf.data kill > /dev/null 2>&1
> sh: line 1: 27104 Segmentation fault      (core dumped) PERF_TEST_ATTR=/tmp/tmpWgRK9D /home/acme/bin/perf stat -o /tmp/tmpWgRK9D/perf.data -d kill > /dev/null 2>&1
> sh: line 1: 27107 Segmentation fault      (core dumped) PERF_TEST_ATTR=/tmp/tmpmCOyBe /home/acme/bin/perf stat -o /tmp/tmpmCOyBe/perf.data -dd kill > /dev/null 2>&1
> sh: line 1: 27110 Segmentation fault      (core dumped) PERF_TEST_ATTR=/tmp/tmpJP9x2e /home/acme/bin/perf stat -o /tmp/tmpJP9x2e/perf.data -ddd kill > /dev/null 2>&1
>  Ok
> 
> Can you please check?

arghh.. sry, I remember running tests :-\ really ;-)
it's the -d default events that do not set evsel->name

attached patch fixes it, but I'll send v3 for the first patch

thanks,
jirka


---
diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c
index d22791d02db0..dba762da5679 100644
--- a/tools/perf/util/stat.c
+++ b/tools/perf/util/stat.c
@@ -88,7 +88,7 @@ void perf_stat_evsel_id_init(struct perf_evsel *evsel)
 	/* ps->id is 0 hence PERF_STAT_EVSEL_ID__NONE by default */
 
 	for (i = 0; i < PERF_STAT_EVSEL_ID__MAX; i++) {
-		if (!strcmp(evsel->name, id_str[i])) {
+		if (evsel->name && !strcmp(evsel->name, id_str[i])) {
 			ps->id = i;
 			break;
 		}

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

* Re: [PATCHv2 0/9] perf stat: Separate shadow counters code
  2015-06-03 22:38     ` Jiri Olsa
@ 2015-06-03 22:42       ` Arnaldo Carvalho de Melo
  2015-06-04 13:49         ` Jiri Olsa
  0 siblings, 1 reply; 30+ messages in thread
From: Arnaldo Carvalho de Melo @ 2015-06-03 22:42 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: Jiri Olsa, lkml, Peter Zijlstra, Paul Mackerras, David Ahern,
	Namhyung Kim, Ingo Molnar, Andi Kleen, Stephane Eranian

Em Thu, Jun 04, 2015 at 12:38:24AM +0200, Jiri Olsa escreveu:
> On Wed, Jun 03, 2015 at 07:24:53PM -0300, Arnaldo Carvalho de Melo wrote:
> > Em Wed, Jun 03, 2015 at 07:07:05PM -0300, Arnaldo Carvalho de Melo escreveu:
> > > Em Wed, Jun 03, 2015 at 04:25:50PM +0200, Jiri Olsa escreveu:
> > > > hi,
> > > > sending cleanup/move of shadow counters. I need it
> > > > for my other changes of stat scripting, but I think
> > > > it can stand alone as a cleanup.
> > > > 
> > > > v2 changes:
> > > >   - move evsel id into 'struct perf_stat'
> > > >     and change the id functions namespace
> > > 
> > > Thanks, applied.
> > 
> > 15: struct perf_event_attr setup                             :sh: line 1: 27101 Segmentation fault      (core dumped) PERF_TEST_ATTR=/tmp/tmptb9pWi /home/acme/bin/perf stat -o /tmp/tmptb9pWi/perf.data kill > /dev/null 2>&1
> > sh: line 1: 27104 Segmentation fault      (core dumped) PERF_TEST_ATTR=/tmp/tmpWgRK9D /home/acme/bin/perf stat -o /tmp/tmpWgRK9D/perf.data -d kill > /dev/null 2>&1
> > sh: line 1: 27107 Segmentation fault      (core dumped) PERF_TEST_ATTR=/tmp/tmpmCOyBe /home/acme/bin/perf stat -o /tmp/tmpmCOyBe/perf.data -dd kill > /dev/null 2>&1
> > sh: line 1: 27110 Segmentation fault      (core dumped) PERF_TEST_ATTR=/tmp/tmpJP9x2e /home/acme/bin/perf stat -o /tmp/tmpJP9x2e/perf.data -ddd kill > /dev/null 2>&1
> >  Ok
> > 
> > Can you please check?
> 
> arghh.. sry, I remember running tests :-\ really ;-)
> it's the -d default events that do not set evsel->name

> attached patch fixes it, but I'll send v3 for the first patch
> 
> thanks,
> jirka
> 
> 
> ---
> diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c
> index d22791d02db0..dba762da5679 100644
> --- a/tools/perf/util/stat.c
> +++ b/tools/perf/util/stat.c
> @@ -88,7 +88,7 @@ void perf_stat_evsel_id_init(struct perf_evsel *evsel)
>  	/* ps->id is 0 hence PERF_STAT_EVSEL_ID__NONE by default */
>  
>  	for (i = 0; i < PERF_STAT_EVSEL_ID__MAX; i++) {
> -		if (!strcmp(evsel->name, id_str[i])) {
> +		if (evsel->name && !strcmp(evsel->name, id_str[i])) {

Why not use perf_evsel__name() then?

>  			ps->id = i;
>  			break;
>  		}

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

* Re: [PATCHv2 0/9] perf stat: Separate shadow counters code
  2015-06-03 22:42       ` Arnaldo Carvalho de Melo
@ 2015-06-04 13:49         ` Jiri Olsa
  0 siblings, 0 replies; 30+ messages in thread
From: Jiri Olsa @ 2015-06-04 13:49 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Jiri Olsa, lkml, Peter Zijlstra, Paul Mackerras, David Ahern,
	Namhyung Kim, Ingo Molnar, Andi Kleen, Stephane Eranian

On Wed, Jun 03, 2015 at 07:42:00PM -0300, Arnaldo Carvalho de Melo wrote:
> Em Thu, Jun 04, 2015 at 12:38:24AM +0200, Jiri Olsa escreveu:
> > On Wed, Jun 03, 2015 at 07:24:53PM -0300, Arnaldo Carvalho de Melo wrote:
> > > Em Wed, Jun 03, 2015 at 07:07:05PM -0300, Arnaldo Carvalho de Melo escreveu:
> > > > Em Wed, Jun 03, 2015 at 04:25:50PM +0200, Jiri Olsa escreveu:
> > > > > hi,
> > > > > sending cleanup/move of shadow counters. I need it
> > > > > for my other changes of stat scripting, but I think
> > > > > it can stand alone as a cleanup.
> > > > > 
> > > > > v2 changes:
> > > > >   - move evsel id into 'struct perf_stat'
> > > > >     and change the id functions namespace
> > > > 
> > > > Thanks, applied.
> > > 
> > > 15: struct perf_event_attr setup                             :sh: line 1: 27101 Segmentation fault      (core dumped) PERF_TEST_ATTR=/tmp/tmptb9pWi /home/acme/bin/perf stat -o /tmp/tmptb9pWi/perf.data kill > /dev/null 2>&1
> > > sh: line 1: 27104 Segmentation fault      (core dumped) PERF_TEST_ATTR=/tmp/tmpWgRK9D /home/acme/bin/perf stat -o /tmp/tmpWgRK9D/perf.data -d kill > /dev/null 2>&1
> > > sh: line 1: 27107 Segmentation fault      (core dumped) PERF_TEST_ATTR=/tmp/tmpmCOyBe /home/acme/bin/perf stat -o /tmp/tmpmCOyBe/perf.data -dd kill > /dev/null 2>&1
> > > sh: line 1: 27110 Segmentation fault      (core dumped) PERF_TEST_ATTR=/tmp/tmpJP9x2e /home/acme/bin/perf stat -o /tmp/tmpJP9x2e/perf.data -ddd kill > /dev/null 2>&1
> > >  Ok
> > > 
> > > Can you please check?
> > 
> > arghh.. sry, I remember running tests :-\ really ;-)
> > it's the -d default events that do not set evsel->name
> 
> > attached patch fixes it, but I'll send v3 for the first patch
> > 
> > thanks,
> > jirka
> > 
> > 
> > ---
> > diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c
> > index d22791d02db0..dba762da5679 100644
> > --- a/tools/perf/util/stat.c
> > +++ b/tools/perf/util/stat.c
> > @@ -88,7 +88,7 @@ void perf_stat_evsel_id_init(struct perf_evsel *evsel)
> >  	/* ps->id is 0 hence PERF_STAT_EVSEL_ID__NONE by default */
> >  
> >  	for (i = 0; i < PERF_STAT_EVSEL_ID__MAX; i++) {
> > -		if (!strcmp(evsel->name, id_str[i])) {
> > +		if (evsel->name && !strcmp(evsel->name, id_str[i])) {
> 
> Why not use perf_evsel__name() then?

right, I'll repost v3 for first patch in a few

jirka

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

* [PATCHv3] perf stat: Add id into perf_stat struct
  2015-06-03 14:25 ` [PATCH 1/9] perf stat: Add id into perf_stat struct Jiri Olsa
@ 2015-06-04 13:50   ` Jiri Olsa
  2015-06-08 14:03     ` Arnaldo Carvalho de Melo
  2015-06-09  9:48     ` [tip:perf/core] " tip-bot for Jiri Olsa
  0 siblings, 2 replies; 30+ messages in thread
From: Jiri Olsa @ 2015-06-04 13:50 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: Arnaldo Carvalho de Melo, lkml, Peter Zijlstra, Paul Mackerras,
	David Ahern, Namhyung Kim, Ingo Molnar, Andi Kleen,
	Stephane Eranian

On Wed, Jun 03, 2015 at 04:25:51PM +0200, Jiri Olsa wrote:
> We need fast way to identify evsel as transaction event
> for shadow counters computation. Currently we are using
> possition (in evlist) based way.
> 
> Adding 'id' into 'struct perf_stat' so it can carry transaction
> event ID and we can use it for shadow counters computations.
> 
> Link: http://lkml.kernel.org/n/tip-9lnvjksibrs0flhkpix2qkm9@git.kernel.org
> Signed-off-by: Jiri Olsa <jolsa@kernel.org>
> ---

using perf_evsel__name instead of evsel->name pointer

jirka

---
We need fast way to identify evsel as transaction event
for shadow counters computation. Currently we are using
possition (in evlist) based way.

Adding 'id' into 'struct perf_stat' so it can carry transaction
event ID and we can use it for shadow counters computations.

Link: http://lkml.kernel.org/n/tip-9lnvjksibrs0flhkpix2qkm9@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/builtin-stat.c |  6 ++----
 tools/perf/util/stat.c    | 31 ++++++++++++++++++++++++++++++-
 tools/perf/util/stat.h    | 20 ++++++++++++++++++++
 3 files changed, 52 insertions(+), 5 deletions(-)

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index fd577f725d23..a6ae1007f1f9 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -147,10 +147,6 @@ static int			(*aggr_get_id)(struct cpu_map *m, int cpu);
 
 static volatile int done = 0;
 
-struct perf_stat {
-	struct stats	  res_stats[3];
-};
-
 static inline void diff_timespec(struct timespec *r, struct timespec *a,
 				 struct timespec *b)
 {
@@ -180,6 +176,8 @@ static void perf_evsel__reset_stat_priv(struct perf_evsel *evsel)
 
 	for (i = 0; i < 3; i++)
 		init_stats(&ps->res_stats[i]);
+
+	perf_stat_evsel_id_init(evsel);
 }
 
 static int perf_evsel__alloc_stat_priv(struct perf_evsel *evsel)
diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c
index 6506b3dfb605..8e9f6bb7581b 100644
--- a/tools/perf/util/stat.c
+++ b/tools/perf/util/stat.c
@@ -1,6 +1,6 @@
 #include <math.h>
-
 #include "stat.h"
+#include "evsel.h"
 
 void update_stats(struct stats *stats, u64 val)
 {
@@ -61,3 +61,32 @@ double rel_stddev_stats(double stddev, double avg)
 
 	return pct;
 }
+
+bool __perf_evsel_stat__is(struct perf_evsel *evsel,
+			   enum perf_stat_evsel_id id)
+{
+	struct perf_stat *ps = evsel->priv;
+
+	return ps->id == id;
+}
+
+#define ID(id, name) [PERF_STAT_EVSEL_ID__##id] = #name
+static const char *id_str[PERF_STAT_EVSEL_ID__MAX] = {
+	ID(NONE, x),
+};
+#undef ID
+
+void perf_stat_evsel_id_init(struct perf_evsel *evsel)
+{
+	struct perf_stat *ps = evsel->priv;
+	int i;
+
+	/* ps->id is 0 hence PERF_STAT_EVSEL_ID__NONE by default */
+
+	for (i = 0; i < PERF_STAT_EVSEL_ID__MAX; i++) {
+		if (!strcmp(perf_evsel__name(evsel), id_str[i])) {
+			ps->id = i;
+			break;
+		}
+	}
+}
diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h
index 5667fc3e39cf..f4136cfd3cc9 100644
--- a/tools/perf/util/stat.h
+++ b/tools/perf/util/stat.h
@@ -9,6 +9,16 @@ struct stats
 	u64 max, min;
 };
 
+enum perf_stat_evsel_id {
+	PERF_STAT_EVSEL_ID__NONE = 0,
+	PERF_STAT_EVSEL_ID__MAX,
+};
+
+struct perf_stat {
+	struct stats		res_stats[3];
+	enum perf_stat_evsel_id	id;
+};
+
 void update_stats(struct stats *stats, u64 val);
 double avg_stats(struct stats *stats);
 double stddev_stats(struct stats *stats);
@@ -22,4 +32,14 @@ static inline void init_stats(struct stats *stats)
 	stats->min  = (u64) -1;
 	stats->max  = 0;
 }
+
+struct perf_evsel;
+bool __perf_evsel_stat__is(struct perf_evsel *evsel,
+			   enum perf_stat_evsel_id id);
+
+#define perf_stat_evsel__is(evsel, id) \
+	__perf_evsel_stat__is(evsel, PERF_STAT_EVSEL_ID__ ## id)
+
+void perf_stat_evsel_id_init(struct perf_evsel *evsel);
+
 #endif
-- 
1.9.3


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

* Re: [PATCHv3] perf stat: Add id into perf_stat struct
  2015-06-04 13:50   ` [PATCHv3] " Jiri Olsa
@ 2015-06-08 14:03     ` Arnaldo Carvalho de Melo
  2015-06-09 20:09       ` Jiri Olsa
  2015-06-09  9:48     ` [tip:perf/core] " tip-bot for Jiri Olsa
  1 sibling, 1 reply; 30+ messages in thread
From: Arnaldo Carvalho de Melo @ 2015-06-08 14:03 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: Jiri Olsa, lkml, Peter Zijlstra, Paul Mackerras, David Ahern,
	Namhyung Kim, Ingo Molnar, Andi Kleen, Stephane Eranian

Em Thu, Jun 04, 2015 at 03:50:55PM +0200, Jiri Olsa escreveu:
> On Wed, Jun 03, 2015 at 04:25:51PM +0200, Jiri Olsa wrote:
> > We need fast way to identify evsel as transaction event
> > for shadow counters computation. Currently we are using
> > possition (in evlist) based way.
> > 
> > Adding 'id' into 'struct perf_stat' so it can carry transaction
> > event ID and we can use it for shadow counters computations.
> > 
> > Link: http://lkml.kernel.org/n/tip-9lnvjksibrs0flhkpix2qkm9@git.kernel.org
> > Signed-off-by: Jiri Olsa <jolsa@kernel.org>
> > ---
> 
> using perf_evsel__name instead of evsel->name pointer

It now passes 'perf test' on rhel7/fedora21 systems, but it fails on a
rhel6 system, I applied it, will test it further on the rhel6 system to
see what went wrong there, unless you do it first ;-)

[root@sandy ~]# perf test 15
15: struct perf_event_attr setup                             :sh: line
1:  5381 Aborted                 (core dumped)
PERF_TEST_ATTR=/tmp/tmp8ZBLwc /home/acme/bin/perf stat -o
/tmp/tmp8ZBLwc/perf.data --group -e cycles,instructions kill > /dev/null
2>&1
sh: line 1:  5438 Aborted                 (core dumped)
PERF_TEST_ATTR=/tmp/tmpnRDADB /home/acme/bin/perf stat -o
/tmp/tmpnRDADB/perf.data -e '{cycles,instructions}' kill > /dev/null
2>&1
 Ok
[root@sandy ~]# uname -r
2.6.32-504.8.1.el6.x86_64
[root@sandy ~]# cat /etc/redhat-release 
Red Hat Enterprise Linux Server release 6.6 (Santiago)
[root@sandy ~]# 

- Arnaldo



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

* [tip:perf/core] perf stat: Add id into perf_stat struct
  2015-06-04 13:50   ` [PATCHv3] " Jiri Olsa
  2015-06-08 14:03     ` Arnaldo Carvalho de Melo
@ 2015-06-09  9:48     ` tip-bot for Jiri Olsa
  1 sibling, 0 replies; 30+ messages in thread
From: tip-bot for Jiri Olsa @ 2015-06-09  9:48 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, eranian, jolsa, jolsa, acme, hpa, namhyung, mingo,
	ak, a.p.zijlstra, tglx, dsahern

Commit-ID:  e2f56da1d6670070f6f55d43007cb7b03ee04c2f
Gitweb:     http://git.kernel.org/tip/e2f56da1d6670070f6f55d43007cb7b03ee04c2f
Author:     Jiri Olsa <jolsa@redhat.com>
AuthorDate: Thu, 4 Jun 2015 15:50:55 +0200
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Mon, 8 Jun 2015 10:30:30 -0300

perf stat: Add id into perf_stat struct

We need fast way to identify evsel as transaction event for shadow
counters computation. Currently we are using possition (in evlist) based
way.

Adding 'id' into 'struct perf_stat' so it can carry transaction event ID
and we can use it for shadow counters computations.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/20150604135055.GB23625@krava.redhat.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/builtin-stat.c |  6 ++----
 tools/perf/util/stat.c    | 31 ++++++++++++++++++++++++++++++-
 tools/perf/util/stat.h    | 20 ++++++++++++++++++++
 3 files changed, 52 insertions(+), 5 deletions(-)

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index fd577f7..a6ae100 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -147,10 +147,6 @@ static int			(*aggr_get_id)(struct cpu_map *m, int cpu);
 
 static volatile int done = 0;
 
-struct perf_stat {
-	struct stats	  res_stats[3];
-};
-
 static inline void diff_timespec(struct timespec *r, struct timespec *a,
 				 struct timespec *b)
 {
@@ -180,6 +176,8 @@ static void perf_evsel__reset_stat_priv(struct perf_evsel *evsel)
 
 	for (i = 0; i < 3; i++)
 		init_stats(&ps->res_stats[i]);
+
+	perf_stat_evsel_id_init(evsel);
 }
 
 static int perf_evsel__alloc_stat_priv(struct perf_evsel *evsel)
diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c
index 6506b3d..8e9f6bb 100644
--- a/tools/perf/util/stat.c
+++ b/tools/perf/util/stat.c
@@ -1,6 +1,6 @@
 #include <math.h>
-
 #include "stat.h"
+#include "evsel.h"
 
 void update_stats(struct stats *stats, u64 val)
 {
@@ -61,3 +61,32 @@ double rel_stddev_stats(double stddev, double avg)
 
 	return pct;
 }
+
+bool __perf_evsel_stat__is(struct perf_evsel *evsel,
+			   enum perf_stat_evsel_id id)
+{
+	struct perf_stat *ps = evsel->priv;
+
+	return ps->id == id;
+}
+
+#define ID(id, name) [PERF_STAT_EVSEL_ID__##id] = #name
+static const char *id_str[PERF_STAT_EVSEL_ID__MAX] = {
+	ID(NONE, x),
+};
+#undef ID
+
+void perf_stat_evsel_id_init(struct perf_evsel *evsel)
+{
+	struct perf_stat *ps = evsel->priv;
+	int i;
+
+	/* ps->id is 0 hence PERF_STAT_EVSEL_ID__NONE by default */
+
+	for (i = 0; i < PERF_STAT_EVSEL_ID__MAX; i++) {
+		if (!strcmp(perf_evsel__name(evsel), id_str[i])) {
+			ps->id = i;
+			break;
+		}
+	}
+}
diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h
index 5667fc3..f4136cf 100644
--- a/tools/perf/util/stat.h
+++ b/tools/perf/util/stat.h
@@ -9,6 +9,16 @@ struct stats
 	u64 max, min;
 };
 
+enum perf_stat_evsel_id {
+	PERF_STAT_EVSEL_ID__NONE = 0,
+	PERF_STAT_EVSEL_ID__MAX,
+};
+
+struct perf_stat {
+	struct stats		res_stats[3];
+	enum perf_stat_evsel_id	id;
+};
+
 void update_stats(struct stats *stats, u64 val);
 double avg_stats(struct stats *stats);
 double stddev_stats(struct stats *stats);
@@ -22,4 +32,14 @@ static inline void init_stats(struct stats *stats)
 	stats->min  = (u64) -1;
 	stats->max  = 0;
 }
+
+struct perf_evsel;
+bool __perf_evsel_stat__is(struct perf_evsel *evsel,
+			   enum perf_stat_evsel_id id);
+
+#define perf_stat_evsel__is(evsel, id) \
+	__perf_evsel_stat__is(evsel, PERF_STAT_EVSEL_ID__ ## id)
+
+void perf_stat_evsel_id_init(struct perf_evsel *evsel);
+
 #endif

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

* [tip:perf/core] perf stat: Replace transaction event possition check with id check
  2015-06-03 14:25 ` [PATCH 2/9] perf stat: Replace transaction event possition check with id check Jiri Olsa
@ 2015-06-09  9:49   ` tip-bot for Jiri Olsa
  0 siblings, 0 replies; 30+ messages in thread
From: tip-bot for Jiri Olsa @ 2015-06-09  9:49 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: dsahern, hpa, tglx, acme, eranian, mingo, ak, linux-kernel,
	namhyung, jolsa, a.p.zijlstra

Commit-ID:  4c358d5cf36192f22b8d331779cb92e3ede9cddf
Gitweb:     http://git.kernel.org/tip/4c358d5cf36192f22b8d331779cb92e3ede9cddf
Author:     Jiri Olsa <jolsa@kernel.org>
AuthorDate: Wed, 3 Jun 2015 16:25:52 +0200
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Mon, 8 Jun 2015 10:30:30 -0300

perf stat: Replace transaction event possition check with id check

Using perf_stat::id to check for transaction events, instead of current
position based way.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1433341559-31848-3-git-send-email-jolsa@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/builtin-stat.c | 55 ++++++-----------------------------------------
 tools/perf/util/stat.c    |  6 +++++-
 tools/perf/util/stat.h    |  4 ++++
 3 files changed, 16 insertions(+), 49 deletions(-)

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index a6ae100..514493d 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -96,17 +96,6 @@ static const char * const transaction_limited_attrs[] = {
 	"}"
 };
 
-/* must match transaction_attrs and the beginning limited_attrs */
-enum {
-	T_TASK_CLOCK,
-	T_INSTRUCTIONS,
-	T_CYCLES,
-	T_CYCLES_IN_TX,
-	T_TRANSACTION_START,
-	T_ELISION_START,
-	T_CYCLES_IN_TX_CP,
-};
-
 static struct perf_evlist	*evsel_list;
 
 static struct target target = {
@@ -352,29 +341,6 @@ static inline int nsec_counter(struct perf_evsel *evsel)
 	return 0;
 }
 
-static struct perf_evsel *nth_evsel(int n)
-{
-	static struct perf_evsel **array;
-	static int array_len;
-	struct perf_evsel *ev;
-	int j;
-
-	/* Assumes this only called when evsel_list does not change anymore. */
-	if (!array) {
-		evlist__for_each(evsel_list, ev)
-			array_len++;
-		array = malloc(array_len * sizeof(void *));
-		if (!array)
-			exit(ENOMEM);
-		j = 0;
-		evlist__for_each(evsel_list, ev)
-			array[j++] = ev;
-	}
-	if (n < array_len)
-		return array[n];
-	return NULL;
-}
-
 /*
  * Update various tracking values we maintain to print
  * more semantic information such as miss/hit ratios,
@@ -389,14 +355,11 @@ static void update_shadow_stats(struct perf_evsel *counter, u64 *count,
 		update_stats(&runtime_nsecs_stats[cpu], count[0]);
 	else if (perf_evsel__match(counter, HARDWARE, HW_CPU_CYCLES))
 		update_stats(&runtime_cycles_stats[ctx][cpu], count[0]);
-	else if (transaction_run &&
-		 perf_evsel__cmp(counter, nth_evsel(T_CYCLES_IN_TX)))
+	else if (transaction_run && perf_stat_evsel__is(counter, CYCLES_IN_TX))
 		update_stats(&runtime_transaction_stats[ctx][cpu], count[0]);
-	else if (transaction_run &&
-		 perf_evsel__cmp(counter, nth_evsel(T_TRANSACTION_START)))
+	else if (transaction_run && perf_stat_evsel__is(counter, TRANSACTION_START))
 		update_stats(&runtime_transaction_stats[ctx][cpu], count[0]);
-	else if (transaction_run &&
-		 perf_evsel__cmp(counter, nth_evsel(T_ELISION_START)))
+	else if (transaction_run && perf_stat_evsel__is(counter, ELISION_START))
 		update_stats(&runtime_elision_stats[ctx][cpu], count[0]);
 	else if (perf_evsel__match(counter, HARDWARE, HW_STALLED_CYCLES_FRONTEND))
 		update_stats(&runtime_stalled_cycles_front_stats[ctx][cpu], count[0]);
@@ -1207,15 +1170,13 @@ static void abs_printout(int id, int nr, struct perf_evsel *evsel, double avg)
 		} else {
 			fprintf(output, "                                   ");
 		}
-	} else if (transaction_run &&
-		   perf_evsel__cmp(evsel, nth_evsel(T_CYCLES_IN_TX))) {
+	} else if (transaction_run && perf_stat_evsel__is(evsel, CYCLES_IN_TX)) {
 		total = avg_stats(&runtime_cycles_stats[ctx][cpu]);
 		if (total)
 			fprintf(output,
 				" #   %5.2f%% transactional cycles   ",
 				100.0 * (avg / total));
-	} else if (transaction_run &&
-		   perf_evsel__cmp(evsel, nth_evsel(T_CYCLES_IN_TX_CP))) {
+	} else if (transaction_run && perf_stat_evsel__is(evsel, CYCLES_IN_TX_CP)) {
 		total = avg_stats(&runtime_cycles_stats[ctx][cpu]);
 		total2 = avg_stats(&runtime_cycles_in_tx_stats[ctx][cpu]);
 		if (total2 < avg)
@@ -1224,8 +1185,7 @@ static void abs_printout(int id, int nr, struct perf_evsel *evsel, double avg)
 			fprintf(output,
 				" #   %5.2f%% aborted cycles         ",
 				100.0 * ((total2-avg) / total));
-	} else if (transaction_run &&
-		   perf_evsel__cmp(evsel, nth_evsel(T_TRANSACTION_START)) &&
+	} else if (transaction_run && perf_stat_evsel__is(evsel, TRANSACTION_START) &&
 		   avg > 0 &&
 		   runtime_cycles_in_tx_stats[ctx][cpu].n != 0) {
 		total = avg_stats(&runtime_cycles_in_tx_stats[ctx][cpu]);
@@ -1234,8 +1194,7 @@ static void abs_printout(int id, int nr, struct perf_evsel *evsel, double avg)
 			ratio = total / avg;
 
 		fprintf(output, " # %8.0f cycles / transaction   ", ratio);
-	} else if (transaction_run &&
-		   perf_evsel__cmp(evsel, nth_evsel(T_ELISION_START)) &&
+	} else if (transaction_run && perf_stat_evsel__is(evsel, ELISION_START) &&
 		   avg > 0 &&
 		   runtime_cycles_in_tx_stats[ctx][cpu].n != 0) {
 		total = avg_stats(&runtime_cycles_in_tx_stats[ctx][cpu]);
diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c
index 8e9f6bb..60b9282 100644
--- a/tools/perf/util/stat.c
+++ b/tools/perf/util/stat.c
@@ -72,7 +72,11 @@ bool __perf_evsel_stat__is(struct perf_evsel *evsel,
 
 #define ID(id, name) [PERF_STAT_EVSEL_ID__##id] = #name
 static const char *id_str[PERF_STAT_EVSEL_ID__MAX] = {
-	ID(NONE, x),
+	ID(NONE,		x),
+	ID(CYCLES_IN_TX,	cpu/cycles-t/),
+	ID(TRANSACTION_START,	cpu/tx-start/),
+	ID(ELISION_START,	cpu/el-start/),
+	ID(CYCLES_IN_TX_CP,	cpu/cycles-ct/),
 };
 #undef ID
 
diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h
index f4136cf..3df529b 100644
--- a/tools/perf/util/stat.h
+++ b/tools/perf/util/stat.h
@@ -11,6 +11,10 @@ struct stats
 
 enum perf_stat_evsel_id {
 	PERF_STAT_EVSEL_ID__NONE = 0,
+	PERF_STAT_EVSEL_ID__CYCLES_IN_TX,
+	PERF_STAT_EVSEL_ID__TRANSACTION_START,
+	PERF_STAT_EVSEL_ID__ELISION_START,
+	PERF_STAT_EVSEL_ID__CYCLES_IN_TX_CP,
 	PERF_STAT_EVSEL_ID__MAX,
 };
 

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

* [tip:perf/core] perf stat: Remove setup_events function
  2015-06-03 14:25 ` [PATCH 3/9] perf stat: Remove setup_events function Jiri Olsa
@ 2015-06-09  9:49   ` tip-bot for Jiri Olsa
  0 siblings, 0 replies; 30+ messages in thread
From: tip-bot for Jiri Olsa @ 2015-06-09  9:49 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: ak, a.p.zijlstra, eranian, linux-kernel, hpa, tglx, acme,
	dsahern, mingo, namhyung, jolsa

Commit-ID:  a454742c1252d6242e00b5f4f6f9e5fbce3859d7
Gitweb:     http://git.kernel.org/tip/a454742c1252d6242e00b5f4f6f9e5fbce3859d7
Author:     Jiri Olsa <jolsa@kernel.org>
AuthorDate: Wed, 3 Jun 2015 16:25:53 +0200
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Mon, 8 Jun 2015 10:30:30 -0300

perf stat: Remove setup_events function

We can use already existing parse_events interface.

Both transaction_attrs and transaction_limited_attrs are changed to be
single strings.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1433341559-31848-4-git-send-email-jolsa@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/builtin-stat.c | 27 +++++++--------------------
 1 file changed, 7 insertions(+), 20 deletions(-)

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 514493d..0c0071c 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -73,8 +73,8 @@ static void print_counter(struct perf_evsel *counter, char *prefix);
 static void print_aggr(char *prefix);
 
 /* Default events used for perf stat -T */
-static const char * const transaction_attrs[] = {
-	"task-clock",
+static const char *transaction_attrs = {
+	"task-clock,"
 	"{"
 	"instructions,"
 	"cycles,"
@@ -86,8 +86,8 @@ static const char * const transaction_attrs[] = {
 };
 
 /* More limited version when the CPU does not have all events. */
-static const char * const transaction_limited_attrs[] = {
-	"task-clock",
+static const char * transaction_limited_attrs = {
+	"task-clock,"
 	"{"
 	"instructions,"
 	"cycles,"
@@ -1533,17 +1533,6 @@ static int perf_stat_init_aggr_mode(void)
 	return 0;
 }
 
-static int setup_events(const char * const *attrs, unsigned len)
-{
-	unsigned i;
-
-	for (i = 0; i < len; i++) {
-		if (parse_events(evsel_list, attrs[i], NULL))
-			return -1;
-	}
-	return 0;
-}
-
 /*
  * Add default attributes, if there were no attributes specified or
  * if -d/--detailed, -d -d or -d -d -d is used:
@@ -1665,12 +1654,10 @@ static int add_default_attributes(void)
 		int err;
 		if (pmu_have_event("cpu", "cycles-ct") &&
 		    pmu_have_event("cpu", "el-start"))
-			err = setup_events(transaction_attrs,
-					ARRAY_SIZE(transaction_attrs));
+			err = parse_events(evsel_list, transaction_attrs, NULL);
 		else
-			err = setup_events(transaction_limited_attrs,
-				 ARRAY_SIZE(transaction_limited_attrs));
-		if (err < 0) {
+			err = parse_events(evsel_list, transaction_limited_attrs, NULL);
+		if (err) {
 			fprintf(stderr, "Cannot set up transaction events\n");
 			return -1;
 		}

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

* [tip:perf/core] perf stat: Remove transaction_run from shadow update/print code
  2015-06-03 14:25 ` [PATCH 4/9] perf stat: Remove transaction_run from shadow update/print code Jiri Olsa
  2015-06-03 15:10   ` Arnaldo Carvalho de Melo
@ 2015-06-09  9:49   ` tip-bot for Jiri Olsa
  1 sibling, 0 replies; 30+ messages in thread
From: tip-bot for Jiri Olsa @ 2015-06-09  9:49 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: dsahern, linux-kernel, ak, a.p.zijlstra, acme, hpa, eranian,
	tglx, namhyung, jolsa, mingo

Commit-ID:  3e99e2f5e78e601591dbcf777c67a84aa9ea2ae5
Gitweb:     http://git.kernel.org/tip/3e99e2f5e78e601591dbcf777c67a84aa9ea2ae5
Author:     Jiri Olsa <jolsa@kernel.org>
AuthorDate: Wed, 3 Jun 2015 16:25:54 +0200
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Mon, 8 Jun 2015 10:30:30 -0300

perf stat: Remove transaction_run from shadow update/print code

It's no longer needed, because we use nameid to recognize transaction
events.

Keeping it only in stat code to initialize transaction events.

I.e. struct perf_stat::id, accessible via evsel->priv, will be only set
for transaction related events.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1433341559-31848-5-git-send-email-jolsa@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/builtin-stat.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 0c0071c..b3e08ce 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -355,11 +355,11 @@ static void update_shadow_stats(struct perf_evsel *counter, u64 *count,
 		update_stats(&runtime_nsecs_stats[cpu], count[0]);
 	else if (perf_evsel__match(counter, HARDWARE, HW_CPU_CYCLES))
 		update_stats(&runtime_cycles_stats[ctx][cpu], count[0]);
-	else if (transaction_run && perf_stat_evsel__is(counter, CYCLES_IN_TX))
+	else if (perf_stat_evsel__is(counter, CYCLES_IN_TX))
 		update_stats(&runtime_transaction_stats[ctx][cpu], count[0]);
-	else if (transaction_run && perf_stat_evsel__is(counter, TRANSACTION_START))
+	else if (perf_stat_evsel__is(counter, TRANSACTION_START))
 		update_stats(&runtime_transaction_stats[ctx][cpu], count[0]);
-	else if (transaction_run && perf_stat_evsel__is(counter, ELISION_START))
+	else if (perf_stat_evsel__is(counter, ELISION_START))
 		update_stats(&runtime_elision_stats[ctx][cpu], count[0]);
 	else if (perf_evsel__match(counter, HARDWARE, HW_STALLED_CYCLES_FRONTEND))
 		update_stats(&runtime_stalled_cycles_front_stats[ctx][cpu], count[0]);
@@ -1170,13 +1170,13 @@ static void abs_printout(int id, int nr, struct perf_evsel *evsel, double avg)
 		} else {
 			fprintf(output, "                                   ");
 		}
-	} else if (transaction_run && perf_stat_evsel__is(evsel, CYCLES_IN_TX)) {
+	} else if (perf_stat_evsel__is(evsel, CYCLES_IN_TX)) {
 		total = avg_stats(&runtime_cycles_stats[ctx][cpu]);
 		if (total)
 			fprintf(output,
 				" #   %5.2f%% transactional cycles   ",
 				100.0 * (avg / total));
-	} else if (transaction_run && perf_stat_evsel__is(evsel, CYCLES_IN_TX_CP)) {
+	} else if (perf_stat_evsel__is(evsel, CYCLES_IN_TX_CP)) {
 		total = avg_stats(&runtime_cycles_stats[ctx][cpu]);
 		total2 = avg_stats(&runtime_cycles_in_tx_stats[ctx][cpu]);
 		if (total2 < avg)
@@ -1185,7 +1185,7 @@ static void abs_printout(int id, int nr, struct perf_evsel *evsel, double avg)
 			fprintf(output,
 				" #   %5.2f%% aborted cycles         ",
 				100.0 * ((total2-avg) / total));
-	} else if (transaction_run && perf_stat_evsel__is(evsel, TRANSACTION_START) &&
+	} else if (perf_stat_evsel__is(evsel, TRANSACTION_START) &&
 		   avg > 0 &&
 		   runtime_cycles_in_tx_stats[ctx][cpu].n != 0) {
 		total = avg_stats(&runtime_cycles_in_tx_stats[ctx][cpu]);
@@ -1194,7 +1194,7 @@ static void abs_printout(int id, int nr, struct perf_evsel *evsel, double avg)
 			ratio = total / avg;
 
 		fprintf(output, " # %8.0f cycles / transaction   ", ratio);
-	} else if (transaction_run && perf_stat_evsel__is(evsel, ELISION_START) &&
+	} else if (perf_stat_evsel__is(evsel, ELISION_START) &&
 		   avg > 0 &&
 		   runtime_cycles_in_tx_stats[ctx][cpu].n != 0) {
 		total = avg_stats(&runtime_cycles_in_tx_stats[ctx][cpu]);

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

* [tip:perf/core] perf stat: Introduce reset_shadow_stats function
  2015-06-03 14:25 ` [PATCH 5/9] perf stat: Introduce reset_shadow_stats function Jiri Olsa
@ 2015-06-09  9:50   ` tip-bot for Jiri Olsa
  0 siblings, 0 replies; 30+ messages in thread
From: tip-bot for Jiri Olsa @ 2015-06-09  9:50 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: hpa, acme, tglx, dsahern, jolsa, ak, a.p.zijlstra, namhyung,
	mingo, eranian, linux-kernel

Commit-ID:  1eda3b2144391e1ec9e1870bb32d5216ac7b384c
Gitweb:     http://git.kernel.org/tip/1eda3b2144391e1ec9e1870bb32d5216ac7b384c
Author:     Jiri Olsa <jolsa@kernel.org>
AuthorDate: Wed, 3 Jun 2015 16:25:55 +0200
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Mon, 8 Jun 2015 10:30:30 -0300

perf stat: Introduce reset_shadow_stats function

Move shadow counters reset code into separate function
as preparation for moving it into its own object.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1433341559-31848-6-git-send-email-jolsa@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/builtin-stat.c | 21 +++++++++++++--------
 1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index b3e08ce..fc85e6b 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -279,15 +279,8 @@ static int evsel_context(struct perf_evsel *evsel)
 	return ctx;
 }
 
-static void perf_stat__reset_stats(struct perf_evlist *evlist)
+static void reset_shadow_stats(void)
 {
-	struct perf_evsel *evsel;
-
-	evlist__for_each(evlist, evsel) {
-		perf_evsel__reset_stat_priv(evsel);
-		perf_evsel__reset_counts(evsel, perf_evsel__nr_cpus(evsel));
-	}
-
 	memset(runtime_nsecs_stats, 0, sizeof(runtime_nsecs_stats));
 	memset(runtime_cycles_stats, 0, sizeof(runtime_cycles_stats));
 	memset(runtime_stalled_cycles_front_stats, 0, sizeof(runtime_stalled_cycles_front_stats));
@@ -307,6 +300,18 @@ static void perf_stat__reset_stats(struct perf_evlist *evlist)
 	memset(&walltime_nsecs_stats, 0, sizeof(walltime_nsecs_stats));
 }
 
+static void perf_stat__reset_stats(struct perf_evlist *evlist)
+{
+	struct perf_evsel *evsel;
+
+	evlist__for_each(evlist, evsel) {
+		perf_evsel__reset_stat_priv(evsel);
+		perf_evsel__reset_counts(evsel, perf_evsel__nr_cpus(evsel));
+	}
+
+	reset_shadow_stats();
+}
+
 static int create_perf_stat_counter(struct perf_evsel *evsel)
 {
 	struct perf_event_attr *attr = &evsel->attr;

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

* [tip:perf/core] perf stat: Introduce print_shadow_stats function
  2015-06-03 14:25 ` [PATCH 6/9] perf stat: Introduce print_shadow_stats function Jiri Olsa
@ 2015-06-09  9:50   ` tip-bot for Jiri Olsa
  0 siblings, 0 replies; 30+ messages in thread
From: tip-bot for Jiri Olsa @ 2015-06-09  9:50 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: namhyung, a.p.zijlstra, eranian, linux-kernel, dsahern, jolsa,
	acme, ak, hpa, mingo, tglx

Commit-ID:  556b1fb7f9c1a9fd43ea4dacd5d14ec39ac6296a
Gitweb:     http://git.kernel.org/tip/556b1fb7f9c1a9fd43ea4dacd5d14ec39ac6296a
Author:     Jiri Olsa <jolsa@kernel.org>
AuthorDate: Wed, 3 Jun 2015 16:25:56 +0200
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Mon, 8 Jun 2015 10:30:31 -0300

perf stat: Introduce print_shadow_stats function

Move shadow counters display code into separate function as preparation
for moving it into its own object.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1433341559-31848-7-git-send-email-jolsa@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/builtin-stat.c | 72 +++++++++++++++++++++++++----------------------
 1 file changed, 39 insertions(+), 33 deletions(-)

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index fc85e6b..2ff2e22 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -1059,43 +1059,11 @@ static void print_ll_cache_misses(int cpu,
 	fprintf(output, " of all LL-cache hits   ");
 }
 
-static void abs_printout(int id, int nr, struct perf_evsel *evsel, double avg)
+static void print_shadow_stats(struct perf_evsel *evsel, double avg, int cpu)
 {
 	double total, ratio = 0.0, total2;
-	double sc =  evsel->scale;
-	const char *fmt;
-	int cpu = cpu_map__id_to_cpu(id);
 	int ctx = evsel_context(evsel);
 
-	if (csv_output) {
-		fmt = sc != 1.0 ?  "%.2f%s" : "%.0f%s";
-	} else {
-		if (big_num)
-			fmt = sc != 1.0 ? "%'18.2f%s" : "%'18.0f%s";
-		else
-			fmt = sc != 1.0 ? "%18.2f%s" : "%18.0f%s";
-	}
-
-	aggr_printout(evsel, id, nr);
-
-	if (aggr_mode == AGGR_GLOBAL)
-		cpu = 0;
-
-	fprintf(output, fmt, avg, csv_sep);
-
-	if (evsel->unit)
-		fprintf(output, "%-*s%s",
-			csv_output ? 0 : unit_width,
-			evsel->unit, csv_sep);
-
-	fprintf(output, "%-*s", csv_output ? 0 : 25, perf_evsel__name(evsel));
-
-	if (evsel->cgrp)
-		fprintf(output, "%s%s", csv_sep, evsel->cgrp->name);
-
-	if (csv_output || interval)
-		return;
-
 	if (perf_evsel__match(evsel, HARDWARE, HW_INSTRUCTIONS)) {
 		total = avg_stats(&runtime_cycles_stats[ctx][cpu]);
 		if (total) {
@@ -1226,6 +1194,44 @@ static void abs_printout(int id, int nr, struct perf_evsel *evsel, double avg)
 	}
 }
 
+static void abs_printout(int id, int nr, struct perf_evsel *evsel, double avg)
+{
+	double sc =  evsel->scale;
+	const char *fmt;
+	int cpu = cpu_map__id_to_cpu(id);
+
+	if (csv_output) {
+		fmt = sc != 1.0 ?  "%.2f%s" : "%.0f%s";
+	} else {
+		if (big_num)
+			fmt = sc != 1.0 ? "%'18.2f%s" : "%'18.0f%s";
+		else
+			fmt = sc != 1.0 ? "%18.2f%s" : "%18.0f%s";
+	}
+
+	aggr_printout(evsel, id, nr);
+
+	if (aggr_mode == AGGR_GLOBAL)
+		cpu = 0;
+
+	fprintf(output, fmt, avg, csv_sep);
+
+	if (evsel->unit)
+		fprintf(output, "%-*s%s",
+			csv_output ? 0 : unit_width,
+			evsel->unit, csv_sep);
+
+	fprintf(output, "%-*s", csv_output ? 0 : 25, perf_evsel__name(evsel));
+
+	if (evsel->cgrp)
+		fprintf(output, "%s%s", csv_sep, evsel->cgrp->name);
+
+	if (csv_output || interval)
+		return;
+
+	print_shadow_stats(evsel, avg, cpu);
+}
+
 static void print_aggr(char *prefix)
 {
 	struct perf_evsel *counter;

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

* [tip:perf/core] perf stat: Add output file argument to print_shadow_stats function
  2015-06-03 14:25 ` [PATCH 7/9] perf stat: Add output file argument to " Jiri Olsa
@ 2015-06-09  9:50   ` tip-bot for Jiri Olsa
  0 siblings, 0 replies; 30+ messages in thread
From: tip-bot for Jiri Olsa @ 2015-06-09  9:50 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: dsahern, a.p.zijlstra, ak, linux-kernel, namhyung, jolsa, acme,
	tglx, mingo, eranian, hpa

Commit-ID:  4d982740cd598bdd876d9a396cc919724af32bc9
Gitweb:     http://git.kernel.org/tip/4d982740cd598bdd876d9a396cc919724af32bc9
Author:     Jiri Olsa <jolsa@kernel.org>
AuthorDate: Wed, 3 Jun 2015 16:25:57 +0200
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Mon, 8 Jun 2015 10:30:31 -0300

perf stat: Add output file argument to print_shadow_stats function

As preparation for moving shadow counters code into its own object.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1433341559-31848-8-git-send-email-jolsa@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/builtin-stat.c | 112 +++++++++++++++++++++++-----------------------
 1 file changed, 56 insertions(+), 56 deletions(-)

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 2ff2e22..14a75dd 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -899,7 +899,7 @@ static const char *get_ratio_color(enum grc_type type, double ratio)
 	return color;
 }
 
-static void print_stalled_cycles_frontend(int cpu,
+static void print_stalled_cycles_frontend(FILE *out, int cpu,
 					  struct perf_evsel *evsel
 					  __maybe_unused, double avg)
 {
@@ -914,12 +914,12 @@ static void print_stalled_cycles_frontend(int cpu,
 
 	color = get_ratio_color(GRC_STALLED_CYCLES_FE, ratio);
 
-	fprintf(output, " #  ");
-	color_fprintf(output, color, "%6.2f%%", ratio);
-	fprintf(output, " frontend cycles idle   ");
+	fprintf(out, " #  ");
+	color_fprintf(out, color, "%6.2f%%", ratio);
+	fprintf(out, " frontend cycles idle   ");
 }
 
-static void print_stalled_cycles_backend(int cpu,
+static void print_stalled_cycles_backend(FILE *out, int cpu,
 					 struct perf_evsel *evsel
 					 __maybe_unused, double avg)
 {
@@ -934,12 +934,12 @@ static void print_stalled_cycles_backend(int cpu,
 
 	color = get_ratio_color(GRC_STALLED_CYCLES_BE, ratio);
 
-	fprintf(output, " #  ");
-	color_fprintf(output, color, "%6.2f%%", ratio);
-	fprintf(output, " backend  cycles idle   ");
+	fprintf(out, " #  ");
+	color_fprintf(out, color, "%6.2f%%", ratio);
+	fprintf(out, " backend  cycles idle   ");
 }
 
-static void print_branch_misses(int cpu,
+static void print_branch_misses(FILE *out, int cpu,
 				struct perf_evsel *evsel __maybe_unused,
 				double avg)
 {
@@ -954,12 +954,12 @@ static void print_branch_misses(int cpu,
 
 	color = get_ratio_color(GRC_CACHE_MISSES, ratio);
 
-	fprintf(output, " #  ");
-	color_fprintf(output, color, "%6.2f%%", ratio);
-	fprintf(output, " of all branches        ");
+	fprintf(out, " #  ");
+	color_fprintf(out, color, "%6.2f%%", ratio);
+	fprintf(out, " of all branches        ");
 }
 
-static void print_l1_dcache_misses(int cpu,
+static void print_l1_dcache_misses(FILE *out, int cpu,
 				   struct perf_evsel *evsel __maybe_unused,
 				   double avg)
 {
@@ -974,12 +974,12 @@ static void print_l1_dcache_misses(int cpu,
 
 	color = get_ratio_color(GRC_CACHE_MISSES, ratio);
 
-	fprintf(output, " #  ");
-	color_fprintf(output, color, "%6.2f%%", ratio);
-	fprintf(output, " of all L1-dcache hits  ");
+	fprintf(out, " #  ");
+	color_fprintf(out, color, "%6.2f%%", ratio);
+	fprintf(out, " of all L1-dcache hits  ");
 }
 
-static void print_l1_icache_misses(int cpu,
+static void print_l1_icache_misses(FILE *out, int cpu,
 				   struct perf_evsel *evsel __maybe_unused,
 				   double avg)
 {
@@ -994,12 +994,12 @@ static void print_l1_icache_misses(int cpu,
 
 	color = get_ratio_color(GRC_CACHE_MISSES, ratio);
 
-	fprintf(output, " #  ");
-	color_fprintf(output, color, "%6.2f%%", ratio);
-	fprintf(output, " of all L1-icache hits  ");
+	fprintf(out, " #  ");
+	color_fprintf(out, color, "%6.2f%%", ratio);
+	fprintf(out, " of all L1-icache hits  ");
 }
 
-static void print_dtlb_cache_misses(int cpu,
+static void print_dtlb_cache_misses(FILE *out, int cpu,
 				    struct perf_evsel *evsel __maybe_unused,
 				    double avg)
 {
@@ -1014,12 +1014,12 @@ static void print_dtlb_cache_misses(int cpu,
 
 	color = get_ratio_color(GRC_CACHE_MISSES, ratio);
 
-	fprintf(output, " #  ");
-	color_fprintf(output, color, "%6.2f%%", ratio);
-	fprintf(output, " of all dTLB cache hits ");
+	fprintf(out, " #  ");
+	color_fprintf(out, color, "%6.2f%%", ratio);
+	fprintf(out, " of all dTLB cache hits ");
 }
 
-static void print_itlb_cache_misses(int cpu,
+static void print_itlb_cache_misses(FILE *out, int cpu,
 				    struct perf_evsel *evsel __maybe_unused,
 				    double avg)
 {
@@ -1034,12 +1034,12 @@ static void print_itlb_cache_misses(int cpu,
 
 	color = get_ratio_color(GRC_CACHE_MISSES, ratio);
 
-	fprintf(output, " #  ");
-	color_fprintf(output, color, "%6.2f%%", ratio);
-	fprintf(output, " of all iTLB cache hits ");
+	fprintf(out, " #  ");
+	color_fprintf(out, color, "%6.2f%%", ratio);
+	fprintf(out, " of all iTLB cache hits ");
 }
 
-static void print_ll_cache_misses(int cpu,
+static void print_ll_cache_misses(FILE *out, int cpu,
 				  struct perf_evsel *evsel __maybe_unused,
 				  double avg)
 {
@@ -1054,12 +1054,12 @@ static void print_ll_cache_misses(int cpu,
 
 	color = get_ratio_color(GRC_CACHE_MISSES, ratio);
 
-	fprintf(output, " #  ");
-	color_fprintf(output, color, "%6.2f%%", ratio);
-	fprintf(output, " of all LL-cache hits   ");
+	fprintf(out, " #  ");
+	color_fprintf(out, color, "%6.2f%%", ratio);
+	fprintf(out, " of all LL-cache hits   ");
 }
 
-static void print_shadow_stats(struct perf_evsel *evsel, double avg, int cpu)
+static void print_shadow_stats(FILE *out, struct perf_evsel *evsel, double avg, int cpu)
 {
 	double total, ratio = 0.0, total2;
 	int ctx = evsel_context(evsel);
@@ -1068,59 +1068,59 @@ static void print_shadow_stats(struct perf_evsel *evsel, double avg, int cpu)
 		total = avg_stats(&runtime_cycles_stats[ctx][cpu]);
 		if (total) {
 			ratio = avg / total;
-			fprintf(output, " #   %5.2f  insns per cycle        ", ratio);
+			fprintf(out, " #   %5.2f  insns per cycle        ", ratio);
 		} else {
-			fprintf(output, "                                   ");
+			fprintf(out, "                                   ");
 		}
 		total = avg_stats(&runtime_stalled_cycles_front_stats[ctx][cpu]);
 		total = max(total, avg_stats(&runtime_stalled_cycles_back_stats[ctx][cpu]));
 
 		if (total && avg) {
 			ratio = total / avg;
-			fprintf(output, "\n");
+			fprintf(out, "\n");
 			if (aggr_mode == AGGR_NONE)
-				fprintf(output, "        ");
-			fprintf(output, "                                                  #   %5.2f  stalled cycles per insn", ratio);
+				fprintf(out, "        ");
+			fprintf(out, "                                                  #   %5.2f  stalled cycles per insn", ratio);
 		}
 
 	} else if (perf_evsel__match(evsel, HARDWARE, HW_BRANCH_MISSES) &&
 			runtime_branches_stats[ctx][cpu].n != 0) {
-		print_branch_misses(cpu, evsel, avg);
+		print_branch_misses(out, cpu, evsel, avg);
 	} else if (
 		evsel->attr.type == PERF_TYPE_HW_CACHE &&
 		evsel->attr.config ==  ( PERF_COUNT_HW_CACHE_L1D |
 					((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
 					((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) &&
 			runtime_l1_dcache_stats[ctx][cpu].n != 0) {
-		print_l1_dcache_misses(cpu, evsel, avg);
+		print_l1_dcache_misses(out, cpu, evsel, avg);
 	} else if (
 		evsel->attr.type == PERF_TYPE_HW_CACHE &&
 		evsel->attr.config ==  ( PERF_COUNT_HW_CACHE_L1I |
 					((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
 					((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) &&
 			runtime_l1_icache_stats[ctx][cpu].n != 0) {
-		print_l1_icache_misses(cpu, evsel, avg);
+		print_l1_icache_misses(out, cpu, evsel, avg);
 	} else if (
 		evsel->attr.type == PERF_TYPE_HW_CACHE &&
 		evsel->attr.config ==  ( PERF_COUNT_HW_CACHE_DTLB |
 					((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
 					((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) &&
 			runtime_dtlb_cache_stats[ctx][cpu].n != 0) {
-		print_dtlb_cache_misses(cpu, evsel, avg);
+		print_dtlb_cache_misses(out, cpu, evsel, avg);
 	} else if (
 		evsel->attr.type == PERF_TYPE_HW_CACHE &&
 		evsel->attr.config ==  ( PERF_COUNT_HW_CACHE_ITLB |
 					((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
 					((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) &&
 			runtime_itlb_cache_stats[ctx][cpu].n != 0) {
-		print_itlb_cache_misses(cpu, evsel, avg);
+		print_itlb_cache_misses(out, cpu, evsel, avg);
 	} else if (
 		evsel->attr.type == PERF_TYPE_HW_CACHE &&
 		evsel->attr.config ==  ( PERF_COUNT_HW_CACHE_LL |
 					((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
 					((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) &&
 			runtime_ll_cache_stats[ctx][cpu].n != 0) {
-		print_ll_cache_misses(cpu, evsel, avg);
+		print_ll_cache_misses(out, cpu, evsel, avg);
 	} else if (perf_evsel__match(evsel, HARDWARE, HW_CACHE_MISSES) &&
 			runtime_cacherefs_stats[ctx][cpu].n != 0) {
 		total = avg_stats(&runtime_cacherefs_stats[ctx][cpu]);
@@ -1128,25 +1128,25 @@ static void print_shadow_stats(struct perf_evsel *evsel, double avg, int cpu)
 		if (total)
 			ratio = avg * 100 / total;
 
-		fprintf(output, " # %8.3f %% of all cache refs    ", ratio);
+		fprintf(out, " # %8.3f %% of all cache refs    ", ratio);
 
 	} else if (perf_evsel__match(evsel, HARDWARE, HW_STALLED_CYCLES_FRONTEND)) {
-		print_stalled_cycles_frontend(cpu, evsel, avg);
+		print_stalled_cycles_frontend(out, cpu, evsel, avg);
 	} else if (perf_evsel__match(evsel, HARDWARE, HW_STALLED_CYCLES_BACKEND)) {
-		print_stalled_cycles_backend(cpu, evsel, avg);
+		print_stalled_cycles_backend(out, cpu, evsel, avg);
 	} else if (perf_evsel__match(evsel, HARDWARE, HW_CPU_CYCLES)) {
 		total = avg_stats(&runtime_nsecs_stats[cpu]);
 
 		if (total) {
 			ratio = avg / total;
-			fprintf(output, " # %8.3f GHz                    ", ratio);
+			fprintf(out, " # %8.3f GHz                    ", ratio);
 		} else {
-			fprintf(output, "                                   ");
+			fprintf(out, "                                   ");
 		}
 	} else if (perf_stat_evsel__is(evsel, CYCLES_IN_TX)) {
 		total = avg_stats(&runtime_cycles_stats[ctx][cpu]);
 		if (total)
-			fprintf(output,
+			fprintf(out,
 				" #   %5.2f%% transactional cycles   ",
 				100.0 * (avg / total));
 	} else if (perf_stat_evsel__is(evsel, CYCLES_IN_TX_CP)) {
@@ -1155,7 +1155,7 @@ static void print_shadow_stats(struct perf_evsel *evsel, double avg, int cpu)
 		if (total2 < avg)
 			total2 = avg;
 		if (total)
-			fprintf(output,
+			fprintf(out,
 				" #   %5.2f%% aborted cycles         ",
 				100.0 * ((total2-avg) / total));
 	} else if (perf_stat_evsel__is(evsel, TRANSACTION_START) &&
@@ -1166,7 +1166,7 @@ static void print_shadow_stats(struct perf_evsel *evsel, double avg, int cpu)
 		if (total)
 			ratio = total / avg;
 
-		fprintf(output, " # %8.0f cycles / transaction   ", ratio);
+		fprintf(out, " # %8.0f cycles / transaction   ", ratio);
 	} else if (perf_stat_evsel__is(evsel, ELISION_START) &&
 		   avg > 0 &&
 		   runtime_cycles_in_tx_stats[ctx][cpu].n != 0) {
@@ -1175,7 +1175,7 @@ static void print_shadow_stats(struct perf_evsel *evsel, double avg, int cpu)
 		if (total)
 			ratio = total / avg;
 
-		fprintf(output, " # %8.0f cycles / elision       ", ratio);
+		fprintf(out, " # %8.0f cycles / elision       ", ratio);
 	} else if (runtime_nsecs_stats[cpu].n != 0) {
 		char unit = 'M';
 
@@ -1188,9 +1188,9 @@ static void print_shadow_stats(struct perf_evsel *evsel, double avg, int cpu)
 			unit = 'K';
 		}
 
-		fprintf(output, " # %8.3f %c/sec                  ", ratio, unit);
+		fprintf(out, " # %8.3f %c/sec                  ", ratio, unit);
 	} else {
-		fprintf(output, "                                   ");
+		fprintf(out, "                                   ");
 	}
 }
 
@@ -1229,7 +1229,7 @@ static void abs_printout(int id, int nr, struct perf_evsel *evsel, double avg)
 	if (csv_output || interval)
 		return;
 
-	print_shadow_stats(evsel, avg, cpu);
+	print_shadow_stats(output, evsel, avg, cpu);
 }
 
 static void print_aggr(char *prefix)

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

* [tip:perf/core] perf stat: Add aggr_mode argument to print_shadow_stats function
  2015-06-03 14:25 ` [PATCH 8/9] perf stat: Add aggr_mode " Jiri Olsa
@ 2015-06-09  9:51   ` tip-bot for Jiri Olsa
  0 siblings, 0 replies; 30+ messages in thread
From: tip-bot for Jiri Olsa @ 2015-06-09  9:51 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: jolsa, ak, hpa, acme, tglx, eranian, mingo, a.p.zijlstra,
	dsahern, linux-kernel, namhyung

Commit-ID:  7a23f57c89cec0e6d3189d420d992902d4465ff4
Gitweb:     http://git.kernel.org/tip/7a23f57c89cec0e6d3189d420d992902d4465ff4
Author:     Jiri Olsa <jolsa@kernel.org>
AuthorDate: Wed, 3 Jun 2015 16:25:58 +0200
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Mon, 8 Jun 2015 10:30:31 -0300

perf stat: Add aggr_mode argument to print_shadow_stats function

As preparation for moving shadow counters code into its own object.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1433341559-31848-9-git-send-email-jolsa@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/builtin-stat.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 14a75dd..50918dc 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -1059,7 +1059,8 @@ static void print_ll_cache_misses(FILE *out, int cpu,
 	fprintf(out, " of all LL-cache hits   ");
 }
 
-static void print_shadow_stats(FILE *out, struct perf_evsel *evsel, double avg, int cpu)
+static void print_shadow_stats(FILE *out, struct perf_evsel *evsel,
+			       double avg, int cpu, enum aggr_mode aggr)
 {
 	double total, ratio = 0.0, total2;
 	int ctx = evsel_context(evsel);
@@ -1078,7 +1079,7 @@ static void print_shadow_stats(FILE *out, struct perf_evsel *evsel, double avg,
 		if (total && avg) {
 			ratio = total / avg;
 			fprintf(out, "\n");
-			if (aggr_mode == AGGR_NONE)
+			if (aggr == AGGR_NONE)
 				fprintf(out, "        ");
 			fprintf(out, "                                                  #   %5.2f  stalled cycles per insn", ratio);
 		}
@@ -1229,7 +1230,7 @@ static void abs_printout(int id, int nr, struct perf_evsel *evsel, double avg)
 	if (csv_output || interval)
 		return;
 
-	print_shadow_stats(output, evsel, avg, cpu);
+	print_shadow_stats(output, evsel, avg, cpu, aggr_mode);
 }
 
 static void print_aggr(char *prefix)

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

* [tip:perf/core] perf stat: Move shadow stat counters into separate object
  2015-06-03 14:25 ` [PATCH 9/9] perf stat: Move shadow stat counters into separate object Jiri Olsa
@ 2015-06-09  9:51   ` tip-bot for Jiri Olsa
  0 siblings, 0 replies; 30+ messages in thread
From: tip-bot for Jiri Olsa @ 2015-06-09  9:51 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: acme, a.p.zijlstra, mingo, tglx, ak, jolsa, hpa, namhyung,
	linux-kernel, dsahern, eranian

Commit-ID:  f87027b9689d591ec22720944563a2d43ec835c4
Gitweb:     http://git.kernel.org/tip/f87027b9689d591ec22720944563a2d43ec835c4
Author:     Jiri Olsa <jolsa@kernel.org>
AuthorDate: Wed, 3 Jun 2015 16:25:59 +0200
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Mon, 8 Jun 2015 10:30:31 -0300

perf stat: Move shadow stat counters into separate object

Separating shadow counters code into separate object as a cleanup, but
mainly for upcomming changes, so could use it from script command
context.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1433341559-31848-10-git-send-email-jolsa@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/builtin-stat.c     | 444 +-----------------------------------------
 tools/perf/util/Build         |   1 +
 tools/perf/util/stat-shadow.c | 434 +++++++++++++++++++++++++++++++++++++++++
 tools/perf/util/stat.h        |  16 ++
 4 files changed, 455 insertions(+), 440 deletions(-)

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 50918dc..ff3d258 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -102,13 +102,6 @@ static struct target target = {
 	.uid	= UINT_MAX,
 };
 
-enum aggr_mode {
-	AGGR_NONE,
-	AGGR_GLOBAL,
-	AGGR_SOCKET,
-	AGGR_CORE,
-};
-
 static int			run_count			=  1;
 static bool			no_inherit			= false;
 static bool			scale				=  true;
@@ -234,72 +227,6 @@ out_free:
 	return -1;
 }
 
-enum {
-	CTX_BIT_USER	= 1 << 0,
-	CTX_BIT_KERNEL	= 1 << 1,
-	CTX_BIT_HV	= 1 << 2,
-	CTX_BIT_HOST	= 1 << 3,
-	CTX_BIT_IDLE	= 1 << 4,
-	CTX_BIT_MAX	= 1 << 5,
-};
-
-#define NUM_CTX CTX_BIT_MAX
-
-static struct stats runtime_nsecs_stats[MAX_NR_CPUS];
-static struct stats runtime_cycles_stats[NUM_CTX][MAX_NR_CPUS];
-static struct stats runtime_stalled_cycles_front_stats[NUM_CTX][MAX_NR_CPUS];
-static struct stats runtime_stalled_cycles_back_stats[NUM_CTX][MAX_NR_CPUS];
-static struct stats runtime_branches_stats[NUM_CTX][MAX_NR_CPUS];
-static struct stats runtime_cacherefs_stats[NUM_CTX][MAX_NR_CPUS];
-static struct stats runtime_l1_dcache_stats[NUM_CTX][MAX_NR_CPUS];
-static struct stats runtime_l1_icache_stats[NUM_CTX][MAX_NR_CPUS];
-static struct stats runtime_ll_cache_stats[NUM_CTX][MAX_NR_CPUS];
-static struct stats runtime_itlb_cache_stats[NUM_CTX][MAX_NR_CPUS];
-static struct stats runtime_dtlb_cache_stats[NUM_CTX][MAX_NR_CPUS];
-static struct stats runtime_cycles_in_tx_stats[NUM_CTX][MAX_NR_CPUS];
-static struct stats walltime_nsecs_stats;
-static struct stats runtime_transaction_stats[NUM_CTX][MAX_NR_CPUS];
-static struct stats runtime_elision_stats[NUM_CTX][MAX_NR_CPUS];
-
-static int evsel_context(struct perf_evsel *evsel)
-{
-	int ctx = 0;
-
-	if (evsel->attr.exclude_kernel)
-		ctx |= CTX_BIT_KERNEL;
-	if (evsel->attr.exclude_user)
-		ctx |= CTX_BIT_USER;
-	if (evsel->attr.exclude_hv)
-		ctx |= CTX_BIT_HV;
-	if (evsel->attr.exclude_host)
-		ctx |= CTX_BIT_HOST;
-	if (evsel->attr.exclude_idle)
-		ctx |= CTX_BIT_IDLE;
-
-	return ctx;
-}
-
-static void reset_shadow_stats(void)
-{
-	memset(runtime_nsecs_stats, 0, sizeof(runtime_nsecs_stats));
-	memset(runtime_cycles_stats, 0, sizeof(runtime_cycles_stats));
-	memset(runtime_stalled_cycles_front_stats, 0, sizeof(runtime_stalled_cycles_front_stats));
-	memset(runtime_stalled_cycles_back_stats, 0, sizeof(runtime_stalled_cycles_back_stats));
-	memset(runtime_branches_stats, 0, sizeof(runtime_branches_stats));
-	memset(runtime_cacherefs_stats, 0, sizeof(runtime_cacherefs_stats));
-	memset(runtime_l1_dcache_stats, 0, sizeof(runtime_l1_dcache_stats));
-	memset(runtime_l1_icache_stats, 0, sizeof(runtime_l1_icache_stats));
-	memset(runtime_ll_cache_stats, 0, sizeof(runtime_ll_cache_stats));
-	memset(runtime_itlb_cache_stats, 0, sizeof(runtime_itlb_cache_stats));
-	memset(runtime_dtlb_cache_stats, 0, sizeof(runtime_dtlb_cache_stats));
-	memset(runtime_cycles_in_tx_stats, 0,
-			sizeof(runtime_cycles_in_tx_stats));
-	memset(runtime_transaction_stats, 0,
-		sizeof(runtime_transaction_stats));
-	memset(runtime_elision_stats, 0, sizeof(runtime_elision_stats));
-	memset(&walltime_nsecs_stats, 0, sizeof(walltime_nsecs_stats));
-}
-
 static void perf_stat__reset_stats(struct perf_evlist *evlist)
 {
 	struct perf_evsel *evsel;
@@ -309,7 +236,7 @@ static void perf_stat__reset_stats(struct perf_evlist *evlist)
 		perf_evsel__reset_counts(evsel, perf_evsel__nr_cpus(evsel));
 	}
 
-	reset_shadow_stats();
+	perf_stat__reset_shadow_stats();
 }
 
 static int create_perf_stat_counter(struct perf_evsel *evsel)
@@ -346,46 +273,6 @@ static inline int nsec_counter(struct perf_evsel *evsel)
 	return 0;
 }
 
-/*
- * Update various tracking values we maintain to print
- * more semantic information such as miss/hit ratios,
- * instruction rates, etc:
- */
-static void update_shadow_stats(struct perf_evsel *counter, u64 *count,
-				int cpu)
-{
-	int ctx = evsel_context(counter);
-
-	if (perf_evsel__match(counter, SOFTWARE, SW_TASK_CLOCK))
-		update_stats(&runtime_nsecs_stats[cpu], count[0]);
-	else if (perf_evsel__match(counter, HARDWARE, HW_CPU_CYCLES))
-		update_stats(&runtime_cycles_stats[ctx][cpu], count[0]);
-	else if (perf_stat_evsel__is(counter, CYCLES_IN_TX))
-		update_stats(&runtime_transaction_stats[ctx][cpu], count[0]);
-	else if (perf_stat_evsel__is(counter, TRANSACTION_START))
-		update_stats(&runtime_transaction_stats[ctx][cpu], count[0]);
-	else if (perf_stat_evsel__is(counter, ELISION_START))
-		update_stats(&runtime_elision_stats[ctx][cpu], count[0]);
-	else if (perf_evsel__match(counter, HARDWARE, HW_STALLED_CYCLES_FRONTEND))
-		update_stats(&runtime_stalled_cycles_front_stats[ctx][cpu], count[0]);
-	else if (perf_evsel__match(counter, HARDWARE, HW_STALLED_CYCLES_BACKEND))
-		update_stats(&runtime_stalled_cycles_back_stats[ctx][cpu], count[0]);
-	else if (perf_evsel__match(counter, HARDWARE, HW_BRANCH_INSTRUCTIONS))
-		update_stats(&runtime_branches_stats[ctx][cpu], count[0]);
-	else if (perf_evsel__match(counter, HARDWARE, HW_CACHE_REFERENCES))
-		update_stats(&runtime_cacherefs_stats[ctx][cpu], count[0]);
-	else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_L1D))
-		update_stats(&runtime_l1_dcache_stats[ctx][cpu], count[0]);
-	else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_L1I))
-		update_stats(&runtime_ll_cache_stats[ctx][cpu], count[0]);
-	else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_LL))
-		update_stats(&runtime_ll_cache_stats[ctx][cpu], count[0]);
-	else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_DTLB))
-		update_stats(&runtime_dtlb_cache_stats[ctx][cpu], count[0]);
-	else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_ITLB))
-		update_stats(&runtime_itlb_cache_stats[ctx][cpu], count[0]);
-}
-
 static void zero_per_pkg(struct perf_evsel *counter)
 {
 	if (counter->per_pkg_mask)
@@ -446,7 +333,7 @@ static int read_cb(struct perf_evsel *evsel, int cpu, int thread __maybe_unused,
 		perf_counts_values__scale(count, scale, NULL);
 		evsel->counts->cpu[cpu] = *count;
 		if (aggr_mode == AGGR_NONE)
-			update_shadow_stats(evsel, count->values, cpu);
+			perf_stat__update_shadow_stats(evsel, count->values, cpu);
 		break;
 	case AGGR_GLOBAL:
 		aggr->val += count->val;
@@ -494,7 +381,7 @@ static int read_counter_aggr(struct perf_evsel *counter)
 	/*
 	 * Save the full runtime - to allow normalization during printout:
 	 */
-	update_shadow_stats(counter, count, 0);
+	perf_stat__update_shadow_stats(counter, count, 0);
 
 	return 0;
 }
@@ -872,329 +759,6 @@ static void nsec_printout(int id, int nr, struct perf_evsel *evsel, double avg)
 		fprintf(output, "                                   ");
 }
 
-/* used for get_ratio_color() */
-enum grc_type {
-	GRC_STALLED_CYCLES_FE,
-	GRC_STALLED_CYCLES_BE,
-	GRC_CACHE_MISSES,
-	GRC_MAX_NR
-};
-
-static const char *get_ratio_color(enum grc_type type, double ratio)
-{
-	static const double grc_table[GRC_MAX_NR][3] = {
-		[GRC_STALLED_CYCLES_FE] = { 50.0, 30.0, 10.0 },
-		[GRC_STALLED_CYCLES_BE] = { 75.0, 50.0, 20.0 },
-		[GRC_CACHE_MISSES] 	= { 20.0, 10.0, 5.0 },
-	};
-	const char *color = PERF_COLOR_NORMAL;
-
-	if (ratio > grc_table[type][0])
-		color = PERF_COLOR_RED;
-	else if (ratio > grc_table[type][1])
-		color = PERF_COLOR_MAGENTA;
-	else if (ratio > grc_table[type][2])
-		color = PERF_COLOR_YELLOW;
-
-	return color;
-}
-
-static void print_stalled_cycles_frontend(FILE *out, int cpu,
-					  struct perf_evsel *evsel
-					  __maybe_unused, double avg)
-{
-	double total, ratio = 0.0;
-	const char *color;
-	int ctx = evsel_context(evsel);
-
-	total = avg_stats(&runtime_cycles_stats[ctx][cpu]);
-
-	if (total)
-		ratio = avg / total * 100.0;
-
-	color = get_ratio_color(GRC_STALLED_CYCLES_FE, ratio);
-
-	fprintf(out, " #  ");
-	color_fprintf(out, color, "%6.2f%%", ratio);
-	fprintf(out, " frontend cycles idle   ");
-}
-
-static void print_stalled_cycles_backend(FILE *out, int cpu,
-					 struct perf_evsel *evsel
-					 __maybe_unused, double avg)
-{
-	double total, ratio = 0.0;
-	const char *color;
-	int ctx = evsel_context(evsel);
-
-	total = avg_stats(&runtime_cycles_stats[ctx][cpu]);
-
-	if (total)
-		ratio = avg / total * 100.0;
-
-	color = get_ratio_color(GRC_STALLED_CYCLES_BE, ratio);
-
-	fprintf(out, " #  ");
-	color_fprintf(out, color, "%6.2f%%", ratio);
-	fprintf(out, " backend  cycles idle   ");
-}
-
-static void print_branch_misses(FILE *out, int cpu,
-				struct perf_evsel *evsel __maybe_unused,
-				double avg)
-{
-	double total, ratio = 0.0;
-	const char *color;
-	int ctx = evsel_context(evsel);
-
-	total = avg_stats(&runtime_branches_stats[ctx][cpu]);
-
-	if (total)
-		ratio = avg / total * 100.0;
-
-	color = get_ratio_color(GRC_CACHE_MISSES, ratio);
-
-	fprintf(out, " #  ");
-	color_fprintf(out, color, "%6.2f%%", ratio);
-	fprintf(out, " of all branches        ");
-}
-
-static void print_l1_dcache_misses(FILE *out, int cpu,
-				   struct perf_evsel *evsel __maybe_unused,
-				   double avg)
-{
-	double total, ratio = 0.0;
-	const char *color;
-	int ctx = evsel_context(evsel);
-
-	total = avg_stats(&runtime_l1_dcache_stats[ctx][cpu]);
-
-	if (total)
-		ratio = avg / total * 100.0;
-
-	color = get_ratio_color(GRC_CACHE_MISSES, ratio);
-
-	fprintf(out, " #  ");
-	color_fprintf(out, color, "%6.2f%%", ratio);
-	fprintf(out, " of all L1-dcache hits  ");
-}
-
-static void print_l1_icache_misses(FILE *out, int cpu,
-				   struct perf_evsel *evsel __maybe_unused,
-				   double avg)
-{
-	double total, ratio = 0.0;
-	const char *color;
-	int ctx = evsel_context(evsel);
-
-	total = avg_stats(&runtime_l1_icache_stats[ctx][cpu]);
-
-	if (total)
-		ratio = avg / total * 100.0;
-
-	color = get_ratio_color(GRC_CACHE_MISSES, ratio);
-
-	fprintf(out, " #  ");
-	color_fprintf(out, color, "%6.2f%%", ratio);
-	fprintf(out, " of all L1-icache hits  ");
-}
-
-static void print_dtlb_cache_misses(FILE *out, int cpu,
-				    struct perf_evsel *evsel __maybe_unused,
-				    double avg)
-{
-	double total, ratio = 0.0;
-	const char *color;
-	int ctx = evsel_context(evsel);
-
-	total = avg_stats(&runtime_dtlb_cache_stats[ctx][cpu]);
-
-	if (total)
-		ratio = avg / total * 100.0;
-
-	color = get_ratio_color(GRC_CACHE_MISSES, ratio);
-
-	fprintf(out, " #  ");
-	color_fprintf(out, color, "%6.2f%%", ratio);
-	fprintf(out, " of all dTLB cache hits ");
-}
-
-static void print_itlb_cache_misses(FILE *out, int cpu,
-				    struct perf_evsel *evsel __maybe_unused,
-				    double avg)
-{
-	double total, ratio = 0.0;
-	const char *color;
-	int ctx = evsel_context(evsel);
-
-	total = avg_stats(&runtime_itlb_cache_stats[ctx][cpu]);
-
-	if (total)
-		ratio = avg / total * 100.0;
-
-	color = get_ratio_color(GRC_CACHE_MISSES, ratio);
-
-	fprintf(out, " #  ");
-	color_fprintf(out, color, "%6.2f%%", ratio);
-	fprintf(out, " of all iTLB cache hits ");
-}
-
-static void print_ll_cache_misses(FILE *out, int cpu,
-				  struct perf_evsel *evsel __maybe_unused,
-				  double avg)
-{
-	double total, ratio = 0.0;
-	const char *color;
-	int ctx = evsel_context(evsel);
-
-	total = avg_stats(&runtime_ll_cache_stats[ctx][cpu]);
-
-	if (total)
-		ratio = avg / total * 100.0;
-
-	color = get_ratio_color(GRC_CACHE_MISSES, ratio);
-
-	fprintf(out, " #  ");
-	color_fprintf(out, color, "%6.2f%%", ratio);
-	fprintf(out, " of all LL-cache hits   ");
-}
-
-static void print_shadow_stats(FILE *out, struct perf_evsel *evsel,
-			       double avg, int cpu, enum aggr_mode aggr)
-{
-	double total, ratio = 0.0, total2;
-	int ctx = evsel_context(evsel);
-
-	if (perf_evsel__match(evsel, HARDWARE, HW_INSTRUCTIONS)) {
-		total = avg_stats(&runtime_cycles_stats[ctx][cpu]);
-		if (total) {
-			ratio = avg / total;
-			fprintf(out, " #   %5.2f  insns per cycle        ", ratio);
-		} else {
-			fprintf(out, "                                   ");
-		}
-		total = avg_stats(&runtime_stalled_cycles_front_stats[ctx][cpu]);
-		total = max(total, avg_stats(&runtime_stalled_cycles_back_stats[ctx][cpu]));
-
-		if (total && avg) {
-			ratio = total / avg;
-			fprintf(out, "\n");
-			if (aggr == AGGR_NONE)
-				fprintf(out, "        ");
-			fprintf(out, "                                                  #   %5.2f  stalled cycles per insn", ratio);
-		}
-
-	} else if (perf_evsel__match(evsel, HARDWARE, HW_BRANCH_MISSES) &&
-			runtime_branches_stats[ctx][cpu].n != 0) {
-		print_branch_misses(out, cpu, evsel, avg);
-	} else if (
-		evsel->attr.type == PERF_TYPE_HW_CACHE &&
-		evsel->attr.config ==  ( PERF_COUNT_HW_CACHE_L1D |
-					((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
-					((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) &&
-			runtime_l1_dcache_stats[ctx][cpu].n != 0) {
-		print_l1_dcache_misses(out, cpu, evsel, avg);
-	} else if (
-		evsel->attr.type == PERF_TYPE_HW_CACHE &&
-		evsel->attr.config ==  ( PERF_COUNT_HW_CACHE_L1I |
-					((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
-					((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) &&
-			runtime_l1_icache_stats[ctx][cpu].n != 0) {
-		print_l1_icache_misses(out, cpu, evsel, avg);
-	} else if (
-		evsel->attr.type == PERF_TYPE_HW_CACHE &&
-		evsel->attr.config ==  ( PERF_COUNT_HW_CACHE_DTLB |
-					((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
-					((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) &&
-			runtime_dtlb_cache_stats[ctx][cpu].n != 0) {
-		print_dtlb_cache_misses(out, cpu, evsel, avg);
-	} else if (
-		evsel->attr.type == PERF_TYPE_HW_CACHE &&
-		evsel->attr.config ==  ( PERF_COUNT_HW_CACHE_ITLB |
-					((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
-					((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) &&
-			runtime_itlb_cache_stats[ctx][cpu].n != 0) {
-		print_itlb_cache_misses(out, cpu, evsel, avg);
-	} else if (
-		evsel->attr.type == PERF_TYPE_HW_CACHE &&
-		evsel->attr.config ==  ( PERF_COUNT_HW_CACHE_LL |
-					((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
-					((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) &&
-			runtime_ll_cache_stats[ctx][cpu].n != 0) {
-		print_ll_cache_misses(out, cpu, evsel, avg);
-	} else if (perf_evsel__match(evsel, HARDWARE, HW_CACHE_MISSES) &&
-			runtime_cacherefs_stats[ctx][cpu].n != 0) {
-		total = avg_stats(&runtime_cacherefs_stats[ctx][cpu]);
-
-		if (total)
-			ratio = avg * 100 / total;
-
-		fprintf(out, " # %8.3f %% of all cache refs    ", ratio);
-
-	} else if (perf_evsel__match(evsel, HARDWARE, HW_STALLED_CYCLES_FRONTEND)) {
-		print_stalled_cycles_frontend(out, cpu, evsel, avg);
-	} else if (perf_evsel__match(evsel, HARDWARE, HW_STALLED_CYCLES_BACKEND)) {
-		print_stalled_cycles_backend(out, cpu, evsel, avg);
-	} else if (perf_evsel__match(evsel, HARDWARE, HW_CPU_CYCLES)) {
-		total = avg_stats(&runtime_nsecs_stats[cpu]);
-
-		if (total) {
-			ratio = avg / total;
-			fprintf(out, " # %8.3f GHz                    ", ratio);
-		} else {
-			fprintf(out, "                                   ");
-		}
-	} else if (perf_stat_evsel__is(evsel, CYCLES_IN_TX)) {
-		total = avg_stats(&runtime_cycles_stats[ctx][cpu]);
-		if (total)
-			fprintf(out,
-				" #   %5.2f%% transactional cycles   ",
-				100.0 * (avg / total));
-	} else if (perf_stat_evsel__is(evsel, CYCLES_IN_TX_CP)) {
-		total = avg_stats(&runtime_cycles_stats[ctx][cpu]);
-		total2 = avg_stats(&runtime_cycles_in_tx_stats[ctx][cpu]);
-		if (total2 < avg)
-			total2 = avg;
-		if (total)
-			fprintf(out,
-				" #   %5.2f%% aborted cycles         ",
-				100.0 * ((total2-avg) / total));
-	} else if (perf_stat_evsel__is(evsel, TRANSACTION_START) &&
-		   avg > 0 &&
-		   runtime_cycles_in_tx_stats[ctx][cpu].n != 0) {
-		total = avg_stats(&runtime_cycles_in_tx_stats[ctx][cpu]);
-
-		if (total)
-			ratio = total / avg;
-
-		fprintf(out, " # %8.0f cycles / transaction   ", ratio);
-	} else if (perf_stat_evsel__is(evsel, ELISION_START) &&
-		   avg > 0 &&
-		   runtime_cycles_in_tx_stats[ctx][cpu].n != 0) {
-		total = avg_stats(&runtime_cycles_in_tx_stats[ctx][cpu]);
-
-		if (total)
-			ratio = total / avg;
-
-		fprintf(out, " # %8.0f cycles / elision       ", ratio);
-	} else if (runtime_nsecs_stats[cpu].n != 0) {
-		char unit = 'M';
-
-		total = avg_stats(&runtime_nsecs_stats[cpu]);
-
-		if (total)
-			ratio = 1000.0 * avg / total;
-		if (ratio < 0.001) {
-			ratio *= 1000;
-			unit = 'K';
-		}
-
-		fprintf(out, " # %8.3f %c/sec                  ", ratio, unit);
-	} else {
-		fprintf(out, "                                   ");
-	}
-}
-
 static void abs_printout(int id, int nr, struct perf_evsel *evsel, double avg)
 {
 	double sc =  evsel->scale;
@@ -1230,7 +794,7 @@ static void abs_printout(int id, int nr, struct perf_evsel *evsel, double avg)
 	if (csv_output || interval)
 		return;
 
-	print_shadow_stats(output, evsel, avg, cpu, aggr_mode);
+	perf_stat__print_shadow_stats(output, evsel, avg, cpu, aggr_mode);
 }
 
 static void print_aggr(char *prefix)
diff --git a/tools/perf/util/Build b/tools/perf/util/Build
index e4b676d..586a59d 100644
--- a/tools/perf/util/Build
+++ b/tools/perf/util/Build
@@ -68,6 +68,7 @@ libperf-y += rblist.o
 libperf-y += intlist.o
 libperf-y += vdso.o
 libperf-y += stat.o
+libperf-y += stat-shadow.o
 libperf-y += record.o
 libperf-y += srcline.o
 libperf-y += data.o
diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c
new file mode 100644
index 0000000..53e8bb7
--- /dev/null
+++ b/tools/perf/util/stat-shadow.c
@@ -0,0 +1,434 @@
+#include <stdio.h>
+#include "evsel.h"
+#include "stat.h"
+#include "color.h"
+
+enum {
+	CTX_BIT_USER	= 1 << 0,
+	CTX_BIT_KERNEL	= 1 << 1,
+	CTX_BIT_HV	= 1 << 2,
+	CTX_BIT_HOST	= 1 << 3,
+	CTX_BIT_IDLE	= 1 << 4,
+	CTX_BIT_MAX	= 1 << 5,
+};
+
+#define NUM_CTX CTX_BIT_MAX
+
+static struct stats runtime_nsecs_stats[MAX_NR_CPUS];
+static struct stats runtime_cycles_stats[NUM_CTX][MAX_NR_CPUS];
+static struct stats runtime_stalled_cycles_front_stats[NUM_CTX][MAX_NR_CPUS];
+static struct stats runtime_stalled_cycles_back_stats[NUM_CTX][MAX_NR_CPUS];
+static struct stats runtime_branches_stats[NUM_CTX][MAX_NR_CPUS];
+static struct stats runtime_cacherefs_stats[NUM_CTX][MAX_NR_CPUS];
+static struct stats runtime_l1_dcache_stats[NUM_CTX][MAX_NR_CPUS];
+static struct stats runtime_l1_icache_stats[NUM_CTX][MAX_NR_CPUS];
+static struct stats runtime_ll_cache_stats[NUM_CTX][MAX_NR_CPUS];
+static struct stats runtime_itlb_cache_stats[NUM_CTX][MAX_NR_CPUS];
+static struct stats runtime_dtlb_cache_stats[NUM_CTX][MAX_NR_CPUS];
+static struct stats runtime_cycles_in_tx_stats[NUM_CTX][MAX_NR_CPUS];
+static struct stats runtime_transaction_stats[NUM_CTX][MAX_NR_CPUS];
+static struct stats runtime_elision_stats[NUM_CTX][MAX_NR_CPUS];
+
+struct stats walltime_nsecs_stats;
+
+static int evsel_context(struct perf_evsel *evsel)
+{
+	int ctx = 0;
+
+	if (evsel->attr.exclude_kernel)
+		ctx |= CTX_BIT_KERNEL;
+	if (evsel->attr.exclude_user)
+		ctx |= CTX_BIT_USER;
+	if (evsel->attr.exclude_hv)
+		ctx |= CTX_BIT_HV;
+	if (evsel->attr.exclude_host)
+		ctx |= CTX_BIT_HOST;
+	if (evsel->attr.exclude_idle)
+		ctx |= CTX_BIT_IDLE;
+
+	return ctx;
+}
+
+void perf_stat__reset_shadow_stats(void)
+{
+	memset(runtime_nsecs_stats, 0, sizeof(runtime_nsecs_stats));
+	memset(runtime_cycles_stats, 0, sizeof(runtime_cycles_stats));
+	memset(runtime_stalled_cycles_front_stats, 0, sizeof(runtime_stalled_cycles_front_stats));
+	memset(runtime_stalled_cycles_back_stats, 0, sizeof(runtime_stalled_cycles_back_stats));
+	memset(runtime_branches_stats, 0, sizeof(runtime_branches_stats));
+	memset(runtime_cacherefs_stats, 0, sizeof(runtime_cacherefs_stats));
+	memset(runtime_l1_dcache_stats, 0, sizeof(runtime_l1_dcache_stats));
+	memset(runtime_l1_icache_stats, 0, sizeof(runtime_l1_icache_stats));
+	memset(runtime_ll_cache_stats, 0, sizeof(runtime_ll_cache_stats));
+	memset(runtime_itlb_cache_stats, 0, sizeof(runtime_itlb_cache_stats));
+	memset(runtime_dtlb_cache_stats, 0, sizeof(runtime_dtlb_cache_stats));
+	memset(runtime_cycles_in_tx_stats, 0,
+			sizeof(runtime_cycles_in_tx_stats));
+	memset(runtime_transaction_stats, 0,
+		sizeof(runtime_transaction_stats));
+	memset(runtime_elision_stats, 0, sizeof(runtime_elision_stats));
+	memset(&walltime_nsecs_stats, 0, sizeof(walltime_nsecs_stats));
+}
+
+/*
+ * Update various tracking values we maintain to print
+ * more semantic information such as miss/hit ratios,
+ * instruction rates, etc:
+ */
+void perf_stat__update_shadow_stats(struct perf_evsel *counter, u64 *count,
+				    int cpu)
+{
+	int ctx = evsel_context(counter);
+
+	if (perf_evsel__match(counter, SOFTWARE, SW_TASK_CLOCK))
+		update_stats(&runtime_nsecs_stats[cpu], count[0]);
+	else if (perf_evsel__match(counter, HARDWARE, HW_CPU_CYCLES))
+		update_stats(&runtime_cycles_stats[ctx][cpu], count[0]);
+	else if (perf_stat_evsel__is(counter, CYCLES_IN_TX))
+		update_stats(&runtime_transaction_stats[ctx][cpu], count[0]);
+	else if (perf_stat_evsel__is(counter, TRANSACTION_START))
+		update_stats(&runtime_transaction_stats[ctx][cpu], count[0]);
+	else if (perf_stat_evsel__is(counter, ELISION_START))
+		update_stats(&runtime_elision_stats[ctx][cpu], count[0]);
+	else if (perf_evsel__match(counter, HARDWARE, HW_STALLED_CYCLES_FRONTEND))
+		update_stats(&runtime_stalled_cycles_front_stats[ctx][cpu], count[0]);
+	else if (perf_evsel__match(counter, HARDWARE, HW_STALLED_CYCLES_BACKEND))
+		update_stats(&runtime_stalled_cycles_back_stats[ctx][cpu], count[0]);
+	else if (perf_evsel__match(counter, HARDWARE, HW_BRANCH_INSTRUCTIONS))
+		update_stats(&runtime_branches_stats[ctx][cpu], count[0]);
+	else if (perf_evsel__match(counter, HARDWARE, HW_CACHE_REFERENCES))
+		update_stats(&runtime_cacherefs_stats[ctx][cpu], count[0]);
+	else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_L1D))
+		update_stats(&runtime_l1_dcache_stats[ctx][cpu], count[0]);
+	else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_L1I))
+		update_stats(&runtime_ll_cache_stats[ctx][cpu], count[0]);
+	else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_LL))
+		update_stats(&runtime_ll_cache_stats[ctx][cpu], count[0]);
+	else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_DTLB))
+		update_stats(&runtime_dtlb_cache_stats[ctx][cpu], count[0]);
+	else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_ITLB))
+		update_stats(&runtime_itlb_cache_stats[ctx][cpu], count[0]);
+}
+
+/* used for get_ratio_color() */
+enum grc_type {
+	GRC_STALLED_CYCLES_FE,
+	GRC_STALLED_CYCLES_BE,
+	GRC_CACHE_MISSES,
+	GRC_MAX_NR
+};
+
+static const char *get_ratio_color(enum grc_type type, double ratio)
+{
+	static const double grc_table[GRC_MAX_NR][3] = {
+		[GRC_STALLED_CYCLES_FE] = { 50.0, 30.0, 10.0 },
+		[GRC_STALLED_CYCLES_BE] = { 75.0, 50.0, 20.0 },
+		[GRC_CACHE_MISSES] 	= { 20.0, 10.0, 5.0 },
+	};
+	const char *color = PERF_COLOR_NORMAL;
+
+	if (ratio > grc_table[type][0])
+		color = PERF_COLOR_RED;
+	else if (ratio > grc_table[type][1])
+		color = PERF_COLOR_MAGENTA;
+	else if (ratio > grc_table[type][2])
+		color = PERF_COLOR_YELLOW;
+
+	return color;
+}
+
+static void print_stalled_cycles_frontend(FILE *out, int cpu,
+					  struct perf_evsel *evsel
+					  __maybe_unused, double avg)
+{
+	double total, ratio = 0.0;
+	const char *color;
+	int ctx = evsel_context(evsel);
+
+	total = avg_stats(&runtime_cycles_stats[ctx][cpu]);
+
+	if (total)
+		ratio = avg / total * 100.0;
+
+	color = get_ratio_color(GRC_STALLED_CYCLES_FE, ratio);
+
+	fprintf(out, " #  ");
+	color_fprintf(out, color, "%6.2f%%", ratio);
+	fprintf(out, " frontend cycles idle   ");
+}
+
+static void print_stalled_cycles_backend(FILE *out, int cpu,
+					 struct perf_evsel *evsel
+					 __maybe_unused, double avg)
+{
+	double total, ratio = 0.0;
+	const char *color;
+	int ctx = evsel_context(evsel);
+
+	total = avg_stats(&runtime_cycles_stats[ctx][cpu]);
+
+	if (total)
+		ratio = avg / total * 100.0;
+
+	color = get_ratio_color(GRC_STALLED_CYCLES_BE, ratio);
+
+	fprintf(out, " #  ");
+	color_fprintf(out, color, "%6.2f%%", ratio);
+	fprintf(out, " backend  cycles idle   ");
+}
+
+static void print_branch_misses(FILE *out, int cpu,
+				struct perf_evsel *evsel __maybe_unused,
+				double avg)
+{
+	double total, ratio = 0.0;
+	const char *color;
+	int ctx = evsel_context(evsel);
+
+	total = avg_stats(&runtime_branches_stats[ctx][cpu]);
+
+	if (total)
+		ratio = avg / total * 100.0;
+
+	color = get_ratio_color(GRC_CACHE_MISSES, ratio);
+
+	fprintf(out, " #  ");
+	color_fprintf(out, color, "%6.2f%%", ratio);
+	fprintf(out, " of all branches        ");
+}
+
+static void print_l1_dcache_misses(FILE *out, int cpu,
+				   struct perf_evsel *evsel __maybe_unused,
+				   double avg)
+{
+	double total, ratio = 0.0;
+	const char *color;
+	int ctx = evsel_context(evsel);
+
+	total = avg_stats(&runtime_l1_dcache_stats[ctx][cpu]);
+
+	if (total)
+		ratio = avg / total * 100.0;
+
+	color = get_ratio_color(GRC_CACHE_MISSES, ratio);
+
+	fprintf(out, " #  ");
+	color_fprintf(out, color, "%6.2f%%", ratio);
+	fprintf(out, " of all L1-dcache hits  ");
+}
+
+static void print_l1_icache_misses(FILE *out, int cpu,
+				   struct perf_evsel *evsel __maybe_unused,
+				   double avg)
+{
+	double total, ratio = 0.0;
+	const char *color;
+	int ctx = evsel_context(evsel);
+
+	total = avg_stats(&runtime_l1_icache_stats[ctx][cpu]);
+
+	if (total)
+		ratio = avg / total * 100.0;
+
+	color = get_ratio_color(GRC_CACHE_MISSES, ratio);
+
+	fprintf(out, " #  ");
+	color_fprintf(out, color, "%6.2f%%", ratio);
+	fprintf(out, " of all L1-icache hits  ");
+}
+
+static void print_dtlb_cache_misses(FILE *out, int cpu,
+				    struct perf_evsel *evsel __maybe_unused,
+				    double avg)
+{
+	double total, ratio = 0.0;
+	const char *color;
+	int ctx = evsel_context(evsel);
+
+	total = avg_stats(&runtime_dtlb_cache_stats[ctx][cpu]);
+
+	if (total)
+		ratio = avg / total * 100.0;
+
+	color = get_ratio_color(GRC_CACHE_MISSES, ratio);
+
+	fprintf(out, " #  ");
+	color_fprintf(out, color, "%6.2f%%", ratio);
+	fprintf(out, " of all dTLB cache hits ");
+}
+
+static void print_itlb_cache_misses(FILE *out, int cpu,
+				    struct perf_evsel *evsel __maybe_unused,
+				    double avg)
+{
+	double total, ratio = 0.0;
+	const char *color;
+	int ctx = evsel_context(evsel);
+
+	total = avg_stats(&runtime_itlb_cache_stats[ctx][cpu]);
+
+	if (total)
+		ratio = avg / total * 100.0;
+
+	color = get_ratio_color(GRC_CACHE_MISSES, ratio);
+
+	fprintf(out, " #  ");
+	color_fprintf(out, color, "%6.2f%%", ratio);
+	fprintf(out, " of all iTLB cache hits ");
+}
+
+static void print_ll_cache_misses(FILE *out, int cpu,
+				  struct perf_evsel *evsel __maybe_unused,
+				  double avg)
+{
+	double total, ratio = 0.0;
+	const char *color;
+	int ctx = evsel_context(evsel);
+
+	total = avg_stats(&runtime_ll_cache_stats[ctx][cpu]);
+
+	if (total)
+		ratio = avg / total * 100.0;
+
+	color = get_ratio_color(GRC_CACHE_MISSES, ratio);
+
+	fprintf(out, " #  ");
+	color_fprintf(out, color, "%6.2f%%", ratio);
+	fprintf(out, " of all LL-cache hits   ");
+}
+
+void perf_stat__print_shadow_stats(FILE *out, struct perf_evsel *evsel,
+				   double avg, int cpu, enum aggr_mode aggr)
+{
+	double total, ratio = 0.0, total2;
+	int ctx = evsel_context(evsel);
+
+	if (perf_evsel__match(evsel, HARDWARE, HW_INSTRUCTIONS)) {
+		total = avg_stats(&runtime_cycles_stats[ctx][cpu]);
+		if (total) {
+			ratio = avg / total;
+			fprintf(out, " #   %5.2f  insns per cycle        ", ratio);
+		} else {
+			fprintf(out, "                                   ");
+		}
+		total = avg_stats(&runtime_stalled_cycles_front_stats[ctx][cpu]);
+		total = max(total, avg_stats(&runtime_stalled_cycles_back_stats[ctx][cpu]));
+
+		if (total && avg) {
+			ratio = total / avg;
+			fprintf(out, "\n");
+			if (aggr == AGGR_NONE)
+				fprintf(out, "        ");
+			fprintf(out, "                                                  #   %5.2f  stalled cycles per insn", ratio);
+		}
+
+	} else if (perf_evsel__match(evsel, HARDWARE, HW_BRANCH_MISSES) &&
+			runtime_branches_stats[ctx][cpu].n != 0) {
+		print_branch_misses(out, cpu, evsel, avg);
+	} else if (
+		evsel->attr.type == PERF_TYPE_HW_CACHE &&
+		evsel->attr.config ==  ( PERF_COUNT_HW_CACHE_L1D |
+					((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
+					((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) &&
+			runtime_l1_dcache_stats[ctx][cpu].n != 0) {
+		print_l1_dcache_misses(out, cpu, evsel, avg);
+	} else if (
+		evsel->attr.type == PERF_TYPE_HW_CACHE &&
+		evsel->attr.config ==  ( PERF_COUNT_HW_CACHE_L1I |
+					((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
+					((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) &&
+			runtime_l1_icache_stats[ctx][cpu].n != 0) {
+		print_l1_icache_misses(out, cpu, evsel, avg);
+	} else if (
+		evsel->attr.type == PERF_TYPE_HW_CACHE &&
+		evsel->attr.config ==  ( PERF_COUNT_HW_CACHE_DTLB |
+					((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
+					((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) &&
+			runtime_dtlb_cache_stats[ctx][cpu].n != 0) {
+		print_dtlb_cache_misses(out, cpu, evsel, avg);
+	} else if (
+		evsel->attr.type == PERF_TYPE_HW_CACHE &&
+		evsel->attr.config ==  ( PERF_COUNT_HW_CACHE_ITLB |
+					((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
+					((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) &&
+			runtime_itlb_cache_stats[ctx][cpu].n != 0) {
+		print_itlb_cache_misses(out, cpu, evsel, avg);
+	} else if (
+		evsel->attr.type == PERF_TYPE_HW_CACHE &&
+		evsel->attr.config ==  ( PERF_COUNT_HW_CACHE_LL |
+					((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
+					((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) &&
+			runtime_ll_cache_stats[ctx][cpu].n != 0) {
+		print_ll_cache_misses(out, cpu, evsel, avg);
+	} else if (perf_evsel__match(evsel, HARDWARE, HW_CACHE_MISSES) &&
+			runtime_cacherefs_stats[ctx][cpu].n != 0) {
+		total = avg_stats(&runtime_cacherefs_stats[ctx][cpu]);
+
+		if (total)
+			ratio = avg * 100 / total;
+
+		fprintf(out, " # %8.3f %% of all cache refs    ", ratio);
+
+	} else if (perf_evsel__match(evsel, HARDWARE, HW_STALLED_CYCLES_FRONTEND)) {
+		print_stalled_cycles_frontend(out, cpu, evsel, avg);
+	} else if (perf_evsel__match(evsel, HARDWARE, HW_STALLED_CYCLES_BACKEND)) {
+		print_stalled_cycles_backend(out, cpu, evsel, avg);
+	} else if (perf_evsel__match(evsel, HARDWARE, HW_CPU_CYCLES)) {
+		total = avg_stats(&runtime_nsecs_stats[cpu]);
+
+		if (total) {
+			ratio = avg / total;
+			fprintf(out, " # %8.3f GHz                    ", ratio);
+		} else {
+			fprintf(out, "                                   ");
+		}
+	} else if (perf_stat_evsel__is(evsel, CYCLES_IN_TX)) {
+		total = avg_stats(&runtime_cycles_stats[ctx][cpu]);
+		if (total)
+			fprintf(out,
+				" #   %5.2f%% transactional cycles   ",
+				100.0 * (avg / total));
+	} else if (perf_stat_evsel__is(evsel, CYCLES_IN_TX_CP)) {
+		total = avg_stats(&runtime_cycles_stats[ctx][cpu]);
+		total2 = avg_stats(&runtime_cycles_in_tx_stats[ctx][cpu]);
+		if (total2 < avg)
+			total2 = avg;
+		if (total)
+			fprintf(out,
+				" #   %5.2f%% aborted cycles         ",
+				100.0 * ((total2-avg) / total));
+	} else if (perf_stat_evsel__is(evsel, TRANSACTION_START) &&
+		   avg > 0 &&
+		   runtime_cycles_in_tx_stats[ctx][cpu].n != 0) {
+		total = avg_stats(&runtime_cycles_in_tx_stats[ctx][cpu]);
+
+		if (total)
+			ratio = total / avg;
+
+		fprintf(out, " # %8.0f cycles / transaction   ", ratio);
+	} else if (perf_stat_evsel__is(evsel, ELISION_START) &&
+		   avg > 0 &&
+		   runtime_cycles_in_tx_stats[ctx][cpu].n != 0) {
+		total = avg_stats(&runtime_cycles_in_tx_stats[ctx][cpu]);
+
+		if (total)
+			ratio = total / avg;
+
+		fprintf(out, " # %8.0f cycles / elision       ", ratio);
+	} else if (runtime_nsecs_stats[cpu].n != 0) {
+		char unit = 'M';
+
+		total = avg_stats(&runtime_nsecs_stats[cpu]);
+
+		if (total)
+			ratio = 1000.0 * avg / total;
+		if (ratio < 0.001) {
+			ratio *= 1000;
+			unit = 'K';
+		}
+
+		fprintf(out, " # %8.3f %c/sec                  ", ratio, unit);
+	} else {
+		fprintf(out, "                                   ");
+	}
+}
diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h
index 3df529b..615c779 100644
--- a/tools/perf/util/stat.h
+++ b/tools/perf/util/stat.h
@@ -2,6 +2,7 @@
 #define __PERF_STATS_H
 
 #include <linux/types.h>
+#include <stdio.h>
 
 struct stats
 {
@@ -23,6 +24,13 @@ struct perf_stat {
 	enum perf_stat_evsel_id	id;
 };
 
+enum aggr_mode {
+	AGGR_NONE,
+	AGGR_GLOBAL,
+	AGGR_SOCKET,
+	AGGR_CORE,
+};
+
 void update_stats(struct stats *stats, u64 val);
 double avg_stats(struct stats *stats);
 double stddev_stats(struct stats *stats);
@@ -46,4 +54,12 @@ bool __perf_evsel_stat__is(struct perf_evsel *evsel,
 
 void perf_stat_evsel_id_init(struct perf_evsel *evsel);
 
+extern struct stats walltime_nsecs_stats;
+
+void perf_stat__reset_shadow_stats(void);
+void perf_stat__update_shadow_stats(struct perf_evsel *counter, u64 *count,
+				    int cpu);
+void perf_stat__print_shadow_stats(FILE *out, struct perf_evsel *evsel,
+				   double avg, int cpu, enum aggr_mode aggr);
+
 #endif

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

* Re: [PATCHv3] perf stat: Add id into perf_stat struct
  2015-06-08 14:03     ` Arnaldo Carvalho de Melo
@ 2015-06-09 20:09       ` Jiri Olsa
  0 siblings, 0 replies; 30+ messages in thread
From: Jiri Olsa @ 2015-06-09 20:09 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Jiri Olsa, lkml, Peter Zijlstra, Paul Mackerras, David Ahern,
	Namhyung Kim, Ingo Molnar, Andi Kleen, Stephane Eranian

On Mon, Jun 08, 2015 at 11:03:40AM -0300, Arnaldo Carvalho de Melo wrote:
> Em Thu, Jun 04, 2015 at 03:50:55PM +0200, Jiri Olsa escreveu:
> > On Wed, Jun 03, 2015 at 04:25:51PM +0200, Jiri Olsa wrote:
> > > We need fast way to identify evsel as transaction event
> > > for shadow counters computation. Currently we are using
> > > possition (in evlist) based way.
> > > 
> > > Adding 'id' into 'struct perf_stat' so it can carry transaction
> > > event ID and we can use it for shadow counters computations.
> > > 
> > > Link: http://lkml.kernel.org/n/tip-9lnvjksibrs0flhkpix2qkm9@git.kernel.org
> > > Signed-off-by: Jiri Olsa <jolsa@kernel.org>
> > > ---
> > 
> > using perf_evsel__name instead of evsel->name pointer
> 
> It now passes 'perf test' on rhel7/fedora21 systems, but it fails on a
> rhel6 system, I applied it, will test it further on the rhel6 system to
> see what went wrong there, unless you do it first ;-)
> 
> [root@sandy ~]# perf test 15
> 15: struct perf_event_attr setup                             :sh: line
> 1:  5381 Aborted                 (core dumped)
> PERF_TEST_ATTR=/tmp/tmp8ZBLwc /home/acme/bin/perf stat -o
> /tmp/tmp8ZBLwc/perf.data --group -e cycles,instructions kill > /dev/null
> 2>&1
> sh: line 1:  5438 Aborted                 (core dumped)
> PERF_TEST_ATTR=/tmp/tmpnRDADB /home/acme/bin/perf stat -o
> /tmp/tmpnRDADB/perf.data -e '{cycles,instructions}' kill > /dev/null
> 2>&1
>  Ok
> [root@sandy ~]# uname -r
> 2.6.32-504.8.1.el6.x86_64
> [root@sandy ~]# cat /etc/redhat-release 
> Red Hat Enterprise Linux Server release 6.6 (Santiago)
> [root@sandy ~]# 

hum, cant reproduce

[root@ibm-x3650m4-02 perf]# ./perf test 15
15: struct perf_event_attr setup                             : Ok


the server is latest rhel6 kernel (scratch):

[root@ibm-x3650m4-02 perf]# uname -a
Linux ibm-x3650m4-02.lab.eng.brq.redhat.com 2.6.32-556.el6perf_ivb_haswell_1.x86_64 #1 SMP Wed Apr 29 06:00:24 EDT 2015 x86_64 x86_64 x86_64 GNU/Linux
[root@ibm-x3650m4-02 perf]# cat /etc/redhat-release 
Red Hat Enterprise Linux Server release 6.6 (Santiago)


jirka

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

end of thread, other threads:[~2015-06-09 20:09 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-06-03 14:25 [PATCHv2 0/9] perf stat: Separate shadow counters code Jiri Olsa
2015-06-03 14:25 ` [PATCH 1/9] perf stat: Add id into perf_stat struct Jiri Olsa
2015-06-04 13:50   ` [PATCHv3] " Jiri Olsa
2015-06-08 14:03     ` Arnaldo Carvalho de Melo
2015-06-09 20:09       ` Jiri Olsa
2015-06-09  9:48     ` [tip:perf/core] " tip-bot for Jiri Olsa
2015-06-03 14:25 ` [PATCH 2/9] perf stat: Replace transaction event possition check with id check Jiri Olsa
2015-06-09  9:49   ` [tip:perf/core] " tip-bot for Jiri Olsa
2015-06-03 14:25 ` [PATCH 3/9] perf stat: Remove setup_events function Jiri Olsa
2015-06-09  9:49   ` [tip:perf/core] " tip-bot for Jiri Olsa
2015-06-03 14:25 ` [PATCH 4/9] perf stat: Remove transaction_run from shadow update/print code Jiri Olsa
2015-06-03 15:10   ` Arnaldo Carvalho de Melo
2015-06-03 15:14     ` Jiri Olsa
2015-06-03 15:55       ` Arnaldo Carvalho de Melo
2015-06-09  9:49   ` [tip:perf/core] " tip-bot for Jiri Olsa
2015-06-03 14:25 ` [PATCH 5/9] perf stat: Introduce reset_shadow_stats function Jiri Olsa
2015-06-09  9:50   ` [tip:perf/core] " tip-bot for Jiri Olsa
2015-06-03 14:25 ` [PATCH 6/9] perf stat: Introduce print_shadow_stats function Jiri Olsa
2015-06-09  9:50   ` [tip:perf/core] " tip-bot for Jiri Olsa
2015-06-03 14:25 ` [PATCH 7/9] perf stat: Add output file argument to " Jiri Olsa
2015-06-09  9:50   ` [tip:perf/core] " tip-bot for Jiri Olsa
2015-06-03 14:25 ` [PATCH 8/9] perf stat: Add aggr_mode " Jiri Olsa
2015-06-09  9:51   ` [tip:perf/core] " tip-bot for Jiri Olsa
2015-06-03 14:25 ` [PATCH 9/9] perf stat: Move shadow stat counters into separate object Jiri Olsa
2015-06-09  9:51   ` [tip:perf/core] " tip-bot for Jiri Olsa
2015-06-03 22:07 ` [PATCHv2 0/9] perf stat: Separate shadow counters code Arnaldo Carvalho de Melo
2015-06-03 22:24   ` Arnaldo Carvalho de Melo
2015-06-03 22:38     ` Jiri Olsa
2015-06-03 22:42       ` Arnaldo Carvalho de Melo
2015-06-04 13:49         ` Jiri Olsa

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.