Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1489004 > unrolled thread

[PATCHv4 00/57] perf c2c: Add new tool to analyze cacheline contention on NUMA systems

Started byJiri Olsa <jolsa@kernel.org>
First post2016-09-22 17:40 +0200
Last post2016-09-22 18:00 +0200
Articles 20 on this page of 52 — 3 participants

Back to article view | Back to linux.kernel


Contents

  [PATCHv4 00/57] perf c2c: Add new tool to analyze cacheline contention on NUMA systems Jiri Olsa <jolsa@kernel.org> - 2016-09-22 17:40 +0200
    [PATCH 01/57] perf tools: Add __hist_entry__snprintf function Jiri Olsa <jolsa@kernel.org> - 2016-09-22 17:40 +0200
      Re: [PATCH 01/57] perf tools: Add __hist_entry__snprintf function Arnaldo Carvalho de Melo <acme@kernel.org> - 2016-09-22 18:00 +0200
      [tip:perf/core] perf hists: Add __hist_entry__snprintf function tip-bot for Jiri Olsa <tipbot@zytor.com> - 2016-09-23 07:30 +0200
    [PATCH 43/57] perf c2c report: Add main browser Jiri Olsa <jolsa@kernel.org> - 2016-09-22 17:40 +0200
    [PATCH 21/57] perf c2c report: Add offset dimension key Jiri Olsa <jolsa@kernel.org> - 2016-09-22 17:40 +0200
    [PATCH 55/57] perf c2c report: Iterate node display in browser Jiri Olsa <jolsa@kernel.org> - 2016-09-22 17:40 +0200
    [PATCH 41/57] perf c2c report: Set final resort fields Jiri Olsa <jolsa@kernel.org> - 2016-09-22 17:50 +0200
    [PATCH 23/57] perf c2c report: Add hitm related dimension keys Jiri Olsa <jolsa@kernel.org> - 2016-09-22 17:50 +0200
    [PATCH 51/57] perf c2c report: Allow to set cacheline sort fields Jiri Olsa <jolsa@kernel.org> - 2016-09-22 17:50 +0200
    [PATCH 39/57] perf c2c report: Add src line sort key Jiri Olsa <jolsa@kernel.org> - 2016-09-22 17:50 +0200
    [PATCH 44/57] perf c2c report: Add cacheline browser Jiri Olsa <jolsa@kernel.org> - 2016-09-22 17:50 +0200
    [PATCH 30/57] perf c2c report: Add hitm percent sort key Jiri Olsa <jolsa@kernel.org> - 2016-09-22 17:50 +0200
    [PATCH 42/57] perf c2c report: Add stdio output support Jiri Olsa <jolsa@kernel.org> - 2016-09-22 17:50 +0200
    [PATCH 53/57] perf c2c report: Add cacheline index entry Jiri Olsa <jolsa@kernel.org> - 2016-09-22 17:50 +0200
    [PATCH 47/57] perf c2c report: Add c2c related stats stdio output Jiri Olsa <jolsa@kernel.org> - 2016-09-22 17:50 +0200
    [PATCH 24/57] perf c2c report: Add stores related dimension keys Jiri Olsa <jolsa@kernel.org> - 2016-09-22 17:50 +0200
    [PATCH 56/57] perf c2c report: Add help windows Jiri Olsa <jolsa@kernel.org> - 2016-09-22 17:50 +0200
    [PATCH 31/57] perf c2c report: Add hitm/store percent related sort keys Jiri Olsa <jolsa@kernel.org> - 2016-09-22 17:50 +0200
    [PATCH 22/57] perf c2c report: Add iaddr dimension key Jiri Olsa <jolsa@kernel.org> - 2016-09-22 17:50 +0200
    [PATCH 33/57] perf c2c report: Add pid sort key Jiri Olsa <jolsa@kernel.org> - 2016-09-22 17:50 +0200
    [PATCH 49/57] perf c2c report: Limit the cachelines table entries Jiri Olsa <jolsa@kernel.org> - 2016-09-22 17:50 +0200
    [PATCH 28/57] perf c2c report: Add total record sort key Jiri Olsa <jolsa@kernel.org> - 2016-09-22 17:50 +0200
    [PATCH 26/57] perf c2c report: Add llc and remote loads related dimension keys Jiri Olsa <jolsa@kernel.org> - 2016-09-22 17:50 +0200
    [PATCH 34/57] perf c2c report: Add tid sort key Jiri Olsa <jolsa@kernel.org> - 2016-09-22 17:50 +0200
    [PATCH 25/57] perf c2c report: Add loads related dimension keys Jiri Olsa <jolsa@kernel.org> - 2016-09-22 17:50 +0200
    [PATCH 37/57] perf c2c report: Add stats related sort keys Jiri Olsa <jolsa@kernel.org> - 2016-09-22 17:50 +0200
    [PATCH 50/57] perf c2c report: Add support to choose local HITMs Jiri Olsa <jolsa@kernel.org> - 2016-09-22 17:50 +0200
    [PATCH 36/57] perf c2c report: Add node sort key Jiri Olsa <jolsa@kernel.org> - 2016-09-22 17:50 +0200
    [PATCH 45/57] perf c2c report: Add global stats stdio output Jiri Olsa <jolsa@kernel.org> - 2016-09-22 17:50 +0200
    [PATCH 52/57] perf c2c report: Recalc width of global sort entries Jiri Olsa <jolsa@kernel.org> - 2016-09-22 17:50 +0200
    [PATCH 38/57] perf c2c report: Add cpu cnt sort key Jiri Olsa <jolsa@kernel.org> - 2016-09-22 17:50 +0200
    [PATCH 08/57] perf tools: Make __hist_entry__snprintf function global Jiri Olsa <jolsa@kernel.org> - 2016-09-22 18:00 +0200
      Re: [PATCH 08/57] perf tools: Make __hist_entry__snprintf function  global Arnaldo Carvalho de Melo <acme@kernel.org> - 2016-09-22 18:00 +0200
      [tip:perf/core] perf hists: Make __hist_entry__snprintf function  global tip-bot for Jiri Olsa <tipbot@zytor.com> - 2016-09-23 07:40 +0200
    [PATCH 06/57] perf tools: Make several sorting functions global Jiri Olsa <jolsa@kernel.org> - 2016-09-22 18:00 +0200
      Re: [PATCH 06/57] perf tools: Make several sorting functions global Arnaldo Carvalho de Melo <acme@kernel.org> - 2016-09-22 18:00 +0200
      [tip:perf/core] perf tools: Make several sorting functions global tip-bot for Jiri Olsa <tipbot@zytor.com> - 2016-09-23 07:40 +0200
    [PATCH 19/57] perf c2c report: Add header macros Jiri Olsa <jolsa@kernel.org> - 2016-09-22 18:00 +0200
    Re: [PATCH 04/57] perf tools: Make reset_dimensions global Arnaldo Carvalho de Melo <acme@kernel.org> - 2016-09-22 18:00 +0200
    [PATCH 03/57] perf tools: Introduce c2c_add_stats function Jiri Olsa <jolsa@kernel.org> - 2016-09-22 18:00 +0200
    [PATCH 11/57] perf c2c: Add record subcommand Jiri Olsa <jolsa@kernel.org> - 2016-09-22 18:00 +0200
    [PATCH 04/57] perf tools: Make reset_dimensions global Jiri Olsa <jolsa@kernel.org> - 2016-09-22 18:00 +0200
      [tip:perf/core] perf tools: Make reset_dimensions global tip-bot for Jiri Olsa <tipbot@zytor.com> - 2016-09-23 07:30 +0200
    [PATCH 17/57] perf c2c report: Add cacheline hists processing Jiri Olsa <jolsa@kernel.org> - 2016-09-22 18:00 +0200
    [PATCH 14/57] perf c2c report: Add sort_entry dimension support Jiri Olsa <jolsa@kernel.org> - 2016-09-22 18:00 +0200
    [PATCH 09/57] perf tools: Make hists__fprintf_headers function global Jiri Olsa <jolsa@kernel.org> - 2016-09-22 18:00 +0200
      Re: [PATCH 09/57] perf tools: Make hists__fprintf_headers function  global Arnaldo Carvalho de Melo <acme@kernel.org> - 2016-09-22 18:00 +0200
      [tip:perf/core] perf hists: Make hists__fprintf_headers function  global tip-bot for Jiri Olsa <tipbot@zytor.com> - 2016-09-23 07:40 +0200
    [PATCH 15/57] perf c2c report: Fallback to standard dimensions Jiri Olsa <jolsa@kernel.org> - 2016-09-22 18:00 +0200
    [PATCH 10/57] perf c2c: Add c2c command Jiri Olsa <jolsa@kernel.org> - 2016-09-22 18:00 +0200
    [PATCH 12/57] perf c2c: Add report subcommand Jiri Olsa <jolsa@kernel.org> - 2016-09-22 18:00 +0200

Page 1 of 3  [1] 2 3  Next page →


#1489004 — [PATCHv4 00/57] perf c2c: Add new tool to analyze cacheline contention on NUMA systems

FromJiri Olsa <jolsa@kernel.org>
Date2016-09-22 17:40 +0200
Subject[PATCHv4 00/57] perf c2c: Add new tool to analyze cacheline contention on NUMA systems
Message-ID<skegp-8a2-3@gated-at.bofh.it>
hi,
sending new version of c2c patches (v3) originally posted in here:
  http://lwn.net/Articles/588866/

I took the old set and reworked it to fit into current upstream code.
It follows the same logic as original patch and provides (almost) the
same stdio interface. In addition new TUI interface was added.

The perf c2c tool provides means for Shared Data C2C/HITM analysis.
It allows you to track down the cacheline contentions. The tool is
based on x86's load latency and precise store facility events provided
by Intel CPUs.

The tool was tested by Joe Mario and has proven to be useful and found
some cachelines contentions. Joe also wrote a blog about c2c tool with
examples located in here:

  https://joemario.github.io/blog/2016/09/01/c2c-blog/

v4 changes:
  - 4 patches already queued
  - used u32 for c2c_stats instead of int [Stanislav]
  - fixed NO_SLANG=1 compilation [Kim]
  - add __hist_entry__snprintf helper [Arnaldo]

Code is also available in:
  git://git.kernel.org/pub/scm/linux/kernel/git/jolsa/perf.git
  perf/c2c_v4

Testing:
  $ perf c2c record -a [workload]
  $ perf c2c report [--stdio]
  $ man perf-c2c

  It's most likely you won't generate any remote HITMs on common
  laptops, so to get results for local HITMs please use:

  $ perf c2c report -d lcl [--stdio]

thanks,
jirka


Cc: "Michael Trapp" <michael.trapp@sap.com>
Cc: "Long, Wai Man" <waiman.long@hpe.com>
Cc: Stanislav Ievlev <stanislav.ievlev@gmail.com>
Cc: Kim Phillips <kim.phillips@arm.com>
---
Jiri Olsa (57):
      perf tools: Add __hist_entry__snprintf function
      perf tools: Introduce c2c_decode_stats function
      perf tools: Introduce c2c_add_stats function
      perf tools: Make reset_dimensions global
      perf tools: Make output_field_add and sort_dimension__add global
      perf tools: Make several sorting functions global
      perf tools: Make several display functions global
      perf tools: Make __hist_entry__snprintf function global
      perf tools: Make hists__fprintf_headers function global
      perf c2c: Add c2c command
      perf c2c: Add record subcommand
      perf c2c: Add report subcommand
      perf c2c report: Add dimension support
      perf c2c report: Add sort_entry dimension support
      perf c2c report: Fallback to standard dimensions
      perf c2c report: Add sample processing
      perf c2c report: Add cacheline hists processing
      perf c2c report: Decode c2c_stats for hist entries
      perf c2c report: Add header macros
      perf c2c report: Add dcacheline dimension key
      perf c2c report: Add offset dimension key
      perf c2c report: Add iaddr dimension key
      perf c2c report: Add hitm related dimension keys
      perf c2c report: Add stores related dimension keys
      perf c2c report: Add loads related dimension keys
      perf c2c report: Add llc and remote loads related dimension keys
      perf c2c report: Add llc load miss dimension key
      perf c2c report: Add total record sort key
      perf c2c report: Add total loads sort key
      perf c2c report: Add hitm percent sort key
      perf c2c report: Add hitm/store percent related sort keys
      perf c2c report: Add dram related sort keys
      perf c2c report: Add pid sort key
      perf c2c report: Add tid sort key
      perf c2c report: Add symbol and dso sort keys
      perf c2c report: Add node sort key
      perf c2c report: Add stats related sort keys
      perf c2c report: Add cpu cnt sort key
      perf c2c report: Add src line sort key
      perf c2c report: Setup number of header lines for hists
      perf c2c report: Set final resort fields
      perf c2c report: Add stdio output support
      perf c2c report: Add main browser
      perf c2c report: Add cacheline browser
      perf c2c report: Add global stats stdio output
      perf c2c report: Add shared cachelines stats stdio output
      perf c2c report: Add c2c related stats stdio output
      perf c2c report: Allow to report callchains
      perf c2c report: Limit the cachelines table entries
      perf c2c report: Add support to choose local HITMs
      perf c2c report: Allow to set cacheline sort fields
      perf c2c report: Recalc width of global sort entries
      perf c2c report: Add cacheline index entry
      perf c2c report: Add support to manage symbol name length
      perf c2c report: Iterate node display in browser
      perf c2c report: Add help windows
      perf c2c: Add man page and credits

 tools/perf/Build                      |    1 +
 tools/perf/Documentation/perf-c2c.txt |  276 ++++
 tools/perf/builtin-c2c.c              | 2742 +++++++++++++++++++++++++++++++++
 tools/perf/builtin.h                  |    1 +
 tools/perf/perf.c                     |    1 +
 tools/perf/ui/browsers/hists.c        |    4 +-
 tools/perf/ui/browsers/hists.h        |    1 +
 tools/perf/ui/hist.c                  |    2 +-
 tools/perf/ui/stdio/hist.c            |   12 +-
 tools/perf/util/hist.c                |    1 +
 tools/perf/util/hist.h                |    6 +
 tools/perf/util/mem-events.c          |  128 ++
 tools/perf/util/mem-events.h          |   37 +
 tools/perf/util/sort.c                |   18 +-
 tools/perf/util/sort.h                |   12 +
 15 files changed, 3227 insertions(+), 15 deletions(-)
 create mode 100644 tools/perf/Documentation/perf-c2c.txt
 create mode 100644 tools/perf/builtin-c2c.c

[toc] | [next] | [standalone]


#1489005 — [PATCH 01/57] perf tools: Add __hist_entry__snprintf function

FromJiri Olsa <jolsa@kernel.org>
Date2016-09-22 17:40 +0200
Subject[PATCH 01/57] perf tools: Add __hist_entry__snprintf function
Message-ID<skegr-8a2-47@gated-at.bofh.it>
In reply to#1489004
Add __hist_entry__snprintf to take perf_hpp_list as an argument
instead of using he->hists->hpp_list. This way we can display
arbitrary list of entries regardles of the hists setup, which
will be useful in following patches.

Link: http://lkml.kernel.org/n/tip-j2sizkyglam3narmndlj99xq@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/ui/stdio/hist.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c
index c8dca34585ea..189665c315cc 100644
--- a/tools/perf/ui/stdio/hist.c
+++ b/tools/perf/ui/stdio/hist.c
@@ -373,7 +373,8 @@ static size_t hist_entry_callchain__fprintf(struct hist_entry *he,
 	return 0;
 }
 
-static int hist_entry__snprintf(struct hist_entry *he, struct perf_hpp *hpp)
+static int __hist_entry__snprintf(struct hist_entry *he, struct perf_hpp *hpp,
+				  struct perf_hpp_list *hpp_list)
 {
 	const char *sep = symbol_conf.field_sep;
 	struct perf_hpp_fmt *fmt;
@@ -384,7 +385,7 @@ static int hist_entry__snprintf(struct hist_entry *he, struct perf_hpp *hpp)
 	if (symbol_conf.exclude_other && !he->parent)
 		return 0;
 
-	hists__for_each_format(he->hists, fmt) {
+	perf_hpp_list__for_each_format(hpp_list, fmt) {
 		if (perf_hpp__should_skip(fmt, he->hists))
 			continue;
 
@@ -410,6 +411,11 @@ static int hist_entry__snprintf(struct hist_entry *he, struct perf_hpp *hpp)
 	return hpp->buf - start;
 }
 
+static int hist_entry__snprintf(struct hist_entry *he, struct perf_hpp *hpp)
+{
+	return __hist_entry__snprintf(he, hpp, he->hists->hpp_list);
+}
+
 static int hist_entry__hierarchy_fprintf(struct hist_entry *he,
 					 struct perf_hpp *hpp,
 					 struct hists *hists,
-- 
2.7.4

[toc] | [prev] | [next] | [standalone]


#1489051 — Re: [PATCH 01/57] perf tools: Add __hist_entry__snprintf function

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2016-09-22 18:00 +0200
SubjectRe: [PATCH 01/57] perf tools: Add __hist_entry__snprintf function
Message-ID<skezM-8hf-25@gated-at.bofh.it>
In reply to#1489005
Em Thu, Sep 22, 2016 at 05:36:29PM +0200, Jiri Olsa escreveu:
> Add __hist_entry__snprintf to take perf_hpp_list as an argument
> instead of using he->hists->hpp_list. This way we can display
> arbitrary list of entries regardles of the hists setup, which
> will be useful in following patches.

Thanks, applied,

- Arnaldo

[toc] | [prev] | [next] | [standalone]


#1489760 — [tip:perf/core] perf hists: Add __hist_entry__snprintf function

Fromtip-bot for Jiri Olsa <tipbot@zytor.com>
Date2016-09-23 07:30 +0200
Subject[tip:perf/core] perf hists: Add __hist_entry__snprintf function
Message-ID<skrdE-7Yp-23@gated-at.bofh.it>
In reply to#1489005
Commit-ID:  9da44db1493a9d384ddc1bcd1553a1803ff985b6
Gitweb:     http://git.kernel.org/tip/9da44db1493a9d384ddc1bcd1553a1803ff985b6
Author:     Jiri Olsa <jolsa@kernel.org>
AuthorDate: Thu, 22 Sep 2016 17:36:29 +0200
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Thu, 22 Sep 2016 13:08:56 -0300

perf hists: Add __hist_entry__snprintf function

Add __hist_entry__snprintf() to take a perf_hpp_list as an argument
instead of using he->hists->hpp_list.

This way we can display arbitrary list of entries regardless of the
hists setup, which will be useful in the upcoming c2c patch series.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: David Ahern <dsahern@gmail.com>
Cc: Don Zickus <dzickus@redhat.com>
Cc: Joe Mario <jmario@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1474558645-19956-2-git-send-email-jolsa@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/ui/stdio/hist.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c
index c8dca34..189665c 100644
--- a/tools/perf/ui/stdio/hist.c
+++ b/tools/perf/ui/stdio/hist.c
@@ -373,7 +373,8 @@ static size_t hist_entry_callchain__fprintf(struct hist_entry *he,
 	return 0;
 }
 
-static int hist_entry__snprintf(struct hist_entry *he, struct perf_hpp *hpp)
+static int __hist_entry__snprintf(struct hist_entry *he, struct perf_hpp *hpp,
+				  struct perf_hpp_list *hpp_list)
 {
 	const char *sep = symbol_conf.field_sep;
 	struct perf_hpp_fmt *fmt;
@@ -384,7 +385,7 @@ static int hist_entry__snprintf(struct hist_entry *he, struct perf_hpp *hpp)
 	if (symbol_conf.exclude_other && !he->parent)
 		return 0;
 
-	hists__for_each_format(he->hists, fmt) {
+	perf_hpp_list__for_each_format(hpp_list, fmt) {
 		if (perf_hpp__should_skip(fmt, he->hists))
 			continue;
 
@@ -410,6 +411,11 @@ static int hist_entry__snprintf(struct hist_entry *he, struct perf_hpp *hpp)
 	return hpp->buf - start;
 }
 
+static int hist_entry__snprintf(struct hist_entry *he, struct perf_hpp *hpp)
+{
+	return __hist_entry__snprintf(he, hpp, he->hists->hpp_list);
+}
+
 static int hist_entry__hierarchy_fprintf(struct hist_entry *he,
 					 struct perf_hpp *hpp,
 					 struct hists *hists,

[toc] | [prev] | [next] | [standalone]


#1489006 — [PATCH 43/57] perf c2c report: Add main browser

FromJiri Olsa <jolsa@kernel.org>
Date2016-09-22 17:40 +0200
Subject[PATCH 43/57] perf c2c report: Add main browser
Message-ID<skegr-8a2-49@gated-at.bofh.it>
In reply to#1489004
Adding the main cachelines TUI browser. It allows
to navigate through cachelines and disaplay their
details and callchains (implemented in following
patches).

Link: http://lkml.kernel.org/n/tip-inykbom2f19difvsu1e18avr@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/builtin-c2c.c       | 117 ++++++++++++++++++++++++++++++++++++++++-
 tools/perf/ui/browsers/hists.c |   2 +-
 tools/perf/ui/browsers/hists.h |   1 +
 3 files changed, 117 insertions(+), 3 deletions(-)

diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c
index add27479cc23..48f926768a59 100644
--- a/tools/perf/builtin-c2c.c
+++ b/tools/perf/builtin-c2c.c
@@ -14,6 +14,7 @@
 #include "data.h"
 #include "sort.h"
 #include <asm/bug.h>
+#include "ui/browsers/hists.h"
 
 struct c2c_hists {
 	struct hists		hists;
@@ -53,6 +54,7 @@ struct perf_c2c {
 	int			 node_info;
 
 	bool			 show_src;
+	bool			 use_stdio;
 };
 
 static struct perf_c2c c2c;
@@ -654,6 +656,10 @@ percent_color(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
 	c2c_he = container_of(he, struct c2c_hist_entry, he);
 	per = get_percent(c2c_he);
 
+#ifdef HAVE_SLANG_SUPPORT
+	if (use_browser)
+		return __hpp__slsmg_color_printf(hpp, "%*.2f%%", width - 1, per);
+#endif
 	return hpp_color_scnprintf(hpp, "%*.2f%%", width - 1, per);
 }
 
@@ -1074,6 +1080,8 @@ static struct c2c_dimension dim_dcacheline = {
 	.width		= 18,
 };
 
+static struct c2c_header header_offset_tui = HEADER_LOW("Off");
+
 static struct c2c_dimension dim_offset = {
 	.header		= HEADER_BOTH("Data address", "Offset"),
 	.name		= "offset",
@@ -1800,6 +1808,100 @@ static void perf_c2c__hists_fprintf(FILE *out)
 	print_pareto(out);
 }
 
+#ifdef HAVE_SLANG_SUPPORT
+static void c2c_browser__update_nr_entries(struct hist_browser *hb)
+{
+	u64 nr_entries = 0;
+	struct rb_node *nd = rb_first(&hb->hists->entries);
+
+	do {
+		struct hist_entry *he = rb_entry(nd, struct hist_entry, rb_node);
+
+		if (!he->filtered)
+			nr_entries++;
+
+		nd = rb_next(nd);
+	} while (nd);
+
+	hb->nr_non_filtered_entries = nr_entries;
+}
+
+static int perf_c2c_browser__title(struct hist_browser *browser,
+				   char *bf, size_t size)
+{
+	scnprintf(bf, size,
+		  "Shared Data Cache Line Table "
+		  "(%lu entries)", browser->nr_non_filtered_entries);
+	return 0;
+}
+
+static struct hist_browser*
+perf_c2c_browser__new(struct hists *hists)
+{
+	struct hist_browser *browser = hist_browser__new(hists);
+
+	if (browser) {
+		browser->title = perf_c2c_browser__title;
+		browser->c2c_filter = true;
+	}
+
+	return browser;
+}
+
+static int perf_c2c__hists_browse(struct hists *hists)
+{
+	struct hist_browser *browser;
+	int key = -1;
+
+	browser = perf_c2c_browser__new(hists);
+	if (browser == NULL)
+		return -1;
+
+	/* reset abort key so that it can get Ctrl-C as a key */
+	SLang_reset_tty();
+	SLang_init_tty(0, 0, 0);
+
+	c2c_browser__update_nr_entries(browser);
+
+	while (1) {
+		key = hist_browser__run(browser, "help");
+
+		switch (key) {
+		case 'q':
+			goto out;
+		default:
+			break;
+		}
+	}
+
+out:
+	hist_browser__delete(browser);
+	return 0;
+}
+
+static void perf_c2c_display(void)
+{
+	if (c2c.use_stdio)
+		perf_c2c__hists_fprintf(stdout);
+	else
+		perf_c2c__hists_browse(&c2c.hists.hists);
+}
+#else
+static void perf_c2c_display(void)
+{
+	use_browser = 0;
+	perf_c2c__hists_fprintf(stdout);
+}
+#endif /* HAVE_SLANG_SUPPORT */
+
+static void ui_quirks(void)
+{
+	if (!c2c.use_stdio) {
+		dim_offset.width  = 5;
+		dim_offset.header = header_offset_tui;
+	}
+}
+
 static int perf_c2c__report(int argc, const char **argv)
 {
 	struct perf_session *session;
@@ -1816,6 +1918,9 @@ static int perf_c2c__report(int argc, const char **argv)
 		   "the input file to process"),
 	OPT_INCR('N', "node-info", &c2c.node_info,
 		 "show extra node info in report (repeat for more info)"),
+#ifdef HAVE_SLANG_SUPPORT
+	OPT_BOOLEAN(0, "stdio", &c2c.use_stdio, "Use the stdio interface"),
+#endif
 	OPT_END()
 	};
 	int err = 0;
@@ -1825,6 +1930,13 @@ static int perf_c2c__report(int argc, const char **argv)
 	if (argc)
 		usage_with_options(report_c2c_usage, c2c_options);
 
+	if (c2c.use_stdio)
+		use_browser = 0;
+	else
+		use_browser = 1;
+
+	setup_browser(false);
+
 	if (!input_name || !strlen(input_name))
 		input_name = "perf.data";
 
@@ -1883,8 +1995,9 @@ static int perf_c2c__report(int argc, const char **argv)
 
 	ui_progress__finish();
 
-	use_browser = 0;
-	perf_c2c__hists_fprintf(stdout);
+	ui_quirks();
+
+	perf_c2c_display();
 
 out_session:
 	perf_session__delete(session);
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index fb8e42c7507a..fb9795a1b638 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -30,7 +30,7 @@ static struct rb_node *hists__filter_entries(struct rb_node *nd,
 
 static bool hist_browser__has_filter(struct hist_browser *hb)
 {
-	return hists__has_filter(hb->hists) || hb->min_pcnt || symbol_conf.has_filter;
+	return hists__has_filter(hb->hists) || hb->min_pcnt || symbol_conf.has_filter || hb->c2c_filter;
 }
 
 static int hist_browser__get_folding(struct hist_browser *browser)
diff --git a/tools/perf/ui/browsers/hists.h b/tools/perf/ui/browsers/hists.h
index 39bd0f28f211..23d6acb84800 100644
--- a/tools/perf/ui/browsers/hists.h
+++ b/tools/perf/ui/browsers/hists.h
@@ -18,6 +18,7 @@ struct hist_browser {
 	u64		     nr_non_filtered_entries;
 	u64		     nr_hierarchy_entries;
 	u64		     nr_callchain_rows;
+	bool		     c2c_filter;
 
 	/* Get title string. */
 	int                  (*title)(struct hist_browser *browser,
-- 
2.7.4

[toc] | [prev] | [next] | [standalone]


#1489007 — [PATCH 21/57] perf c2c report: Add offset dimension key

FromJiri Olsa <jolsa@kernel.org>
Date2016-09-22 17:40 +0200
Subject[PATCH 21/57] perf c2c report: Add offset dimension key
Message-ID<skegr-8a2-55@gated-at.bofh.it>
In reply to#1489004
Adding cacheline offset dimension key support.
It displays cacheline offset as hex number.

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

diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c
index 335c0fd30757..7c52481ec36b 100644
--- a/tools/perf/builtin-c2c.c
+++ b/tools/perf/builtin-c2c.c
@@ -300,6 +300,32 @@ static int dcacheline_entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
 	return snprintf(hpp->buf, hpp->size, "%*s", width, hex_str(addr));
 }
 
+static int offset_entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
+			struct hist_entry *he)
+{
+	uint64_t addr = 0;
+	int width = c2c_width(fmt, hpp, he->hists);
+
+	if (he->mem_info)
+		addr = cl_offset(he->mem_info->daddr.al_addr);
+
+	return snprintf(hpp->buf, hpp->size, "%*s", width, hex_str(addr));
+}
+
+static int64_t
+offset_cmp(struct perf_hpp_fmt *fmt __maybe_unused,
+	   struct hist_entry *left, struct hist_entry *right)
+{
+	uint64_t l = 0, r = 0;
+
+	if (left->mem_info)
+		l = cl_offset(left->mem_info->daddr.addr);
+	if (right->mem_info)
+		r = cl_offset(right->mem_info->daddr.addr);
+
+	return (int64_t)(r - l);
+}
+
 #define HEADER_LOW(__h)			\
 	{				\
 		.line[1] = {		\
@@ -343,8 +369,17 @@ static struct c2c_dimension dim_dcacheline = {
 	.width		= 18,
 };
 
+static struct c2c_dimension dim_offset = {
+	.header		= HEADER_BOTH("Data address", "Offset"),
+	.name		= "offset",
+	.cmp		= offset_cmp,
+	.entry		= offset_entry,
+	.width		= 18,
+};
+
 static struct c2c_dimension *dimensions[] = {
 	&dim_dcacheline,
+	&dim_offset,
 	NULL,
 };
 
-- 
2.7.4

[toc] | [prev] | [next] | [standalone]


#1489008 — [PATCH 55/57] perf c2c report: Iterate node display in browser

FromJiri Olsa <jolsa@kernel.org>
Date2016-09-22 17:40 +0200
Subject[PATCH 55/57] perf c2c report: Iterate node display in browser
Message-ID<skegr-8a2-53@gated-at.bofh.it>
In reply to#1489004
Adding TUI support to switch between Node entry versions
in real time with 'n' key.

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

diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c
index 73771c3f600e..3728e6c7d0cd 100644
--- a/tools/perf/builtin-c2c.c
+++ b/tools/perf/builtin-c2c.c
@@ -2201,6 +2201,10 @@ static int perf_c2c__browse_cacheline(struct hist_entry *he)
 		case 's':
 			c2c.symbol_full = !c2c.symbol_full;
 			break;
+		case 'n':
+			c2c.node_info = (c2c.node_info + 1) % 3;
+			setup_nodes_header();
+			break;
 		case 'q':
 			goto out;
 		default:
-- 
2.7.4

[toc] | [prev] | [next] | [standalone]


#1489009 — [PATCH 41/57] perf c2c report: Set final resort fields

FromJiri Olsa <jolsa@kernel.org>
Date2016-09-22 17:50 +0200
Subject[PATCH 41/57] perf c2c report: Set final resort fields
Message-ID<skeq5-8dN-3@gated-at.bofh.it>
In reply to#1489004
Set resort/display fields for both cachelines and
single cacheline displays.

Cachelines are sorted on:
  rmt_hitm

will be made configurable in following patches.

Following fields are display for cachelines:
  dcacheline
  tot_recs
  percent_hitm
  tot_hitm,lcl_hitm,rmt_hitm
  stores,stores_l1hit,stores_l1miss
  dram_lcl,dram_rmt
  ld_llcmiss
  tot_loads
  ld_fbhit,ld_l1hit,ld_l2hit
  ld_lclhit,ld_rmthit

The single cacheline is sort by:
  offset,rmt_hitm,lcl_hitm

will be made configurable in following patches.

Following fields are display for each cacheline:
  percent_rmt_hitm
  percent_lcl_hitm
  percent_stores_l1hit
  percent_stores_l1miss
  offset
  pid
  tid
  mean_rmt
  mean_lcl
  mean_load
  cpucnt
  symbol
  dso
  node

Link: http://lkml.kernel.org/n/tip-0rclftliywdq9qr2sjbugb6b@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/builtin-c2c.c | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c
index e281930e57da..b7404387faf7 100644
--- a/tools/perf/builtin-c2c.c
+++ b/tools/perf/builtin-c2c.c
@@ -1634,6 +1634,23 @@ static int resort_cl_cb(struct hist_entry *he)
 	c2c_hists = c2c_he->hists;
 
 	if (c2c_hists) {
+		c2c_hists__reinit(c2c_hists,
+			"percent_rmt_hitm,"
+			"percent_lcl_hitm,"
+			"percent_stores_l1hit,"
+			"percent_stores_l1miss,"
+			"offset,"
+			"pid,"
+			"tid,"
+			"mean_rmt,"
+			"mean_lcl,"
+			"mean_load,"
+			"cpucnt,"
+			"symbol,"
+			"dso,"
+			"node",
+			"offset,rmt_hitm,lcl_hitm");
+
 		hists__collapse_resort(&c2c_hists->hists, NULL);
 		hists__output_resort_cb(&c2c_hists->hists, NULL, filter_cb);
 	}
@@ -1765,6 +1782,20 @@ static int perf_c2c__report(int argc, const char **argv)
 		goto out_session;
 	}
 
+	c2c_hists__reinit(&c2c.hists,
+			"dcacheline,"
+			"tot_recs,"
+			"percent_hitm,"
+			"tot_hitm,lcl_hitm,rmt_hitm,"
+			"stores,stores_l1hit,stores_l1miss,"
+			"dram_lcl,dram_rmt,"
+			"ld_llcmiss,"
+			"tot_loads,"
+			"ld_fbhit,ld_l1hit,ld_l2hit,"
+			"ld_lclhit,ld_rmthit",
+			"rmt_hitm"
+			);
+
 	ui_progress__init(&prog, c2c.hists.hists.nr_entries, "Sorting...");
 
 	hists__collapse_resort(&c2c.hists.hists, NULL);
-- 
2.7.4

[toc] | [prev] | [next] | [standalone]


#1489010 — [PATCH 23/57] perf c2c report: Add hitm related dimension keys

FromJiri Olsa <jolsa@kernel.org>
Date2016-09-22 17:50 +0200
Subject[PATCH 23/57] perf c2c report: Add hitm related dimension keys
Message-ID<skeq5-8dN-1@gated-at.bofh.it>
In reply to#1489004
Adding 5 hitm related dimension key wrappers.

First 3 are to be displayed in the main cachelines
overall output:

  tot_hitm, lcl_hitm, rmt_hitm

The latter 2 are to be displayed within single
cacheline output:

  cl_rmt_hitm, cl_lcl_hitm

They all display bare numbers of remote/local/total
HITMs for cacheline or its related offsets.

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

diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c
index a2881677c315..06c4d3e92ed2 100644
--- a/tools/perf/builtin-c2c.c
+++ b/tools/perf/builtin-c2c.c
@@ -346,6 +346,70 @@ iaddr_cmp(struct perf_hpp_fmt *fmt __maybe_unused,
 	return sort__iaddr_cmp(left, right);
 }
 
+static int
+tot_hitm_entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
+	       struct hist_entry *he)
+{
+	struct c2c_hist_entry *c2c_he;
+	int width = c2c_width(fmt, hpp, he->hists);
+	unsigned int tot_hitm;
+
+	c2c_he = container_of(he, struct c2c_hist_entry, he);
+	tot_hitm = c2c_he->stats.lcl_hitm + c2c_he->stats.rmt_hitm;
+
+	return snprintf(hpp->buf, hpp->size, "%*u", width, tot_hitm);
+}
+
+static int64_t
+tot_hitm_cmp(struct perf_hpp_fmt *fmt __maybe_unused,
+	     struct hist_entry *left, struct hist_entry *right)
+{
+	struct c2c_hist_entry *c2c_left;
+	struct c2c_hist_entry *c2c_right;
+	unsigned int tot_hitm_left;
+	unsigned int tot_hitm_right;
+
+	c2c_left  = container_of(left, struct c2c_hist_entry, he);
+	c2c_right = container_of(right, struct c2c_hist_entry, he);
+
+	tot_hitm_left  = c2c_left->stats.lcl_hitm + c2c_left->stats.rmt_hitm;
+	tot_hitm_right = c2c_right->stats.lcl_hitm + c2c_right->stats.rmt_hitm;
+
+	return tot_hitm_left - tot_hitm_right;
+}
+
+#define STAT_FN_ENTRY(__f)					\
+static int							\
+__f ## _entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,	\
+	      struct hist_entry *he)				\
+{								\
+	struct c2c_hist_entry *c2c_he;				\
+	int width = c2c_width(fmt, hpp, he->hists);		\
+								\
+	c2c_he = container_of(he, struct c2c_hist_entry, he);	\
+	return snprintf(hpp->buf, hpp->size, "%*u", width,	\
+			c2c_he->stats.__f);			\
+}
+
+#define STAT_FN_CMP(__f)						\
+static int64_t								\
+__f ## _cmp(struct perf_hpp_fmt *fmt __maybe_unused,			\
+	    struct hist_entry *left, struct hist_entry *right)		\
+{									\
+	struct c2c_hist_entry *c2c_left, *c2c_right;			\
+									\
+	c2c_left  = container_of(left, struct c2c_hist_entry, he);	\
+	c2c_right = container_of(right, struct c2c_hist_entry, he);	\
+	return c2c_left->stats.__f - c2c_right->stats.__f;		\
+}
+
+#define STAT_FN(__f)		\
+	STAT_FN_ENTRY(__f)	\
+	STAT_FN_CMP(__f)
+
+STAT_FN(rmt_hitm)
+STAT_FN(lcl_hitm)
+
 #define HEADER_LOW(__h)			\
 	{				\
 		.line[1] = {		\
@@ -405,10 +469,55 @@ static struct c2c_dimension dim_iaddr = {
 	.width		= 18,
 };
 
+static struct c2c_dimension dim_tot_hitm = {
+	.header		= HEADER_SPAN("----- LLC Load Hitm -----", "Total", 2),
+	.name		= "tot_hitm",
+	.cmp		= tot_hitm_cmp,
+	.entry		= tot_hitm_entry,
+	.width		= 7,
+};
+
+static struct c2c_dimension dim_lcl_hitm = {
+	.header		= HEADER_SPAN_LOW("Lcl"),
+	.name		= "lcl_hitm",
+	.cmp		= lcl_hitm_cmp,
+	.entry		= lcl_hitm_entry,
+	.width		= 7,
+};
+
+static struct c2c_dimension dim_rmt_hitm = {
+	.header		= HEADER_SPAN_LOW("Rmt"),
+	.name		= "rmt_hitm",
+	.cmp		= rmt_hitm_cmp,
+	.entry		= rmt_hitm_entry,
+	.width		= 7,
+};
+
+static struct c2c_dimension dim_cl_rmt_hitm = {
+	.header		= HEADER_SPAN("----- HITM -----", "Rmt", 1),
+	.name		= "cl_rmt_hitm",
+	.cmp		= rmt_hitm_cmp,
+	.entry		= rmt_hitm_entry,
+	.width		= 7,
+};
+
+static struct c2c_dimension dim_cl_lcl_hitm = {
+	.header		= HEADER_SPAN_LOW("Lcl"),
+	.name		= "cl_lcl_hitm",
+	.cmp		= lcl_hitm_cmp,
+	.entry		= lcl_hitm_entry,
+	.width		= 7,
+};
+
 static struct c2c_dimension *dimensions[] = {
 	&dim_dcacheline,
 	&dim_offset,
 	&dim_iaddr,
+	&dim_tot_hitm,
+	&dim_lcl_hitm,
+	&dim_rmt_hitm,
+	&dim_cl_lcl_hitm,
+	&dim_cl_rmt_hitm,
 	NULL,
 };
 
-- 
2.7.4

[toc] | [prev] | [next] | [standalone]


#1489011 — [PATCH 51/57] perf c2c report: Allow to set cacheline sort fields

FromJiri Olsa <jolsa@kernel.org>
Date2016-09-22 17:50 +0200
Subject[PATCH 51/57] perf c2c report: Allow to set cacheline sort fields
Message-ID<skeq6-8dN-11@gated-at.bofh.it>
In reply to#1489004
Allowing user to configure the way the single cacheline
data are sorted after being sorted by offset.

Adding 'c' option to specify sorting fields for single cacheline:

    -c, --coalesce <coalesce fields>
                          coalesce fields: pid,tid,iaddr,dso

It's allowed to use following combination of fields:
  pid   - process pid
  tid   - process tid
  iaddr - code address
  dso   - shared object

Link: http://lkml.kernel.org/n/tip-aka8z31umxoq2gqr5mjd81zr@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/builtin-c2c.c | 119 ++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 102 insertions(+), 17 deletions(-)

diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c
index 771991cf6946..ee64537493ce 100644
--- a/tools/perf/builtin-c2c.c
+++ b/tools/perf/builtin-c2c.c
@@ -46,6 +46,8 @@ struct c2c_hist_entry {
 	struct hist_entry	he;
 };
 
+static char const *coalesce_default = "pid,tid,iaddr";
+
 struct perf_c2c {
 	struct perf_tool	tool;
 	struct c2c_hists	hists;
@@ -65,6 +67,11 @@ struct perf_c2c {
 	int			shared_clines;
 
 	int			 display;
+
+	const char		*coalesce;
+	char			*cl_sort;
+	char			*cl_resort;
+	char			*cl_output;
 };
 
 enum {
@@ -237,7 +244,7 @@ static int process_sample_event(struct perf_tool *tool __maybe_unused,
 		if (!mi_dup)
 			goto free_mi;
 
-		c2c_hists = he__get_c2c_hists(he, "offset", 2);
+		c2c_hists = he__get_c2c_hists(he, c2c.cl_sort, 2);
 		if (!c2c_hists)
 			goto free_mi_dup;
 
@@ -1736,22 +1743,7 @@ static int resort_cl_cb(struct hist_entry *he)
 	c2c_hists = c2c_he->hists;
 
 	if (display && c2c_hists) {
-		c2c_hists__reinit(c2c_hists,
-			"percent_rmt_hitm,"
-			"percent_lcl_hitm,"
-			"percent_stores_l1hit,"
-			"percent_stores_l1miss,"
-			"offset,"
-			"pid,"
-			"tid,"
-			"mean_rmt,"
-			"mean_lcl,"
-			"mean_load,"
-			"cpucnt,"
-			"symbol,"
-			"dso,"
-			"node",
-			"offset,rmt_hitm,lcl_hitm");
+		c2c_hists__reinit(c2c_hists, c2c.cl_output, c2c.cl_resort);
 
 		hists__collapse_resort(&c2c_hists->hists, NULL);
 		hists__output_resort_cb(&c2c_hists->hists, NULL, filter_cb);
@@ -1995,6 +1987,7 @@ static void print_c2c_info(FILE *out, struct perf_session *session)
 	}
 	fprintf(out, "  Cachelines sort on                : %s HITMs\n",
 		c2c.display == DISPLAY_LCL ? "Local" : "Remote");
+	fprintf(out, "  Cacheline data grouping           : %s\n", c2c.cl_sort);
 }
 
 static void perf_c2c__hists_fprintf(FILE *out, struct perf_session *session)
@@ -2274,6 +2267,89 @@ static int setup_display(const char *str)
 	return 0;
 }
 
+#define for_each_token(__tok, __buf, __sep, __tmp)		\
+	for (__tok = strtok_r(__buf, __sep, &__tmp); __tok;	\
+	     __tok = strtok_r(NULL,  __sep, &__tmp))
+
+static int build_cl_output(char *cl_sort)
+{
+	char *tok, *tmp, *buf = strdup(cl_sort);
+	bool add_pid   = false;
+	bool add_tid   = false;
+	bool add_iaddr = false;
+	bool add_sym   = false;
+	bool add_dso   = false;
+	bool add_src   = false;
+
+	if (!buf)
+		return -ENOMEM;
+
+	for_each_token(tok, buf, ",", tmp) {
+		if (!strcmp(tok, "tid")) {
+			add_tid = true;
+		} else if (!strcmp(tok, "pid")) {
+			add_pid = true;
+		} else if (!strcmp(tok, "iaddr")) {
+			add_iaddr = true;
+			add_sym   = true;
+			add_dso   = true;
+			add_src   = true;
+		} else if (!strcmp(tok, "dso")) {
+			add_dso = true;
+		} else if (strcmp(tok, "offset")) {
+			pr_err("unrecognized sort token: %s\n", tok);
+			return -EINVAL;
+		}
+	}
+
+	if (asprintf(&c2c.cl_output,
+		"%s%s%s%s%s%s%s%s%s",
+		"percent_rmt_hitm,"
+		"percent_lcl_hitm,"
+		"percent_stores_l1hit,"
+		"percent_stores_l1miss,"
+		"offset,",
+		add_pid   ? "pid," : "",
+		add_tid   ? "tid," : "",
+		add_iaddr ? "iaddr," : "",
+		"mean_rmt,"
+		"mean_lcl,"
+		"mean_load,"
+		"cpucnt,",
+		add_sym ? "symbol," : "",
+		add_dso ? "dso," : "",
+		add_src ? "cl_srcline," : "",
+		"node") < 0)
+		return -ENOMEM;
+
+	c2c.show_src = add_src;
+
+	free(buf);
+	return 0;
+}
+
+static int setup_coalesce(const char *coalesce)
+{
+	const char *c = coalesce ?: coalesce_default;
+
+	if (asprintf(&c2c.cl_sort, "offset,%s", c) < 0)
+		return -ENOMEM;
+
+	if (build_cl_output(c2c.cl_sort))
+		return -1;
+
+	if (asprintf(&c2c.cl_resort, "offset,%s",
+		     c2c.display == DISPLAY_RMT ?
+		     "rmt_hitm,lcl_hitm" :
+		     "lcl_hitm,rmt_hitm") < 0)
+		return -ENOMEM;
+
+	pr_debug("coalesce sort   fields: %s\n", c2c.cl_sort);
+	pr_debug("coalesce resort fields: %s\n", c2c.cl_resort);
+	pr_debug("coalesce output fields: %s\n", c2c.cl_output);
+	return 0;
+}
+
 static int perf_c2c__report(int argc, const char **argv)
 {
 	struct perf_session *session;
@@ -2283,6 +2359,7 @@ static int perf_c2c__report(int argc, const char **argv)
 	};
 	char callchain_default_opt[] = CALLCHAIN_DEFAULT_OPT;
 	const char *display = NULL;
+	const char *coalesce = NULL;
 	const struct option c2c_options[] = {
 	OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
 		   "file", "vmlinux pathname"),
@@ -2302,6 +2379,8 @@ static int perf_c2c__report(int argc, const char **argv)
 			     callchain_help, &parse_callchain_opt,
 			     callchain_default_opt),
 	OPT_STRING('d', "display", &display, NULL, "lcl,rmt"),
+	OPT_STRING('c', "coalesce", &coalesce, "coalesce fields",
+		   "coalesce fields: pid,tid,iaddr,dso"),
 	OPT_END()
 	};
 	int err = 0;
@@ -2330,6 +2409,12 @@ static int perf_c2c__report(int argc, const char **argv)
 	if (err)
 		goto out;
 
+	err = setup_coalesce(coalesce);
+	if (err) {
+		pr_debug("Failed to initialize hists\n");
+		goto out;
+	}
+
 	err = c2c_hists__init(&c2c.hists, "dcacheline", 2);
 	if (err) {
 		pr_debug("Failed to initialize hists\n");
-- 
2.7.4

[toc] | [prev] | [next] | [standalone]


#1489012 — [PATCH 39/57] perf c2c report: Add src line sort key

FromJiri Olsa <jolsa@kernel.org>
Date2016-09-22 17:50 +0200
Subject[PATCH 39/57] perf c2c report: Add src line sort key
Message-ID<skeq6-8dN-15@gated-at.bofh.it>
In reply to#1489004
Adding source line dimension key wrapper.

It is to be displayed in the single cacheline output:

  cl_srcline

It displays source line related to the code address that
accessed cacheline. It's a wrapper to global srcline sort
entry.

Link: http://lkml.kernel.org/n/tip-cmnzgm37mjz56ozsg4mnbgxq@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/builtin-c2c.c | 11 +++++++++++
 tools/perf/util/sort.c   |  2 +-
 tools/perf/util/sort.h   |  1 +
 3 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c
index 2318249362f8..8fb798c8a790 100644
--- a/tools/perf/builtin-c2c.c
+++ b/tools/perf/builtin-c2c.c
@@ -50,6 +50,8 @@ struct perf_c2c {
 	int			 cpus_cnt;
 	int			*cpu2node;
 	int			 node_info;
+
+	bool			 show_src;
 };
 
 static struct perf_c2c c2c;
@@ -1360,6 +1362,11 @@ static struct c2c_dimension dim_cpucnt = {
 	.width		= 8,
 };
 
+static struct c2c_dimension dim_srcline = {
+	.name		= "cl_srcline",
+	.se		= &sort_srcline,
+};
+
 static struct c2c_dimension *dimensions[] = {
 	&dim_dcacheline,
 	&dim_offset,
@@ -1398,6 +1405,7 @@ static struct c2c_dimension *dimensions[] = {
 	&dim_mean_lcl,
 	&dim_mean_load,
 	&dim_cpucnt,
+	&dim_srcline,
 	NULL,
 };
 
@@ -1605,6 +1613,9 @@ static int c2c_hists__reinit(struct c2c_hists *c2c_hists,
 
 static int filter_cb(struct hist_entry *he __maybe_unused)
 {
+	if (c2c.show_src && !he->srcline)
+		he->srcline = hist_entry__get_srcline(he);
+
 	return 0;
 }
 
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index 452e15a10dd2..df622f4e301e 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -315,7 +315,7 @@ struct sort_entry sort_sym = {
 
 /* --sort srcline */
 
-static char *hist_entry__get_srcline(struct hist_entry *he)
+char *hist_entry__get_srcline(struct hist_entry *he)
 {
 	struct map *map = he->ms.map;
 
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
index 099c97557d33..7aff317fc7c4 100644
--- a/tools/perf/util/sort.h
+++ b/tools/perf/util/sort.h
@@ -280,4 +280,5 @@ int64_t
 sort__daddr_cmp(struct hist_entry *left, struct hist_entry *right);
 int64_t
 sort__dcacheline_cmp(struct hist_entry *left, struct hist_entry *right);
+char *hist_entry__get_srcline(struct hist_entry *he);
 #endif	/* __PERF_SORT_H */
-- 
2.7.4

[toc] | [prev] | [next] | [standalone]


#1489013 — [PATCH 44/57] perf c2c report: Add cacheline browser

FromJiri Olsa <jolsa@kernel.org>
Date2016-09-22 17:50 +0200
Subject[PATCH 44/57] perf c2c report: Add cacheline browser
Message-ID<skeq6-8dN-17@gated-at.bofh.it>
In reply to#1489004
Adding single cacheline TUI browser. It triggers when
you press 'd' in the main browser on the specific cacheline.

It allows to navigate through cacheline's offsets and display
callchains (implemented in following patches).

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

diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c
index 48f926768a59..a89aa8408c45 100644
--- a/tools/perf/builtin-c2c.c
+++ b/tools/perf/builtin-c2c.c
@@ -1826,6 +1826,84 @@ static void c2c_browser__update_nr_entries(struct hist_browser *hb)
 	hb->nr_non_filtered_entries = nr_entries;
 }
 
+struct c2c_cacheline_browser {
+	struct hist_browser	 hb;
+	struct hist_entry	*he;
+};
+
+static int
+perf_c2c_cacheline_browser__title(struct hist_browser *browser,
+				  char *bf, size_t size)
+{
+	struct c2c_cacheline_browser *cl_browser;
+	struct hist_entry *he;
+	uint64_t addr = 0;
+
+	cl_browser = container_of(browser, struct c2c_cacheline_browser, hb);
+	he = cl_browser->he;
+
+	if (he->mem_info)
+		addr = cl_address(he->mem_info->daddr.addr);
+
+	scnprintf(bf, size, "Cacheline 0x%lx", addr);
+	return 0;
+}
+
+static struct c2c_cacheline_browser*
+c2c_cacheline_browser__new(struct hists *hists, struct hist_entry *he)
+{
+	struct c2c_cacheline_browser *browser;
+
+	browser = zalloc(sizeof(*browser));
+	if (browser) {
+		hist_browser__init(&browser->hb, hists);
+		browser->hb.c2c_filter	= true;
+		browser->hb.title	= perf_c2c_cacheline_browser__title;
+		browser->he		= he;
+	}
+
+	return browser;
+}
+
+static int perf_c2c__browse_cacheline(struct hist_entry *he)
+{
+	struct c2c_hist_entry *c2c_he;
+	struct c2c_hists *c2c_hists;
+	struct c2c_cacheline_browser *cl_browser;
+	struct hist_browser *browser;
+	int key = -1;
+
+	c2c_he = container_of(he, struct c2c_hist_entry, he);
+	c2c_hists = c2c_he->hists;
+
+	cl_browser = c2c_cacheline_browser__new(&c2c_hists->hists, he);
+	if (cl_browser == NULL)
+		return -1;
+
+	browser = &cl_browser->hb;
+
+	/* reset abort key so that it can get Ctrl-C as a key */
+	SLang_reset_tty();
+	SLang_init_tty(0, 0, 0);
+
+	c2c_browser__update_nr_entries(browser);
+
+	while (1) {
+		key = hist_browser__run(browser, "help");
+
+		switch (key) {
+		case 'q':
+			goto out;
+		default:
+			break;
+		}
+	}
+
+out:
+	free(cl_browser);
+	return 0;
+}
+
 static int perf_c2c_browser__title(struct hist_browser *browser,
 				   char *bf, size_t size)
 {
@@ -1869,6 +1947,9 @@ static int perf_c2c__hists_browse(struct hists *hists)
 		switch (key) {
 		case 'q':
 			goto out;
+		case 'd':
+			perf_c2c__browse_cacheline(browser->he_selection);
+			break;
 		default:
 			break;
 		}
-- 
2.7.4

[toc] | [prev] | [next] | [standalone]


#1489014 — [PATCH 30/57] perf c2c report: Add hitm percent sort key

FromJiri Olsa <jolsa@kernel.org>
Date2016-09-22 17:50 +0200
Subject[PATCH 30/57] perf c2c report: Add hitm percent sort key
Message-ID<skeq5-8dN-7@gated-at.bofh.it>
In reply to#1489004
Adding HITM percent dimension key wrapper.

It is to be displayed in the main cachelines
overall output:

  percent_hitm

It displays HITMs percentage for cacheline.

It counts remote HITMs at the moment, but it
is changed later to support local as well,
based on the sort configuration.

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

diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c
index 11b3db91fce9..e24472f100c6 100644
--- a/tools/perf/builtin-c2c.c
+++ b/tools/perf/builtin-c2c.c
@@ -562,6 +562,83 @@ tot_loads_cmp(struct perf_hpp_fmt *fmt __maybe_unused,
 	return tot_recs_left - tot_recs_right;
 }
 
+typedef double (get_percent_cb)(struct c2c_hist_entry *);
+
+static int
+percent_color(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
+	      struct hist_entry *he, get_percent_cb get_percent)
+{
+	struct c2c_hist_entry *c2c_he;
+	int width = c2c_width(fmt, hpp, he->hists);
+	double per;
+
+	c2c_he = container_of(he, struct c2c_hist_entry, he);
+	per = get_percent(c2c_he);
+
+	return hpp_color_scnprintf(hpp, "%*.2f%%", width - 1, per);
+}
+
+static double percent_hitm(struct c2c_hist_entry *c2c_he)
+{
+	struct c2c_hists *hists;
+	struct c2c_stats *stats;
+	struct c2c_stats *total;
+	int tot, st;
+	double p;
+
+	hists = container_of(c2c_he->he.hists, struct c2c_hists, hists);
+	stats = &c2c_he->stats;
+	total = &hists->stats;
+
+	st  = stats->rmt_hitm;
+	tot = total->rmt_hitm;
+
+	p = tot ? (double) st / tot : 0;
+
+	return 100 * p;
+}
+
+static int
+percent_hitm_entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
+		   struct hist_entry *he)
+{
+	struct c2c_hist_entry *c2c_he;
+	int width = c2c_width(fmt, hpp, he->hists);
+	char buf[10];
+	double per;
+
+	c2c_he = container_of(he, struct c2c_hist_entry, he);
+	per = percent_hitm(c2c_he);
+
+	snprintf(buf, 10, "%.2F%%", per);
+	return snprintf(hpp->buf, hpp->size, "%*s", width, buf);
+}
+
+static int
+percent_hitm_color(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
+		   struct hist_entry *he)
+{
+	return percent_color(fmt, hpp, he, percent_hitm);
+}
+
+static int64_t
+percent_hitm_cmp(struct perf_hpp_fmt *fmt __maybe_unused,
+		 struct hist_entry *left, struct hist_entry *right)
+{
+	struct c2c_hist_entry *c2c_left;
+	struct c2c_hist_entry *c2c_right;
+	double per_left;
+	double per_right;
+
+	c2c_left  = container_of(left, struct c2c_hist_entry, he);
+	c2c_right = container_of(right, struct c2c_hist_entry, he);
+
+	per_left  = percent_hitm(c2c_left);
+	per_right = percent_hitm(c2c_right);
+
+	return per_left - per_right;
+}
+
 #define HEADER_LOW(__h)			\
 	{				\
 		.line[1] = {		\
@@ -765,6 +842,15 @@ static struct c2c_dimension dim_tot_loads = {
 	.width		= 7,
 };
 
+static struct c2c_dimension dim_percent_hitm = {
+	.header		= HEADER_LOW("%hitm"),
+	.name		= "percent_hitm",
+	.cmp		= percent_hitm_cmp,
+	.entry		= percent_hitm_entry,
+	.color		= percent_hitm_color,
+	.width		= 7,
+};
+
 static struct c2c_dimension *dimensions[] = {
 	&dim_dcacheline,
 	&dim_offset,
@@ -787,6 +873,7 @@ static struct c2c_dimension *dimensions[] = {
 	&dim_ld_llcmiss,
 	&dim_tot_recs,
 	&dim_tot_loads,
+	&dim_percent_hitm,
 	NULL,
 };
 
-- 
2.7.4

[toc] | [prev] | [next] | [standalone]


#1489015 — [PATCH 42/57] perf c2c report: Add stdio output support

FromJiri Olsa <jolsa@kernel.org>
Date2016-09-22 17:50 +0200
Subject[PATCH 42/57] perf c2c report: Add stdio output support
Message-ID<skeq6-8dN-21@gated-at.bofh.it>
In reply to#1489004
Adding the --stdio option output support. The output
tables are dumped directly to the stdio.

$ perf c2c report
  =================================================
             Shared Data Cache Line Table
  =================================================
  #
  #                       Total           ----- LLC Load Hitm -----  ---- Store Reference ----  --- Load Dram ----      LLC    Total  ----- Core Load Hit -----  -- LLC Load Hit --
  #          Cacheline  records    %hitm    Total      Lcl      Rmt    Total    L1Hit   L1Miss       Lcl       Rmt  Ld Miss    Loads       FB       L1       L2       Llc       Rmt
  # ..................  .......  .......  .......  .......  .......  .......  .......  .......  ........  ........  .......  .......  .......  .......  .......  ........  ........
  #
    0xffff88000235f840       17    0.00%        0        0        0       17       17        0         0         0        0        0        0        0        0         0         0
  ...

  =================================================
        Shared Cache Line Distribution Pareto
  =================================================
  #
  # ----- HITM -----  -- Store Refs --        Data address                                  ---------- cycles ----------       cpu                                   Shared
  #     Rmt      Lcl   L1 Hit  L1 Miss              Offset      Pid                    Tid  rmt hitm  lcl hitm      load       cnt                Symbol             Object  Node
  # .......  .......  .......  .......  ..................  .......  .....................  ........  ........  ........  ........  ....................  .................  ....
  #
    ------------------------------------------------------
          0        0       17        0  0xffff88000235f840
    ------------------------------------------------------
      0.00%    0.00%    5.88%    0.00%                 0x0    11474    11474:kworker/u16:5         0         0         0         1  [k] rmap_walk_file             [kernel.kallsyms]   0
      0.00%    0.00%    5.88%    0.00%                0x10    11474    11474:kworker/u16:5         0         0         0         1  [k] lock_page_memcg            [kernel.kallsyms]   0
      0.00%    0.00%   11.76%    0.00%                0x20    11474    11474:kworker/u16:5         0         0         0         1  [k] page_mapping               [kernel.kallsyms]   0
      0.00%    0.00%   64.71%    0.00%                0x28    11474    11474:kworker/u16:5         0         0         0         1  [k] __test_set_page_writeback  [kernel.kallsyms]   0
      0.00%    0.00%   11.76%    0.00%                0x30    11474    11474:kworker/u16:5         0         0         0         1  [k] page_mapped                [kernel.kallsyms]   0
  ...

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

diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c
index b7404387faf7..add27479cc23 100644
--- a/tools/perf/builtin-c2c.c
+++ b/tools/perf/builtin-c2c.c
@@ -13,6 +13,7 @@
 #include "tool.h"
 #include "data.h"
 #include "sort.h"
+#include <asm/bug.h>
 
 struct c2c_hists {
 	struct hists		hists;
@@ -1719,6 +1720,85 @@ static int setup_nodes(struct perf_session *session)
 	return 0;
 }
 
+static void print_cacheline(struct c2c_hists *c2c_hists,
+			    struct hist_entry *he_cl,
+			    struct perf_hpp_list *hpp_list,
+			    FILE *out)
+{
+	char bf[1000];
+	struct perf_hpp hpp = {
+		.buf            = bf,
+		.size           = 1000,
+	};
+	static bool once;
+
+	if (!once) {
+		hists__fprintf_headers(&c2c_hists->hists, out);
+		once = true;
+	} else {
+		fprintf(out, "\n");
+	}
+
+	fprintf(out, "  ------------------------------------------------------\n");
+	__hist_entry__snprintf(he_cl, &hpp, hpp_list);
+	fprintf(out, "%s\n", bf);
+	fprintf(out, "  ------------------------------------------------------\n");
+
+	hists__fprintf(&c2c_hists->hists, false, 0, 0, 0, out, true);
+}
+
+static void print_pareto(FILE *out)
+{
+	struct perf_hpp_list hpp_list;
+	struct rb_node *nd;
+	int ret;
+
+	perf_hpp_list__init(&hpp_list);
+	ret = hpp_list__parse(&hpp_list,
+				"cl_rmt_hitm,"
+				"cl_lcl_hitm,"
+				"cl_stores_l1hit,"
+				"cl_stores_l1miss,"
+				"dcacheline",
+				NULL);
+
+	if (WARN_ONCE(ret, "failed to setup sort entries\n"))
+		return;
+
+	nd = rb_first(&c2c.hists.hists.entries);
+
+	for (; nd; nd = rb_next(nd)) {
+		struct hist_entry *he = rb_entry(nd, struct hist_entry, rb_node);
+		struct c2c_hist_entry *c2c_he;
+
+		if (he->filtered)
+			continue;
+
+		c2c_he = container_of(he, struct c2c_hist_entry, he);
+		print_cacheline(c2c_he->hists, he, &hpp_list, out);
+	}
+}
+
+static void perf_c2c__hists_fprintf(FILE *out)
+{
+	setup_pager();
+
+	fprintf(out, "\n");
+	fprintf(out, "=================================================\n");
+	fprintf(out, "           Shared Data Cache Line Table          \n");
+	fprintf(out, "=================================================\n");
+	fprintf(out, "#\n");
+
+	hists__fprintf(&c2c.hists.hists, true, 0, 0, 0, stdout, false);
+
+	fprintf(out, "\n");
+	fprintf(out, "=================================================\n");
+	fprintf(out, "      Shared Cache Line Distribution Pareto      \n");
+	fprintf(out, "=================================================\n");
+	fprintf(out, "#\n");
+
+	print_pareto(out);
+}
 
 static int perf_c2c__report(int argc, const char **argv)
 {
@@ -1803,6 +1883,9 @@ static int perf_c2c__report(int argc, const char **argv)
 
 	ui_progress__finish();
 
+	use_browser = 0;
+	perf_c2c__hists_fprintf(stdout);
+
 out_session:
 	perf_session__delete(session);
 out:
-- 
2.7.4

[toc] | [prev] | [next] | [standalone]


#1489016 — [PATCH 53/57] perf c2c report: Add cacheline index entry

FromJiri Olsa <jolsa@kernel.org>
Date2016-09-22 17:50 +0200
Subject[PATCH 53/57] perf c2c report: Add cacheline index entry
Message-ID<skeq5-8dN-5@gated-at.bofh.it>
In reply to#1489004
It's convenient to have an index for each cacheline to
help discussions about results over the phone.

Add new 'Index' and 'Num' fields in main and single
cacheline tables.

$ perf c2c report
  =================================================
             Shared Data Cache Line Table
  =================================================
  #
  #                              Total      Lcl  ----- LLC Load Hitm -----
  # Index           Cacheline  records     Hitm    Total      Lcl      Rmt  ...
  # .....  ..................  .......  .......  .......  .......  .......
  #
        0  0xffff880036233b40        1   11.11%        1        1        0
        1  0xffff88009ccb2900        1   11.11%        1        1        0
        2  0xffff8800b5b3bc40        7   11.11%        1        1        0
  ...

  =================================================
        Shared Cache Line Distribution Pareto
  =================================================
  #
  #        ----- HITM -----  -- Store Refs --        Data address
  #   Num      Rmt      Lcl   L1 Hit  L1 Miss              Offset      Pid  ...
  # .....  .......  .......  .......  .......  ..................  .......
  #
    -------------------------------------------------------------
        0        0        1        0        0  0xffff880036233b40
    -------------------------------------------------------------
             0.00%  100.00%    0.00%    0.00%                0x30        0

    -------------------------------------------------------------
        1        0        1        0        0  0xffff88009ccb2900
    -------------------------------------------------------------
             0.00%  100.00%    0.00%    0.00%                0x28      549
  ...

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

diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c
index c7fe81d49016..f39947d29765 100644
--- a/tools/perf/builtin-c2c.c
+++ b/tools/perf/builtin-c2c.c
@@ -36,6 +36,7 @@ struct c2c_hist_entry {
 	struct c2c_stats	 stats;
 	unsigned long		*cpuset;
 	struct c2c_stats	*node_stats;
+	unsigned int		 cacheline_idx;
 
 	struct compute_stats	 cstats;
 
@@ -1085,6 +1086,29 @@ cpucnt_entry(struct perf_hpp_fmt *fmt __maybe_unused, struct perf_hpp *hpp,
 	return snprintf(hpp->buf, hpp->size, "%*s", width, buf);
 }
 
+static int
+cl_idx_entry(struct perf_hpp_fmt *fmt __maybe_unused, struct perf_hpp *hpp,
+	     struct hist_entry *he)
+{
+	struct c2c_hist_entry *c2c_he;
+	int width = c2c_width(fmt, hpp, he->hists);
+	char buf[10];
+
+	c2c_he = container_of(he, struct c2c_hist_entry, he);
+
+	snprintf(buf, 10, "%u", c2c_he->cacheline_idx);
+	return snprintf(hpp->buf, hpp->size, "%*s", width, buf);
+}
+
+static int
+cl_idx_empty_entry(struct perf_hpp_fmt *fmt __maybe_unused, struct perf_hpp *hpp,
+		   struct hist_entry *he)
+{
+	int width = c2c_width(fmt, hpp, he->hists);
+
+	return snprintf(hpp->buf, hpp->size, "%*s", width, "");
+}
+
 #define HEADER_LOW(__h)			\
 	{				\
 		.line[1] = {		\
@@ -1430,6 +1454,30 @@ static struct c2c_dimension dim_srcline = {
 	.se		= &sort_srcline,
 };
 
+static struct c2c_dimension dim_dcacheline_idx = {
+	.header		= HEADER_LOW("Index"),
+	.name		= "cl_idx",
+	.cmp		= empty_cmp,
+	.entry		= cl_idx_entry,
+	.width		= 5,
+};
+
+static struct c2c_dimension dim_dcacheline_num = {
+	.header		= HEADER_LOW("Num"),
+	.name		= "cl_num",
+	.cmp		= empty_cmp,
+	.entry		= cl_idx_entry,
+	.width		= 5,
+};
+
+static struct c2c_dimension dim_dcacheline_num_empty = {
+	.header		= HEADER_LOW("Num"),
+	.name		= "cl_num_empty",
+	.cmp		= empty_cmp,
+	.entry		= cl_idx_empty_entry,
+	.width		= 5,
+};
+
 static struct c2c_dimension *dimensions[] = {
 	&dim_dcacheline,
 	&dim_offset,
@@ -1469,6 +1517,9 @@ static struct c2c_dimension *dimensions[] = {
 	&dim_mean_load,
 	&dim_cpucnt,
 	&dim_srcline,
+	&dim_dcacheline_idx,
+	&dim_dcacheline_num,
+	&dim_dcacheline_num_empty,
 	NULL,
 };
 
@@ -1755,6 +1806,10 @@ static int resort_cl_cb(struct hist_entry *he)
 	calc_width(he);
 
 	if (display && c2c_hists) {
+		static unsigned int idx;
+
+		c2c_he->cacheline_idx = idx++;
+
 		c2c_hists__reinit(c2c_hists, c2c.cl_output, c2c.cl_resort);
 
 		hists__collapse_resort(&c2c_hists->hists, NULL);
@@ -1942,10 +1997,10 @@ static void print_cacheline(struct c2c_hists *c2c_hists,
 		fprintf(out, "\n");
 	}
 
-	fprintf(out, "  ------------------------------------------------------\n");
+	fprintf(out, "  -------------------------------------------------------------\n");
 	__hist_entry__snprintf(he_cl, &hpp, hpp_list);
 	fprintf(out, "%s\n", bf);
-	fprintf(out, "  ------------------------------------------------------\n");
+	fprintf(out, "  -------------------------------------------------------------\n");
 
 	hists__fprintf(&c2c_hists->hists, false, 0, 0, 0, out, true);
 }
@@ -1958,6 +2013,7 @@ static void print_pareto(FILE *out)
 
 	perf_hpp_list__init(&hpp_list);
 	ret = hpp_list__parse(&hpp_list,
+				"cl_num,"
 				"cl_rmt_hitm,"
 				"cl_lcl_hitm,"
 				"cl_stores_l1hit,"
@@ -2315,7 +2371,8 @@ static int build_cl_output(char *cl_sort)
 	}
 
 	if (asprintf(&c2c.cl_output,
-		"%s%s%s%s%s%s%s%s%s",
+		"%s%s%s%s%s%s%s%s%s%s",
+		c2c.use_stdio ? "cl_num_empty," : "",
 		"percent_rmt_hitm,"
 		"percent_lcl_hitm,"
 		"percent_stores_l1hit,"
@@ -2464,6 +2521,7 @@ static int perf_c2c__report(int argc, const char **argv)
 	}
 
 	c2c_hists__reinit(&c2c.hists,
+			"cl_idx,"
 			"dcacheline,"
 			"tot_recs,"
 			"percent_hitm,"
-- 
2.7.4

[toc] | [prev] | [next] | [standalone]


#1489017 — [PATCH 47/57] perf c2c report: Add c2c related stats stdio output

FromJiri Olsa <jolsa@kernel.org>
Date2016-09-22 17:50 +0200
Subject[PATCH 47/57] perf c2c report: Add c2c related stats stdio output
Message-ID<skeq6-8dN-13@gated-at.bofh.it>
In reply to#1489004
Display c2c related configuration options/setup.
So far it's output of monitored events:

  $ perf c2c report --stats
  ...

  =================================================
                   c2c details
  =================================================
    Events                            : cpu/mem-loads,ldlat=50/pp
                                      : cpu/mem-stores/pp

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

diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c
index e85343e4ffe7..71b6850809a2 100644
--- a/tools/perf/builtin-c2c.c
+++ b/tools/perf/builtin-c2c.c
@@ -13,6 +13,8 @@
 #include "tool.h"
 #include "data.h"
 #include "sort.h"
+#include "evlist.h"
+#include "evsel.h"
 #include <asm/bug.h>
 #include "ui/browsers/hists.h"
 
@@ -1890,13 +1892,32 @@ static void print_pareto(FILE *out)
 	}
 }
 
-static void perf_c2c__hists_fprintf(FILE *out)
+static void print_c2c_info(FILE *out, struct perf_session *session)
+{
+	struct perf_evlist *evlist = session->evlist;
+	struct perf_evsel *evsel;
+	bool first = true;
+
+	fprintf(out, "=================================================\n");
+	fprintf(out, "                 c2c details                     \n");
+	fprintf(out, "=================================================\n");
+
+	evlist__for_each_entry(evlist, evsel) {
+		fprintf(out, "%-36s: %s\n", first ? "  Events" : "",
+			perf_evsel__name(evsel));
+		first = false;
+	}
+}
+
+static void perf_c2c__hists_fprintf(FILE *out, struct perf_session *session)
 {
 	setup_pager();
 
 	print_c2c__display_stats(out);
 	fprintf(out, "\n");
 	print_shared_cacheline_info(out);
+	fprintf(out, "\n");
+	print_c2c_info(out, session);
 
 	if (c2c.stats_only)
 		return;
@@ -2070,18 +2091,18 @@ out:
 	return 0;
 }
 
-static void perf_c2c_display(void)
+static void perf_c2c_display(struct perf_session *session)
 {
 	if (c2c.use_stdio)
-		perf_c2c__hists_fprintf(stdout);
+		perf_c2c__hists_fprintf(stdout, session);
 	else
 		perf_c2c__hists_browse(&c2c.hists.hists);
 }
 #else
-static void perf_c2c_display(void)
+static void perf_c2c_display(struct perf_session *session)
 {
 	use_browser = 0;
-	perf_c2c__hists_fprintf(stdout);
+	perf_c2c__hists_fprintf(stdout, session);
 }
 #endif /* HAVE_SLANG_SUPPORT */
 
@@ -2194,7 +2215,7 @@ static int perf_c2c__report(int argc, const char **argv)
 
 	ui_quirks();
 
-	perf_c2c_display();
+	perf_c2c_display(session);
 
 out_session:
 	perf_session__delete(session);
-- 
2.7.4

[toc] | [prev] | [next] | [standalone]


#1489018 — [PATCH 24/57] perf c2c report: Add stores related dimension keys

FromJiri Olsa <jolsa@kernel.org>
Date2016-09-22 17:50 +0200
Subject[PATCH 24/57] perf c2c report: Add stores related dimension keys
Message-ID<skeq6-8dN-29@gated-at.bofh.it>
In reply to#1489004
Adding 5 stores related dimension key wrappers.

First 3 are to be displayed in the main cachelines
overall output:

  stores, stores_l1hit, stores_l1miss

The latter 2 are to be displayed within single
cacheline output:

  cl_stores_l1hit, cl_stores_l1miss

They all display bare numbers of stores for
cacheline or its related offsets.

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

diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c
index 06c4d3e92ed2..7c62a749eaca 100644
--- a/tools/perf/builtin-c2c.c
+++ b/tools/perf/builtin-c2c.c
@@ -409,6 +409,9 @@ __f ## _cmp(struct perf_hpp_fmt *fmt __maybe_unused,			\
 
 STAT_FN(rmt_hitm)
 STAT_FN(lcl_hitm)
+STAT_FN(store)
+STAT_FN(st_l1hit)
+STAT_FN(st_l1miss)
 
 #define HEADER_LOW(__h)			\
 	{				\
@@ -509,6 +512,46 @@ static struct c2c_dimension dim_cl_lcl_hitm = {
 	.width		= 7,
 };
 
+static struct c2c_dimension dim_stores = {
+	.header		= HEADER_SPAN("---- Store Reference ----", "Total", 2),
+	.name		= "stores",
+	.cmp		= store_cmp,
+	.entry		= store_entry,
+	.width		= 7,
+};
+
+static struct c2c_dimension dim_stores_l1hit = {
+	.header		= HEADER_SPAN_LOW("L1Hit"),
+	.name		= "stores_l1hit",
+	.cmp		= st_l1hit_cmp,
+	.entry		= st_l1hit_entry,
+	.width		= 7,
+};
+
+static struct c2c_dimension dim_stores_l1miss = {
+	.header		= HEADER_SPAN_LOW("L1Miss"),
+	.name		= "stores_l1miss",
+	.cmp		= st_l1miss_cmp,
+	.entry		= st_l1miss_entry,
+	.width		= 7,
+};
+
+static struct c2c_dimension dim_cl_stores_l1hit = {
+	.header		= HEADER_SPAN("-- Store Refs --", "L1 Hit", 1),
+	.name		= "cl_stores_l1hit",
+	.cmp		= st_l1hit_cmp,
+	.entry		= st_l1hit_entry,
+	.width		= 7,
+};
+
+static struct c2c_dimension dim_cl_stores_l1miss = {
+	.header		= HEADER_SPAN_LOW("L1 Miss"),
+	.name		= "cl_stores_l1miss",
+	.cmp		= st_l1miss_cmp,
+	.entry		= st_l1miss_entry,
+	.width		= 7,
+};
+
 static struct c2c_dimension *dimensions[] = {
 	&dim_dcacheline,
 	&dim_offset,
@@ -518,6 +561,11 @@ static struct c2c_dimension *dimensions[] = {
 	&dim_rmt_hitm,
 	&dim_cl_lcl_hitm,
 	&dim_cl_rmt_hitm,
+	&dim_stores,
+	&dim_stores_l1hit,
+	&dim_stores_l1miss,
+	&dim_cl_stores_l1hit,
+	&dim_cl_stores_l1miss,
 	NULL,
 };
 
-- 
2.7.4

[toc] | [prev] | [next] | [standalone]


#1489019 — [PATCH 56/57] perf c2c report: Add help windows

FromJiri Olsa <jolsa@kernel.org>
Date2016-09-22 17:50 +0200
Subject[PATCH 56/57] perf c2c report: Add help windows
Message-ID<skeq6-8dN-33@gated-at.bofh.it>
In reply to#1489004
Adding help windows to display key/action mappings
for both browsers.

Link: http://lkml.kernel.org/n/tip-zni4apopx6a9eyxsosm1ebh1@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/builtin-c2c.c | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c
index 3728e6c7d0cd..dce3e32cef75 100644
--- a/tools/perf/builtin-c2c.c
+++ b/tools/perf/builtin-c2c.c
@@ -2175,6 +2175,11 @@ static int perf_c2c__browse_cacheline(struct hist_entry *he)
 	struct c2c_cacheline_browser *cl_browser;
 	struct hist_browser *browser;
 	int key = -1;
+	const char help[] =
+	" ENTER         Togle callchains (if present) \n"
+	" n             Togle Node details info \n"
+	" s             Togle full lenght of symbol and source line columns \n"
+	" q             Return back to cacheline list \n";
 
 	/* Display compact version first. */
 	c2c.symbol_full = false;
@@ -2195,7 +2200,7 @@ static int perf_c2c__browse_cacheline(struct hist_entry *he)
 	c2c_browser__update_nr_entries(browser);
 
 	while (1) {
-		key = hist_browser__run(browser, "help");
+		key = hist_browser__run(browser, "? - help");
 
 		switch (key) {
 		case 's':
@@ -2207,6 +2212,9 @@ static int perf_c2c__browse_cacheline(struct hist_entry *he)
 			break;
 		case 'q':
 			goto out;
+		case '?':
+			ui_browser__help_window(&browser->b, help);
+			break;
 		default:
 			break;
 		}
@@ -2245,6 +2253,10 @@ static int perf_c2c__hists_browse(struct hists *hists)
 {
 	struct hist_browser *browser;
 	int key = -1;
+	const char help[] =
+	" d             Display cacheline details \n"
+	" ENTER         Togle callchains (if present) \n"
+	" q             Quit \n";
 
 	browser = perf_c2c_browser__new(hists);
 	if (browser == NULL)
@@ -2257,7 +2269,7 @@ static int perf_c2c__hists_browse(struct hists *hists)
 	c2c_browser__update_nr_entries(browser);
 
 	while (1) {
-		key = hist_browser__run(browser, "help");
+		key = hist_browser__run(browser, "? - help");
 
 		switch (key) {
 		case 'q':
@@ -2265,6 +2277,9 @@ static int perf_c2c__hists_browse(struct hists *hists)
 		case 'd':
 			perf_c2c__browse_cacheline(browser->he_selection);
 			break;
+		case '?':
+			ui_browser__help_window(&browser->b, help);
+			break;
 		default:
 			break;
 		}
-- 
2.7.4

[toc] | [prev] | [next] | [standalone]


#1489021 — [PATCH 31/57] perf c2c report: Add hitm/store percent related sort keys

FromJiri Olsa <jolsa@kernel.org>
Date2016-09-22 17:50 +0200
Subject[PATCH 31/57] perf c2c report: Add hitm/store percent related sort keys
Message-ID<skeq6-8dN-35@gated-at.bofh.it>
In reply to#1489004
Adding hitm/store percent dimension key wrappers.

They are to be displayed in the single cacheline output:

  percent_rmt_hitm, percent_lcl_hitm, percent_stores_l1hit, percent_stores_l1miss

They display percentage of HITMs/stores for specific
offset in the cacheline.

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

diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c
index e24472f100c6..b2992cf96130 100644
--- a/tools/perf/builtin-c2c.c
+++ b/tools/perf/builtin-c2c.c
@@ -639,6 +639,171 @@ percent_hitm_cmp(struct perf_hpp_fmt *fmt __maybe_unused,
 	return per_left - per_right;
 }
 
+static struct c2c_stats *he_stats(struct hist_entry *he)
+{
+	struct c2c_hist_entry *c2c_he;
+
+	c2c_he = container_of(he, struct c2c_hist_entry, he);
+	return &c2c_he->stats;
+}
+
+static struct c2c_stats *total_stats(struct hist_entry *he)
+{
+	struct c2c_hists *hists;
+
+	hists = container_of(he->hists, struct c2c_hists, hists);
+	return &hists->stats;
+}
+
+static double percent(int st, int tot)
+{
+	return tot ? 100. * (double) st / (double) tot : 0;
+}
+
+#define PERCENT(__h, __f) percent(he_stats(__h)->__f, total_stats(__h)->__f)
+
+#define PERCENT_FN(__f)								\
+static double percent_ ## __f(struct c2c_hist_entry *c2c_he)			\
+{										\
+	struct c2c_hists *hists;						\
+										\
+	hists = container_of(c2c_he->he.hists, struct c2c_hists, hists);	\
+	return percent(c2c_he->stats.__f, hists->stats.__f);			\
+}
+
+PERCENT_FN(rmt_hitm)
+PERCENT_FN(lcl_hitm)
+PERCENT_FN(st_l1hit)
+PERCENT_FN(st_l1miss)
+
+static int
+percent_rmt_hitm_entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
+		       struct hist_entry *he)
+{
+	int width = c2c_width(fmt, hpp, he->hists);
+	double per = PERCENT(he, rmt_hitm);
+	char buf[10];
+
+	snprintf(buf, 10, "%.2F%%", per);
+	return snprintf(hpp->buf, hpp->size, "%*s", width, buf);
+}
+
+static int
+percent_rmt_hitm_color(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
+		       struct hist_entry *he)
+{
+	return percent_color(fmt, hpp, he, percent_rmt_hitm);
+}
+
+static int64_t
+percent_rmt_hitm_cmp(struct perf_hpp_fmt *fmt __maybe_unused,
+		     struct hist_entry *left, struct hist_entry *right)
+{
+	double per_left;
+	double per_right;
+
+	per_left  = PERCENT(left, lcl_hitm);
+	per_right = PERCENT(right, lcl_hitm);
+
+	return per_left - per_right;
+}
+
+static int
+percent_lcl_hitm_entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
+		       struct hist_entry *he)
+{
+	int width = c2c_width(fmt, hpp, he->hists);
+	double per = PERCENT(he, lcl_hitm);
+	char buf[10];
+
+	snprintf(buf, 10, "%.2F%%", per);
+	return snprintf(hpp->buf, hpp->size, "%*s", width, buf);
+}
+
+static int
+percent_lcl_hitm_color(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
+		       struct hist_entry *he)
+{
+	return percent_color(fmt, hpp, he, percent_lcl_hitm);
+}
+
+static int64_t
+percent_lcl_hitm_cmp(struct perf_hpp_fmt *fmt __maybe_unused,
+		     struct hist_entry *left, struct hist_entry *right)
+{
+	double per_left;
+	double per_right;
+
+	per_left  = PERCENT(left, lcl_hitm);
+	per_right = PERCENT(right, lcl_hitm);
+
+	return per_left - per_right;
+}
+
+static int
+percent_stores_l1hit_entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
+			   struct hist_entry *he)
+{
+	int width = c2c_width(fmt, hpp, he->hists);
+	double per = PERCENT(he, st_l1hit);
+	char buf[10];
+
+	snprintf(buf, 10, "%.2F%%", per);
+	return snprintf(hpp->buf, hpp->size, "%*s", width, buf);
+}
+
+static int
+percent_stores_l1hit_color(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
+			   struct hist_entry *he)
+{
+	return percent_color(fmt, hpp, he, percent_st_l1hit);
+}
+
+static int64_t
+percent_stores_l1hit_cmp(struct perf_hpp_fmt *fmt __maybe_unused,
+			struct hist_entry *left, struct hist_entry *right)
+{
+	double per_left;
+	double per_right;
+
+	per_left  = PERCENT(left, st_l1hit);
+	per_right = PERCENT(right, st_l1hit);
+
+	return per_left - per_right;
+}
+
+static int
+percent_stores_l1miss_entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
+			   struct hist_entry *he)
+{
+	int width = c2c_width(fmt, hpp, he->hists);
+	double per = PERCENT(he, st_l1miss);
+	char buf[10];
+
+	snprintf(buf, 10, "%.2F%%", per);
+	return snprintf(hpp->buf, hpp->size, "%*s", width, buf);
+}
+
+static int
+percent_stores_l1miss_color(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
+			    struct hist_entry *he)
+{
+	return percent_color(fmt, hpp, he, percent_st_l1miss);
+}
+
+static int64_t
+percent_stores_l1miss_cmp(struct perf_hpp_fmt *fmt __maybe_unused,
+			  struct hist_entry *left, struct hist_entry *right)
+{
+	double per_left;
+	double per_right;
+
+	per_left  = PERCENT(left, st_l1miss);
+	per_right = PERCENT(right, st_l1miss);
+
+	return per_left - per_right;
+}
+
 #define HEADER_LOW(__h)			\
 	{				\
 		.line[1] = {		\
@@ -851,6 +1016,42 @@ static struct c2c_dimension dim_percent_hitm = {
 	.width		= 7,
 };
 
+static struct c2c_dimension dim_percent_rmt_hitm = {
+	.header		= HEADER_SPAN("----- HITM -----", "Rmt", 1),
+	.name		= "percent_rmt_hitm",
+	.cmp		= percent_rmt_hitm_cmp,
+	.entry		= percent_rmt_hitm_entry,
+	.color		= percent_rmt_hitm_color,
+	.width		= 7,
+};
+
+static struct c2c_dimension dim_percent_lcl_hitm = {
+	.header		= HEADER_SPAN_LOW("Lcl"),
+	.name		= "percent_lcl_hitm",
+	.cmp		= percent_lcl_hitm_cmp,
+	.entry		= percent_lcl_hitm_entry,
+	.color		= percent_lcl_hitm_color,
+	.width		= 7,
+};
+
+static struct c2c_dimension dim_percent_stores_l1hit = {
+	.header		= HEADER_SPAN("-- Store Refs --", "L1 Hit", 1),
+	.name		= "percent_stores_l1hit",
+	.cmp		= percent_stores_l1hit_cmp,
+	.entry		= percent_stores_l1hit_entry,
+	.color		= percent_stores_l1hit_color,
+	.width		= 7,
+};
+
+static struct c2c_dimension dim_percent_stores_l1miss = {
+	.header		= HEADER_SPAN_LOW("L1 Miss"),
+	.name		= "percent_stores_l1miss",
+	.cmp		= percent_stores_l1miss_cmp,
+	.entry		= percent_stores_l1miss_entry,
+	.color		= percent_stores_l1miss_color,
+	.width		= 7,
+};
+
 static struct c2c_dimension *dimensions[] = {
 	&dim_dcacheline,
 	&dim_offset,
@@ -874,6 +1075,10 @@ static struct c2c_dimension *dimensions[] = {
 	&dim_tot_recs,
 	&dim_tot_loads,
 	&dim_percent_hitm,
+	&dim_percent_rmt_hitm,
+	&dim_percent_lcl_hitm,
+	&dim_percent_stores_l1hit,
+	&dim_percent_stores_l1miss,
 	NULL,
 };
 
@@ -961,6 +1166,7 @@ static struct c2c_fmt *get_format(const char *name)
 
 	fmt->cmp	= dim->se ? c2c_se_cmp   : dim->cmp;
 	fmt->sort	= dim->se ? c2c_se_cmp   : dim->cmp;
+	fmt->color	= dim->se ? NULL	 : dim->color;
 	fmt->entry	= dim->se ? c2c_se_entry : dim->entry;
 	fmt->header	= c2c_header;
 	fmt->width	= c2c_width;
-- 
2.7.4

[toc] | [prev] | [next] | [standalone]


#1489022 — [PATCH 22/57] perf c2c report: Add iaddr dimension key

FromJiri Olsa <jolsa@kernel.org>
Date2016-09-22 17:50 +0200
Subject[PATCH 22/57] perf c2c report: Add iaddr dimension key
Message-ID<skeq6-8dN-39@gated-at.bofh.it>
In reply to#1489004
Adding iaddr dimension key support. It displays
code address (as hex number) responsible for the
accesses.

Using c2c wrapper to standard 'symbol_iaddr' object
to define own header and simple (just address) code
address output.

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

diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c
index 7c52481ec36b..a2881677c315 100644
--- a/tools/perf/builtin-c2c.c
+++ b/tools/perf/builtin-c2c.c
@@ -326,6 +326,26 @@ offset_cmp(struct perf_hpp_fmt *fmt __maybe_unused,
 	return (int64_t)(r - l);
 }
 
+static int
+iaddr_entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
+	    struct hist_entry *he)
+{
+	uint64_t addr = 0;
+	int width = c2c_width(fmt, hpp, he->hists);
+
+	if (he->mem_info)
+		addr = he->mem_info->iaddr.addr;
+
+	return snprintf(hpp->buf, hpp->size, "%*s", width, hex_str(addr));
+}
+
+static int64_t
+iaddr_cmp(struct perf_hpp_fmt *fmt __maybe_unused,
+	  struct hist_entry *left, struct hist_entry *right)
+{
+	return sort__iaddr_cmp(left, right);
+}
+
 #define HEADER_LOW(__h)			\
 	{				\
 		.line[1] = {		\
@@ -377,9 +397,18 @@ static struct c2c_dimension dim_offset = {
 	.width		= 18,
 };
 
+static struct c2c_dimension dim_iaddr = {
+	.header		= HEADER_LOW("Code address"),
+	.name		= "iaddr",
+	.cmp		= iaddr_cmp,
+	.entry		= iaddr_entry,
+	.width		= 18,
+};
+
 static struct c2c_dimension *dimensions[] = {
 	&dim_dcacheline,
 	&dim_offset,
+	&dim_iaddr,
 	NULL,
 };
 
-- 
2.7.4

[toc] | [prev] | [next] | [standalone]


Page 1 of 3  [1] 2 3  Next page →

Back to top | Article view | linux.kernel


csiph-web